Repository navigation
Fix extended star group directly after a star - #246
Merged
facelessuser merged 1 commit intoOct 19, 2026
Merged
Conversation
With the EXTMATCH or EXTGLOB flag, `fnmatch.fnmatch('abb', 'a**(b)')`
returned False. The second star opens the group `*(b)`, but the code that
collapses repeated stars consumed it, so `(b)` was matched as literal
text. At the start of a path segment with GLOBSTAR, `**(b)` had the same
problem because the two stars were read as a possible globstar, and with
GLOBSTARLONG so did `***(b)`, read as a possible `***`.
Stop collapsing at a star that is followed by `(` when extended groups
are enabled, and do not read such a star as the second star of `**` or
the third star of `***`.
Owner
|
@gir-bot lgtm |
Owner
|
Another good find. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fnmatch.fnmatch('abb', 'a**(b)', flags=fnmatch.EXTMATCH)returnsFalse, and so doesglob.globmatch('b', '**(a|b)b', flags=glob.GLOBSTAR | glob.EXTGLOB). Both should returnTrue, as Bash does:**(b)is a*followed by the group*(b), which matches zero or more occurrences. The latest release, 11.1, returnsFalsefor both, anda**(b)matches only names ending in the literal(b).The star that opens the group is consumed by the loop that collapses repeated stars, so
(b)is matched as literal text. Before 11.0 that loop only ran at the start of a segment, soa**(b)worked up to 10.2.1. WithGLOBSTAR, a**at the start of a segment is read as a possible globstar, and withGLOBSTARLONGa third star is read as***.These three places now leave a star that is followed by
(when extended groups are enabled. A**(x)now compiles like a*followed by*(x), so**(a|aa)ccan backtrack on a long name that does not match, as*+(a|aa)calready does.I added three rows to
TestFnMatch.casesand five toTestGlobMatch.cases. Without the fix,pytest tests/test_fnmatch.py tests/test_globmatch.pygives 8 failed, 866 passed, 64 skipped. With it, 874 passed, 64 skipped. The full suite passes with the fix. There is a changelog line under 11.2.