Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6fdb74f

Browse files
committed
Re-apply r83871.
1 parent e81c806 commit 6fdb74f

3 files changed

Lines changed: 14 additions & 60 deletions

File tree

Doc/library/fnmatch.rst

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,6 @@ patterns.
8484
<_sre.SRE_Match object at 0x...>
8585

8686

87-
.. function:: purge()
88-
89-
Clear the internal pattern cache.
90-
91-
.. versionadded:: 3.2
92-
93-
9487
.. seealso::
9588

9689
Module :mod:`glob`

Lib/fnmatch.py

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,9 @@
1212
import os
1313
import posixpath
1414
import re
15+
import functools
1516

16-
__all__ = ["filter", "fnmatch", "fnmatchcase", "purge", "translate"]
17-
18-
_cache = {} # Maps text patterns to compiled regexen.
19-
_cacheb = {} # Ditto for bytes patterns.
20-
_MAXCACHE = 100 # Maximum size of caches.
21-
22-
23-
def purge():
24-
"""Clear the pattern cache."""
25-
_cache.clear()
26-
_cacheb.clear()
27-
17+
__all__ = ["filter", "fnmatch", "fnmatchcase", "translate"]
2818

2919
def fnmatch(name, pat):
3020
"""Test whether FILENAME matches PATTERN.
@@ -45,28 +35,21 @@ def fnmatch(name, pat):
4535
pat = os.path.normcase(pat)
4636
return fnmatchcase(name, pat)
4737

48-
49-
def _compile_pattern(pat):
50-
cache = _cacheb if isinstance(pat, bytes) else _cache
51-
regex = cache.get(pat)
52-
if regex is None:
53-
if isinstance(pat, bytes):
54-
pat_str = str(pat, 'ISO-8859-1')
55-
res_str = translate(pat_str)
56-
res = bytes(res_str, 'ISO-8859-1')
57-
else:
58-
res = translate(pat)
59-
if len(cache) >= _MAXCACHE:
60-
cache.clear()
61-
cache[pat] = regex = re.compile(res)
62-
return regex.match
63-
38+
@functools.lru_cache(maxsize=250)
39+
def _compile_pattern(pat, is_bytes=False):
40+
if is_bytes:
41+
pat_str = str(pat, 'ISO-8859-1')
42+
res_str = translate(pat_str)
43+
res = bytes(res_str, 'ISO-8859-1')
44+
else:
45+
res = translate(pat)
46+
return re.compile(res).match
6447

6548
def filter(names, pat):
6649
"""Return the subset of the list NAMES that match PAT."""
6750
result = []
6851
pat = os.path.normcase(pat)
69-
match = _compile_pattern(pat)
52+
match = _compile_pattern(pat, isinstance(pat, bytes))
7053
if os.path is posixpath:
7154
# normcase on posix is NOP. Optimize it away from the loop.
7255
for name in names:
@@ -78,14 +61,13 @@ def filter(names, pat):
7861
result.append(name)
7962
return result
8063

81-
8264
def fnmatchcase(name, pat):
8365
"""Test whether FILENAME matches PATTERN, including case.
8466
8567
This is a version of fnmatch() which doesn't case-normalize
8668
its arguments.
8769
"""
88-
match = _compile_pattern(pat)
70+
match = _compile_pattern(pat, isinstance(pat, bytes))
8971
return match(name) is not None
9072

9173

Lib/test/test_fnmatch.py

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,10 @@
33
from test import support
44
import unittest
55

6-
from fnmatch import (fnmatch, fnmatchcase, _MAXCACHE, _cache, _cacheb, purge,
7-
translate, filter)
8-
6+
from fnmatch import fnmatch, fnmatchcase, translate, filter
97

108
class FnmatchTestCase(unittest.TestCase):
119

12-
def tearDown(self):
13-
purge()
14-
1510
def check_match(self, filename, pattern, should_match=1, fn=fnmatch):
1611
if should_match:
1712
self.assertTrue(fn(filename, pattern),
@@ -65,22 +60,6 @@ def test_bytes(self):
6560
self.check_match(b'test\xff', b'te*\xff')
6661
self.check_match(b'foo\nbar', b'foo*')
6762

68-
def test_cache_clearing(self):
69-
# check that caches do not grow too large
70-
# http://bugs.python.org/issue7846
71-
72-
# string pattern cache
73-
for i in range(_MAXCACHE + 1):
74-
fnmatch('foo', '?' * i)
75-
76-
self.assertLessEqual(len(_cache), _MAXCACHE)
77-
78-
# bytes pattern cache
79-
for i in range(_MAXCACHE + 1):
80-
fnmatch(b'foo', b'?' * i)
81-
self.assertLessEqual(len(_cacheb), _MAXCACHE)
82-
83-
8463
class TranslateTestCase(unittest.TestCase):
8564

8665
def test_translate(self):

0 commit comments

Comments
 (0)