Skip to content

Match relative patterns from the right in UPath.match - #568

Open
syahra712 wants to merge 1 commit into
fsspec:mainfrom
syahra712:fix-match-relative-pattern
Open

syahra712 wants to merge 1 commit into
fsspec:mainfrom
syahra712:fix-match-relative-pattern

Conversation

@syahra712

Copy link
Copy Markdown

UPath.match() passes the pattern straight to full_match(), so a relative pattern has to cover the whole path. pathlib.PurePath.match() matches relative patterns from the right instead:

>>> from pathlib import PurePosixPath
>>> PurePosixPath("/x/a/b").match("a/b")
True
>>> from upath import UPath
>>> UPath("s3://bucket/x/a/b").match("a/b")
False   # before
True    # after

The same thing happens with match("b"), match("*/b") and so on, and for every protocol (memory, s3, gcs, http, ...).

Fix: match() tries full_match() first, so nothing that matched before stops matching. If that fails and the pattern is relative (it has no leading / and no ://), it compares the pattern's segments against the path's last parts, using fnmatchcase on each segment. The anchor (bucket/, https://host/) is left out of that comparison, as pathlib does. The ** → * handling is unchanged.

Tests: added test_match to the shared BaseTests in upath/tests/cases.py, so it runs for every implementation. DataPath gets an override, as it already does for test_full_match. The new test fails on main and passes with this change. These local runs pass: memory, local, data, s3, zip, tar, test_relative.py, test_core.py and the pathlib suites (1588 + 736). pre-commit is clean.

AI-assisted (Claude): I used it to help read the code and draft the test. I reviewed and ran everything myself.

UPath.match delegated to full_match, so a relative pattern had to cover
the whole path. pathlib.PurePath.match matches relative patterns from
the right, so UPath('s3://bucket/x/a/b').match('a/b') returned False
where PurePosixPath('/x/a/b').match('a/b') returns True.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant