Skip to content

fix: support path-like pattern in match, reject ContainerPath#524

Open
tonyandrewmeyer wants to merge 3 commits into
canonical:mainfrom
tonyandrewmeyer:fix/369-match-pathlike
Open

fix: support path-like pattern in match, reject ContainerPath#524
tonyandrewmeyer wants to merge 3 commits into
canonical:mainfrom
tonyandrewmeyer:fix/369-match-pathlike

Conversation

@tonyandrewmeyer

@tonyandrewmeyer tonyandrewmeyer commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

This PR widens match() on PathProtocol, LocalPath, and ContainerPath to accept str | os.PathLike[str], matching pathlib.Path.match on Python 3.12+ and the signature already used by glob() (see #505).

ContainerPath.match additionally rejects ContainerPath arguments with a TypeError. This restores the pre-3.14 behaviour: Python 3.14's pathlib.PurePath.match accepts any object that implements with_segments, which would otherwise silently let a ContainerPath through and match the wrong filesystem.

LocalPath gains a thin match override that calls os.fspath before delegating, so the path-like pattern works on 3.10/3.11 too (where pathlib.Path.match is str-only). The override also forwards the case_sensitive keyword on 3.12+ to stay signature-compatible with the parent across all supported Python versions.

Refs #369

@tonyandrewmeyer tonyandrewmeyer requested a review from a team as a code owner June 14, 2026 21:50
@tonyandrewmeyer tonyandrewmeyer force-pushed the fix/369-match-pathlike branch from e54ffea to 229b2f6 Compare June 14, 2026 22:41
Comment on lines +174 to +186
def match(self, path_pattern: str | os.PathLike[str]) -> bool:
def match(
self, path_pattern: str | os.PathLike[str], *, case_sensitive: bool | None = None
) -> bool:
# On Python 3.11, pathlib.Path.match only accepts a str pattern (3.12 widened it to
# path-like). On Python 3.14, pathlib.PurePath.match accepts any object with
# `with_segments`, which would silently allow a ContainerPath through. Normalising
# via os.fspath gives us a consistent, narrow API: str | os.PathLike[str] on every
# supported version, with a clear TypeError for anything else (including ContainerPath,
# which is not os.PathLike).
return super().match(os.fspath(path_pattern))
kwargs: dict[str, bool] = {}
if case_sensitive is not None:
kwargs['case_sensitive'] = case_sensitive
return super().match(os.fspath(path_pattern), **kwargs)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this change. It does resolve the incompatible override error across all Python versions. But the error is because match added case_sensitive in Python 3.12. It's valid in typing terms for the override to add an extra argument (as we're now doing on Python 3.10), but we've implemented our handling of the extra argument in such a way that we hide from both callers of the function and from our own static analysis that it's an error to pass case_sensitive on Python <3.12.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that we need to satisfy the checker that wants an ignore in one version and forbids having an ignore in another version. Any suggestions?

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.

2 participants