From a8456a8b5d4fdbfdc8ec478d7814629e9a932814 Mon Sep 17 00:00:00 2001 From: Sashko <20253875+sashko1988@users.noreply.github.com> Date: Thu, 29 May 2025 15:21:52 +0200 Subject: [PATCH] Improve `nodes._check_initialpaths_for_relpath` performance (#13448) Use `Path` facilities to greatly improve performance of `nodes._check_initialpaths_for_relpath` (see #13448 for performance comparison). Related: #13420, #13413. --------- Co-authored-by: Bruno Oliveira (cherry picked from commit bd6877e5874b50ee57d0f63b342a67298ee9a1c3) --- AUTHORS | 1 + changelog/13420.improvement.rst | 1 + src/_pytest/nodes.py | 12 +++++++----- 3 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 changelog/13420.improvement.rst diff --git a/AUTHORS b/AUTHORS index 2cf48dd00f9..0a94dba871d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -319,6 +319,7 @@ Nikolay Kondratyev Nipunn Koorapati Oleg Pidsadnyi Oleg Sushchenko +Oleksandr Zavertniev Olga Matoula Oliver Bestwalter Omar Kohl diff --git a/changelog/13420.improvement.rst b/changelog/13420.improvement.rst new file mode 100644 index 00000000000..54fe50a72b0 --- /dev/null +++ b/changelog/13420.improvement.rst @@ -0,0 +1 @@ +Improved test collection performance by optimizing path resolution used in ``FSCollector``. diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 2b818ade252..33aaae9e81d 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -38,7 +38,6 @@ from _pytest.mark.structures import NodeKeywords from _pytest.outcomes import fail from _pytest.pathlib import absolutepath -from _pytest.pathlib import commonpath from _pytest.stash import Stash from _pytest.warning_types import PytestWarning @@ -548,10 +547,13 @@ def _traceback_filter(self, excinfo: ExceptionInfo[BaseException]) -> Traceback: def _check_initialpaths_for_relpath( initial_paths: frozenset[Path], path: Path ) -> str | None: - for initial_path in initial_paths: - if commonpath(path, initial_path) == initial_path: - rel = str(path.relative_to(initial_path)) - return "" if rel == "." else rel + if path in initial_paths: + return "" + + for parent in path.parents: + if parent in initial_paths: + return str(path.relative_to(parent)) + return None