From 07a62b53d1d7e50a61c81145118347d01de65bdd Mon Sep 17 00:00:00 2001 From: trtllm-agent <296075020+trtllm-agent@users.noreply.github.com> Date: Tue, 8 Sep 2026 19:54:26 -0700 Subject: [PATCH] [https://nvbugs/6739553][fix] exempt the interpreter's own installation from the sys.path check Signed-off-by: trtllm-agent <296075020+trtllm-agent@users.noreply.github.com> --- tests/test_common/magic_import_hooks.py | 41 +++++++++++++++-- tests/unittest/others/test_magic_import.py | 52 ++++++++++++++++++++++ 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/tests/test_common/magic_import_hooks.py b/tests/test_common/magic_import_hooks.py index e7817aeb45c5..43d44da4bbcc 100644 --- a/tests/test_common/magic_import_hooks.py +++ b/tests/test_common/magic_import_hooks.py @@ -34,6 +34,7 @@ import os import sys +from pathlib import PurePath import pytest @@ -61,6 +62,12 @@ "jenkins/scripts/cbts", ) +# Prefixes of the current installation. +_INTERPRETER_ROOTS = frozenset( + os.path.realpath(prefix) + for prefix in (sys.prefix, sys.base_prefix, sys.exec_prefix, sys.base_exec_prefix) +) + # Debug variable for local runs to skip this check. _SKIP_CHECK_ENV = "TRTLLM_SKIP_SYS_PATH_CHECK" @@ -150,6 +157,16 @@ def pytest_runtest_protocol(item, nextitem): MagicFinder.purge_magic_sys_modules() +def _within(path: str, directory: str) -> bool: + """Whether ``path`` is ``directory`` itself or sits below it. + + Compared as whole path components, so a sibling whose name merely starts + with the directory's -- ``.venv-3.12-notes`` beside ``.venv-3.12`` -- is not + treated as being inside it. + """ + return PurePath(path).is_relative_to(directory) + + def _project_relative(entry: str) -> str | None: """Path of ``entry`` relative to the project root, or None if outside it. @@ -158,7 +175,7 @@ def _project_relative(entry: str) -> str | None: """ root = os.path.realpath(MagicFinder.project_root) resolved = os.path.realpath(entry or os.getcwd()) - if resolved != root and not resolved.startswith(root + os.sep): + if not _within(resolved, root): return None return os.path.relpath(resolved, root) @@ -192,12 +209,25 @@ def _under_exempt_tree(relative: str) -> bool: nested path such as a build directory matches its whole tree. """ for tree in _NON_TEST_TREES: - prefix = tree.replace("/", os.sep) - if relative == prefix or relative.startswith(prefix + os.sep): + if _within(relative, tree.replace("/", os.sep)): return True return False +def _under_interpreter_root(resolved: str, project_root: str) -> bool: + """Whether an already-resolved path is part of the interpreter's install. + + Other packages may live inside them and add their paths to sys.path, + which is not our fault so don't report those paths. + + However, we should still report paths under our project root + even if our project root lives inside any of them. + """ + return any( + _within(resolved, root) for root in _INTERPRETER_ROOTS if not _within(project_root, root) + ) + + def _expected_entries(config) -> set[str]: """Project-relative sys.path entries that a run is allowed to contain.""" expected = {"."} # the project root itself @@ -244,7 +274,10 @@ def _check_sys_path(config) -> list[str]: continue if _under_exempt_tree(relative): continue - if _is_pytest_basedir(os.path.join(root, relative)): + resolved = os.path.join(root, relative) + if _under_interpreter_root(resolved, root): + continue + if _is_pytest_basedir(resolved): continue if relative not in unexpected: unexpected.append(relative) diff --git a/tests/unittest/others/test_magic_import.py b/tests/unittest/others/test_magic_import.py index 14d4fe7e74a6..4e682d5fe0c7 100644 --- a/tests/unittest/others/test_magic_import.py +++ b/tests/unittest/others/test_magic_import.py @@ -25,6 +25,7 @@ from types import ModuleType, SimpleNamespace import pytest +from test_common import magic_import_hooks from test_common.magic_import import MagicFinder from test_common.magic_import_hooks import ( _NON_TEST_TREES, @@ -808,6 +809,57 @@ def test_sys_path_check_matches_exempt_trees_by_path_component(sys_path_report, assert sys_path_report(sibling) == [(exempt + "_other").replace("/", os.sep)] +@pytest.fixture +def in_tree_venv(tree, monkeypatch): + """Points the interpreter-root exemption at a venv inside the project. + + Patches the resolved roots rather than ``sys.prefix``, which the module + reads once at import time. + """ + venv = tree.project_root / ".venv-3.12" + site_packages = venv / "lib" / "python3.12" / "site-packages" + site_packages.mkdir(parents=True) + monkeypatch.setattr(magic_import_hooks, "_INTERPRETER_ROOTS", (str(venv),)) + return SimpleNamespace(prefix=venv, site_packages=site_packages) + + +def test_sys_path_check_accepts_an_in_tree_virtual_environment(sys_path_report, in_tree_venv): + """A venv under the project root is supported layout, not a leak. + + build_wheel.py defaults to ``/.venv-``, so a developer who + builds that way and then runs pytest from it would otherwise have the + interpreter's own library directories reported as if a test file had added + them. + """ + vendored = in_tree_venv.site_packages / "some_pkg" / "vendored" + + assert sys_path_report(in_tree_venv.prefix / "bin", vendored) == [] + + +def test_sys_path_check_still_reports_a_sibling_of_the_venv(sys_path_report, tree, in_tree_venv): + """The venv exemption matches whole components, so a sibling still counts.""" + sibling = tree.project_root / (in_tree_venv.prefix.name + "-notes") + sibling.mkdir(parents=True) + + assert sys_path_report(sibling) == [sibling.name] + + +def test_sys_path_check_ignores_an_interpreter_root_above_the_project( + sys_path_report, tree, monkeypatch +): + """A prefix containing the project root must not exempt the whole tree. + + Honouring it would place every entry under the root inside the exemption, + so the check would report nothing at all -- sys.base_prefix is ``/usr`` on a + system interpreter, which contains a checkout under ``/usr/local``. + """ + helpers = tree.project_root / "tests" / "helpers" + helpers.mkdir(parents=True) + monkeypatch.setattr(magic_import_hooks, "_INTERPRETER_ROOTS", (str(tree.project_root.parent),)) + + assert sys_path_report(helpers) == [os.path.join("tests", "helpers")] + + def test_sys_path_check_accepts_pythonpath_ini_entries(sys_path_report, tree): """pytest.ini's pythonpath is a declared, reviewed entry, not a leak.""" declared = tree.project_root / "tests" / "declared"