From 5bdd01355e742392554360f9b6da384e2a17ceb8 Mon Sep 17 00:00:00 2001 From: ybai08 <271969568+ybai08@users.noreply.github.com> Date: Sat, 17 Oct 2026 12:21:29 -0500 Subject: [PATCH] Make trio.Path.full_match synchronous PurePath.full_match() is a pure path method like match(), but trio.Path wrapped it to run in a worker thread, so path.full_match(pattern) returned a coroutine (always truthy) instead of a bool. Drop the wrapper so the inherited PurePath implementation is used. --- newsfragments/3547.bugfix.rst | 1 + src/trio/_path.py | 2 -- src/trio/_tests/test_path.py | 12 ++++++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 newsfragments/3547.bugfix.rst diff --git a/newsfragments/3547.bugfix.rst b/newsfragments/3547.bugfix.rst new file mode 100644 index 000000000..d3ddc694e --- /dev/null +++ b/newsfragments/3547.bugfix.rst @@ -0,0 +1 @@ +`trio.Path.full_match` is now a synchronous method, like `pathlib.PurePath.full_match` and `trio.Path.match`. It was previously wrapped to run in a worker thread, so calling it without ``await`` returned a coroutine, which is always truthy. diff --git a/src/trio/_path.py b/src/trio/_path.py index ea571c9c0..d21dd51e1 100644 --- a/src/trio/_path.py +++ b/src/trio/_path.py @@ -260,8 +260,6 @@ def __repr__(self) -> str: write_text = _wrap_method(pathlib.Path.write_text) if sys.version_info < (3, 12): link_to = _wrap_method(pathlib.Path.link_to) - if sys.version_info >= (3, 13): - full_match = _wrap_method(pathlib.Path.full_match) def as_uri(self) -> str: return self._wrapped_cls(self).as_uri() diff --git a/src/trio/_tests/test_path.py b/src/trio/_tests/test_path.py index 9fe3920df..7b283a562 100644 --- a/src/trio/_tests/test_path.py +++ b/src/trio/_tests/test_path.py @@ -2,6 +2,7 @@ import os import pathlib +import sys from typing import TYPE_CHECKING import pytest @@ -230,6 +231,17 @@ async def test_globmethods(path: trio.Path) -> None: assert entries == {"_bar.txt", "bar.txt"} +def test_full_match_is_sync() -> None: + if sys.version_info < (3, 13): + pytest.skip("PurePath.full_match is 3.13+") + + # full_match() is a pure path method like match(), so it must not be async + path = trio.Path("foo/bar.py") + assert path.full_match("**/*.py") is True + assert path.full_match("*.py") is False + assert path.full_match("FOO/BAR.PY", case_sensitive=False) is True + + async def test_as_uri(path: trio.Path) -> None: path = await path.parent.resolve()