diff --git a/tools/python/runfiles/runfiles.py b/tools/python/runfiles/runfiles.py index 52dd64d23e380e..96a62e19622e39 100644 --- a/tools/python/runfiles/runfiles.py +++ b/tools/python/runfiles/runfiles.py @@ -66,11 +66,22 @@ from ._runfiles_constants import MAIN_REPOSITORY_RUNFILES_DIRECTORY def CreateManifestBased(manifest_path): - return _Runfiles(_ManifestBased(manifest_path)) + # Based on + # https://cs.opensource.google/bazel/bazel/+/master:src/main/java/com/google/devtools/build/lib/bazel/rules/python/python_stub_template.txt;l=134-144 + runfiles_dir_path = os.environ.get('RUNFILES_DIR', None) + if not runfiles_dir_path: + if (manifest_path.endswith('.runfiles_manifest') or + manifest_path.endswith('.runfiles/MANIFEST')): + runfiles_dir_path = manifest_path[:-9] + else: + raise ValueError( + "failed to find runfiles directory for manifest '%s'" % manifest_path) + + return _Runfiles(_ManifestBased(manifest_path), runfiles_dir_path) def CreateDirectoryBased(runfiles_dir_path): - return _Runfiles(_DirectoryBased(runfiles_dir_path)) + return _Runfiles(_DirectoryBased(runfiles_dir_path), runfiles_dir_path) def Create(env=None): @@ -109,15 +120,17 @@ def Create(env=None): return None +_UNC_PREFIX = "\\\\?\\" + class _Runfiles(object): """Returns the runtime location of runfiles. Runfiles are data-dependencies of Bazel-built binaries and tests. """ - def __init__(self, strategy): + def __init__(self, strategy, runfiles_dir_path): self._strategy = strategy - self._python_runfiles_root = _FindPythonRunfilesRoot() + self._runfiles_dir_path = runfiles_dir_path def Rlocation(self, path): """Returns the runtime path of a runfile. @@ -198,9 +211,11 @@ def CurrentRepository(self, frame = 1): caller_path = inspect.getfile(sys._getframe(frame)) except ValueError: raise ValueError("failed to determine caller's file path") - caller_runfiles_path = os.path.relpath(caller_path, self._python_runfiles_root) + if caller_path.startswith(_UNC_PREFIX): + caller_path = caller_path[len(_UNC_PREFIX):] + caller_runfiles_path = os.path.relpath(caller_path, self._runfiles_dir_path) if caller_runfiles_path.startswith(".." + os.path.sep): - raise ValueError('{} does not lie under the runfiles root {}'.format(caller_path, self._python_runfiles_root)) + raise ValueError("{} does not lie under the runfiles root {}".format(caller_path, self._runfiles_dir_path)) caller_runfiles_directory = caller_runfiles_path[:caller_runfiles_path.find(os.path.sep)] if caller_runfiles_directory == MAIN_REPOSITORY_RUNFILES_DIRECTORY: @@ -211,16 +226,6 @@ def CurrentRepository(self, frame = 1): # canonical name. return caller_runfiles_directory -def _FindPythonRunfilesRoot(): - root = __file__ - # Walk up our own runfiles path to the root of the runfiles tree from which - # the current file is being run. This path coincides with what the Bazel - # Python stub sets up as sys.path[0]. Since that entry can be changed at - # runtime, we rederive it here. - for _ in range("bazel_tools/tools/python/runfiles/runfiles.py".count("/") + 1): - root = os.path.dirname(root) - return root - class _ManifestBased(object): """`Runfiles` strategy that parses a runfiles-manifest to look up runfiles."""