Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: support runfiles.CurrentRepository with non-hermetic sys.path #1634

Merged
merged 4 commits into from
Aug 15, 2024

Conversation

fmeum
Copy link
Contributor

@fmeum fmeum commented Dec 19, 2023

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

@fmeum
Copy link
Contributor Author

fmeum commented Dec 19, 2023

@rickeylev Not sure what the CI failures are about.

# 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.path[0] != self._python_runfiles_root:
Copy link
Collaborator

Choose a reason for hiding this comment

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

What about checking that we are running on python 3.10 and older and applying this behaviour only then? That may be easier to understand later that we can remove it once the lowest supported Python version is 3.11 (which will probably be a while), but it would also give validation errors on Python 3.11 and above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added a minor version check. Why would we see a validation error on Python 3.11?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think with python 3.11, the hermeticity is improved and sys.path entries within the script are better isolated from the the system python. The comment in the code mentions that this affects only 3.10 and below, so I thought that this should not change anything for 3.11 and above, or should it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It shouldn't, I was just referring to your comment, which said "but it would also give validation errors on Python 3.11 and above.". I wasn't sure what that was about.

Copy link
Contributor

Choose a reason for hiding this comment

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

Just wanted to note that the sys.path isolation is technically an opt-in behavior, not intrinsic to Python 3.11. rules_python's bootstrap sets PYTHONSAFEPATH, so it opts in.

@aignas
Copy link
Collaborator

aignas commented Jan 2, 2024

The CI should be happy again if you rebase. We had some issues when this PR was created, if I remember correctly.

@rickeylev
Copy link
Contributor

re: just assume the file is in the main repo if its loaded from outside the runfiles

Yeah, that's probably fine. This is to support older Python versions that were already relying on non-hermetic behavior.

I think this problem would only happen for files that are in the same directory (or a subdirectory of) as the main .py file? I don't see how an import would be able to find such files otherwise. So I suppose the sys.modules["__main__"].__file__ could be used in lieu of the caller's file in this situation. A main entry point that is in another repo and is relying on sys.path[0] being main's directory is likely for an ad-hoc tool in the main repo, but seems unlikely for any sort of library code.

python/runfiles/runfiles.py Outdated Show resolved Hide resolved
python/runfiles/runfiles.py Show resolved Hide resolved
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.
Copy link
Collaborator

@aignas aignas left a comment

Choose a reason for hiding this comment

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

I think this got lost, @rickeylev, any extra comments you have here?

@limdor
Copy link

limdor commented Jul 17, 2024

Any updates on this PR? I think I'm hitting the same issue

@aignas
Copy link
Collaborator

aignas commented Jul 17, 2024

I merged main into this PR, let's see how it goes.

@alexander-scott
Copy link

The problem indeed does only surface in edge-cases where:

  • Bazel 7 is used, with or without bzlmod
  • Python 3.9 or earlier is used
  • Runfiles rlocation is called from a file which is in the same directory as the main.py file (or test entry point)

But still I think this looks like the best solution for now, so it would be great to get this integrated if possible. Gentle ping @rickeylev

Copy link
Contributor

@rickeylev rickeylev left a comment

Choose a reason for hiding this comment

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

I updated this to main and added changelog text. LGTM.

@rickeylev rickeylev added this pull request to the merge queue Aug 15, 2024
Merged via the queue into bazelbuild:main with commit 0d6d8f3 Aug 15, 2024
4 checks passed
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.

bazel-runfiles module always throws ValueError
5 participants