From 0d6d8f303a5d8cbd1f0a94984395725eb5642473 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Thu, 15 Aug 2024 21:22:41 +0200 Subject: [PATCH] fix: support `runfiles.CurrentRepository` with non-hermetic `sys.path` (#1634) When using Python 3.10 or earlier, the first `sys.path` entry is the directory containing the script. This can result in modules being loaded from the source root rather than the runfiles root, which the runfiles library previously didn't support. Fixes #1631 --------- Co-authored-by: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Co-authored-by: Richard Levasseur --- CHANGELOG.md | 4 ++++ python/runfiles/runfiles.py | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 118af045c2..8d52bace11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,10 @@ A brief description of the categories of changes: cause warnings by default. In order to see the warnings for diagnostic purposes set the env var `RULES_PYTHON_REPO_DEBUG_VERBOSITY` to one of `INFO`, `DEBUG` or `TRACE`. Fixes [#1818](https://github.com/bazelbuild/rules_python/issues/1818). +* (runfiles) Make runfiles lookups work for the situation of Bazel 7, + Python 3.9 (or earlier, where safepath isn't present), and the Rlocation call + in the same directory as the main file. + Fixes [#1631](https://github.com/bazelbuild/rules_python/issues/1631). ### Added * (rules) `PYTHONSAFEPATH` is inherited from the calling environment to allow diff --git a/python/runfiles/runfiles.py b/python/runfiles/runfiles.py index ffa2473f5c..6d47d249b4 100644 --- a/python/runfiles/runfiles.py +++ b/python/runfiles/runfiles.py @@ -247,6 +247,20 @@ def CurrentRepository(self, frame: int = 1) -> str: raise ValueError("failed to determine caller's file path") from exc caller_runfiles_path = os.path.relpath(caller_path, self._python_runfiles_root) if caller_runfiles_path.startswith(".." + os.path.sep): + # With Python 3.10 and earlier, sys.path contains the directory + # of the script, which can result in a module being loaded from + # outside the runfiles tree. In this case, assume that the module is + # located in the main repository. + # With Python 3.11 and higher, the Python launcher sets + # PYTHONSAFEPATH, which prevents this behavior. + # TODO: This doesn't cover the case of a script being run from an + # external repository, which could be heuristically detected + # by parsing the script's path. + if ( + sys.version_info.minor <= 10 + and sys.path[0] != self._python_runfiles_root + ): + return "" raise ValueError( "{} does not lie under the runfiles root {}".format( caller_path, self._python_runfiles_root