Skip to content

feat(runfiles): create pathlib api for runfiles library#3694

Open
rickeylev wants to merge 3 commits intobazel-contrib:mainfrom
rickeylev:runfiles.pathlib
Open

feat(runfiles): create pathlib api for runfiles library#3694
rickeylev wants to merge 3 commits intobazel-contrib:mainfrom
rickeylev:runfiles.pathlib

Conversation

@rickeylev
Copy link
Copy Markdown
Collaborator

This adds a pathlib.Path-based API for interacting with runfiles. This
makes it easier to interact with runfiles.

Fixes #3296

@rickeylev rickeylev requested a review from aignas as a code owner April 11, 2026 09:20
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a Path class to the runfiles library, which implements the pathlib.PurePath API to allow for idiomatic path manipulation of Bazel runfiles. It also adds a root() method to the Runfiles class to return these new path objects. The review feedback suggests improving the robustness of the Path class by handling potential None values for the internal _runfiles attribute in str and runfiles_root methods, and using a more robust string formatting in repr.

Comment on lines +248 to +254
def __str__(self) -> str:
path_posix = super().__str__().replace("\\", "/")
if not path_posix or path_posix == ".":
# pylint: disable=protected-access
return self._runfiles._python_runfiles_root # type: ignore
resolved = self._runfiles.Rlocation(path_posix, source_repo=self._source_repo) # type: ignore
return resolved if resolved is not None else super().__str__()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The __str__ method assumes that self._runfiles is not None. However, since Path is a public class, it can be instantiated directly without a Runfiles instance (e.g., runfiles.Path("foo")), in which case self._runfiles will be None and this method will raise an AttributeError. It should fallback to the default string representation if no Runfiles instance is associated.

Suggested change
def __str__(self) -> str:
path_posix = super().__str__().replace("\\", "/")
if not path_posix or path_posix == ".":
# pylint: disable=protected-access
return self._runfiles._python_runfiles_root # type: ignore
resolved = self._runfiles.Rlocation(path_posix, source_repo=self._source_repo) # type: ignore
return resolved if resolved is not None else super().__str__()
def __str__(self) -> str:
if self._runfiles is None:
return super().__str__()
path_posix = super().__str__().replace("\\", "/")
if not path_posix or path_posix == ".":
# pylint: disable=protected-access
return self._runfiles._python_runfiles_root # type: ignore
resolved = self._runfiles.Rlocation(path_posix, source_repo=self._source_repo) # type: ignore
return resolved if resolved is not None else super().__str__()

Comment on lines +259 to +261
def runfiles_root(self) -> "Path":
"""Returns a Path object representing the runfiles root."""
return self._runfiles.root(source_repo=self._source_repo) # type: ignore
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to __str__, runfiles_root will crash if self._runfiles is None. It should check for the presence of the runfiles instance and perhaps raise a more descriptive error if it's missing.

Suggested change
def runfiles_root(self) -> "Path":
"""Returns a Path object representing the runfiles root."""
return self._runfiles.root(source_repo=self._source_repo) # type: ignore
def runfiles_root(self) -> "Path":
"""Returns a Path object representing the runfiles root."""
if self._runfiles is None:
raise ValueError("Path object is not associated with a Runfiles instance")
return self._runfiles.root(source_repo=self._source_repo) # type: ignore

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

runfiles: add pathlib.Path or importlib.Traversable API

1 participant