You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
/a/** is understood by Path.full_match as /a followed by multiple segments, at least one #139580
/a/** is understood by Path.full_match as "/a followed by multiple segments, at least one", instead of "/a followed by multiple segments, including zero".
** (entire segment)
Matches any number of file or directory segments, including zero.
# one segment per **Path('/a/b').full_match('/a/**') # True# zero segments per **Path('/a').full_match('/a/**') # False - expected True# interestinglyPath('/').full_match('/**') # True
In Path('/a').glob('**'), it means "all files and directories under '/a', including '/a' itself"
If pathlib preserved trailing slashes, then the glob would yield '/a/', and that would match '/a/**'. The inconsistency comes from pathlib stripping trailing slashes unfortunately...
It's probably too late to change pathlib.Path to preserve trailing slashes - it would cause a lot of breakage.
But I'm open to the idea of a new class, perhaps pathlib.SimplePath, that is merely an object-orientated version of os.path without any path normalization. That would look like:
If pathlib preserved trailing slashes, then the glob would yield '/a/', and that would match '/a/**'. The inconsistency comes from pathlib stripping trailing slashes unfortunately...
While this explains the technical reason behind the behavior, it's essentially an implementation detail. From a user's perspective, the functionality shouldn't depend on such nuances; Path('/a').full_match('/a/**') returning False remains counter-intuitive, in my opinion.
If modifying full_match's behavior is impractical, the documentation should at least clearly explain how full_match interprets the ** pattern, since it differs from glob's interpretation.
Activity
picnixz commentedon Oct 5, 2025
I was wrong before, and
/a/is also not matched. I don't know if it's a bug in the code or in the docs.cc @barneygale
barneygale commentedon Oct 5, 2025
I think this is expected, because the path does not begin with
/a/. The docs could be clearer on this point.pathlib.Pathremoves trailing slashes soPath('/a/')becomesPath('/a')and fails to match.picnixz commentedon Oct 5, 2025
Oh, so I wasn't wrong before! I don't know how the docs could be improved though.
macmarrum commentedon Oct 5, 2025
The
**pattern has different interpretations inglobandfull_match:Path('/a').glob('**'), it means "all files and directories under '/a', including '/a' itself"Path('/a').full_match('/a/**')interprets it differently, which I find unexpectedbarneygale commentedon Oct 5, 2025
If pathlib preserved trailing slashes, then the glob would yield
'/a/', and that would match'/a/**'. The inconsistency comes from pathlib stripping trailing slashes unfortunately...barneygale commentedon Oct 5, 2025
It's probably too late to change
pathlib.Pathto preserve trailing slashes - it would cause a lot of breakage.But I'm open to the idea of a new class, perhaps
pathlib.SimplePath, that is merely an object-orientated version ofos.pathwithout any path normalization. That would look like:If anyone wants to pursue this, I'd recommend starting a topic in the Ideas forum.
macmarrum commentedon Oct 5, 2025
While this explains the technical reason behind the behavior, it's essentially an implementation detail. From a user's perspective, the functionality shouldn't depend on such nuances;
Path('/a').full_match('/a/**')returningFalseremains counter-intuitive, in my opinion.If modifying
full_match's behavior is impractical, the documentation should at least clearly explain howfull_matchinterprets the**pattern, since it differs fromglob's interpretation.pythongh-139580: Clarify pathlib full_match recursive pattern docs
pythongh-139580: Clarify pathlib full_match recursive pattern docs
harjothkhara commentedon Aug 18, 2026
There's a docs PR open for this: #151479. It adds a
/a/**example and a note on the trailing-slash normalization.pythongh-139580: Condense pathlib full_match recursive pattern docs
pythongh-139580: Apply review wording suggestions