1616
1717__all__ = ["filter" , "fnmatch" , "fnmatchcase" , "translate" ]
1818
19- # Build a thread-safe incrementing counter to help create unique regexp group
20- # names across calls.
21- from itertools import count
22- _nextgroupnum = count ().__next__
23- del count
24-
2519def fnmatch (name , pat ):
2620 """Test whether FILENAME matches PATTERN.
2721
@@ -149,17 +143,10 @@ def translate(pat):
149143 # Now deal with STAR fixed STAR fixed ...
150144 # For an interior `STAR fixed` pairing, we want to do a minimal
151145 # .*? match followed by `fixed`, with no possibility of backtracking.
152- # We can't spell that directly, but can trick it into working by matching
153- # .*?fixed
154- # in a lookahead assertion, save the matched part in a group, then
155- # consume that group via a backreference. If the overall match fails,
156- # the lookahead assertion won't try alternatives. So the translation is:
157- # (?=(?P<name>.*?fixed))(?P=name)
158- # Group names are created as needed: g0, g1, g2, ...
159- # The numbers are obtained from _nextgroupnum() to ensure they're unique
160- # across calls and across threads. This is because people rely on the
161- # undocumented ability to join multiple translate() results together via
162- # "|" to build large regexps matching "one of many" shell patterns.
146+ # Atomic groups ("(?>...)") allow us to spell that directly.
147+ # Note: people rely on the undocumented ability to join multiple
148+ # translate() results together via "|" to build large regexps matching
149+ # "one of many" shell patterns.
163150 while i < n :
164151 assert inp [i ] is STAR
165152 i += 1
@@ -176,8 +163,7 @@ def translate(pat):
176163 add (".*" )
177164 add (fixed )
178165 else :
179- groupnum = _nextgroupnum ()
180- add (f"(?=(?P<g{ groupnum } >.*?{ fixed } ))(?P=g{ groupnum } )" )
166+ add (f"(?>.*?{ fixed } )" )
181167 assert i == n
182168 res = "" .join (res )
183169 return fr'(?s:{ res } )\Z'
0 commit comments