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

Add ability for Bazel >=5.0.0 users to use downloaded py interpreter in py_binary stub script #699

Closed
wants to merge 4 commits into from

Conversation

thundergolfer
Copy link
Collaborator

PR Checklist

Please check if your PR fulfills the following requirements:

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features) TODO

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature (please, look at the "Scope of the project" section in the README.md file)
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

Issue Number: #691

What is the new behavior?

Bazel users on a version greater than or equal to version 5 will avoid using a system Python interpreter when running py_binary or py_test targets.

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@@ -154,6 +168,7 @@ py_runtime(
files = [":files"],
interpreter = "{python_path}",
python_version = "PY3",
{stub_shebang_assignment}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think this functionality could be behind a default True configuration knob. I'm not confident it will be the right move in all scenarios.

When doing bazel run (or test) it will work, but if the py_binary is moved in any way, for example to layer it into a container, then the absolute path will not be valid.

With 'in-build' Python toolchains, I'm pretty sure the toolchain interpreter is moved with the rest of the application files. So it can be found at a relative path to the stub_script, for example foo.runfiles/python39_x86_64-apple-darwin/bin/python3.

# "0.10.0rc1 abc123d" => (0, 10, 0)
# "0.3.0" => (0, 3, 0)
def _parse_native_bazel_version(bazel_version):
return tuple([int(n) for n in bazel_version.split(".")])
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I took this from https://github.com/bazelbuild/bazel-skylib/blob/main/lib/versions.bzl#L22 but I don't really want this file to take a dependency on skylib for such simple functionality. 🤷

print(native.bazel_version)
if _parse_native_bazel_version(native.bazel_version) >= (5,0,0):
abs_python_bin_path = rctx.path(python_bin)
stub_shebang_assignment = "stub_shebang = \"#!{}\"".format(abs_python_bin_path)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I have been thinking about this recently, and setting the shebang line to an absolute path that changes from machine to machine will introduce non-deterministic inputs, resulting in lots of cache misses.

Comment on lines +115 to +117
if _parse_native_bazel_version(native.bazel_version) >= (5,0,0):
abs_python_bin_path = rctx.path(python_bin)
stub_shebang_assignment = "stub_shebang = \"#!{}\"".format(abs_python_bin_path)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if _parse_native_bazel_version(native.bazel_version) >= (5,0,0):
abs_python_bin_path = rctx.path(python_bin)
stub_shebang_assignment = "stub_shebang = \"#!{}\"".format(abs_python_bin_path)
if _parse_native_bazel_version(native.bazel_version) >= (5,0,0):
execroot = "/".join(str(rctx.path(".")).replace("\\", "/").split("/")[:-2])
python_bin_path = str(rctx.path(python_bin)).removeprefix(execroot + "/")
shebang_line = "#!./" + python_bin_path
stub_shebang_assignment = "stub_shebang = '{}',".format(shebang_line)

Copy link
Collaborator

Choose a reason for hiding this comment

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

This will find the binary relative to the execroot.

Copy link
Contributor

Choose a reason for hiding this comment

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

I tried something similar, unfortunately this does not work for me (bazel 5.1.0, rules_python 0.9.0) as the python repository is not part of the linux sandbox dependencies when running the py_binary().

Did you run this successfully?

@github-actions
Copy link

This Pull Request has been automatically marked as stale because it has not had any activity for 180 days. It will be closed if no further activity occurs in 30 days.
Collaborators can add an assignee to keep this open indefinitely. Thanks for your contributions to rules_python!

@github-actions github-actions bot added the Can Close? Will close in 30 days if there is no new activity label Dec 17, 2022
@github-actions
Copy link

This PR was automatically closed because it went 30 days without a reply since it was labeled "Can Close?"

@github-actions github-actions bot closed this Jan 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Can Close? Will close in 30 days if there is no new activity
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants