-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Switch Python rules to use toolchains #7375
Comments
(Plan is to use this work to also address #4815, rather than implement an ad hoc solution to that bug.) |
Overall, this looks good. A few points:
|
|
I think the distinction between "delete" and "ignore with a warning" is worth calling out. |
(See also Nicolas's comments here.) |
Replying to @nlopezgi's concern about toolchains and extensibility here:
Users who operate at the level of BUILD targets and macros only need to worry about having definitions for their platforms and python toolchains, i.e. the Users who are writing new rules that interoperate with the Python rules may need to manipulate Python toolchains. To receive a Python toolchain, they should declare I didn't go into too much detail about how to write rules that produce or consume Python toolchains (aside from a description of the provider schema) because this is already covered by the general toolchain documentation linked in the doc's abstract. |
(please do not assign issues to more than one |
Moved its configured target factory, provider, and test to the ...lib/rules/python directory instead of ...lib/bazel/rules/python. Simplified the test. Also moved BazelPythonConfigurationTest into the bazel dir. The `files` attribute of py_runtime is no longer mandatory. Since a non-empty value is not permitted when `interpreter_path` is used, it makes more sense to omit it rather than explicitly set it to empty. The error messages and rule logic are simplified. The provider now has an invariant that either interpreter is null or else interpreterPath and files are null; this will be clarified in a follow-up CL that exposes PyRuntimeProvider to Starlark. Work toward #7375. PiperOrigin-RevId: 234174755
Let me add my 5 coins as an end user
Also related the section
Based on jdk toolchain implementation it doesn't look like a problem - tools/jdk/BUILD
doesn't break the convention but helps avoids problems with a missed py_runtime attribute in the pair and provide an opportunity to force version as
Also it allows to rid of python_version attribute from |
Hi Guro, thanks for the comments. There's a few reasons I didn't organize it that way.
It's not clear what the ideal way to deal with multiple Python runtimes will be long-term. Currently the rules are organized around this PY2/PY3 distinction, but in the future that will become less important and there may be more emphasis on choosing minor versions. Building the current schema into the rule name gives us a little more room to redesign it in the future without extra breaking changes.
Again, future-proofing is part of the reason. It's easier to migrate the schema of a For platforms that do not provide an implementation for one of these toolchains, we'd still have to define a dummy toolchain that fails at analysis time, since even if a target does not use the toolchain its rule type will still require both toolchain types. Also, creating
I don't believe there's anything in the toolchain framework that would allow you to directly force the toolchain implementation to use for a given toolchain type, as opposed to just letting Bazel select one based on constraints, though I could be wrong.
I checked with @katre before starting the design doc, and it turns out that currently toolchains can really only differentiate themselves based on platform constraints, not other rule logic constraints. You can't easily express that a given py_binary has a constraint of "I want Python 2". |
Looks good to me. |
Thanks for addressing my question about extending python rules. It would be ideal to get this info as part of user docs whenever the right time for that comes. Looks good to me. |
@brandjon is it really not possible to express a version constraint for e.g. a py_binary using toolchains? There is an example here: https://docs.bazel.build/versions/master/platforms.html#defining-constraints-and-platforms talking about defining Version as a constraint. That could not be used? This is sidetracking a bit but I am also curios about this as I was planning to implement to add a constraint for the nodejs toolchains so it would be possible to use different versions of nodejs in the same workspace and one could choose on nodejs_binary level. |
In that example the platform either supports one version or the other, and targets build/run on whichever platform has the version they require. Here the same platform is generally expected to provide both Python versions. Currently all values for a constraint setting are considered mutually exclusive. I think the bigger issue is that Python version is a property of the target, not the platform. @katre could comment more. |
This creates a top-level symbol `PyRuntimeInfo` representing the provider created by the `py_runtime` rule and consumed by `py_binary` and `py_test`. PyRuntimeProvider is refactored to not implement TransitiveInfoProvider, and to now be split into separate classes for the provider instance vs provider type. Fakes are created for Stardoc and friends. Tests are added for the API of `PyRuntimeInfo` and for the ability to sandwich a Starlark rule between a py_runtime and its consuming py_binary. As drive-by cleanups, the provider is now instantiated in Java code via factory methods instead of its constructor, and the isHermetic method is renamed to isInBuild to be consistent with the terminology in the design doc for #7375. Rule documentation is also updated. Work toward #7375. RELNOTES: (Python rules) PyRuntimeInfo is exposed to Starlark, making it possible for Starlark rules to depend on or imitate `py_runtime`. The `files` attribute of `py_runtime` is no longer mandatory. PiperOrigin-RevId: 235224774
Rename BazelPyRuntimeRule to BazelPyRuntimeRule, and moved it to lib/rules/python instead of lib/bazel/rules/python. Improved documentation, and eliminated an unneeded declaration on configuration fragments it does not actually use. Work toward #7375. RELNOTES: None PiperOrigin-RevId: 235237085
Ah yeah I see, so I can say a platform is compatible with a certain version, but I can not say that a platform is compatible with multiple versions and then just choose the version on a per-target level. It would be nice to hear more details about how to make such a use-case possible in a generic way from @katre. As I imagine this could come up again and again. I am also happy to pull this in a separate issue or bazel-discuss as this is just tangentially related to this issue. I also do wonder how |
This replaces the stub default Python toolchain with one that actually locates the target platform's Python interpreter at runtime. Try it out with bazel build //some_py_binary --experimental_use_python_toolchains and note that, unlike before (#4815), the correct Python interpreter gets invoked by default regardless of whether you specify `--python_version=PY2` or `--python_version=PY3`. This toolchain is only intended as a last resort, if the user doesn't define and register a better toolchain (that satisfies the target platform constraints). Work toward #7375 and #4815. Follow-up work needed to add a test (#7843) and windows support (#7844). RELNOTES: None PiperOrigin-RevId: 240417315
This is for improved compatibility, although platforms should still provide their own Python toolchain where possible. Work toward #7375. RELNOTES: None PiperOrigin-RevId: 240549112
This renames --experimental_use_python_toolchains to --incompatible. It also adds the behavior to the flag that 1) py_runtime's python_version attribute becomes manadatory, and 2) the --python_top flag is disallowed (it is superseded by toolchains), as well as --python2_path and --python3_path (they were already no-ops). --python_path is strongly discouraged but not yet banned due to an existing use on Windows (#7901). Feature issue is #7375, incompatible change migration issue is #7899. RELNOTES[INC]: Introduced --incompatible_use_python_toolchains, which supersedes --python_top/--python_path. See #7899 and #7375 for more information. PiperOrigin-RevId: 241134532
Legacy code cleanup tracked by #8169. |
In Python rules, the Python stub script is responsible for extracting the runfiles from the zip file when --build_python_zip is used. However, there's a bug in the standard Python library (https://bugs.python.org/issue15795) that causes file permissions to be lost when extracting zips. This causes runfiles to not be marked executable, which is a problem when the py_runtime is an in-build runtime (issue #5104). This change updates the stub script to workaround the bug by directly chmodding extracted files with their intended mode. It also adds a regression test combining a custom py_runtime with --build_python_zip. Fixes #5104, unblocks #7375. RELNOTES: Fixed an issue where some `py_runtime`s were incompatible with using `--build_python_zip` (#5104). PiperOrigin-RevId: 246195931
Baseline: 0366246 Cherry picks: + 3f7f255: Windows: fix native test wrapper's arg. escaping + afeb8d0: Flip --incompatible_windows_escape_jvm_flags + 4299b65: Sort DirectoryNode children to ensure validity. + 231270c: Conditionally use deprecated signature for initWithContentsOfURL + 75a3a53: Add http_archive entries for testing with various JDK versions. + 4a6354a: Now that ubuntu1804 uses JDK 11, remove explicit ubuntu1804_java11 tests. + ae102fb: Fix wrong name of ubuntu1804_javabase9 task. + 0020a97: Remove @executable_path/Frameworks from rpaths + 130f86d: Download stderr/stdout to a temporary FileOutErr Incompatible changes: - (Starlark rules) The legacy "py" provider can no longer be passed to or produced by native Python rules; use [PyInfo](https://docs.bazel.build/versions/master/skylark/lib/PyIn fo.html) instead. See [#7298](#7298) for more information. - (Python rules) The `default_python_version` attribute of the `py_binary` and `py_test` rules has been renamed to `python_version`. Also, the `--force_python` flag has been renamed to `--python_version`. See [#7308](#7308) for more information. - (Python rules) The python version now changes to whatever version is specified in a `py_binary` or `py_test`'s `python_version` attribute, instead of being forced to the value set by a command line flag. You can temporarily revert this change with `--incompatible_allow_python_version_transitions=false`. See [#7307](#7307) for more information. - --incompatible_disable_third_party_license_checking` is enabled by default - Introduced --incompatible_use_python_toolchains, which supersedes --python_top/--python_path. See #7899 and #7375 for more information. - Python 3 is now the default Python version (for `py_binary` and `py_test` targets that don't specify the `python_version` attribute). Targets that are built for Python 3 will no longer have their output put in a separate `-py3` directory; instead there is now a separate `-py2` directory for Python 2 targets. See #7359 and #7593 for more information. - objc_library resource attributes are now disabled by default. Please migrate them to data instead. See #7594 for more info. - Flip --incompatible_windows_escape_jvm_flags to true. See #7486 New features: - genrules now support a $(RULEDIR) variable that resolves to the directory where the outputs of the rule are put. - Added --incompatible_windows_native_test_wrapper flag: enables using the Bash-less test wrapper on Windows. (No-op on other platforms.) Important changes: - incompatible_use_jdk11_as_host_javabase: makes JDK 11 the default --host_javabase for remote jdk (#7219) - Makes genquery somepath output deterministic. - Tristate attributes of native rules now reject True/False (use 1/0) - Rollback of "Tristate attributes of native rules now reject True/False (use 1/0)" - Tristate attributes of native rules now reject True/False (use 1/0) - Added -incompatible_do_not_split_linking_cmdline flag. See #7670 - Tristate attributes of native rules now temporarily accept True/False again - `--incompatible_disable_legacy_crosstool_fields` has been flipped (#6861) `--incompatible_disable_expand_if_all_available_in_flag_set` has been flipped (#7008) - `--incompatible_disable_legacy_crosstool_fields` has been flipped (#6861) `--incompatible_disable_expand_if_all_available_in_flag_set... RELNOTES: None. - --incompatible_no_transitive_loads is enabled by default. - Makes TreeArtifact deterministic. - --incompatible_no_transitive_loads is enabled by default. - Android NDK C++ toolchain is now configured in Starlark. This should be a backwards compatible change, but in case of bugs blame unknown commit. - `--incompatible_disable_legacy_crosstool_fields` has been flipped (#6861) `--incompatible_disable_expand_if_all_available_in_flag_set` has been flipped (#7008) - --incompatible_no_transitive_loads is enabled by default. - --incompatible_bzl_disallow_load_after_statement is enabled - Added `--incompatible_require_ctx_in_configure_features`, see #7793 for details. - Flag --incompatible_merge_genfiles_directory is flipped. This removes the directory `bazel-genfiles` in favor of `bazel-bin`. - previously deprecated flag --experimental_remote_spawn_cache was removed - `--incompatible_disallow_load_labels_to_cross_package_boundaries` is enabled by default - Fix an issue where the Android resource processor did not surface errors from aapt2 compile and link actions. - --incompatible_no_attr_license is enabled by default - `--incompatible_disable_crosstool_file` has been flipped (#7320) - A new flag `--incompatible_string_join_requires_strings` is introduced. The sequence argument of `string.join` must contain only string elements. - --incompatible_symlinked_sandbox_expands_tree_artifacts_in_runfile s_tree has been flipped - Incompatible flag `--incompatible_disable_legacy_cc_provider` has been flipped (see #7036 for details). - Don't drop the analysis cache when the same --define flag is set multiple times and the last value is the same (e.g. if the current invocation was run with "--define foo=bar" and the previous one was run with "--define foo=baz --define foo=bar"). - The --incompatible_disable_genrule_cc_toolchain_dependency flag has been flipped (see #6867 for details). - Incompatible change `--incompatible_remove_cpu_and_compiler_attributes_from_cc_toolcha in` has been flipped (see #7075 for details). - --noexperimental_java_coverage is a no-op flag. - --experimental_java_coverage/--incompatible_java_coverage flag was removed. See #7425. - incompatible_use_toolchain_providers_in_java_common: pass JavaToolchainInfo and JavaRuntimeInfo providers to java_common APIs instead of configured targets (#7186.) - --incompatible_remote_symlinks has been flipped. The remote caching and execution protocol will now represent symlinks in outputs as such. See #7917 for more details. - Bazel is now ~20MiB smaller, from unbundling the Android rules' runtime dependencies. This release contains contributions from many people at Google, as well as Andreas Herrmann, Andrew Suffield, Andy Scott, Benjamin Peterson, Ed Baunton, George Gensure, Ian McGinnis, Ity Kaul, Jingwen Chen, John Millikin, Keith Smiley, Marwan Tammam, Mike Fourie, Oscar Bonilla, perwestling, petros, Robert Sayre, Ryan Beasley, silvergasp, Stanimir Mladenov, Travis Cline, Vladimir Chebotarev, ??.
Reopening this because the flag flip failed due to downstream breakages. Follow the migration tracking bug #7899. |
Baseline: 0366246 Cherry picks: + 3f7f255: Windows: fix native test wrapper's arg. escaping + afeb8d0: Flip --incompatible_windows_escape_jvm_flags + 4299b65: Sort DirectoryNode children to ensure validity. + 231270c: Conditionally use deprecated signature for initWithContentsOfURL + 75a3a53: Add http_archive entries for testing with various JDK versions. + 4a6354a: Now that ubuntu1804 uses JDK 11, remove explicit ubuntu1804_java11 tests. + ae102fb: Fix wrong name of ubuntu1804_javabase9 task. + 0020a97: Remove @executable_path/Frameworks from rpaths + 130f86d: Download stderr/stdout to a temporary FileOutErr Incompatible changes: - (Starlark rules) The legacy "py" provider can no longer be passed to or produced by native Python rules; use [PyInfo](https://docs.bazel.build/versions/master/skylark/lib/PyIn fo.html) instead. See [#7298](#7298) for more information. - (Python rules) The `default_python_version` attribute of the `py_binary` and `py_test` rules has been renamed to `python_version`. Also, the `--force_python` flag has been renamed to `--python_version`. See [#7308](#7308) for more information. - (Python rules) The python version now changes to whatever version is specified in a `py_binary` or `py_test`'s `python_version` attribute, instead of being forced to the value set by a command line flag. You can temporarily revert this change with `--incompatible_allow_python_version_transitions=false`. See [#7307](#7307) for more information. - --incompatible_disable_third_party_license_checking` is enabled by default - Introduced --incompatible_use_python_toolchains, which supersedes --python_top/--python_path. See #7899 and #7375 for more information. - Python 3 is now the default Python version (for `py_binary` and `py_test` targets that don't specify the `python_version` attribute). Targets that are built for Python 3 will no longer have their output put in a separate `-py3` directory; instead there is now a separate `-py2` directory for Python 2 targets. See #7359 and #7593 for more information. - objc_library resource attributes are now disabled by default. Please migrate them to data instead. See #7594 for more info. - Flip --incompatible_windows_escape_jvm_flags to true. See #7486 New features: - genrules now support a $(RULEDIR) variable that resolves to the directory where the outputs of the rule are put. - Added --incompatible_windows_native_test_wrapper flag: enables using the Bash-less test wrapper on Windows. (No-op on other platforms.) Important changes: - incompatible_use_jdk11_as_host_javabase: makes JDK 11 the default --host_javabase for remote jdk (#7219) - Makes genquery somepath output deterministic. - Tristate attributes of native rules now reject True/False (use 1/0) - Rollback of "Tristate attributes of native rules now reject True/False (use 1/0)" - Tristate attributes of native rules now reject True/False (use 1/0) - Added -incompatible_do_not_split_linking_cmdline flag. See #7670 - Tristate attributes of native rules now temporarily accept True/False again - `--incompatible_disable_legacy_crosstool_fields` has been flipped (#6861) `--incompatible_disable_expand_if_all_available_in_flag_set` has been flipped (#7008) - `--incompatible_disable_legacy_crosstool_fields` has been flipped (#6861) `--incompatible_disable_expand_if_all_available_in_flag_set... RELNOTES: None. - --incompatible_no_transitive_loads is enabled by default. - Makes TreeArtifact deterministic. - --incompatible_no_transitive_loads is enabled by default. - Android NDK C++ toolchain is now configured in Starlark. This should be a backwards compatible change, but in case of bugs blame unknown commit. - `--incompatible_disable_legacy_crosstool_fields` has been flipped (#6861) `--incompatible_disable_expand_if_all_available_in_flag_set` has been flipped (#7008) - --incompatible_no_transitive_loads is enabled by default. - --incompatible_bzl_disallow_load_after_statement is enabled - Added `--incompatible_require_ctx_in_configure_features`, see #7793 for details. - Flag --incompatible_merge_genfiles_directory is flipped. This removes the directory `bazel-genfiles` in favor of `bazel-bin`. - previously deprecated flag --experimental_remote_spawn_cache was removed - `--incompatible_disallow_load_labels_to_cross_package_boundaries` is enabled by default - Fix an issue where the Android resource processor did not surface errors from aapt2 compile and link actions. - --incompatible_no_attr_license is enabled by default - `--incompatible_disable_crosstool_file` has been flipped (#7320) - A new flag `--incompatible_string_join_requires_strings` is introduced. The sequence argument of `string.join` must contain only string elements. - --incompatible_symlinked_sandbox_expands_tree_artifacts_in_runfile s_tree has been flipped - Incompatible flag `--incompatible_disable_legacy_cc_provider` has been flipped (see #7036 for details). - Don't drop the analysis cache when the same --define flag is set multiple times and the last value is the same (e.g. if the current invocation was run with "--define foo=bar" and the previous one was run with "--define foo=baz --define foo=bar"). - The --incompatible_disable_genrule_cc_toolchain_dependency flag has been flipped (see #6867 for details). - Incompatible change `--incompatible_remove_cpu_and_compiler_attributes_from_cc_toolcha in` has been flipped (see #7075 for details). - --noexperimental_java_coverage is a no-op flag. - --experimental_java_coverage/--incompatible_java_coverage flag was removed. See #7425. - incompatible_use_toolchain_providers_in_java_common: pass JavaToolchainInfo and JavaRuntimeInfo providers to java_common APIs instead of configured targets (#7186.) - --incompatible_remote_symlinks has been flipped. The remote caching and execution protocol will now represent symlinks in outputs as such. See #7917 for more details. - Bazel is now ~20MiB smaller, from unbundling the Android rules' runtime dependencies. This release contains contributions from many people at Google, as well as Andreas Herrmann, Andrew Suffield, Andy Scott, Benjamin Peterson, Ed Baunton, George Gensure, Ian McGinnis, Ity Kaul, Jingwen Chen, John Millikin, Keith Smiley, Marwan Tammam, Mike Fourie, Oscar Bonilla, perwestling, petros, Robert Sayre, Ryan Beasley, silvergasp, Stanimir Mladenov, Travis Cline, Vladimir Chebotarev, ??.
(This is a roll-forward of bf66dc7.) This flips --incompatible_use_python_toolchains, which deprecates --python_top (and for the most part, --python_path). See #7899 for more on the change and migration procedure. RELNOTES[INC]: Python rules now determine the Python runtime using toolchains rather than `--python_top` and `--python_path`, which are deprecated. See #7899 for information on declaring Python toolchains and migrating your code. As a side-benefit, this addresses #4815 (incorrect interpreter version used) on non-Windows platforms. You can temporarily opt out of this change with `--incompatible_use_python_toolchains=false`. Fixes #7899, fixes #7375, significant progress on #4815. DO NOT SUBMIT: Waiting on fixes for downstream projects, and a bazel breaking change release. PiperOrigin-RevId: 246409519 Change-Id: I52dd56bac83e74405d713db9f9966daa641c0bae
(This is a roll-forward of bazelbuild@bf66dc7.) This flips --incompatible_use_python_toolchains, which deprecates --python_top (and for the most part, --python_path). See bazelbuild#7899 for more on the change and migration procedure. Known downstream breakages are summarized [here](bazelbuild#7899 (comment)). Fixes bazelbuild#7899, fixes bazelbuild#7375, significant progress on bazelbuild#4815. RELNOTES[INC]: Python rules now determine the Python runtime using toolchains rather than `--python_top` and `--python_path`, which are deprecated. See [bazelbuild#7899](bazelbuild#7899) for information on declaring Python toolchains and migrating your code. As a side-benefit, this addresses [bazelbuild#4815](bazelbuild#4815) (incorrect interpreter version used) on non-Windows platforms. Note however that some builds break due to getting the version they asked for -- consider setting `python_version = "PY2"` on Python 2 targets and `--host_force_python=PY2` if any Python 2 targets are used in the host configuration. You can temporarily opt out of this change with `--incompatible_use_python_toolchains=false`. PiperOrigin-RevId: 250918912
(This is a roll-forward of bazelbuild@bf66dc7.) This flips --incompatible_use_python_toolchains, which deprecates --python_top (and for the most part, --python_path). See bazelbuild#7899 for more on the change and migration procedure. Known downstream breakages are summarized [here](bazelbuild#7899 (comment)). Fixes bazelbuild#7899, fixes bazelbuild#7375, significant progress on bazelbuild#4815. RELNOTES[INC]: Python rules now determine the Python runtime using toolchains rather than `--python_top` and `--python_path`, which are deprecated. See [bazelbuild#7899](bazelbuild#7899) for information on declaring Python toolchains and migrating your code. As a side-benefit, this addresses [bazelbuild#4815](bazelbuild#4815) (incorrect interpreter version used) on non-Windows platforms. Note however that some builds break due to getting the version they asked for -- consider setting `python_version = "PY2"` on Python 2 targets and `--host_force_python=PY2` if any Python 2 targets are used in the host configuration. You can temporarily opt out of this change with `--incompatible_use_python_toolchains=false`. PiperOrigin-RevId: 250918912
This seems to be resolved, but as a casual user of Python and new user of rules_python, it would be helpful to have simple documentation explaining how to do a hermetic build. (Somehow I am able to run my py_binary targets at the moment even though I know the dependencies in the BUILD.bazel files are inadequate.) |
This bug tracks designing, implementing, and migrating built-in Python rules to use the toolchain mechanism for resolving the Python runtime. This replaces the legacy mechanism of specifying
--python_top
to globally make all Python targets look at a specificpy_runtime
, or omitting--python_top
to use the system default "python" command.This is prioritized. Design doc to follow.
The text was updated successfully, but these errors were encountered: