From 188598ab8348ac1d84e417a66ebb8501506041e6 Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Wed, 22 Jan 2025 11:31:12 +0900 Subject: [PATCH] chore: remove internal usage of deprecated py_binary ad py_test (#2569) This goes together with #2565 to remove the internal usage of the deprecated symbols. This also fixes the compile_pip_requirements symbol to print the correct deprecation message. Builds on top of 611eda8 The example message that would be printed is as follows: ``` The 'py_test' symbol in '@+python+python_3_11//:defs.bzl' is deprecated. It is an alias to the regular rule; use it directly instead: load("@rules_python//python:py_test.bzl", "py_test") py_test( name = "versioned_py_test", srcs = ["dummy.py"], main = "dummy.py", python_version = "3.11.11", ) ``` --------- Co-authored-by: Richard Levasseur --- CHANGELOG.md | 3 + MODULE.bazel | 7 +- WORKSPACE | 4 +- docs/environment-variables.md | 6 ++ examples/bzlmod/other_module/BUILD.bazel | 5 +- .../other_module/other_module/pkg/BUILD.bazel | 8 +- examples/bzlmod/tests/BUILD.bazel | 39 ++++---- .../requirements/BUILD.bazel | 17 ++-- .../multi_python_versions/tests/BUILD.bazel | 43 +++++---- python/config_settings/transition.bzl | 30 +++--- python/private/BUILD.bazel | 8 ++ python/private/deprecation.bzl | 59 ++++++++++++ python/private/internal_config_repo.bzl | 8 +- python/private/toolchains_repo.bzl | 90 +++++++++-------- python/uv/private/lock.bzl | 3 +- .../transition/multi_version_tests.bzl | 9 +- tests/deprecated/BUILD.bazel | 96 +++++++++++++++++++ tests/deprecated/dummy.py | 0 tests/deprecated/requirements.in | 0 tests/deprecated/requirements.txt | 6 ++ tests/deprecated/requirements_hub.txt | 6 ++ tools/publish/BUILD.bazel | 8 +- 22 files changed, 336 insertions(+), 119 deletions(-) create mode 100644 python/private/deprecation.bzl create mode 100644 tests/deprecated/BUILD.bazel create mode 100644 tests/deprecated/dummy.py create mode 100644 tests/deprecated/requirements.in create mode 100644 tests/deprecated/requirements.txt create mode 100644 tests/deprecated/requirements_hub.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d8c1631ed..00624db01f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,9 @@ Unreleased changes template. ### Changed * (pypi) {obj}`pip.override` will now be ignored instead of raising an error, fixes [#2550](https://github.com/bazelbuild/rules_python/issues/2550). +* (rules) deprecation warnings for deprecated symbols have been turned off by + default for now and can be enabled with `RULES_PYTHON_DEPRECATION_WARNINGS` + env var. {#v0-0-0-fixed} ### Fixed diff --git a/MODULE.bazel b/MODULE.bazel index 57780b2369..2ac5a27223 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -46,7 +46,12 @@ python.toolchain( is_default = True, python_version = "3.11", ) -use_repo(python, "python_3_11", "python_versions", "pythons_hub") +use_repo( + python, + "python_3_11", + "pythons_hub", + python = "python_versions", +) # This call registers the Python toolchains. register_toolchains("@pythons_hub//:all") diff --git a/WORKSPACE b/WORKSPACE index 7303b480f2..902af58ec8 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -68,12 +68,12 @@ load("//:internal_dev_setup.bzl", "rules_python_internal_setup") rules_python_internal_setup() -load("@pythons_hub//:versions.bzl", "MINOR_MAPPING", "PYTHON_VERSIONS") +load("@pythons_hub//:versions.bzl", "PYTHON_VERSIONS") load("//python:repositories.bzl", "python_register_multi_toolchains") python_register_multi_toolchains( name = "python", - default_version = MINOR_MAPPING.values()[-3], # Use 3.11.10 + default_version = "3.11", # Integration tests verify each version, so register all of them. python_versions = PYTHON_VERSIONS, ) diff --git a/docs/environment-variables.md b/docs/environment-variables.md index 12c1bcf0c2..fb9971597b 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -40,6 +40,12 @@ When `1`, bzlmod extensions will print debug information about what they're doing. This is mostly useful for development to debug errors. ::: +:::{envvar} RULES_PYTHON_DEPRECATION_WARNINGS + +When `1`, the rules_python will warn users about deprecated functionality that will +be removed in a subsequent major `rules_python` version. Defaults to `0` if unset. +::: + :::{envvar} RULES_PYTHON_ENABLE_PYSTAR When `1`, the rules_python Starlark implementation of the core rules is used diff --git a/examples/bzlmod/other_module/BUILD.bazel b/examples/bzlmod/other_module/BUILD.bazel index a93b92aaed..6294c5b0ae 100644 --- a/examples/bzlmod/other_module/BUILD.bazel +++ b/examples/bzlmod/other_module/BUILD.bazel @@ -1,9 +1,10 @@ -load("@python_versions//3.11:defs.bzl", compile_pip_requirements_311 = "compile_pip_requirements") +load("@rules_python//python:pip.bzl", "compile_pip_requirements") # NOTE: To update the requirements, you need to uncomment the rules_python # override in the MODULE.bazel. -compile_pip_requirements_311( +compile_pip_requirements( name = "requirements", src = "requirements.in", + python_version = "3.11", requirements_txt = "requirements_lock_3_11.txt", ) diff --git a/examples/bzlmod/other_module/other_module/pkg/BUILD.bazel b/examples/bzlmod/other_module/other_module/pkg/BUILD.bazel index 4fe392841e..53344c708a 100644 --- a/examples/bzlmod/other_module/other_module/pkg/BUILD.bazel +++ b/examples/bzlmod/other_module/other_module/pkg/BUILD.bazel @@ -1,7 +1,4 @@ -load( - "@python_3_11//:defs.bzl", - py_binary_311 = "py_binary", -) +load("@rules_python//python:py_binary.bzl", "py_binary") load("@rules_python//python:py_library.bzl", "py_library") py_library( @@ -15,11 +12,12 @@ py_library( # 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( +py_binary( name = "bin", srcs = ["bin.py"], data = ["data/data.txt"], main = "bin.py", + python_version = "3.11", visibility = ["//visibility:public"], deps = [ ":lib", diff --git a/examples/bzlmod/tests/BUILD.bazel b/examples/bzlmod/tests/BUILD.bazel index dd50cf3294..4650fb8788 100644 --- a/examples/bzlmod/tests/BUILD.bazel +++ b/examples/bzlmod/tests/BUILD.bazel @@ -1,10 +1,6 @@ -load("@python_versions//3.10:defs.bzl", py_binary_3_10 = "py_binary", py_test_3_10 = "py_test") -load("@python_versions//3.11:defs.bzl", py_binary_3_11 = "py_binary", py_test_3_11 = "py_test") -load("@python_versions//3.9:defs.bzl", py_binary_3_9 = "py_binary", py_test_3_9 = "py_test") load("@pythons_hub//:versions.bzl", "MINOR_MAPPING") load("@rules_python//python:py_binary.bzl", "py_binary") load("@rules_python//python:py_test.bzl", "py_test") -load("@rules_python//python/config_settings:transition.bzl", py_versioned_binary = "py_binary", py_versioned_test = "py_test") load("@rules_shell//shell:sh_test.bzl", "sh_test") py_binary( @@ -13,25 +9,28 @@ py_binary( main = "version.py", ) -py_binary_3_9( +py_binary( name = "version_3_9", srcs = ["version.py"], main = "version.py", + python_version = "3.9", ) -py_binary_3_10( +py_binary( name = "version_3_10", srcs = ["version.py"], main = "version.py", + python_version = "3.10", ) -py_binary_3_11( +py_binary( name = "version_3_11", srcs = ["version.py"], main = "version.py", + python_version = "3.11", ) -py_versioned_binary( +py_binary( name = "version_3_10_versioned", srcs = ["version.py"], main = "version.py", @@ -49,21 +48,23 @@ py_test( deps = ["//libs/my_lib"], ) -py_test_3_9( +py_test( name = "my_lib_3_9_test", srcs = ["my_lib_test.py"], main = "my_lib_test.py", + python_version = "3.9", deps = ["//libs/my_lib"], ) -py_test_3_10( +py_test( name = "my_lib_3_10_test", srcs = ["my_lib_test.py"], main = "my_lib_test.py", + python_version = "3.10", deps = ["//libs/my_lib"], ) -py_versioned_test( +py_test( name = "my_lib_versioned_test", srcs = ["my_lib_test.py"], main = "my_lib_test.py", @@ -92,21 +93,23 @@ py_test( main = "version_test.py", ) -py_test_3_9( +py_test( name = "version_3_9_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.9"}, main = "version_test.py", + python_version = "3.9", ) -py_test_3_10( +py_test( name = "version_3_10_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.10"}, main = "version_test.py", + python_version = "3.10", ) -py_versioned_test( +py_test( name = "version_versioned_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.10"}, @@ -114,11 +117,12 @@ py_versioned_test( python_version = "3.10", ) -py_test_3_11( +py_test( name = "version_3_11_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.11"}, main = "version_test.py", + python_version = "3.11", ) py_test( @@ -133,7 +137,7 @@ py_test( main = "cross_version_test.py", ) -py_test_3_10( +py_test( name = "version_3_10_takes_3_9_subprocess_test", srcs = ["cross_version_test.py"], data = [":version_3_9"], @@ -143,9 +147,10 @@ py_test_3_10( "VERSION_CHECK": "3.10", }, main = "cross_version_test.py", + python_version = "3.10", ) -py_versioned_test( +py_test( name = "version_3_10_takes_3_9_subprocess_test_2", srcs = ["cross_version_test.py"], data = [":version_3_9"], diff --git a/examples/multi_python_versions/requirements/BUILD.bazel b/examples/multi_python_versions/requirements/BUILD.bazel index f67333a657..c9b695e8e4 100644 --- a/examples/multi_python_versions/requirements/BUILD.bazel +++ b/examples/multi_python_versions/requirements/BUILD.bazel @@ -1,28 +1,29 @@ -load("@python//3.10:defs.bzl", compile_pip_requirements_3_10 = "compile_pip_requirements") -load("@python//3.11:defs.bzl", compile_pip_requirements_3_11 = "compile_pip_requirements") -load("@python//3.8:defs.bzl", compile_pip_requirements_3_8 = "compile_pip_requirements") -load("@python//3.9:defs.bzl", compile_pip_requirements_3_9 = "compile_pip_requirements") +load("@rules_python//python:pip.bzl", "compile_pip_requirements") -compile_pip_requirements_3_8( +compile_pip_requirements( name = "requirements_3_8", src = "requirements.in", + python_version = "3.8", requirements_txt = "requirements_lock_3_8.txt", ) -compile_pip_requirements_3_9( +compile_pip_requirements( name = "requirements_3_9", src = "requirements.in", + python_version = "3.9", requirements_txt = "requirements_lock_3_9.txt", ) -compile_pip_requirements_3_10( +compile_pip_requirements( name = "requirements_3_10", src = "requirements.in", + python_version = "3.10", requirements_txt = "requirements_lock_3_10.txt", ) -compile_pip_requirements_3_11( +compile_pip_requirements( name = "requirements_3_11", src = "requirements.in", + python_version = "3.11", requirements_txt = "requirements_lock_3_11.txt", ) diff --git a/examples/multi_python_versions/tests/BUILD.bazel b/examples/multi_python_versions/tests/BUILD.bazel index d04ac6bb0a..e3dfb48cca 100644 --- a/examples/multi_python_versions/tests/BUILD.bazel +++ b/examples/multi_python_versions/tests/BUILD.bazel @@ -1,10 +1,6 @@ load("@bazel_skylib//rules:copy_file.bzl", "copy_file") load("@bazel_skylib//rules:diff_test.bzl", "diff_test") load("@bazel_skylib//rules:write_file.bzl", "write_file") -load("@python//3.10:defs.bzl", py_binary_3_10 = "py_binary", py_test_3_10 = "py_test") -load("@python//3.11:defs.bzl", py_binary_3_11 = "py_binary", py_test_3_11 = "py_test") -load("@python//3.8:defs.bzl", py_binary_3_8 = "py_binary", py_test_3_8 = "py_test") -load("@python//3.9:defs.bzl", py_binary_3_9 = "py_binary", py_test_3_9 = "py_test") load("@pythons_hub//:versions.bzl", "MINOR_MAPPING", "PYTHON_VERSIONS") load("@rules_python//python:py_binary.bzl", "py_binary") load("@rules_python//python:py_test.bzl", "py_test") @@ -26,28 +22,32 @@ py_binary( srcs = ["version_default.py"], ) -py_binary_3_8( +py_binary( name = "version_3_8", srcs = ["version.py"], main = "version.py", + python_version = "3.8", ) -py_binary_3_9( +py_binary( name = "version_3_9", srcs = ["version.py"], main = "version.py", + python_version = "3.9", ) -py_binary_3_10( +py_binary( name = "version_3_10", srcs = ["version.py"], main = "version.py", + python_version = "3.10", ) -py_binary_3_11( +py_binary( name = "version_3_11", srcs = ["version.py"], main = "version.py", + python_version = "3.11", ) py_test( @@ -57,31 +57,35 @@ py_test( deps = ["//libs/my_lib"], ) -py_test_3_8( +py_test( name = "my_lib_3_8_test", srcs = ["my_lib_test.py"], main = "my_lib_test.py", + python_version = "3.8", deps = ["//libs/my_lib"], ) -py_test_3_9( +py_test( name = "my_lib_3_9_test", srcs = ["my_lib_test.py"], main = "my_lib_test.py", + python_version = "3.9", deps = ["//libs/my_lib"], ) -py_test_3_10( +py_test( name = "my_lib_3_10_test", srcs = ["my_lib_test.py"], main = "my_lib_test.py", + python_version = "3.10", deps = ["//libs/my_lib"], ) -py_test_3_11( +py_test( name = "my_lib_3_11_test", srcs = ["my_lib_test.py"], main = "my_lib_test.py", + python_version = "3.11", deps = ["//libs/my_lib"], ) @@ -98,32 +102,36 @@ py_test( env = {"VERSION_CHECK": "3.9"}, # The default defined in the WORKSPACE. ) -py_test_3_8( +py_test( name = "version_3_8_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.8"}, main = "version_test.py", + python_version = "3.8", ) -py_test_3_9( +py_test( name = "version_3_9_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.9"}, main = "version_test.py", + python_version = "3.9", ) -py_test_3_10( +py_test( name = "version_3_10_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.10"}, main = "version_test.py", + python_version = "3.10", ) -py_test_3_11( +py_test( name = "version_3_11_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.11"}, main = "version_test.py", + python_version = "3.11", ) py_test( @@ -138,7 +146,7 @@ py_test( main = "cross_version_test.py", ) -py_test_3_10( +py_test( name = "version_3_10_takes_3_9_subprocess_test", srcs = ["cross_version_test.py"], data = [":version_3_9"], @@ -148,6 +156,7 @@ py_test_3_10( "VERSION_CHECK": "3.10", }, main = "cross_version_test.py", + python_version = "3.10", ) sh_test( diff --git a/python/config_settings/transition.bzl b/python/config_settings/transition.bzl index c241f20746..937f33bb88 100644 --- a/python/config_settings/transition.bzl +++ b/python/config_settings/transition.bzl @@ -23,12 +23,18 @@ of them should be changed to load the regular rules directly. load("//python:py_binary.bzl", _py_binary = "py_binary") load("//python:py_test.bzl", _py_test = "py_test") - -_DEPRECATION_MESSAGE = """ -The {name} symbol in @rules_python//python/config_settings:transition.bzl -is deprecated. It is an alias to the regular rule; use it directly instead: - load("@rules_python//python:{name}.bzl", "{name}") -""" +load("//python/private:deprecation.bzl", "with_deprecation") +load("//python/private:text_util.bzl", "render") + +def _with_deprecation(kwargs, *, name, python_version): + kwargs["python_version"] = python_version + return with_deprecation.symbol( + kwargs, + symbol_name = name, + old_load = "@rules_python//python/config_settings:transition.bzl", + new_load = "@rules_python//python:{}.bzl".format(name), + snippet = render.call(name, **{k: repr(v) for k, v in kwargs.items()}), + ) def py_binary(**kwargs): """[DEPRECATED] Deprecated alias for py_binary. @@ -37,11 +43,7 @@ def py_binary(**kwargs): **kwargs: keyword args forwarded onto {obj}`py_binary`. """ - deprecation = _DEPRECATION_MESSAGE.format(name = "py_binary") - if kwargs.get("deprecation"): - deprecation = kwargs.get("deprecation") + "\n\n" + deprecation - kwargs["deprecation"] = deprecation - _py_binary(**kwargs) + _py_binary(**_with_deprecation(kwargs, name = "py_binary", python_version = kwargs.get("python_version"))) def py_test(**kwargs): """[DEPRECATED] Deprecated alias for py_test. @@ -49,8 +51,4 @@ def py_test(**kwargs): Args: **kwargs: keyword args forwarded onto {obj}`py_binary`. """ - deprecation = _DEPRECATION_MESSAGE.format(name = "py_test") - if kwargs.get("deprecation"): - deprecation = kwargs.get("deprecation") + "\n\n" + deprecation - kwargs["deprecation"] = deprecation - _py_test(**kwargs) + _py_test(**_with_deprecation(kwargs, name = "py_test", python_version = kwargs.get("python_version"))) diff --git a/python/private/BUILD.bazel b/python/private/BUILD.bazel index 706506a19c..14f52c541b 100644 --- a/python/private/BUILD.bazel +++ b/python/private/BUILD.bazel @@ -138,6 +138,14 @@ bzl_library( ], ) +bzl_library( + name = "deprecation_bzl", + srcs = ["deprecation.bzl"], + deps = [ + "@rules_python_internal//:rules_python_config_bzl", + ], +) + bzl_library( name = "enum_bzl", srcs = ["enum.bzl"], diff --git a/python/private/deprecation.bzl b/python/private/deprecation.bzl new file mode 100644 index 0000000000..70461c2fa1 --- /dev/null +++ b/python/private/deprecation.bzl @@ -0,0 +1,59 @@ +# Copyright 2024 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. + +"""Helper functions to deprecation utilities. +""" + +load("@rules_python_internal//:rules_python_config.bzl", "config") + +_DEPRECATION_MESSAGE = """ +The '{name}' symbol in '{old_load}' +is deprecated. It is an alias to the regular rule; use it directly instead: + +load("{new_load}", "{name}") + +{snippet} +""" + +def _symbol(kwargs, *, symbol_name, new_load, old_load, snippet = ""): + """An internal function to propagate the deprecation warning. + + This is not an API that should be used outside `rules_python`. + + Args: + kwargs: Arguments to modify. + symbol_name: {type}`str` the symbol name that is deprecated. + new_load: {type}`str` the new load location under `//`. + old_load: {type}`str` the symbol import location that we are deprecating. + snippet: {type}`str` the usage snippet of the new symbol. + + Returns: + The kwargs to be used in the macro creation. + """ + + if config.enable_deprecation_warnings: + deprecation = _DEPRECATION_MESSAGE.format( + name = symbol_name, + old_load = old_load, + new_load = new_load, + snippet = snippet, + ) + if kwargs.get("deprecation"): + deprecation = kwargs.get("deprecation") + "\n\n" + deprecation + kwargs["deprecation"] = deprecation + return kwargs + +with_deprecation = struct( + symbol = _symbol, +) diff --git a/python/private/internal_config_repo.bzl b/python/private/internal_config_repo.bzl index 7b6869e9a5..a5c4787161 100644 --- a/python/private/internal_config_repo.bzl +++ b/python/private/internal_config_repo.bzl @@ -18,12 +18,17 @@ such as globals available to Bazel versions, or propagating user environment settings for rules to later use. """ +load(":repo_utils.bzl", "repo_utils") + _ENABLE_PYSTAR_ENVVAR_NAME = "RULES_PYTHON_ENABLE_PYSTAR" _ENABLE_PYSTAR_DEFAULT = "1" +_ENABLE_DEPRECATION_WARNINGS_ENVVAR_NAME = "RULES_PYTHON_DEPRECATION_WARNINGS" +_ENABLE_DEPRECATION_WARNINGS_DEFAULT = "0" _CONFIG_TEMPLATE = """\ config = struct( enable_pystar = {enable_pystar}, + enable_deprecation_warnings = {enable_deprecation_warnings}, BuiltinPyInfo = getattr(getattr(native, "legacy_globals", None), "PyInfo", {builtin_py_info_symbol}), BuiltinPyRuntimeInfo = getattr(getattr(native, "legacy_globals", None), "PyRuntimeInfo", {builtin_py_runtime_info_symbol}), BuiltinPyCcLinkParamsProvider = getattr(getattr(native, "legacy_globals", None), "PyCcLinkParamsProvider", {builtin_py_cc_link_params_provider}), @@ -79,6 +84,7 @@ def _internal_config_repo_impl(rctx): rctx.file("rules_python_config.bzl", _CONFIG_TEMPLATE.format( enable_pystar = enable_pystar, + enable_deprecation_warnings = _bool_from_environ(rctx, _ENABLE_DEPRECATION_WARNINGS_ENVVAR_NAME, _ENABLE_DEPRECATION_WARNINGS_DEFAULT), builtin_py_info_symbol = builtin_py_info_symbol, builtin_py_runtime_info_symbol = builtin_py_runtime_info_symbol, builtin_py_cc_link_params_provider = builtin_py_cc_link_params_provider, @@ -112,4 +118,4 @@ internal_config_repo = repository_rule( ) def _bool_from_environ(rctx, key, default): - return bool(int(rctx.os.environ.get(key, default))) + return bool(int(repo_utils.getenv(rctx, key, default))) diff --git a/python/private/toolchains_repo.bzl b/python/private/toolchains_repo.bzl index 7e9a0c7ff9..5082047135 100644 --- a/python/private/toolchains_repo.bzl +++ b/python/private/toolchains_repo.bzl @@ -151,47 +151,39 @@ toolchain_aliases( rctx.file("defs.bzl", content = """\ # Generated by python/private/toolchains_repo.bzl -load( - "{rules_python}//python/config_settings:transition.bzl", - _py_binary = "py_binary", - _py_test = "py_test", -) +load("{rules_python}//python:pip.bzl", _compile_pip_requirements = "compile_pip_requirements") +load("{rules_python}//python/private:deprecation.bzl", "with_deprecation") +load("{rules_python}//python/private:text_util.bzl", "render") +load("{rules_python}//python:py_binary.bzl", _py_binary = "py_binary") +load("{rules_python}//python:py_test.bzl", _py_test = "py_test") load( "{rules_python}//python/entry_points:py_console_script_binary.bzl", _py_console_script_binary = "py_console_script_binary", ) -load("{rules_python}//python:pip.bzl", _compile_pip_requirements = "compile_pip_requirements") -def py_binary(name, **kwargs): - return _py_binary( - name = name, - python_version = "{python_version}", - **kwargs +def _with_deprecation(kwargs, *, name): + kwargs["python_version"] = "{python_version}" + return with_deprecation.symbol( + kwargs, + symbol_name = name, + old_load = "@{name}//:defs.bzl", + new_load = "@rules_python//python:{{}}.bzl".format(name), + snippet = render.call(name, **{{k: repr(v) for k,v in kwargs.items()}}) ) -def py_console_script_binary(name, **kwargs): - return _py_console_script_binary( - name = name, - binary_rule = py_binary, - **kwargs - ) +def py_binary(**kwargs): + return _py_binary(**_with_deprecation(kwargs, name = "py_binary")) -def py_test(name, **kwargs): - return _py_test( - name = name, - python_version = "{python_version}", - **kwargs - ) +def py_console_script_binary(**kwargs): + return _py_console_script_binary(**_with_deprecation(kwargs, name = "py_console_script_binary")) -def compile_pip_requirements(name, **kwargs): - return _compile_pip_requirements( - name = name, - py_binary = py_binary, - py_test = py_test, - **kwargs - ) +def py_test(**kwargs): + return _py_test(**_with_deprecation(kwargs, name = "py_test")) +def compile_pip_requirements(**kwargs): + return _compile_pip_requirements(**_with_deprecation(kwargs, name = "compile_pip_requirements")) """.format( + name = rctx.attr.name, python_version = rctx.attr.python_version, rules_python = get_repository_name(rctx.attr._rules_python_workspace), )) @@ -316,20 +308,42 @@ def _multi_toolchain_aliases_impl(rctx): rctx.file(file, content = """\ # Generated by python/private/toolchains_repo.bzl +load("{rules_python}//python:pip.bzl", _compile_pip_requirements = "compile_pip_requirements") +load("{rules_python}//python/private:deprecation.bzl", "with_deprecation") +load("{rules_python}//python/private:text_util.bzl", "render") +load("{rules_python}//python:py_binary.bzl", _py_binary = "py_binary") +load("{rules_python}//python:py_test.bzl", _py_test = "py_test") load( - "@{repository_name}//:defs.bzl", - _compile_pip_requirements = "compile_pip_requirements", - _py_binary = "py_binary", + "{rules_python}//python/entry_points:py_console_script_binary.bzl", _py_console_script_binary = "py_console_script_binary", - _py_test = "py_test", ) -compile_pip_requirements = _compile_pip_requirements -py_binary = _py_binary -py_console_script_binary = _py_console_script_binary -py_test = _py_test +def _with_deprecation(kwargs, *, name): + kwargs["python_version"] = "{python_version}" + return with_deprecation.symbol( + kwargs, + symbol_name = name, + old_load = "@{name}//{python_version}:defs.bzl", + new_load = "@rules_python//python:{{}}.bzl".format(name), + snippet = render.call(name, **{{k: repr(v) for k,v in kwargs.items()}}) + ) + +def py_binary(**kwargs): + return _py_binary(**_with_deprecation(kwargs, name = "py_binary")) + +def py_console_script_binary(**kwargs): + return _py_console_script_binary(**_with_deprecation(kwargs, name = "py_console_script_binary")) + +def py_test(**kwargs): + return _py_test(**_with_deprecation(kwargs, name = "py_test")) + +def compile_pip_requirements(**kwargs): + return _compile_pip_requirements(**_with_deprecation(kwargs, name = "compile_pip_requirements")) """.format( repository_name = repository_name, + name = rctx.attr.name, + python_version = python_version, + rules_python = get_repository_name(rctx.attr._rules_python_workspace), )) rctx.file("{}/BUILD.bazel".format(python_version), "") diff --git a/python/uv/private/lock.bzl b/python/uv/private/lock.bzl index 217b6e4831..f4dfa36eff 100644 --- a/python/uv/private/lock.bzl +++ b/python/uv/private/lock.bzl @@ -17,7 +17,6 @@ load("@bazel_skylib//rules:write_file.bzl", "write_file") load("//python:py_binary.bzl", "py_binary") -load("//python/config_settings:transition.bzl", transition_py_binary = "py_binary") load("//python/private:bzlmod_enabled.bzl", "BZLMOD_ENABLED") # buildifier: disable=bzl-visibility visibility(["//..."]) @@ -94,7 +93,7 @@ def lock(*, name, srcs, out, upgrade = False, universal = True, python_version = ], ) if python_version: - py_binary_rule = lambda *args, **kwargs: transition_py_binary(python_version = python_version, *args, **kwargs) + py_binary_rule = lambda *args, **kwargs: py_binary(python_version = python_version, *args, **kwargs) else: py_binary_rule = py_binary diff --git a/tests/config_settings/transition/multi_version_tests.bzl b/tests/config_settings/transition/multi_version_tests.bzl index 50b4402fce..aca341a295 100644 --- a/tests/config_settings/transition/multi_version_tests.bzl +++ b/tests/config_settings/transition/multi_version_tests.bzl @@ -16,8 +16,9 @@ load("@rules_testing//lib:analysis_test.bzl", "analysis_test") load("@rules_testing//lib:test_suite.bzl", "test_suite") load("@rules_testing//lib:util.bzl", "TestingAspectInfo", rt_util = "util") +load("//python:py_binary.bzl", "py_binary") load("//python:py_info.bzl", "PyInfo") -load("//python/config_settings:transition.bzl", py_binary_transitioned = "py_binary", py_test_transitioned = "py_test") +load("//python:py_test.bzl", "py_test") load("//python/private:reexports.bzl", "BuiltinPyInfo") # buildifier: disable=bzl-visibility load("//python/private:util.bzl", "IS_BAZEL_7_OR_HIGHER") # buildifier: disable=bzl-visibility load("//tests/support:support.bzl", "CC_TOOLCHAIN") @@ -34,7 +35,7 @@ _tests = [] def _test_py_test_with_transition(name): rt_util.helper_target( - py_test_transitioned, + py_test, name = name + "_subject", srcs = [name + "_subject.py"], python_version = _PYTHON_VERSION, @@ -56,7 +57,7 @@ _tests.append(_test_py_test_with_transition) def _test_py_binary_with_transition(name): rt_util.helper_target( - py_binary_transitioned, + py_binary, name = name + "_subject", srcs = [name + "_subject.py"], python_version = _PYTHON_VERSION, @@ -78,7 +79,7 @@ _tests.append(_test_py_binary_with_transition) def _setup_py_binary_windows(name, *, impl, build_python_zip): rt_util.helper_target( - py_binary_transitioned, + py_binary, name = name + "_subject", srcs = [name + "_subject.py"], python_version = _PYTHON_VERSION, diff --git a/tests/deprecated/BUILD.bazel b/tests/deprecated/BUILD.bazel new file mode 100644 index 0000000000..4b920679f1 --- /dev/null +++ b/tests/deprecated/BUILD.bazel @@ -0,0 +1,96 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") +load( + "@python//3.11:defs.bzl", + hub_compile_pip_requirements = "compile_pip_requirements", + hub_py_binary = "py_binary", + hub_py_console_script_binary = "py_console_script_binary", + hub_py_test = "py_test", +) +load( + "@python_3_11//:defs.bzl", + versioned_compile_pip_requirements = "compile_pip_requirements", + versioned_py_binary = "py_binary", + versioned_py_console_script_binary = "py_console_script_binary", + versioned_py_test = "py_test", +) +load("//python/config_settings:transition.bzl", transition_py_binary = "py_binary", transition_py_test = "py_test") + +# TODO @aignas 2025-01-22: remove the referenced symbols when releasing v2 + +transition_py_binary( + name = "transition_py_binary", + srcs = ["dummy.py"], + main = "dummy.py", + python_version = "3.11", +) + +transition_py_test( + name = "transition_py_test", + srcs = ["dummy.py"], + main = "dummy.py", + python_version = "3.11", +) + +versioned_py_binary( + name = "versioned_py_binary", + srcs = ["dummy.py"], + main = "dummy.py", +) + +versioned_py_test( + name = "versioned_py_test", + srcs = ["dummy.py"], + main = "dummy.py", +) + +versioned_py_console_script_binary( + name = "versioned_py_console_script_binary", + pkg = "@rules_python_publish_deps//twine", + script = "twine", +) + +versioned_compile_pip_requirements( + name = "versioned_compile_pip_requirements", + src = "requirements.in", + requirements_txt = "requirements.txt", +) + +hub_py_binary( + name = "hub_py_binary", + srcs = ["dummy.py"], + main = "dummy.py", +) + +hub_py_test( + name = "hub_py_test", + srcs = ["dummy.py"], + main = "dummy.py", +) + +hub_py_console_script_binary( + name = "hub_py_console_script_binary", + pkg = "@rules_python_publish_deps//twine", + script = "twine", +) + +hub_compile_pip_requirements( + name = "hub_compile_pip_requirements", + src = "requirements.in", + requirements_txt = "requirements_hub.txt", +) + +build_test( + name = "build_test", + targets = [ + "transition_py_binary", + "transition_py_test", + "versioned_py_binary", + "versioned_py_test", + "versioned_py_console_script_binary", + "versioned_compile_pip_requirements", + "hub_py_binary", + "hub_py_test", + "hub_py_console_script_binary", + "hub_compile_pip_requirements", + ], +) diff --git a/tests/deprecated/dummy.py b/tests/deprecated/dummy.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/deprecated/requirements.in b/tests/deprecated/requirements.in new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/deprecated/requirements.txt b/tests/deprecated/requirements.txt new file mode 100644 index 0000000000..4d53f7c4e3 --- /dev/null +++ b/tests/deprecated/requirements.txt @@ -0,0 +1,6 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# bazel run //tests/deprecated:versioned_compile_pip_requirements.update +# diff --git a/tests/deprecated/requirements_hub.txt b/tests/deprecated/requirements_hub.txt new file mode 100644 index 0000000000..444beb63a5 --- /dev/null +++ b/tests/deprecated/requirements_hub.txt @@ -0,0 +1,6 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# bazel run //tests/deprecated:hub_compile_pip_requirements.update +# diff --git a/tools/publish/BUILD.bazel b/tools/publish/BUILD.bazel index 1648ac85df..4cf99e4d97 100644 --- a/tools/publish/BUILD.bazel +++ b/tools/publish/BUILD.bazel @@ -1,14 +1,10 @@ -load("//python/config_settings:transition.bzl", "py_binary") load("//python/entry_points:py_console_script_binary.bzl", "py_console_script_binary") load("//tools/private:publish_deps.bzl", "publish_deps") py_console_script_binary( name = "twine", - # We use a py_binary rule with version transitions to ensure that we do not - # rely on the default version of the registered python toolchain. What is more - # we are using this instead of `@python_versions//3.11:defs.bzl` because loading - # that file relies on bzlmod being enabled. - binary_rule = py_binary, + # We transition to a specific python version in order to ensure that we + # don't rely on the default version configured by the root module. pkg = "@rules_python_publish_deps//twine", python_version = "3.11", script = "twine",