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

feat: provide access to arbitrary interpreters #2507

Open
wants to merge 28 commits into
base: main
Choose a base branch
from

Conversation

philsc
Copy link
Contributor

@philsc philsc commented Dec 16, 2024

There are some use cases that folks want to cover here. They are
discussed in this Slack thread. The high-level summary is:

  1. Users want to run the exact same interpreter that Bazel is running
    to minimize environmental issues.
  2. It is useful to pass a target label to third-party tools like mypy
    so that they can use the correct interpreter.

This patch adds to @rickeylev's work from #2359 by adding docs
and a few integration tests.

rickeylev and others added 10 commits October 29, 2024 21:05
Run a specific interpreter:
* `bazel run @rules_python//tools/run --@rules_python//python/config_settings:python_version=3.12`

Run interpreter from a binary:
* `bazel run @rules_python//tools/run --@rules_python//tools/run:bin=//my:binary`
    $ bazel run //python/bin:repl
    $ bazel run //python/bin:repl --//python/bin:repl_dep=//python/runfiles
docs/toolchains.md Outdated Show resolved Hide resolved
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 know this is still a draft, so take my suggestions with a grain of salt :)

docs/toolchains.md Outdated Show resolved Hide resolved
python/bin/interpreter.bzl Outdated Show resolved Hide resolved
docs/toolchains.md Outdated Show resolved Hide resolved
self._run_module_test("3.11")

def test_run_module_3_12(self):
self._run_module_test("3.12")
Copy link
Collaborator

Choose a reason for hiding this comment

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

It would be great to add a test that imports:

  • The code that is in the //python/bin:interpreter_src
  • The code that is in the transitive deps of the //python/bin:interpreter_src. Maybe depending on twine could be an option in the tests and then we could attempt importing one of its deps?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unless I'm misunderstanding something, that's currently not possible with the current implementation. The current implementation is purely there to get the interpreter, nothing else.

I'd like to follow this PR up with another PR that enables the use of the REPL with a specific py_* target (and its dependencies) importable.

docs/toolchains.md Outdated Show resolved Hide resolved
tests/integration/BUILD.bazel Outdated Show resolved Hide resolved
@rickeylev rickeylev marked this pull request as ready for review January 27, 2025 16:41
@rickeylev rickeylev requested a review from groodt as a code owner January 27, 2025 16:41
Copy link
Collaborator

@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.

re: the change the the env attribute in sh_py_run_test: Please partially undo this change.

The key thing is that I don't want the inner py binary to contaminate the outer sh binary's environment. One of the purpose's of the sh-side of sh_py_run_test is to run a py_binary with a particular environment.

So I think it's fine if sh_py_run_test.env is passed to only the inner py_binary and not the outer sh_binary. Similarly, the outer sh_binary shouldn't inherit TestEnvironment from the inner py binary. If there are separate env vars that should be set only in the sh-side of things, then either (a) create a sh_env arg to pass to sh, or (b) create a .sh file that sets the desired env prior to invoking the inner py binary.

Almost LGTM. Just that and the visibility comment.


To run the interpreter that Bazel will use, you can use the
`@rules_python//python/bin:python` target. This is a binary target with
the executable pointing at the `python3` binary plus the relevent runfiles.
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
the executable pointing at the `python3` binary plus the relevent runfiles.
the executable pointing at the `python3` binary plus its relevant runfiles.


:::{note}
The `python` target does not provide access to any modules from `py_*`
targets on its own. Work is ongoing to support that.
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
targets on its own. Work is ongoing to support that.
targets on its own. Please file a feature request if this is desired.

Just encouraging users to give feedback

@@ -0,0 +1,21 @@
load(":interpreter.bzl", "interpreter")

package(default_visibility = ["//visibility:public"])
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
package(default_visibility = ["//visibility:public"])

Leave visibility as private (default). Explicitly add visbility=public where necessary. This just helps make it clear about what is actually public.

filegroup(
name = "distribution",
srcs = glob(["**"]),
visibility = ["//python:__pkg__"],
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
visibility = ["//python:__pkg__"],
visibility = ["//:__subpackages__"],

For simplicity, we generally just grant visibility to our whole repo or public. It just makes it easier to reuse other parts within our codebase without having to go edit visibility stuff frequently.

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 only distribution was following this pedantic visibility setting.


interpreter(
name = "python",
binary = ":python_src",
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
binary = ":python_src",
binary = ":python_src",
visibility = ["//visibility:public"],


load("//python/private:interpreter.bzl", _interpeter = "interpreter")

interpreter = _interpeter
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hm. Should this be public?

What use case would users have for defining their own interpreter target?


load("//python/private:interpreter.bzl", _interpeter = "interpreter")

interpreter = _interpeter
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please name this interpreter_binary. This is to match the Bazel convention that runnable things are suffixed with _binary.

),
]

interpreter = rule(
Copy link
Collaborator

Choose a reason for hiding this comment

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

If this is public, then we'll need to add docs to the rule impl. Eventually, anyways -- I'm fine with docs being done in a separate PR.



class InterpreterTest(unittest.TestCase):
def setUp(self):
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
def setUp(self):
def setUp(self):
super().setUp()

Best practice: call the superclass unless there's a specific reason the parent functionality shouldn't be invoked.

tests/support/sh_py_run_test.bzl Show resolved Hide resolved
@rickeylev
Copy link
Collaborator

Doh, actually, I was mistaken. The RunEnvironmentInfo propagation is fine.

I misread the diff and thought the ctx.attr.target[RunEnvironmentInfo], line was in the wiring between the sh_test and the py target -- it's not. It's between the py_reconfig rule and the inner py target. Propagating that makes sense.

@philsc
Copy link
Contributor Author

philsc commented Jan 31, 2025

Doh, actually, I was mistaken. The RunEnvironmentInfo propagation is fine.

I misread the diff and thought the ctx.attr.target[RunEnvironmentInfo], line was in the wiring between the sh_test and the py target -- it's not. It's between the py_reconfig rule and the inner py target. Propagating that makes sense.

Whew. Okay. I was not sure how I was going to accomplish that otherwise 🙂 Will clean up the rest this weekend (and also figure out how to fix the RBE failures).

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.

3 participants