Configuring Python toolchains and runtimes
This document explains how to configure the Python toolchain and runtimes for differentuse cases.
Bzlmod MODULE configuration
How to configurerules_python in yourMODULE.bazel file depends on how and whyyou’re using Python. There are four basic use cases:
A root module that always uses Python. For example, you’re building aPython application.
A library module with dev-only uses of Python. For example, a Java projectthat only uses Python as part of testing itself.
A library module without version constraints. For example, a rule set withPython build tools, but defers to the user as to what Python version is usedfor the tools.
A library module with version constraints. For example, a rule set withPython build tools, and the module requires a specific version of Pythonbe used with its tools.
Root modules
Root modules are always the top-most module. These are special in two ways:
Some
rules_pythonbzlmod APIs are only respected by the root module.The root module can force module overrides and specific module dependencyordering.
When configuringrules_python for a root module, you typically want toexplicitly specify the Python version you want to use. This ensures thatdependencies don’t change the Python version out from under you. Remember thatrules_python will set a version by default, but it will change regularly asit tracks a recent Python version.
NOTE: If your root module only uses Python for development of the module itself,you should read the dev-only library module section.
bazel_dep(name="rules_python",version=...)python=use_extension("@rules_python//python/extensions:python.bzl","python")python.defaults(python_version="3.12")python.toolchain(python_version="3.12")
Library modules
A library module is a module that can show up in arbitrary locations in theBzlmod module graph – it’s unknown where in the breadth-first search order themodule will be relative to other modules. For example,rules_python is alibrary module.
Library modules with dev-only Python usage
A library module with dev-only Python usage is usually one where Python is onlyused as part of its tests. For example, a module for Java rules might run somePython program to generate test data, but real usage of the rules don’t needPython to work. To configure this, follow the root-module setup, but remember tospecifydev_dependency=True to the bzlmod APIs:
# MODULE.bazelbazel_dep(name="rules_python",version=...,dev_dependency=True)python=use_extension("@rules_python//python/extensions:python.bzl","python",dev_dependency=True)python.defaults(python_version="3.12")python.toolchain(python_version="3.12")
Library modules without version constraints
A library module without version constraints is one where the version of Pythonused for the Python programs it runs isn’t chosen by the module itself. Instead,it’s up to the root module to pick an appropriate version of Python.
For this case, configuration is simple: just depend onrules_python and usethe normal//python:py_binary.bzl et al. rules. There is no need to callpython.toolchain –rules_python ensuressome Python version is available,but more often, the root module will specify some version.
# MODULE.bazelbazel_dep(name="rules_python",version=...)
Library modules with version constraints
A library module with version constraints is one where the module requires aspecific Python version be used with its tools. This has some pros/cons:
It allows the library’s tools to use a different version of Python thanthe rest of the build. For example, a user’s program could use Python 3.12,while the library module’s tools use Python 3.10.
It reduces the support burden for the library module because the library only needsto test for the particular Python version they intend to run as.
It raises the support burden for the library module because the version ofPython being used needs to be regularly incremented.
It has higher build overhead because additional runtimes and libraries needto be downloaded, and Bazel has to keep additional configuration state.
To configure this, request the Python versions needed inMODULE.bazel and usethe version-aware rules forpy_binary.
# MODULE.bazelbazel_dep(name="rules_python",version=...)python=use_extension("@rules_python//python/extensions:python.bzl","python")python.toolchain(python_version="3.12")# BUILD.bazelload("@rules_python//python:py_binary.bzl","py_binary")py_binary(...,python_version="3.12")
Pinning to a Python version
Pinning to a version allows targets to force that a specific Python version isused, even if the root module configures a different version as a default. Thisis most useful for two cases:
For submodules to ensure they run with the appropriate Python version
To allow incremental, per-target, upgrading to newer Python versions,typically in a monorepo situation.
To configure a submodule with the version-aware rules, request the particularversion you need when defining the toolchain:
# MODULE.bazelpython=use_extension("@rules_python//python/extensions:python.bzl","python")python.toolchain(python_version="3.11",)use_repo(python)
Then use the@rules_python repo in yourBUILD file to explicitly pin the Python version when calling the rule:
# BUILD.bazelload("@rules_python//python:py_binary.bzl","py_binary")py_binary(...,python_version="3.11")py_test(...,python_version="3.11")
Multiple versions can be specified and used within a single build.
# MODULE.bazelpython=use_extension("@rules_python//python/extensions:python.bzl","python")python.defaults(# The environment variable takes precedence if set.python_version="3.11",python_version_env="BAZEL_PYTHON_VERSION",)python.toolchain(python_version="3.11",)python.toolchain(python_version="3.12",)# BUILD.bazelload("@rules_python//python:py_binary.bzl","py_binary")load("@rules_python//python:py_test.bzl","py_test")# Defaults to 3.11py_binary(...)py_test(...)# Explicitly use Python 3.11py_binary(...,python_version="3.11")py_test(...,python_version="3.11")# Explicitly use Python 3.12py_binary(...,python_version="3.12")py_test(...,python_version="3.12")
For more documentation, see the bzlmod examples under theexamplesfolder. Look for the examples that contain aMODULE.bazel file.
Other toolchain details
Thepython.toolchain() call makes its contents available under a repo namedpython_X_Y, where X and Y are the major and minor versions. For example,python.toolchain(python_version="3.11") creates the repo@python_3_11.Remember to calluse_repo() to make repos visible to your module:use_repo(python,"python_3_11").
Deprecated since version 1.1.0:The toolchain-specificpy_binary andpy_test symbols are aliases to the regular rules.For example,load("@python_versions//3.11:defs.bzl","py_binary") &load("@python_versions//3.11:defs.bzl","py_test") are deprecated.
Usages of them should be changed to load the regular rules directly.For example, useload("@rules_python//python:py_binary.bzl","py_binary") &load("@rules_python//python:py_test.bzl","py_test") and then specify thepython_version when using the rules corresponding to the Python version you defined in your toolchain.Library modules with version constraints
Toolchain usage in other rules
Python toolchains can be utilized in other Bazel rules, such asgenrule(), byadding thetoolchains=["@rules_python//python:current_py_toolchain"]attribute. You can obtain the path to the Python interpreter using the$(PYTHON2) and$(PYTHON3)“Make”Variables. See thetest_current_py_toolchain targetfor an example. We also make available$(PYTHON2_ROOTPATH) and$(PYTHON3_ROOTPATH),which are Make Variable equivalents of$(PYTHON2) and$(PYTHON3) but for runfileslocations. These will be helpful if you need to set environment variables of binary/test ruleswhile using--nolegacy_external_runfiles.The original make variables still work in exec contexts such as genrules.
Overriding toolchain defaults and adding more versions
One can perform various overrides for the registered toolchains from the rootmodule. For example, the following use cases would be supported using theexisting attributes:
Limiting the available toolchains for the entire
bzlmodtransitive graphviapython.override.available_python_versions.Setting particular
X.Y.ZPython versions when modules requestX.Yversionviapython.override.minor_mapping.Per-version control of the coverage tool used using
python.single_version_platform_override.coverage_tool.Adding additional Python versions via
python.single_version_overrideorpython.single_version_platform_override.
Registering custom runtimes
Because the python-build-standalone project hasthousands of prebuilt runtimesavailable,rules_python only includes popular runtimes in its built-inconfigurations. If you want to use a runtime that isn’t already known torules_python, thensingle_version_platform_override() can be used to doso. In short, it allows specifying an arbitrary URL and using custom flagsto control when a runtime is used.
In the example below, we register a particular python-build-standalone runtimethat is activated for Linux x86 builds when the custom flag--//:runtime=my-custom-runtime is set.
# File: MODULE.bazelbazel_dep(name="bazel_skylib",version="1.7.1.")bazel_dep(name="rules_python",version="1.5.0")python=use_extension("@rules_python//python/extensions:python.bzl","python")python.single_version_platform_override(platform="my-platform",python_version="3.13.3",sha256="01d08b9bc8a96698b9d64c2fc26da4ecc4fa9e708ce0a34fb88f11ab7e552cbd",os_name="linux",arch="x86_64",target_settings=["@@//:runtime=my-custom-runtime",],urls=["https://github.com/astral-sh/python-build-standalone/releases/download/20250409/cpython-3.13.3+20250409-x86_64-unknown-linux-gnu-install_only_stripped.tar.gz"],)# File: //:BUILD.bazelload("@bazel_skylib//rules:common_settings.bzl","string_flag")string_flag(name="custom_runtime",build_setting_default="",)config_setting(name="is_custom_runtime_linux-x86-install-only-stripped",flag_values={":custom_runtime":"linux-x86-install-only-stripped",},)
Notes:
While any URL and archive can be used, it’s assumed their content looks likea python-build-standalone archive.
A “version-aware” toolchain is registered, which means the Python version flagmust also match (e.g.,
--@rules_python//python/config_settings:python_version=3.13.3must be set – seeminor_mappingandis_defaultfor controls and docsabout version matching and selection).The
target_compatible_withattribute can be used to entirely specify theargument of the same name that the toolchain uses.The labels in
target_settingsmust be absolute;@@refers to the main repo.The
target_settingsareconfig_settingtargets, which means you cancustomize how matching occurs.
See also
See//python/config_settings for flagsrules_python already definesthat can be used withtarget_settings. Some particular ones of note are--py_linux_libc and--py_freethreaded, among others.
Added in version 1.5.0:Added support for custom platform names,target_compatible_with, andtarget_settings withsingle_version_platform_override.
Using defined toolchains from WORKSPACE
It is possible to use toolchains defined inMODULE.bazel inWORKSPACE. For example,the followingMODULE.bazel andWORKSPACE provides a workingpip_parse setup:
# File: WORKSPACEload("@rules_python//python:repositories.bzl","py_repositories")py_repositories()load("@rules_python//python:pip.bzl","pip_parse")pip_parse(name="third_party",requirements_lock="//:requirements.txt",python_interpreter_target="@python_3_10_host//:python",)load("@third_party//:requirements.bzl","install_deps")install_deps()# File: MODULE.bazelbazel_dep(name="rules_python",version="0.40.0")python=use_extension("@rules_python//python/extensions:python.bzl","python")python.defaults(python_version="3.10")python.toolchain(python_version="3.10")use_repo(python,"python_3_10","python_3_10_host")
Note, the user has to import the*_host repository to use the Python interpreter in thepip_parse andwhl_library repository rules, and once that is done,users should be able to ensure the setting of the default toolchain even during thetransition period when some of the code is still defined inWORKSPACE.
Workspace configuration
To importrules_python in your project, you first need to add it to yourWORKSPACE file, using the snippet provided in therelease you choose.
To depend on a particular unreleased version, you can do the following:
load("@bazel_tools//tools/build_defs/repo:http.bzl","http_archive")# Update the SHA and VERSION to the lastest version available here:# https://github.com/bazel-contrib/rules_python/releases.SHA="84aec9e21cc56fbc7f1335035a71c850d1b9b5cc6ff497306f84cced9a769841"VERSION="0.23.1"http_archive(name="rules_python",sha256=SHA,strip_prefix="rules_python-{}".format(VERSION),url="https://github.com/bazel-contrib/rules_python/releases/download/{}/rules_python-{}.tar.gz".format(VERSION,VERSION),)load("@rules_python//python:repositories.bzl","py_repositories")py_repositories()
Workspace toolchain registration
To register a hermetic Python toolchain rather than rely on a system-installed interpreter for runtime execution, you can add to theWORKSPACE file:
load("@rules_python//python:repositories.bzl","python_register_toolchains")python_register_toolchains(name="python_3_11",# Available versions are listed in @rules_python//python:versions.bzl.# We recommend using the same version your team is already standardized on.python_version="3.11",)load("@rules_python//python:pip.bzl","pip_parse")pip_parse(...python_interpreter_target="@python_3_11_host//:python",...)
After registration, your Python targets will use the toolchain’s interpreter during execution, but a system-installed interpreteris still used to “bootstrap” Python targets (see https://github.com/bazel-contrib/rules_python/issues/691).You may also find some quirks while using this toolchain. Please refer topython-build-standalone documentation’sQuirks section.
Local toolchain
It’s possible to use a locally installed Python runtime instead of the regularprebuilt, remotely downloaded ones. A local toolchain contains the Pythonruntime metadata (Python version, headers, ABI flags, etc.) that the regularremotely downloaded runtimes contain, which makes it possible to build, e.g., Cextensions (unlike the autodetecting and runtime environment toolchains).
For simple cases, thelocal_runtime_repo andlocal_runtime_toolchains_repo rules are provided that will introspect aPython installation and create an appropriate Bazel definition from it. To dothis, three pieces need to be wired together:
Specify a path or command to a Python interpreter (multiple can be defined).
Create toolchains for the runtimes in (1).
Register the toolchains created by (2).
The following is an example that will usepython3 fromPATH to find theinterpreter, then introspect its installation to generate a full toolchain.
# File: MODULE.bazellocal_runtime_repo=use_repo_rule("@rules_python//python/local_toolchains:repos.bzl","local_runtime_repo",)local_runtime_toolchains_repo=use_repo_rule("@rules_python//python/local_toolchains:repos.bzl","local_runtime_toolchains_repo",)# Step 1: Define the Python runtimelocal_runtime_repo(name="local_python3",interpreter_path="python3",on_failure="fail",dev_dependency=True)# Step 2: Create toolchains for the runtimeslocal_runtime_toolchains_repo(name="local_toolchains",runtimes=["local_python3"],# TIP: The `target_settings` arg can be used to activate them based on# command line flags; see docs below.dev_dependency=True)# Step 3: Register the toolchainsregister_toolchains("@local_toolchains//:all",dev_dependency=True)
In the example above,interpreter_path is used to find Python viaPATHlookups. Alternatively,interpreter_target can be set, which canrefer to a Python in an arbitrary Bazel repository.
Important
Be sure to setdev_dependency=True. Using a local toolchain only makes sensefor the root module.
If an intermediate module does it, then theregister_toolchains() call willtake precedence over the default rules_python toolchains and cause problems fordownstream modules.
Multiple runtimes and/or toolchains can be defined, which allows for multiplePython versions and/or platforms to be configured in a singleMODULE.bazel.Note thatregister_toolchains will insert the local toolchain earlier in thetoolchain ordering, so it will take precedence over other registered toolchains.To better control when the toolchain is used, see [Conditionally using localtoolchains].
Conditionally using local toolchains
By default, a local toolchain has few constraints and is early in the toolchainordering, which means it will usually be used no matter what. This can beproblematic for CI (where it shouldn’t be used), expensive for CI (CI mustinitialize/download the repository to determine its Python version), andannoying for iterative development (enabling/disabling it requires modifyingMODULE.bazel).
These behaviors can be mitigated, but it requires additional configurationto avoid triggering the local toolchain repository to initialize (i.e., runlocal commands and perform downloads).
The two settings to change arelocal_runtime_toolchains_repo.target_compatible_with andlocal_runtime_toolchains_repo.target_settings, which control how Bazeldecides if a toolchain should match. By default, they point to targetswithinthe local runtime repository (triggering repo initialization). We have to overridethem tonot reference the local runtime repository at all.
In the example below, we reconfigure the local toolchains so they are onlyactivated if the custom flag--//:py=local is set and the target platformmatches the Bazel host platform. The net effect is that CI won’t use the localtoolchain (nor initialize its repository), and developers can easilyenable/disable the local toolchain with a command line flag.
# File: MODULE.bazelbazel_dep(name="bazel_skylib",version="1.7.1")local_runtime_toolchains_repo(name="local_toolchains",runtimes=["local_python3"],target_compatible_with={"local_python3":["HOST_CONSTRAINTS"],},target_settings={"local_python3":["@//:is_py_local"]})# File: BUILD.bazelload("@bazel_skylib//rules:common_settings.bzl","string_flag")config_setting(name="is_py_local",flag_values={":py":"local"},)string_flag(name="py",build_setting_default="",)
Tip
Easily switching betweenmultiple local toolchains can be accomplished byadding additional:is_py_X targets and setting--//:py to match.to easily switch between different local toolchains.
Runtime environment toolchain
The runtime environment toolchain is a minimal toolchain that doesn’t provideinformation about Python at build time. In particular, this means it is not ableto build C extensions – doing so requires knowing, at build time, what Pythonheaders to use.
In effect, all it does is generate a small wrapper script that simply calls, e.g.,/usr/bin/envpython3 to run a program. This makes it easy to change whatPython is used to run a program but also makes it easy to use a Python versionthat isn’t compatible with build-time assumptions.
register_toolchains("@rules_python//python/runtime_env_toolchains:all")
Note that this toolchain has no constraints, i.e. it will match any platform,Python version, etc.
See also
[Local toolchain], which creates a more full featured toolchain from alocally installed Python.
Autodetecting toolchain
The autodetecting toolchain is a deprecated toolchain that is built into Bazel.Its name is a bit misleading: it doesn’t autodetect anything. All it does isusepython3 from the environment a binary runs within. This provides extremelylimited functionality to the rules (at build time, nothing is knowable aboutthe Python runtime).
Bazel itself automatically registers@bazel_tools//tools/python:autodetecting_toolchainas the lowest priority toolchain. ForWORKSPACE builds, if no other toolchainis registered, that toolchain will be used. For Bzlmod builds,rules_pythonautomatically registers a higher-priority toolchain; it won’t be used unlessthere is a toolchain misconfiguration somewhere.
To aid migration off the Bazel-builtin toolchain,rules_python provides@rules_python//python/runtime_env_toolchains:all. This is an equivalenttoolchain but is implemented usingrules_python’s objects.
Custom toolchains
Whilerules_python provides toolchains by default, it is not required to usethem, and you can define your own toolchains to use instead. This sectiongives an introduction to how to define them yourself.
Note
Defining your own toolchains is an advanced feature.
APIs used for defining them are less stable and may change more often.
Under the hood, there are multiple toolchains that comprise the differentinformation necessary to build Python targets. Each one has anassociatedtoolchain type that identifies it. We call the collection of thesetoolchains a “toolchain suite”.
One of the underlying design goals of the toolchains is to support complex andbespoke environments. Such environments may use an arbitrary combination ofRBE, cross-platform building, multiple Python versions,building Python from source, embedding Python (as opposed to building separateinterpreters), using prebuilt binaries, or using binaries built from source. Tothat end, many of the attributes they accept, and fields they provide, areoptional.
Target toolchain type
The target toolchain type is//python:toolchain_type, and itis fortarget configuration runtime information, e.g., the Python versionand interpreter binary that a program will use.
This is typically implemented usingpy_runtime(), whichprovides thePyRuntimeInfo provider. For historical reasons from thePython 2 transition,py_runtime is wrapped inpy_runtime_pair,which providesToolchainInfo with the fieldpy3_runtime, which is aninstance ofPyRuntimeInfo.
This toolchain type is intended to hold onlytarget configuration values. Assuch, when defining its associatedtoolchain target, onlysettoolchain.target_compatible_with and/ortoolchain.target_settings constraints; there is no need tosettoolchain.exec_compatible_with.
Python C toolchain type
The Python C toolchain type (“py cc”) is//python/cc:toolchain_type, andit has C/C++ information for thetarget configuration, e.g., the C headers thatprovidePython.h.
This is typically implemented usingpy_cc_toolchain(), which providesToolchainInfo with the fieldpy_cc_toolchain set, which is aPyCcToolchainInfo provider instance.
This toolchain type is intended to hold onlytarget configuration valuesrelating to the C/C++ information for the Python runtime. As such, when definingits associatedtoolchain target, only settoolchain.target_compatible_with and/ortoolchain.target_settings constraints; there is no need tosettoolchain.exec_compatible_with.
Exec tools toolchain type
The exec tools toolchain type is//python:exec_tools_toolchain_type,and it is for supporting tools forbuilding programs, e.g., the binary toprecompile code at build time.
This toolchain type is intended to hold onlyexec configuration values –usually tools (prebuilt or from-source) used to build Python targets.
This is typically implemented usingpy_exec_tools_toolchain, whichprovidesToolchainInfo with the fieldexec_tools set, which is aninstance ofPyExecToolsInfo.
The toolchain constraints of this toolchain type can be a bit more nuanced thanthe other toolchain types. Typically, you settoolchain.target_settings to the Python version the toolsare for, andtoolchain.exec_compatible_with to the platformthey can run on. This allows the toolchain to first be considered based on thetarget configuration (e.g. Python version), then for one to be chosen based onfinding one compatible with the available host platforms to run the tool on.
However, whattarget_compatible_with/target_settings andexec_compatible_with values to use depends on the details of the tools being used.For example:
If you had a precompiler that supported any version of Python, thenputting the Python version in
target_settingsis unnecessary.If you had a prebuilt polyglot precompiler binary that could run on anyplatform, then setting
exec_compatible_withis unnecessary.
This can work because, when the rules invoke these build tools, they pass alongall necessary information so that the tool can be entirely independent of thetarget configuration being built for.
Alternatively, if you had a precompiler that only ran on Linux and onlyproduced valid output for programs intended to run on Linux, thenbothexec_compatible_with andtarget_compatible_with must be set to Linux.
Custom toolchain example
Here, we show an example for a semi-complicated toolchain suite, one that is:
A CPython-based interpreter
For Python version 3.12.0
Using an in-build interpreter built from source
That only runs on Linux
Using a prebuilt precompiler that only runs on Linux and only producesbytecode valid for 3.12
With the exec tools interpreter disabled (unnecessary with a prebuiltprecompiler)
Providing C headers and libraries
Defining toolchains for this might look something like this:
# -------------------------------------------------------# File: toolchain_impl/BUILD# Contains the tool definitions (runtime, headers, libs).# -------------------------------------------------------load("@rules_python//python:py_cc_toolchain.bzl","py_cc_toolchain")load("@rules_python//python:py_exec_tools_toolchain.bzl","py_exec_tools_toolchain")load("@rules_python//python:py_runtime.bzl","py_runtime")load("@rules_python//python:py_runtime_pair.bzl","py_runtime_pair")MAJOR=3MINOR=12MICRO=0py_runtime(name="runtime",interpreter=":python",interpreter_version_info={"major":str(MAJOR),"minor":str(MINOR),"micro":str(MICRO),}implementation="cpython")py_runtime_pair(name="runtime_pair",py3_runtime=":runtime")py_cc_toolchain(name="py_cc_toolchain_impl",headers=":headers",libs=":libs",python_version="{}.{}".format(MAJOR,MINOR))py_exec_tools_toolchain(name="exec_tools_toolchain_impl",exec_interpreter="@rules_python/python:none",precompiler="precompiler-cpython-3.12")cc_binary(name="python3.12",...)cc_library(name="headers",...)cc_library(name="libs",...)# ------------------------------------------------------------------# File: toolchains/BUILD# Putting toolchain() calls in a separate package from the toolchain# implementations minimizes Bazel loading overhead.# ------------------------------------------------------------------toolchain(name="runtime_toolchain",toolchain="//toolchain_impl:runtime_pair",toolchain_type="@rules_python//python:toolchain_type",target_compatible_with=["@platforms/os:linux"],)toolchain(name="py_cc_toolchain",toolchain="//toolchain_impl:py_cc_toolchain_impl",toolchain_type="@rules_python//python/cc:toolchain_type",target_compatible_with=["@platforms/os:linux"],)toolchain(name="exec_tools_toolchain",toolchain="//toolchain_impl:exec_tools_toolchain_impl",toolchain_type="@rules_python//python:exec_tools_toolchain_type",target_settings=["@rules_python//python/config_settings:is_python_3.12",],exec_compatible_with=["@platforms/os:linux"],)# -----------------------------------------------# File: MODULE.bazel or WORKSPACE.bazel# These toolchains will be considered before others.# -----------------------------------------------register_toolchains("//toolchains:all")
When registering custom toolchains, be aware of thetoolchain registrationorder. In brief,toolchain order is the BFS-order of the modules; see the Bazel docs for a moredetailed description.
Note
The toolchain() calls should be in a separate BUILD file from everything else.This avoids Bazel having to perform unnecessary work when it discovers the listof available toolchains.
Toolchain selection flags
Currently the following flags are used to influence toolchain selection:
--@rules_python//python/config_settings:py_linux_libcfor selecting the Linux libc variant.--@rules_python//python/config_settings:py_freethreadedfor selectingthe freethreaded experimental Python builds available from3.13.0onwards.
Running the underlying interpreter
To run the interpreter that Bazel will use, you can use the@rules_python//python/bin:python target. This is a binary target withthe executable pointing at thepython3 binary plus its relevant runfiles.
$bazelrun@rules_python//python/bin:pythonPython 3.11.1 (main, Jan 16 2023, 22:41:20) [Clang 15.0.7 ] on linuxType "help", "copyright", "credits" or "license" for more information.>>>$bazelrun@rules_python//python/bin:python--@rules_python//python/config_settings:python_version=3.12Python 3.12.0 (main, Oct 3 2023, 01:27:23) [Clang 17.0.1 ] on linuxType "help", "copyright", "credits" or "license" for more information.>>>
You can also access a specific binary’s interpreter this way by using the@rules_python//python/bin:python_src target. In the example below, it isassumed that the@rules_python//tools/publish:twine binary is fixed at Python3.11.
$bazelrun@rules_python//python/bin:python--@rules_python//python/bin:interpreter_src=@rules_python//tools/publish:twinePython 3.11.1 (main, Jan 16 2023, 22:41:20) [Clang 15.0.7 ] on linuxType "help", "copyright", "credits" or "license" for more information.>>>$bazelrun@rules_python//python/bin:python--@rules_python//python/bin:interpreter_src=@rules_python//tools/publish:twine--@rules_python//python/config_settings:python_version=3.12Python 3.11.1 (main, Jan 16 2023, 22:41:20) [Clang 15.0.7 ] on linuxType "help", "copyright", "credits" or "license" for more information.>>>
Despite setting the Python version explicitly to 3.12 in the example above, theinterpreter comes from the@rules_python//tools/publish:twine binary. That isa fixed version.
Note
Thepython target does not provide access to any modules frompy_*targets on its own. Please file a feature request if this is desired.
Differences from//python/bin:repl
The//python/bin:python target provides access to the underlying interpreterwithout any hermeticity guarantees.
The//python/bin:repl target provides an environment identical towhatpy_binary provides. That means it handles things like thePYTHONSAFEPATHenvironment variable automatically. The//python/bin:python target will not.