__all__ = ["filter", "fnmatch","fnmatchcase","translate"]
_cache = {}
+_MAXCACHE = 100
def fnmatch(name, pat):
"""Test whether FILENAME matches PATTERN.
pat=os.path.normcase(pat)
if not pat in _cache:
res = translate(pat)
+ if len(_cache) >= _MAXCACHE:
+ _cache.clear()
_cache[pat] = re.compile(res)
match=_cache[pat].match
if os.path is posixpath:
if not pat in _cache:
res = translate(pat)
+ if len(_cache) >= _MAXCACHE:
+ _cache.clear()
_cache[pat] = re.compile(res)
return _cache[pat].match(name) is not None
from test import test_support
import unittest
-from fnmatch import fnmatch, fnmatchcase
+from fnmatch import fnmatch, fnmatchcase, _MAXCACHE, _cache
class FnmatchTestCase(unittest.TestCase):
check('AbC', 'abc', 0, fnmatchcase)
check('abc', 'AbC', 0, fnmatchcase)
+ def test_cache_clearing(self):
+ # check that caches do not grow too large
+ # http://bugs.python.org/issue7846
+
+ # string pattern cache
+ for i in range(_MAXCACHE + 1):
+ fnmatch('foo', '?' * i)
+
+ self.assertTrue(len(_cache) <= _MAXCACHE)
def test_main():
test_support.run_unittest(FnmatchTestCase)
Library
-------
+- Issue #7646: The fnmatch pattern cache no longer grows without bound.
+
- Issue #9136: Fix 'dictionary changed size during iteration'
RuntimeError produced when profiling the decimal module. This was
due to a dangerous iteration over 'locals()' in Context.__init__.