Index: fnmatch.py =================================================================== --- fnmatch.py (revision 83087) +++ fnmatch.py (working copy) @@ -10,19 +10,23 @@ corresponding to PATTERN. (It does not compile it.) """ +import os +import posixpath import re __all__ = ["filter", "fnmatch", "fnmatchcase", "translate"] -_cache = {} # Maps text patterns to compiled regexen. -_cacheb = {} # Ditto for bytes patterns. -_MAXCACHE = 100 # Maximum size of caches +_cache = {} # Maps text patterns to compiled regexen +_cacheb = {} # Ditto for bytes patterns +_MAXCACHE = 100 # Maximum size of caches + def _purge(): - """Clear the pattern cache""" + """Clear the pattern cache.""" _cache.clear() _cacheb.clear() + def fnmatch(name, pat): """Test whether FILENAME matches PATTERN. @@ -44,6 +48,7 @@ pat = os.path.normcase(pat) return fnmatchcase(name, pat) + def _compile_pattern(pat): cache = _cacheb if isinstance(pat, bytes) else _cache regex = cache.get(pat) @@ -59,9 +64,9 @@ cache[pat] = regex = re.compile(res) return regex.match + def filter(names, pat): - """Return the subset of the list NAMES that match PAT""" - import os,posixpath + """Return the subset of the list NAMES that match PAT.""" result = [] pat = os.path.normcase(pat) match = _compile_pattern(pat) @@ -76,6 +81,7 @@ result.append(name) return result + def fnmatchcase(name, pat): """Test whether FILENAME matches PATTERN, including case. @@ -86,6 +92,7 @@ match = _compile_pattern(pat) return match(name) is not None + def translate(pat): """Translate a shell PATTERN to a regular expression. Index: test/test_fnmatch.py =================================================================== --- test/test_fnmatch.py (revision 83087) +++ test/test_fnmatch.py (working copy) @@ -3,7 +3,8 @@ from test import support import unittest -from fnmatch import fnmatch, fnmatchcase, _MAXCACHE, _cache, _cacheb, _purge +from fnmatch import (fnmatch, fnmatchcase, _MAXCACHE, _cache, _cacheb, _purge, + translate, filter) class FnmatchTestCase(unittest.TestCase): @@ -75,8 +76,29 @@ self.assertLessEqual(len(_cacheb), _MAXCACHE) +class TranslateTestCase(unittest.TestCase): + + def test_translate(self): + self.assertEqual(translate('*'), '.*\Z(?ms)') + self.assertEqual(translate('?'), '.\Z(?ms)') + self.assertEqual(translate('a?b*'), 'a.b.*\Z(?ms)') + self.assertEqual(translate('[abc]'), '[abc]\Z(?ms)') + self.assertEqual(translate('[]]'), '[]]\Z(?ms)') + self.assertEqual(translate('[!x]'), '[^x]\Z(?ms)') + self.assertEqual(translate('[^x]'), '[\\^x]\Z(?ms)') + self.assertEqual(translate('[x'), '\\[x\Z(?ms)') + + +class FilterTestCase(unittest.TestCase): + + def test_filter(self): + self.assertEqual(filter(['a', 'b'], 'a'), ['a']) + + def test_main(): support.run_unittest(FnmatchTestCase) + support.run_unittest(TranslateTestCase) + support.run_unittest(FilterTestCase) if __name__ == "__main__":