Skip to content

Commit

Permalink
Added missing Path properties from Python 3.13 (#740)
Browse files Browse the repository at this point in the history
Fixes #737.
  • Loading branch information
agronholm committed May 28, 2024
1 parent 053e8f0 commit 0558fbb
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 3 deletions.
5 changes: 5 additions & 0 deletions docs/versionhistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ Version history

This library adheres to `Semantic Versioning 2.0 <http://semver.org/>`_.

**UNRELEASED**

- Added support for the ``from_uri()``, ``full_match()``, ``parser`` methods/properties
in ``anyio.Path``, newly added in Python 3.13

**4.4.0**

- Added the ``BlockingPortalProvider`` class to aid with constructing synchronous
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ extend-select = [
"required-imports" = ["from __future__ import annotations"]

[tool.mypy]
python_version = "3.12"
python_version = "3.13"
strict = true
ignore_missing_imports = true
disallow_any_generics = false
Expand Down
24 changes: 22 additions & 2 deletions src/anyio/_core/_fileio.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,28 @@ def as_posix(self) -> str:
def as_uri(self) -> str:
return self._path.as_uri()

def match(self, path_pattern: str) -> bool:
return self._path.match(path_pattern)
if sys.version_info >= (3, 13):
parser = pathlib.Path.parser # type: ignore[attr-defined]

@classmethod
def from_uri(cls, uri: str) -> Path:
return Path(pathlib.Path.from_uri(uri)) # type: ignore[attr-defined]

def full_match(
self, path_pattern: str, *, case_sensitive: bool | None = None
) -> bool:
return self._path.full_match( # type: ignore[attr-defined]
path_pattern, case_sensitive=case_sensitive
)

def match(
self, path_pattern: str, *, case_sensitive: bool | None = None
) -> bool:
return self._path.match(path_pattern, case_sensitive=case_sensitive)
else:

def match(self, path_pattern: str) -> bool:
return self._path.match(path_pattern)

def is_relative_to(self, other: str | PathLike[str]) -> bool:
try:
Expand Down
18 changes: 18 additions & 0 deletions tests/test_fileio.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,15 @@ def test_as_uri(self) -> None:
else:
assert Path("/foo/bar").as_uri() == "file:///foo/bar"

@pytest.mark.skipif(
sys.version_info < (3, 13),
reason="Path.from_uri() is only available on Python 3.13+",
)
def test_from_uri(self) -> None:
path = Path.from_uri("file:///foo/bar")
assert isinstance(path, Path)
assert path.as_uri() == "file:///foo/bar"

async def test_cwd(self) -> None:
result = await Path.cwd()
assert isinstance(result, Path)
Expand Down Expand Up @@ -269,6 +278,7 @@ async def test_is_mount(self) -> None:
assert not await Path("/gfobj4ewiotj").is_mount()
assert await Path("/").is_mount()

@pytest.mark.filterwarnings("ignore::DeprecationWarning")
def test_is_reserved(self) -> None:
expected_result = platform.system() == "Windows"
assert Path("nul").is_reserved() == expected_result
Expand Down Expand Up @@ -339,6 +349,14 @@ def test_joinpath(self) -> None:
path = Path("/foo").joinpath("bar")
assert path == Path("/foo/bar")

@pytest.mark.skipif(
sys.version_info < (3, 13),
reason="Path.full_match() is only available on Python 3.13+",
)
def test_fullmatch(self) -> None:
assert Path("/foo/bar").full_match("/foo/*")
assert not Path("/foo/bar").full_match("/baz/*")

def test_match(self) -> None:
assert Path("/foo/bar").match("/foo/*")
assert not Path("/foo/bar").match("/baz/*")
Expand Down

0 comments on commit 0558fbb

Please sign in to comment.