{'main': 'examples.wheel.main:main'}
.entry_points
attribute, which supports console_scripts
as well as other entry points. | Dictionary: String -> String | optional | {}
|
| deps | Targets to be included in the distribution.py_library
rules or filesets (for packaging data files).py_library
targets and use entry_points
attribute to specify console_scripts
than to package py_binary
rules. py_binary
targets would wrap a executable script that tries to locate .runfiles
directory which is not packaged in the wheel. | List of labels | optional | []
|
| description_file | A file containing text describing the package. | Label | optional | None
|
-| distribution | Name of the distribution.{NAME}
format, for example: - distribution = "package.{CLASSIFIER}"
- distribution = "{DISTRIBUTION}"
{'console_scripts': ['main = examples.wheel.main:main']}
. | Dictionary: String -> List of strings | optional | {}
|
| extra_distinfo_files | Extra files to add to distinfo directory in the archive. | Dictionary: Label -> String | optional | {}
|
| extra_requires | List of optional requirements for this package | Dictionary: String -> List of strings | optional | {}
|
diff --git a/docs/pip.md b/docs/pip.md
index e4c3f21b79..8ad5b6903a 100644
--- a/docs/pip.md
+++ b/docs/pip.md
@@ -45,6 +45,9 @@ It also generates two targets for running pip-compile:
- validate with `bazel test [name]_test`
- update with `bazel run [name].update`
+If you are using a version control system, the requirements.txt generated by this rule should
+be checked into it to ensure that all developers/users have the same dependency versions.
+
**PARAMETERS**
diff --git a/examples/bzlmod/.bazelrc b/examples/bzlmod/.bazelrc
index b8c233f98c..6f557e67b9 100644
--- a/examples/bzlmod/.bazelrc
+++ b/examples/bzlmod/.bazelrc
@@ -1,3 +1,10 @@
common --experimental_enable_bzlmod
coverage --java_runtime_version=remotejdk_11
+
+test --test_output=errors --enable_runfiles
+
+# Windows requires these for multi-python support:
+build --enable_runfiles
+
+startup --windows_enable_symlinks
diff --git a/examples/bzlmod/BUILD.bazel b/examples/bzlmod/BUILD.bazel
index e1f5790631..3bff20836d 100644
--- a/examples/bzlmod/BUILD.bazel
+++ b/examples/bzlmod/BUILD.bazel
@@ -1,9 +1,18 @@
+# Load various rules so that we can have bazel download
+# various rulesets and dependencies.
+# The `load` statement imports the symbol for the rule, in the defined
+# ruleset. When the symbol is loaded you can use the rule.
+
+# The names @pip and @python_39 are values that are repository
+# names. Those names are defined in the MODULES.bazel file.
load("@bazel_skylib//rules:build_test.bzl", "build_test")
load("@pip//:requirements.bzl", "all_requirements", "all_whl_requirements", "requirement")
-load("@python3_9//:defs.bzl", py_test_with_transition = "py_test")
+load("@python_3_9//:defs.bzl", py_test_with_transition = "py_test")
load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_test")
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
+# This stanza calls a rule that generates targets for managing pip dependencies
+# with pip-compile.
compile_pip_requirements(
name = "requirements",
extra_args = ["--allow-unsafe"],
@@ -12,6 +21,11 @@ compile_pip_requirements(
requirements_windows = "requirements_windows.txt",
)
+# The rules below are language specific rules defined in
+# rules_python. See
+# https://bazel.build/reference/be/python
+
+# see https://bazel.build/reference/be/python#py_library
py_library(
name = "lib",
srcs = ["lib.py"],
@@ -22,6 +36,7 @@ py_library(
],
)
+# see https://bazel.build/reference/be/python#py_binary
py_binary(
name = "bzlmod",
srcs = ["__main__.py"],
@@ -32,6 +47,7 @@ py_binary(
],
)
+# see https://bazel.build/reference/be/python#py_test
py_test(
name = "test",
srcs = ["test.py"],
@@ -46,6 +62,11 @@ py_test_with_transition(
deps = [":lib"],
)
+# This example is also used for integration tests within
+# rules_python. We are using
+# https://github.com/bazelbuild/bazel-skylib
+# to run some of the tests.
+# See: https://github.com/bazelbuild/bazel-skylib/blob/main/docs/build_test_doc.md
build_test(
name = "all_wheels",
targets = all_whl_requirements,
diff --git a/examples/bzlmod/MODULE.bazel b/examples/bzlmod/MODULE.bazel
index 145cebd276..40dfb6aed1 100644
--- a/examples/bzlmod/MODULE.bazel
+++ b/examples/bzlmod/MODULE.bazel
@@ -11,32 +11,64 @@ local_path_override(
path = "../..",
)
+# This name is generated by python.toolchain(), and is later passed
+# to use_repo() and interpreter.install().
+PYTHON_NAME_39 = "python_3_9"
+
+INTERPRETER_NAME_39 = "interpreter_39"
+
+PYTHON_NAME_310 = "python_3_10"
+
+INTERPRETER_NAME_310 = "interpreter_310"
+
+# We next initialize the python toolchain using the extension.
+# You can set different Python versions in this block.
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
python.toolchain(
- name = "python3_9",
configure_coverage_tool = True,
+ # Only set when you have mulitple toolchain versions.
+ is_default = True,
python_version = "3.9",
)
-use_repo(python, "python3_9")
-use_repo(python, "python3_9_toolchains")
-register_toolchains(
- "@python3_9_toolchains//:all",
+# We are also using a second version of Python in this project.
+# Typically you will only need a single version of Python, but
+# If you need a different vesion we support more than one.
+# Note: we do not supporting using multiple pip extensions, this is
+# work in progress.
+python.toolchain(
+ configure_coverage_tool = True,
+ python_version = "3.10",
)
+# You only need to load this repositories if you are using muiltple Python versions.
+# See the tests folder for various examples.
+use_repo(python, PYTHON_NAME_39, "python_aliases")
+
+# The interpreter extension discovers the platform specific Python binary.
+# It creates a symlink to the binary, and we pass the label to the following
+# pip.parse call.
interpreter = use_extension("@rules_python//python/extensions:interpreter.bzl", "interpreter")
interpreter.install(
- name = "interpreter_python3_9",
- python_name = "python3_9",
+ name = INTERPRETER_NAME_39,
+ python_name = PYTHON_NAME_39,
+)
+
+# This second call is only needed if you are using mulitple different
+# Python versions/interpreters.
+interpreter.install(
+ name = INTERPRETER_NAME_310,
+ python_name = PYTHON_NAME_310,
)
-use_repo(interpreter, "interpreter_python3_9")
+use_repo(interpreter, INTERPRETER_NAME_39, INTERPRETER_NAME_310)
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
pip.parse(
name = "pip",
- # Intentionally set it false because the "true" case is already covered by examples/bzlmod_build_file_generation
+ # Intentionally set it false because the "true" case is already
+ # covered by examples/bzlmod_build_file_generation
incompatible_generate_aliases = False,
- python_interpreter_target = "@interpreter_python3_9//:python",
+ python_interpreter_target = "@{}//:python".format(INTERPRETER_NAME_39),
requirements_lock = "//:requirements_lock.txt",
requirements_windows = "//:requirements_windows.txt",
)
diff --git a/examples/bzlmod/__main__.py b/examples/bzlmod/__main__.py
index 099493b3c8..daf17495c2 100644
--- a/examples/bzlmod/__main__.py
+++ b/examples/bzlmod/__main__.py
@@ -13,6 +13,8 @@
# limitations under the License.
from lib import main
+import sys
if __name__ == "__main__":
print(main([["A", 1], ["B", 2]]))
+ print(sys.version)
diff --git a/examples/bzlmod/other_module/MODULE.bazel b/examples/bzlmod/other_module/MODULE.bazel
index 992e120760..cc23a51601 100644
--- a/examples/bzlmod/other_module/MODULE.bazel
+++ b/examples/bzlmod/other_module/MODULE.bazel
@@ -2,4 +2,33 @@ module(
name = "other_module",
)
+# This module is using the same version of rules_python
+# that the parent module uses.
bazel_dep(name = "rules_python", version = "")
+
+# It is not best practice to use a python.toolchian in
+# a submodule. This code only exists to test that
+# we support doing this. This code is only for rules_python
+# testing purposes.
+PYTHON_NAME_39 = "python_3_9"
+
+PYTHON_NAME_311 = "python_3_11"
+
+python = use_extension("@rules_python//python/extensions:python.bzl", "python")
+python.toolchain(
+ configure_coverage_tool = True,
+ python_version = "3.9",
+)
+python.toolchain(
+ configure_coverage_tool = True,
+ # In a submodule this is ignored
+ is_default = True,
+ python_version = "3.11",
+)
+
+# created by the above python.toolchain calls.
+use_repo(
+ python,
+ PYTHON_NAME_39,
+ PYTHON_NAME_311,
+)
diff --git a/examples/bzlmod/other_module/other_module/pkg/BUILD.bazel b/examples/bzlmod/other_module/other_module/pkg/BUILD.bazel
index 9a130e3554..6e37df8233 100644
--- a/examples/bzlmod/other_module/other_module/pkg/BUILD.bazel
+++ b/examples/bzlmod/other_module/other_module/pkg/BUILD.bazel
@@ -1,3 +1,4 @@
+load("@python_3_11//:defs.bzl", py_binary_311 = "py_binary")
load("@rules_python//python:defs.bzl", "py_library")
py_library(
@@ -8,4 +9,15 @@ py_library(
deps = ["@rules_python//python/runfiles"],
)
+# This is used for testing mulitple versions of Python. This is
+# used only when you need to support multiple versions of Python
+# in the same project.
+py_binary_311(
+ name = "lib_311",
+ srcs = ["lib.py"],
+ data = ["data/data.txt"],
+ visibility = ["//visibility:public"],
+ deps = ["@rules_python//python/runfiles"],
+)
+
exports_files(["data/data.txt"])
diff --git a/examples/bzlmod/runfiles/BUILD.bazel b/examples/bzlmod/runfiles/BUILD.bazel
index 3503ac3017..add56b3bd0 100644
--- a/examples/bzlmod/runfiles/BUILD.bazel
+++ b/examples/bzlmod/runfiles/BUILD.bazel
@@ -1,6 +1,5 @@
load("@rules_python//python:defs.bzl", "py_test")
-# gazelle:ignore
py_test(
name = "runfiles_test",
srcs = ["runfiles_test.py"],
diff --git a/examples/bzlmod/test.py b/examples/bzlmod/test.py
index a36c19dc63..0486916e1b 100644
--- a/examples/bzlmod/test.py
+++ b/examples/bzlmod/test.py
@@ -30,6 +30,18 @@ def test_coverage_doesnt_shadow_stdlib(self):
except ImportError:
self.skipTest("not running under coverage, skipping")
+ self.assertEqual(
+ "html",
+ f"{html_stdlib.__name__}",
+ "'html' from stdlib was not loaded correctly",
+ )
+
+ self.assertEqual(
+ "coverage.html",
+ f"{html_coverage.__name__}",
+ "'coverage.html' was not loaded correctly",
+ )
+
self.assertNotEqual(
html_stdlib,
html_coverage,
diff --git a/examples/bzlmod/tests/BUILD.bazel b/examples/bzlmod/tests/BUILD.bazel
new file mode 100644
index 0000000000..5331f4ab96
--- /dev/null
+++ b/examples/bzlmod/tests/BUILD.bazel
@@ -0,0 +1,142 @@
+load("@python_aliases//3.10:defs.bzl", py_binary_3_10 = "py_binary", py_test_3_10 = "py_test")
+load("@python_aliases//3.11:defs.bzl", py_binary_3_11 = "py_binary", py_test_3_11 = "py_test")
+load("@python_aliases//3.9:defs.bzl", py_binary_3_9 = "py_binary", py_test_3_9 = "py_test")
+load("@rules_python//python:defs.bzl", "py_binary", "py_test")
+
+py_binary(
+ name = "version_default",
+ srcs = ["version.py"],
+ main = "version.py",
+)
+
+py_binary_3_9(
+ name = "version_3_9",
+ srcs = ["version.py"],
+ main = "version.py",
+)
+
+py_binary_3_10(
+ name = "version_3_10",
+ srcs = ["version.py"],
+ main = "version.py",
+)
+
+py_binary_3_11(
+ name = "version_3_11",
+ srcs = ["version.py"],
+ main = "version.py",
+)
+
+# This is a work in progress and the commented
+# tests will not work until we can support
+# multiple pips with bzlmod.
+
+#py_test(
+# name = "my_lib_default_test",
+# srcs = ["my_lib_test.py"],
+# main = "my_lib_test.py",
+# deps = ["//libs/my_lib"],
+#)
+
+#py_test_3_9(
+# name = "my_lib_3_9_test",
+# srcs = ["my_lib_test.py"],
+# main = "my_lib_test.py",
+# deps = ["//libs/my_lib"],
+#)
+
+#py_test_3_10(
+# name = "my_lib_3_10_test",
+# srcs = ["my_lib_test.py"],
+# main = "my_lib_test.py",
+# deps = ["//libs/my_lib"],
+#)
+
+#py_test_3_11(
+# name = "my_lib_3_11_test",
+# srcs = ["my_lib_test.py"],
+# main = "my_lib_test.py",
+# deps = ["//libs/my_lib"],
+#)
+
+py_test(
+ name = "version_default_test",
+ srcs = ["version_test.py"],
+ env = {"VERSION_CHECK": "3.9"}, # The default defined in the WORKSPACE.
+ main = "version_test.py",
+)
+
+py_test_3_9(
+ name = "version_3_9_test",
+ srcs = ["version_test.py"],
+ env = {"VERSION_CHECK": "3.9"},
+ main = "version_test.py",
+)
+
+py_test_3_10(
+ name = "version_3_10_test",
+ srcs = ["version_test.py"],
+ env = {"VERSION_CHECK": "3.10"},
+ main = "version_test.py",
+)
+
+py_test_3_11(
+ name = "version_3_11_test",
+ srcs = ["version_test.py"],
+ env = {"VERSION_CHECK": "3.11"},
+ main = "version_test.py",
+)
+
+py_test(
+ name = "version_default_takes_3_10_subprocess_test",
+ srcs = ["cross_version_test.py"],
+ data = [":version_3_10"],
+ env = {
+ "SUBPROCESS_VERSION_CHECK": "3.10",
+ "SUBPROCESS_VERSION_PY_BINARY": "$(rootpath :version_3_10)",
+ "VERSION_CHECK": "3.9",
+ },
+ main = "cross_version_test.py",
+)
+
+py_test_3_10(
+ name = "version_3_10_takes_3_9_subprocess_test",
+ srcs = ["cross_version_test.py"],
+ data = [":version_3_9"],
+ env = {
+ "SUBPROCESS_VERSION_CHECK": "3.9",
+ "SUBPROCESS_VERSION_PY_BINARY": "$(rootpath :version_3_9)",
+ "VERSION_CHECK": "3.10",
+ },
+ main = "cross_version_test.py",
+)
+
+sh_test(
+ name = "version_test_binary_default",
+ srcs = ["version_test.sh"],
+ data = [":version_default"],
+ env = {
+ "VERSION_CHECK": "3.9", # The default defined in the WORKSPACE.
+ "VERSION_PY_BINARY": "$(rootpath :version_default)",
+ },
+)
+
+sh_test(
+ name = "version_test_binary_3_9",
+ srcs = ["version_test.sh"],
+ data = [":version_3_9"],
+ env = {
+ "VERSION_CHECK": "3.9",
+ "VERSION_PY_BINARY": "$(rootpath :version_3_9)",
+ },
+)
+
+sh_test(
+ name = "version_test_binary_3_10",
+ srcs = ["version_test.sh"],
+ data = [":version_3_10"],
+ env = {
+ "VERSION_CHECK": "3.10",
+ "VERSION_PY_BINARY": "$(rootpath :version_3_10)",
+ },
+)
diff --git a/examples/bzlmod/tests/cross_version_test.py b/examples/bzlmod/tests/cross_version_test.py
new file mode 100644
index 0000000000..437be2ed5a
--- /dev/null
+++ b/examples/bzlmod/tests/cross_version_test.py
@@ -0,0 +1,39 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import subprocess
+import sys
+
+process = subprocess.run(
+ [os.getenv("SUBPROCESS_VERSION_PY_BINARY")],
+ stdout=subprocess.PIPE,
+ universal_newlines=True,
+)
+
+subprocess_current = process.stdout.strip()
+subprocess_expected = os.getenv("SUBPROCESS_VERSION_CHECK")
+
+if subprocess_current != subprocess_expected:
+ print(
+ f"expected subprocess version '{subprocess_expected}' is different than returned '{subprocess_current}'"
+ )
+ sys.exit(1)
+
+expected = os.getenv("VERSION_CHECK")
+current = f"{sys.version_info.major}.{sys.version_info.minor}"
+
+if current != expected:
+ print(f"expected version '{expected}' is different than returned '{current}'")
+ sys.exit(1)
diff --git a/examples/bzlmod/tests/version.py b/examples/bzlmod/tests/version.py
new file mode 100644
index 0000000000..2d293c1571
--- /dev/null
+++ b/examples/bzlmod/tests/version.py
@@ -0,0 +1,17 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+
+print(f"{sys.version_info.major}.{sys.version_info.minor}")
diff --git a/examples/bzlmod/tests/version_test.py b/examples/bzlmod/tests/version_test.py
new file mode 100644
index 0000000000..444f5e4321
--- /dev/null
+++ b/examples/bzlmod/tests/version_test.py
@@ -0,0 +1,23 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import sys
+
+expected = os.getenv("VERSION_CHECK")
+current = f"{sys.version_info.major}.{sys.version_info.minor}"
+
+if current != expected:
+ print(f"expected version '{expected}' is different than returned '{current}'")
+ sys.exit(1)
diff --git a/examples/bzlmod/tests/version_test.sh b/examples/bzlmod/tests/version_test.sh
new file mode 100755
index 0000000000..3bedb95ef9
--- /dev/null
+++ b/examples/bzlmod/tests/version_test.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+set -o errexit -o nounset -o pipefail
+
+version_py_binary=$("${VERSION_PY_BINARY}")
+
+if [[ "${version_py_binary}" != "${VERSION_CHECK}" ]]; then
+ echo >&2 "expected version '${VERSION_CHECK}' is different than returned '${version_py_binary}'"
+ exit 1
+fi
diff --git a/examples/bzlmod_build_file_generation/BUILD.bazel b/examples/bzlmod_build_file_generation/BUILD.bazel
index c667f1e49b..498969ba3a 100644
--- a/examples/bzlmod_build_file_generation/BUILD.bazel
+++ b/examples/bzlmod_build_file_generation/BUILD.bazel
@@ -7,7 +7,6 @@
# requirements.
load("@bazel_gazelle//:def.bzl", "gazelle")
load("@pip//:requirements.bzl", "all_whl_requirements")
-load("@python3//:defs.bzl", py_test_with_transition = "py_test")
load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_test")
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
load("@rules_python_gazelle_plugin//:def.bzl", "GAZELLE_PYTHON_RUNTIME_DEPS")
@@ -72,13 +71,6 @@ gazelle(
gazelle = "@rules_python_gazelle_plugin//python:gazelle_binary",
)
-py_test_with_transition(
- name = "test_with_transition",
- srcs = ["__test__.py"],
- main = "__test__.py",
- deps = [":bzlmod_build_file_generation"],
-)
-
# The following targets are created and maintained by gazelle
py_library(
name = "bzlmod_build_file_generation",
diff --git a/examples/bzlmod_build_file_generation/MODULE.bazel b/examples/bzlmod_build_file_generation/MODULE.bazel
index 179fe1bdea..fab2a26a83 100644
--- a/examples/bzlmod_build_file_generation/MODULE.bazel
+++ b/examples/bzlmod_build_file_generation/MODULE.bazel
@@ -46,40 +46,27 @@ python = use_extension("@rules_python//python/extensions:python.bzl", "python")
# This name is passed into python.toolchain and it's use_repo statement.
# We also use the same name for python.host_python_interpreter.
-PYTHON_NAME = "python3"
+PYTHON_NAME = "python_3_9"
+
+INTERPRETER_NAME = "interpreter"
# We next initialize the python toolchain using the extension.
# You can set different Python versions in this block.
python.toolchain(
- # This name is used in the various use_repo statements
- # below, and in the local extension that is in this
- # example.
- name = PYTHON_NAME,
configure_coverage_tool = True,
+ is_default = True,
python_version = "3.9",
)
-# Import the python repositories generated by the given module extension
-# into the scope of the current module.
-# All of the python3 repositories use the PYTHON_NAME as there prefix. They
-# are not catenated for ease of reading.
-use_repo(python, PYTHON_NAME, "python3_toolchains")
-
-# Register an already-defined toolchain so that Bazel can use it during
-# toolchain resolution.
-register_toolchains(
- "@python3_toolchains//:all",
-)
-
# The interpreter extension discovers the platform specific Python binary.
# It creates a symlink to the binary, and we pass the label to the following
# pip.parse call.
interpreter = use_extension("@rules_python//python/extensions:interpreter.bzl", "interpreter")
interpreter.install(
- name = "interpreter_python3",
+ name = INTERPRETER_NAME,
python_name = PYTHON_NAME,
)
-use_repo(interpreter, "interpreter_python3")
+use_repo(interpreter, INTERPRETER_NAME)
# Use the extension, pip.parse, to call the `pip_repository` rule that invokes
# `pip`, with `incremental` set. The pip call accepts a locked/compiled
@@ -102,7 +89,7 @@ pip.parse(
# is used for both resolving dependencies and running tests/binaries.
# If this isn't specified, then you'll get whatever is locally installed
# on your system.
- python_interpreter_target = "@interpreter_python3//:python",
+ python_interpreter_target = "@{}//:python".format(INTERPRETER_NAME),
requirements_lock = "//:requirements_lock.txt",
requirements_windows = "//:requirements_windows.txt",
)
diff --git a/examples/py_proto_library/MODULE.bazel b/examples/py_proto_library/MODULE.bazel
index 6fb1a05548..feb938da5c 100644
--- a/examples/py_proto_library/MODULE.bazel
+++ b/examples/py_proto_library/MODULE.bazel
@@ -14,15 +14,10 @@ local_path_override(
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
python.toolchain(
- name = "python3_9",
configure_coverage_tool = True,
python_version = "3.9",
)
-use_repo(python, "python3_9_toolchains")
-
-register_toolchains(
- "@python3_9_toolchains//:all",
-)
+use_repo(python, "python_3_9")
# We are using rules_proto to define rules_proto targets to be consumed by py_proto_library.
bazel_dep(name = "rules_proto", version = "5.3.0-21.7")
diff --git a/examples/wheel/BUILD.bazel b/examples/wheel/BUILD.bazel
index 61a43ae6cf..49a212b311 100644
--- a/examples/wheel/BUILD.bazel
+++ b/examples/wheel/BUILD.bazel
@@ -94,7 +94,7 @@ build_test(
py_wheel(
name = "minimal_with_py_library_with_stamp",
# Package data. We're building "example_minimal_library-0.0.1-py3-none-any.whl"
- distribution = "example_minimal_library",
+ distribution = "example_minimal_library{BUILD_USER}",
python_tag = "py3",
stamp = 1,
version = "0.1.{BUILD_TIMESTAMP}",
diff --git a/examples/wheel/wheel_test.py b/examples/wheel/wheel_test.py
index c292c87132..591e0571de 100644
--- a/examples/wheel/wheel_test.py
+++ b/examples/wheel/wheel_test.py
@@ -374,30 +374,36 @@ def test_rule_creates_directory_and_is_included_in_wheel(self):
],
)
- def test_rule_sets_stamped_version_in_wheel_metadata(self):
+ def test_rule_expands_workspace_status_keys_in_wheel_metadata(self):
filename = os.path.join(
os.environ["TEST_SRCDIR"],
"rules_python",
"examples",
"wheel",
- "example_minimal_library-0.1._BUILD_TIMESTAMP_-py3-none-any.whl",
+ "example_minimal_library_BUILD_USER_-0.1._BUILD_TIMESTAMP_-py3-none-any.whl",
)
with zipfile.ZipFile(filename) as zf:
metadata_file = None
for f in zf.namelist():
self.assertNotIn("_BUILD_TIMESTAMP_", f)
+ self.assertNotIn("_BUILD_USER_", f)
if os.path.basename(f) == "METADATA":
metadata_file = f
self.assertIsNotNone(metadata_file)
version = None
+ name = None
with zf.open(metadata_file) as fp:
for line in fp:
- if line.startswith(b'Version:'):
+ if line.startswith(b"Version:"):
version = line.decode().split()[-1]
+ if line.startswith(b"Name:"):
+ name = line.decode().split()[-1]
self.assertIsNotNone(version)
+ self.assertIsNotNone(name)
self.assertNotIn("{BUILD_TIMESTAMP}", version)
+ self.assertNotIn("{BUILD_USER}", name)
if __name__ == "__main__":
diff --git a/gazelle/MODULE.bazel b/gazelle/MODULE.bazel
index bd634020f3..ae94a5f863 100644
--- a/gazelle/MODULE.bazel
+++ b/gazelle/MODULE.bazel
@@ -6,7 +6,7 @@ module(
bazel_dep(name = "rules_python", version = "0.18.0")
bazel_dep(name = "rules_go", version = "0.38.1", repo_name = "io_bazel_rules_go")
-bazel_dep(name = "gazelle", version = "0.29.0", repo_name = "bazel_gazelle")
+bazel_dep(name = "gazelle", version = "0.31.0", repo_name = "bazel_gazelle")
go_deps = use_extension("@bazel_gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//:go.mod")
diff --git a/gazelle/README.md b/gazelle/README.md
index e36f3a303a..ba8520d36b 100644
--- a/gazelle/README.md
+++ b/gazelle/README.md
@@ -35,14 +35,14 @@ Here is a snippet of a `MODULE.bazel` file.
```starlark
# The following stanza defines the dependency rules_python.
-bazel_dep(name = "rules_python", version = "0.20.0")
+bazel_dep(name = "rules_python", version = "0.22.0")
-# The following stanza defines the dependency rules_python.
+# The following stanza defines the dependency rules_python_gazelle_plugin.
# For typical setups you set the version.
-bazel_dep(name = "rules_python_gazelle_plugin", version = "0.20.0")
+bazel_dep(name = "rules_python_gazelle_plugin", version = "0.22.0")
-# The following stanza defines the dependency rules_python.
-bazel_dep(name = "gazelle", version = "0.30.0", repo_name = "bazel_gazelle")
+# The following stanza defines the dependency gazelle.
+bazel_dep(name = "gazelle", version = "0.31.0", repo_name = "bazel_gazelle")
# Import the python repositories generated by the given module extension into the scope of the current module.
use_repo(python, "python3_9")
diff --git a/gazelle/WORKSPACE b/gazelle/WORKSPACE
index 55cf1b0d40..eef16e924d 100644
--- a/gazelle/WORKSPACE
+++ b/gazelle/WORKSPACE
@@ -13,10 +13,10 @@ http_archive(
http_archive(
name = "bazel_gazelle",
- sha256 = "448e37e0dbf61d6fa8f00aaa12d191745e14f07c31cabfa731f0c8e8a4f41b97",
+ sha256 = "29d5dafc2a5582995488c6735115d1d366fcd6a0fc2e2a153f02988706349825",
urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.28.0/bazel-gazelle-v0.28.0.tar.gz",
- "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.28.0/bazel-gazelle-v0.28.0.tar.gz",
+ "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.31.0/bazel-gazelle-v0.31.0.tar.gz",
+ "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.31.0/bazel-gazelle-v0.31.0.tar.gz",
],
)
diff --git a/python/extensions/interpreter.bzl b/python/extensions/interpreter.bzl
index b9afe1abda..bbeadc26b8 100644
--- a/python/extensions/interpreter.bzl
+++ b/python/extensions/interpreter.bzl
@@ -53,7 +53,7 @@ def _interpreter_repo_impl(rctx):
actual_interpreter_label = INTERPRETER_LABELS.get(rctx.attr.python_name)
if actual_interpreter_label == None:
- fail("Unable to find interpreter with name {}".format(rctx.attr.python_name))
+ fail("Unable to find interpreter with name '{}'".format(rctx.attr.python_name))
rctx.symlink(actual_interpreter_label, "python")
diff --git a/python/extensions/private/interpreter_hub.bzl b/python/extensions/private/interpreter_hub.bzl
deleted file mode 100644
index f1ca670cf2..0000000000
--- a/python/extensions/private/interpreter_hub.bzl
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2023 The Bazel Authors. All rights reserved
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"Repo rule used by bzlmod extension to create a repo that has a map of Python interpreters and their labels"
-
-load("//python:versions.bzl", "WINDOWS_NAME")
-load("//python/private:toolchains_repo.bzl", "get_host_os_arch", "get_host_platform")
-
-_build_file_for_hub_template = """
-INTERPRETER_LABELS = {{
-{lines}
-}}
-"""
-
-_line_for_hub_template = """\
- "{name}": Label("@{name}_{platform}//:{path}"),
-"""
-
-def _hub_repo_impl(rctx):
- (os, arch) = get_host_os_arch(rctx)
- platform = get_host_platform(os, arch)
-
- rctx.file("BUILD.bazel", "")
- is_windows = (os == WINDOWS_NAME)
- path = "python.exe" if is_windows else "bin/python3"
-
- lines = "\n".join([_line_for_hub_template.format(
- name = name,
- platform = platform,
- path = path,
- ) for name in rctx.attr.toolchains])
-
- rctx.file("interpreters.bzl", _build_file_for_hub_template.format(lines = lines))
-
-hub_repo = repository_rule(
- doc = """\
-This private rule create a repo with a BUILD file that contains a map of interpreter names
-and the labels to said interpreters. This map is used to by the interpreter hub extension.
-""",
- implementation = _hub_repo_impl,
- attrs = {
- "toolchains": attr.string_list(
- doc = "List of the base names the toolchain repo defines.",
- mandatory = True,
- ),
- },
-)
diff --git a/python/extensions/private/pythons_hub.bzl b/python/extensions/private/pythons_hub.bzl
new file mode 100644
index 0000000000..5baaef96fd
--- /dev/null
+++ b/python/extensions/private/pythons_hub.bzl
@@ -0,0 +1,136 @@
+# Copyright 2023 The Bazel Authors. All rights reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"Repo rule used by bzlmod extension to create a repo that has a map of Python interpreters and their labels"
+
+load("//python:versions.bzl", "MINOR_MAPPING", "WINDOWS_NAME")
+load(
+ "//python/private:toolchains_repo.bzl",
+ "get_host_os_arch",
+ "get_host_platform",
+ "get_repository_name",
+ "python_toolchain_build_file_content",
+)
+
+def _have_same_length(*lists):
+ if not lists:
+ fail("expected at least one list")
+ return len({len(length): None for length in lists}) == 1
+
+def _get_version(python_version):
+ # we need to get the MINOR_MAPPING or use the full version
+ if python_version in MINOR_MAPPING:
+ python_version = MINOR_MAPPING[python_version]
+ return python_version
+
+def _python_toolchain_build_file_content(
+ prefixes,
+ python_versions,
+ set_python_version_constraints,
+ user_repository_names,
+ workspace_location):
+ """This macro iterates over each of the lists and returns the toolchain content.
+
+ python_toolchain_build_file_content is called to generate each of the toolchain
+ definitions.
+ """
+
+ if not _have_same_length(python_versions, set_python_version_constraints, user_repository_names):
+ fail("all lists must have the same length")
+
+ rules_python = get_repository_name(workspace_location)
+
+ # Iterate over the length of python_versions and call
+ # build the toolchain content by calling python_toolchain_build_file_content
+ return "\n".join([python_toolchain_build_file_content(
+ prefix = prefixes[i],
+ python_version = _get_version(python_versions[i]),
+ set_python_version_constraint = set_python_version_constraints[i],
+ user_repository_name = user_repository_names[i],
+ rules_python = rules_python,
+ ) for i in range(len(python_versions))])
+
+_build_file_for_hub_template = """
+INTERPRETER_LABELS = {{
+{interpreter_labels}
+}}
+"""
+
+_line_for_hub_template = """\
+ "{name}": Label("@{name}_{platform}//:{path}"),
+"""
+
+def _hub_repo_impl(rctx):
+ # Create the various toolchain definitions and
+ # write them to the BUILD file.
+ rctx.file(
+ "BUILD.bazel",
+ _python_toolchain_build_file_content(
+ rctx.attr.toolchain_prefixes,
+ rctx.attr.toolchain_python_versions,
+ rctx.attr.toolchain_set_python_version_constraints,
+ rctx.attr.toolchain_user_repository_names,
+ rctx.attr._rules_python_workspace,
+ ),
+ executable = False,
+ )
+
+ (os, arch) = get_host_os_arch(rctx)
+ platform = get_host_platform(os, arch)
+ is_windows = (os == WINDOWS_NAME)
+ path = "python.exe" if is_windows else "bin/python3"
+
+ # Create a dict that is later used to create
+ # a symlink to a interpreter.
+ interpreter_labels = "".join([_line_for_hub_template.format(
+ name = name,
+ platform = platform,
+ path = path,
+ ) for name in rctx.attr.toolchain_user_repository_names])
+
+ rctx.file(
+ "interpreters.bzl",
+ _build_file_for_hub_template.format(
+ interpreter_labels = interpreter_labels,
+ ),
+ executable = False,
+ )
+
+hub_repo = repository_rule(
+ doc = """\
+This private rule create a repo with a BUILD file that contains a map of interpreter names
+and the labels to said interpreters. This map is used to by the interpreter hub extension.
+This rule also writes out the various toolchains for the different Python versions.
+""",
+ implementation = _hub_repo_impl,
+ attrs = {
+ "toolchain_prefixes": attr.string_list(
+ doc = "List prefixed for the toolchains",
+ mandatory = True,
+ ),
+ "toolchain_python_versions": attr.string_list(
+ doc = "List of Python versions for the toolchains",
+ mandatory = True,
+ ),
+ "toolchain_set_python_version_constraints": attr.string_list(
+ doc = "List of version contraints for the toolchains",
+ mandatory = True,
+ ),
+ "toolchain_user_repository_names": attr.string_list(
+ doc = "List of the user repo names for the toolchains",
+ mandatory = True,
+ ),
+ "_rules_python_workspace": attr.label(default = Label("//:does_not_matter_what_this_name_is")),
+ },
+)
diff --git a/python/extensions/python.bzl b/python/extensions/python.bzl
index 9a3d9ed959..d7a466ae10 100644
--- a/python/extensions/python.bzl
+++ b/python/extensions/python.bzl
@@ -14,38 +14,225 @@
"Python toolchain module extensions for use with bzlmod"
-load("@rules_python//python:repositories.bzl", "python_register_toolchains")
-load("@rules_python//python/extensions/private:interpreter_hub.bzl", "hub_repo")
+load("//python:repositories.bzl", "python_register_toolchains")
+load("//python/extensions/private:pythons_hub.bzl", "hub_repo")
+load("//python/private:toolchains_repo.bzl", "multi_toolchain_aliases")
+
+# This limit can be increased essentially arbitrarily, but doing so will cause a rebuild of all
+# targets using any of these toolchains due to the changed repository name.
+_MAX_NUM_TOOLCHAINS = 9999
+_TOOLCHAIN_INDEX_PAD_LENGTH = len(str(_MAX_NUM_TOOLCHAINS))
+
+def _toolchain_prefix(index, name):
+ """Prefixes the given name with the index, padded with zeros to ensure lexicographic sorting.
+
+ Examples:
+ _toolchain_prefix( 2, "foo") == "_0002_foo_"
+ _toolchain_prefix(2000, "foo") == "_2000_foo_"
+ """
+ return "_{}_{}_".format(_left_pad_zero(index, _TOOLCHAIN_INDEX_PAD_LENGTH), name)
+
+def _left_pad_zero(index, length):
+ if index < 0:
+ fail("index must be non-negative")
+ return ("0" * length + str(index))[-length:]
+
+# Printing a warning msg not debugging, so we have to disable
+# the buildifier check.
+# buildifier: disable=print
+def _print_warn(msg):
+ print("WARNING:", msg)
+
+def _python_register_toolchains(name, toolchain_attr, version_constraint):
+ """Calls python_register_toolchains and returns a struct used to collect the toolchains.
+ """
+ python_register_toolchains(
+ name = name,
+ python_version = toolchain_attr.python_version,
+ register_coverage_tool = toolchain_attr.configure_coverage_tool,
+ ignore_root_user_error = toolchain_attr.ignore_root_user_error,
+ set_python_version_constraint = version_constraint,
+ )
+ return struct(
+ python_version = toolchain_attr.python_version,
+ set_python_version_constraint = str(version_constraint),
+ name = name,
+ )
def _python_impl(module_ctx):
+ # The toolchain info structs to register, in the order to register them in.
toolchains = []
+
+ # We store the default toolchain separately to ensure it is the last
+ # toolchain added to toolchains.
+ default_toolchain = None
+
+ # Map of string Major.Minor to the toolchain name and module name
+ global_toolchain_versions = {}
+
for mod in module_ctx.modules:
+ module_toolchain_versions = []
+
for toolchain_attr in mod.tags.toolchain:
- python_register_toolchains(
- name = toolchain_attr.name,
- python_version = toolchain_attr.python_version,
- bzlmod = True,
- # Toolchain registration in bzlmod is done in MODULE file
- register_toolchains = False,
- register_coverage_tool = toolchain_attr.configure_coverage_tool,
- ignore_root_user_error = toolchain_attr.ignore_root_user_error,
+ toolchain_version = toolchain_attr.python_version
+ toolchain_name = "python_" + toolchain_version.replace(".", "_")
+
+ # Duplicate versions within a module indicate a misconfigured module.
+ if toolchain_version in module_toolchain_versions:
+ _fail_duplicate_module_toolchain_version(toolchain_version, mod.name)
+ module_toolchain_versions.append(toolchain_version)
+
+ # Ignore version collisions in the global scope because there isn't
+ # much else that can be done. Modules don't know and can't control
+ # what other modules do, so the first in the dependency graph wins.
+ if toolchain_version in global_toolchain_versions:
+ _warn_duplicate_global_toolchain_version(
+ toolchain_version,
+ first = global_toolchain_versions[toolchain_version],
+ second_toolchain_name = toolchain_name,
+ second_module_name = mod.name,
+ )
+ continue
+ global_toolchain_versions[toolchain_version] = struct(
+ toolchain_name = toolchain_name,
+ module_name = mod.name,
)
- # We collect all of the toolchain names to create
- # the INTERPRETER_LABELS map. This is used
- # by interpreter_extensions.bzl
- toolchains.append(toolchain_attr.name)
+ # Only the root module and rules_python are allowed to specify the default
+ # toolchain for a couple reasons:
+ # * It prevents submodules from specifying different defaults and only
+ # one of them winning.
+ # * rules_python needs to set a soft default in case the root module doesn't,
+ # e.g. if the root module doesn't use Python itself.
+ # * The root module is allowed to override the rules_python default.
+ if mod.is_root:
+ # A single toolchain is treated as the default because it's unambiguous.
+ is_default = toolchain_attr.is_default or len(mod.tags.toolchain) == 1
+ elif mod.name == "rules_python" and not default_toolchain:
+ # We don't do the len() check because we want the default that rules_python
+ # sets to be clearly visible.
+ is_default = toolchain_attr.is_default
+ else:
+ is_default = False
+
+ # We have already found one default toolchain, and we can only have
+ # one.
+ if is_default and default_toolchain != None:
+ _fail_multiple_default_toolchains(
+ first = default_toolchain.name,
+ second = toolchain_name,
+ )
+
+ toolchain_info = _python_register_toolchains(
+ toolchain_name,
+ toolchain_attr,
+ version_constraint = not is_default,
+ )
+
+ if is_default:
+ default_toolchain = toolchain_info
+ else:
+ toolchains.append(toolchain_info)
+
+ # A default toolchain is required so that the non-version-specific rules
+ # are able to match a toolchain.
+ if default_toolchain == None:
+ fail("No default Python toolchain configured. Is rules_python missing `is_default=True`?")
+ # The last toolchain in the BUILD file is set as the default
+ # toolchain. We need the default last.
+ toolchains.append(default_toolchain)
+
+ if len(toolchains) > _MAX_NUM_TOOLCHAINS:
+ fail("more than {} python versions are not supported".format(_MAX_NUM_TOOLCHAINS))
+
+ # Create the pythons_hub repo for the interpreter meta data and the
+ # the various toolchains.
hub_repo(
name = "pythons_hub",
- toolchains = toolchains,
+ toolchain_prefixes = [
+ _toolchain_prefix(index, toolchain.name)
+ for index, toolchain in enumerate(toolchains)
+ ],
+ toolchain_python_versions = [t.python_version for t in toolchains],
+ toolchain_set_python_version_constraints = [t.set_python_version_constraint for t in toolchains],
+ toolchain_user_repository_names = [t.name for t in toolchains],
)
+ # This is require in order to support multiple version py_test
+ # and py_binary
+ multi_toolchain_aliases(
+ name = "python_aliases",
+ python_versions = {
+ version: entry.toolchain_name
+ for version, entry in global_toolchain_versions.items()
+ },
+ )
+
+def _fail_duplicate_module_toolchain_version(version, module):
+ fail(("Duplicate module toolchain version: module '{module}' attempted " +
+ "to use version '{version}' multiple times in itself").format(
+ version = version,
+ module = module,
+ ))
+
+def _warn_duplicate_global_toolchain_version(version, first, second_toolchain_name, second_module_name):
+ _print_warn((
+ "Ignoring toolchain '{second_toolchain}' from module '{second_module}': " +
+ "Toolchain '{first_toolchain}' from module '{first_module}' " +
+ "already registered Python version {version} and has precedence"
+ ).format(
+ first_toolchain = first.toolchain_name,
+ first_module = first.module_name,
+ second_module = second_module_name,
+ second_toolchain = second_toolchain_name,
+ version = version,
+ ))
+
+def _fail_multiple_default_toolchains(first, second):
+ fail(("Multiple default toolchains: only one toolchain " +
+ "can have is_default=True. First default " +
+ "was toolchain '{first}'. Second was '{second}'").format(
+ first = first,
+ second = second,
+ ))
+
python = module_extension(
- doc = "Bzlmod extension that is used to register a Python toolchain.",
+ doc = """Bzlmod extension that is used to register Python toolchains.
+""",
implementation = _python_impl,
tag_classes = {
"toolchain": tag_class(
+ doc = """Tag class used to register Python toolchains.
+Use this tag class to register one or more Python toolchains. This class
+is also potentially called by sub modules. The following covers different
+business rules and use cases.
+
+Toolchains in the Root Module
+
+This class registers all toolchains in the root module.
+
+Toolchains in Sub Modules
+
+It will create a toolchain that is in a sub module, if the toolchain
+of the same name does not exist in the root module. The extension stops name
+clashing between toolchains in the root module and toolchains in sub modules.
+You cannot configure more than one toolchain as the default toolchain.
+
+Toolchain set as the default version
+
+This extension will not create a toolchain that exists in a sub module,
+if the sub module toolchain is marked as the default version. If you have
+more than one toolchain in your root module, you need to set one of the
+toolchains as the default version. If there is only one toolchain it
+is set as the default toolchain.
+
+Toolchain repository name
+
+A toolchain's repository name uses the format `python_{major}_{minor}`, e.g.
+`python_3_10`. The `major` and `minor` components are
+`major` and `minor` are the Python version from the `python_version` attribute.
+""",
attrs = {
"configure_coverage_tool": attr.bool(
mandatory = False,
@@ -56,8 +243,14 @@ python = module_extension(
doc = "Whether the check for root should be ignored or not. This causes cache misses with .pyc files.",
mandatory = False,
),
- "name": attr.string(mandatory = True),
- "python_version": attr.string(mandatory = True),
+ "is_default": attr.bool(
+ mandatory = False,
+ doc = "Whether the toolchain is the default version",
+ ),
+ "python_version": attr.string(
+ mandatory = True,
+ doc = "The Python version, in `major.minor` format, e.g '3.12', to create a toolchain for.",
+ ),
},
),
},
diff --git a/python/pip_install/requirements.bzl b/python/pip_install/requirements.bzl
index 7594471897..86fd408647 100644
--- a/python/pip_install/requirements.bzl
+++ b/python/pip_install/requirements.bzl
@@ -42,6 +42,9 @@ def compile_pip_requirements(
- validate with `bazel test [name]_test`
- update with `bazel run [name].update`
+ If you are using a version control system, the requirements.txt generated by this rule should
+ be checked into it to ensure that all developers/users have the same dependency versions.
+
Args:
name: base name for generated targets, typically "requirements".
extra_args: passed to pip-compile.
diff --git a/python/pip_install/tools/dependency_resolver/dependency_resolver.py b/python/pip_install/tools/dependency_resolver/dependency_resolver.py
index 89e355806c..ceb20db7ef 100644
--- a/python/pip_install/tools/dependency_resolver/dependency_resolver.py
+++ b/python/pip_install/tools/dependency_resolver/dependency_resolver.py
@@ -95,25 +95,30 @@ def _locate(bazel_runfiles, file):
requirements_windows = parse_str_none(sys.argv.pop(1))
update_target_label = sys.argv.pop(1)
+ requirements_file = _select_golden_requirements_file(
+ requirements_txt=requirements_txt, requirements_linux=requirements_linux,
+ requirements_darwin=requirements_darwin, requirements_windows=requirements_windows
+ )
+
resolved_requirements_in = _locate(bazel_runfiles, requirements_in)
- resolved_requirements_txt = _locate(bazel_runfiles, requirements_txt)
+ resolved_requirements_file = _locate(bazel_runfiles, requirements_file)
# Files in the runfiles directory has the following naming schema:
# Main repo: __main__/Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: