From 1e9e76f71179cb82babd3ad64c93ad626f8eff39 Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Tue, 21 Jan 2025 11:13:58 +0900 Subject: [PATCH 01/17] chore: remove the internal usages of the deprecated py_binary and py_test --- examples/bzlmod/tests/BUILD.bazel | 39 +++++++++-------- .../requirements/BUILD.bazel | 17 ++++---- .../multi_python_versions/tests/BUILD.bazel | 43 +++++++++++-------- python/private/toolchains_repo.bzl | 14 +++++- python/uv/private/lock.bzl | 3 +- .../transition/multi_version_tests.bzl | 9 ++-- tools/publish/BUILD.bazel | 2 +- 7 files changed, 76 insertions(+), 51 deletions(-) diff --git a/examples/bzlmod/tests/BUILD.bazel b/examples/bzlmod/tests/BUILD.bazel index dd50cf3294..dd58551f12 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( + python_version = "3.9", name = "version_3_9", srcs = ["version.py"], main = "version.py", ) -py_binary_3_10( +py_binary( + python_version = "3.10", name = "version_3_10", srcs = ["version.py"], main = "version.py", ) -py_binary_3_11( +py_binary( + python_version = "3.11", name = "version_3_11", srcs = ["version.py"], main = "version.py", ) -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( + python_version = "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( +py_test( name = "my_lib_3_10_test", + python_version = "3.10", srcs = ["my_lib_test.py"], main = "my_lib_test.py", 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( + python_version = "3.9", name = "version_3_9_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.9"}, main = "version_test.py", ) -py_test_3_10( +py_test( + python_version = "3.10", name = "version_3_10_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.10"}, main = "version_test.py", ) -py_versioned_test( +py_test( name = "version_versioned_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.10"}, @@ -114,7 +117,8 @@ py_versioned_test( python_version = "3.10", ) -py_test_3_11( +py_test( + python_version = "3.11", name = "version_3_11_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.11"}, @@ -133,7 +137,8 @@ py_test( main = "cross_version_test.py", ) -py_test_3_10( +py_test( + python_version = "3.10", name = "version_3_10_takes_3_9_subprocess_test", srcs = ["cross_version_test.py"], data = [":version_3_9"], @@ -145,7 +150,7 @@ py_test_3_10( main = "cross_version_test.py", ) -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..3930ed4f3b 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,25 +22,29 @@ py_binary( srcs = ["version_default.py"], ) -py_binary_3_8( +py_binary( + python_version = "3.8", name = "version_3_8", srcs = ["version.py"], main = "version.py", ) -py_binary_3_9( +py_binary( + python_version = "3.9", name = "version_3_9", srcs = ["version.py"], main = "version.py", ) -py_binary_3_10( +py_binary( + python_version = "3.10", name = "version_3_10", srcs = ["version.py"], main = "version.py", ) -py_binary_3_11( +py_binary( + python_version = "3.11", name = "version_3_11", srcs = ["version.py"], main = "version.py", @@ -57,28 +57,32 @@ py_test( deps = ["//libs/my_lib"], ) -py_test_3_8( +py_test( + python_version = "3.8", name = "my_lib_3_8_test", srcs = ["my_lib_test.py"], main = "my_lib_test.py", deps = ["//libs/my_lib"], ) -py_test_3_9( +py_test( + python_version = "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( +py_test( + python_version = "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( +py_test( + python_version = "3.11", name = "my_lib_3_11_test", srcs = ["my_lib_test.py"], main = "my_lib_test.py", @@ -98,28 +102,32 @@ py_test( env = {"VERSION_CHECK": "3.9"}, # The default defined in the WORKSPACE. ) -py_test_3_8( +py_test( + python_version = "3.8", name = "version_3_8_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.8"}, main = "version_test.py", ) -py_test_3_9( +py_test( + python_version = "3.9", name = "version_3_9_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.9"}, main = "version_test.py", ) -py_test_3_10( +py_test( + python_version = "3.10", name = "version_3_10_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.10"}, main = "version_test.py", ) -py_test_3_11( +py_test( + python_version = "3.11", name = "version_3_11_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.11"}, @@ -138,7 +146,8 @@ py_test( main = "cross_version_test.py", ) -py_test_3_10( +py_test( + python_version = "3.10", name = "version_3_10_takes_3_9_subprocess_test", srcs = ["cross_version_test.py"], data = [":version_3_9"], diff --git a/python/private/toolchains_repo.bzl b/python/private/toolchains_repo.bzl index 7e9a0c7ff9..62475f640a 100644 --- a/python/private/toolchains_repo.bzl +++ b/python/private/toolchains_repo.bzl @@ -183,11 +183,21 @@ def py_test(name, **kwargs): **kwargs ) +_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}") +\"\"\" + def compile_pip_requirements(name, **kwargs): + deprecation = _DEPRECATION_MESSAGE.format(name = "compile_pip_requirements") + if kwargs.get("deprecation"): + deprecation = kwargs.pop("deprecation") + "\n\n" + deprecation + kwargs["deprecation"] = deprecation + return _compile_pip_requirements( name = name, - py_binary = py_binary, - py_test = py_test, + python_version = "{python_version}", **kwargs ) 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/tools/publish/BUILD.bazel b/tools/publish/BUILD.bazel index 1648ac85df..0145904dc8 100644 --- a/tools/publish/BUILD.bazel +++ b/tools/publish/BUILD.bazel @@ -1,4 +1,4 @@ -load("//python/config_settings:transition.bzl", "py_binary") +load("//python:py_binary.bzl", "py_binary") load("//python/entry_points:py_console_script_binary.bzl", "py_console_script_binary") load("//tools/private:publish_deps.bzl", "publish_deps") From f14d91beffd7b59365e684f8849076b72a62ad47 Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Tue, 21 Jan 2025 11:18:50 +0900 Subject: [PATCH 02/17] buildifier --- examples/bzlmod/tests/BUILD.bazel | 18 ++++++------- .../multi_python_versions/tests/BUILD.bazel | 26 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/examples/bzlmod/tests/BUILD.bazel b/examples/bzlmod/tests/BUILD.bazel index dd58551f12..4650fb8788 100644 --- a/examples/bzlmod/tests/BUILD.bazel +++ b/examples/bzlmod/tests/BUILD.bazel @@ -10,24 +10,24 @@ py_binary( ) py_binary( - python_version = "3.9", name = "version_3_9", srcs = ["version.py"], main = "version.py", + python_version = "3.9", ) py_binary( - python_version = "3.10", name = "version_3_10", srcs = ["version.py"], main = "version.py", + python_version = "3.10", ) py_binary( - python_version = "3.11", name = "version_3_11", srcs = ["version.py"], main = "version.py", + python_version = "3.11", ) py_binary( @@ -49,18 +49,18 @@ py_test( ) py_test( - python_version = "3.9", 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( name = "my_lib_3_10_test", - python_version = "3.10", srcs = ["my_lib_test.py"], main = "my_lib_test.py", + python_version = "3.10", deps = ["//libs/my_lib"], ) @@ -94,19 +94,19 @@ py_test( ) py_test( - python_version = "3.9", name = "version_3_9_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.9"}, main = "version_test.py", + python_version = "3.9", ) py_test( - python_version = "3.10", name = "version_3_10_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.10"}, main = "version_test.py", + python_version = "3.10", ) py_test( @@ -118,11 +118,11 @@ py_test( ) py_test( - python_version = "3.11", 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 +138,6 @@ py_test( ) py_test( - python_version = "3.10", name = "version_3_10_takes_3_9_subprocess_test", srcs = ["cross_version_test.py"], data = [":version_3_9"], @@ -148,6 +147,7 @@ py_test( "VERSION_CHECK": "3.10", }, main = "cross_version_test.py", + python_version = "3.10", ) py_test( diff --git a/examples/multi_python_versions/tests/BUILD.bazel b/examples/multi_python_versions/tests/BUILD.bazel index 3930ed4f3b..e3dfb48cca 100644 --- a/examples/multi_python_versions/tests/BUILD.bazel +++ b/examples/multi_python_versions/tests/BUILD.bazel @@ -23,31 +23,31 @@ py_binary( ) py_binary( - python_version = "3.8", name = "version_3_8", srcs = ["version.py"], main = "version.py", + python_version = "3.8", ) py_binary( - python_version = "3.9", name = "version_3_9", srcs = ["version.py"], main = "version.py", + python_version = "3.9", ) py_binary( - python_version = "3.10", name = "version_3_10", srcs = ["version.py"], main = "version.py", + python_version = "3.10", ) py_binary( - python_version = "3.11", name = "version_3_11", srcs = ["version.py"], main = "version.py", + python_version = "3.11", ) py_test( @@ -58,34 +58,34 @@ py_test( ) py_test( - python_version = "3.8", 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( - python_version = "3.9", 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( - python_version = "3.10", 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( - python_version = "3.11", name = "my_lib_3_11_test", srcs = ["my_lib_test.py"], main = "my_lib_test.py", + python_version = "3.11", deps = ["//libs/my_lib"], ) @@ -103,35 +103,35 @@ py_test( ) py_test( - python_version = "3.8", name = "version_3_8_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.8"}, main = "version_test.py", + python_version = "3.8", ) py_test( - python_version = "3.9", name = "version_3_9_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.9"}, main = "version_test.py", + python_version = "3.9", ) py_test( - python_version = "3.10", name = "version_3_10_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.10"}, main = "version_test.py", + python_version = "3.10", ) py_test( - python_version = "3.11", name = "version_3_11_test", srcs = ["version_test.py"], env = {"VERSION_CHECK": "3.11"}, main = "version_test.py", + python_version = "3.11", ) py_test( @@ -147,7 +147,6 @@ py_test( ) py_test( - python_version = "3.10", name = "version_3_10_takes_3_9_subprocess_test", srcs = ["cross_version_test.py"], data = [":version_3_9"], @@ -157,6 +156,7 @@ py_test( "VERSION_CHECK": "3.10", }, main = "cross_version_test.py", + python_version = "3.10", ) sh_test( From 66e8896c21e7b89a99e1952e52dde9aca48f9762 Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Tue, 21 Jan 2025 11:21:23 +0900 Subject: [PATCH 03/17] add a note --- python/private/toolchains_repo.bzl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/private/toolchains_repo.bzl b/python/private/toolchains_repo.bzl index 62475f640a..4ed88e415b 100644 --- a/python/private/toolchains_repo.bzl +++ b/python/private/toolchains_repo.bzl @@ -151,6 +151,8 @@ toolchain_aliases( rctx.file("defs.bzl", content = """\ # Generated by python/private/toolchains_repo.bzl +# NOTE @aignas 2025-01-21: we have deprecated these in favour of just using +# `py_binary`. So users of these should also migrate. load( "{rules_python}//python/config_settings:transition.bzl", _py_binary = "py_binary", From b63e8a214ccd7776d38a4a8b95734bb232197136 Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Tue, 21 Jan 2025 12:56:15 +0900 Subject: [PATCH 04/17] deprecation message centralization --- python/config_settings/transition.bzl | 40 ++++++--- python/private/toolchains_repo.bzl | 121 ++++++++++++++++++-------- 2 files changed, 113 insertions(+), 48 deletions(-) diff --git a/python/config_settings/transition.bzl b/python/config_settings/transition.bzl index c241f20746..e6471ea3b5 100644 --- a/python/config_settings/transition.bzl +++ b/python/config_settings/transition.bzl @@ -25,11 +25,35 @@ 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 +The {name} symbol in @{deprecated} is deprecated. It is an alias to the regular rule; use it directly instead: - load("@rules_python//python:{name}.bzl", "{name}") + +load("@rules_python//python{load_name}.bzl", "{name}") + +{name}( + # ... + python_version = {python_version}, + # ... +) """ +def with_deprecation(kwargs, *, symbol_name, python_version, load_name = None, deprecated = "rules_python//python/config_settings:transition.bzl"): + """Internal function to propagate the deprecation warning.""" + # TODO @aignas 2025-01-21: should we add a flag that silences this? + load_name = load_name or (":" + symbol_name) + + deprecation = _DEPRECATION_MESSAGE.format( + name = symbol_name, + load_name = load_name, + python_version = python_version, + deprecated = deprecated, + ) + if kwargs.get("deprecation"): + deprecation = kwargs.get("deprecation") + "\n\n" + deprecation + kwargs["deprecation"] = deprecation + kwargs["python_version"] = python_version + return kwargs + def py_binary(**kwargs): """[DEPRECATED] Deprecated alias for py_binary. @@ -37,11 +61,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 +69,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/toolchains_repo.bzl b/python/private/toolchains_repo.bzl index 4ed88e415b..cd1d77e70c 100644 --- a/python/private/toolchains_repo.bzl +++ b/python/private/toolchains_repo.bzl @@ -151,59 +151,63 @@ toolchain_aliases( rctx.file("defs.bzl", content = """\ # Generated by python/private/toolchains_repo.bzl -# NOTE @aignas 2025-01-21: we have deprecated these in favour of just using -# `py_binary`. So users of these should also migrate. -load( - "{rules_python}//python/config_settings:transition.bzl", - _py_binary = "py_binary", - _py_test = "py_test", -) +load("{rules_python}//python/config_settings:transition.bzl", "with_deprecation") +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): +def py_binary(**kwargs): return _py_binary( - name = name, - python_version = "{python_version}", - **kwargs + **with_deprecation( + kwargs, + symbol_name = "py_binary", + python_version = "{python_version}", + deprecated = "@{name}//:defs.bzl", + ), ) def py_console_script_binary(name, **kwargs): return _py_console_script_binary( name = name, - binary_rule = py_binary, - **kwargs + binary_rule = _py_binary, + **with_deprecation( + kwargs, + symbol_name = "py_console_script_binary", + load_name = "entry_points:py_console_script_binary", + python_version = "{python_version}", + deprecated = "@{name}//:defs.bzl", + ), ) def py_test(name, **kwargs): return _py_test( name = name, - python_version = "{python_version}", - **kwargs + **with_deprecation( + kwargs, + symbol_name = "py_test", + python_version = "{python_version}", + deprecated = "@{name}//:defs.bzl", + ), ) -_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}") -\"\"\" - def compile_pip_requirements(name, **kwargs): - deprecation = _DEPRECATION_MESSAGE.format(name = "compile_pip_requirements") - if kwargs.get("deprecation"): - deprecation = kwargs.pop("deprecation") + "\n\n" + deprecation - kwargs["deprecation"] = deprecation - return _compile_pip_requirements( name = name, - python_version = "{python_version}", - **kwargs + **with_deprecation( + kwargs, + symbol_name = "compile_pip_requirements", + load_name = "pip", + python_version = "{python_version}", + deprecated = "@{name}//:defs.bzl", + ), ) """.format( + name = rctx.attr.name, python_version = rctx.attr.python_version, rules_python = get_repository_name(rctx.attr._rules_python_workspace), )) @@ -328,20 +332,65 @@ def _multi_toolchain_aliases_impl(rctx): rctx.file(file, content = """\ # Generated by python/private/toolchains_repo.bzl +load("{rules_python}//python/config_settings:transition.bzl", "with_deprecation") +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", ) +load("{rules_python}//python:pip.bzl", _compile_pip_requirements = "compile_pip_requirements") + +def py_binary(**kwargs): + return _py_binary( + **with_deprecation( + kwargs, + symbol_name = "py_binary", + python_version = "{python_version}", + deprecated = "@{name}//{python_version}:defs.bzl", + ), + ) + +def py_console_script_binary(name, **kwargs): + return _py_console_script_binary( + name = name, + binary_rule = _py_binary, + **with_deprecation( + kwargs, + symbol_name = "py_console_script_binary", + load_name = "entry_points:py_console_script_binary", + python_version = "{python_version}", + deprecated = "@{name}//{python_version}:defs.bzl", + ), + ) + +def py_test(name, **kwargs): + return _py_test( + name = name, + **with_deprecation( + kwargs, + symbol_name = "py_test", + python_version = "{python_version}", + deprecated = "@{name}//{python_version}:defs.bzl", + ), + ) + +def compile_pip_requirements(name, **kwargs): + return _compile_pip_requirements( + name = name, + **with_deprecation( + kwargs, + symbol_name = "compile_pip_requirements", + load_name = "pip", + python_version = "{python_version}", + deprecated = "@{name}//{python_version}:defs.bzl", + ), + ) -compile_pip_requirements = _compile_pip_requirements -py_binary = _py_binary -py_console_script_binary = _py_console_script_binary -py_test = _py_test """.format( repository_name = repository_name, + name = rctx.attr.name, + python_version = python_version, )) rctx.file("{}/BUILD.bazel".format(python_version), "") From 8c89c7e17a11160b05aeb839cc75deb041f9569b Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Tue, 21 Jan 2025 13:01:00 +0900 Subject: [PATCH 05/17] add more stuff --- .../bzlmod/other_module/other_module/pkg/BUILD.bazel | 8 +++----- python/config_settings/transition.bzl | 5 +++-- python/private/toolchains_repo.bzl | 11 ++++++----- 3 files changed, 12 insertions(+), 12 deletions(-) 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/python/config_settings/transition.bzl b/python/config_settings/transition.bzl index e6471ea3b5..10bd464dd5 100644 --- a/python/config_settings/transition.bzl +++ b/python/config_settings/transition.bzl @@ -25,20 +25,21 @@ load("//python:py_binary.bzl", _py_binary = "py_binary") load("//python:py_test.bzl", _py_test = "py_test") _DEPRECATION_MESSAGE = """ -The {name} symbol in @{deprecated} +The '{name}' symbol in @{deprecated} is deprecated. It is an alias to the regular rule; use it directly instead: load("@rules_python//python{load_name}.bzl", "{name}") {name}( # ... - python_version = {python_version}, + python_version = "{python_version}", # ... ) """ def with_deprecation(kwargs, *, symbol_name, python_version, load_name = None, deprecated = "rules_python//python/config_settings:transition.bzl"): """Internal function to propagate the deprecation warning.""" + # TODO @aignas 2025-01-21: should we add a flag that silences this? load_name = load_name or (":" + symbol_name) diff --git a/python/private/toolchains_repo.bzl b/python/private/toolchains_repo.bzl index cd1d77e70c..4140cde63e 100644 --- a/python/private/toolchains_repo.bzl +++ b/python/private/toolchains_repo.bzl @@ -332,14 +332,14 @@ def _multi_toolchain_aliases_impl(rctx): rctx.file(file, content = """\ # Generated by python/private/toolchains_repo.bzl -load("{rules_python}//python/config_settings:transition.bzl", "with_deprecation") -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/config_settings:transition.bzl", "with_deprecation") +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", + "@@{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") +load("@@{rules_python}//python:pip.bzl", _compile_pip_requirements = "compile_pip_requirements") def py_binary(**kwargs): return _py_binary( @@ -391,6 +391,7 @@ def compile_pip_requirements(name, **kwargs): repository_name = repository_name, name = rctx.attr.name, python_version = python_version, + rules_python = rules_python, )) rctx.file("{}/BUILD.bazel".format(python_version), "") From 0a7e42fde326898ec0fdda8d54638298278c5a10 Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Tue, 21 Jan 2025 13:01:58 +0900 Subject: [PATCH 06/17] add more stuff --- examples/bzlmod/other_module/BUILD.bazel | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/bzlmod/other_module/BUILD.bazel b/examples/bzlmod/other_module/BUILD.bazel index a93b92aaed..34b4e54833 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", + python_version = "3.11", src = "requirements.in", requirements_txt = "requirements_lock_3_11.txt", ) From 61f1bba6394653d830eceba191a568e965eaef43 Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Tue, 21 Jan 2025 13:02:04 +0900 Subject: [PATCH 07/17] buildifier --- examples/bzlmod/other_module/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/bzlmod/other_module/BUILD.bazel b/examples/bzlmod/other_module/BUILD.bazel index 34b4e54833..6294c5b0ae 100644 --- a/examples/bzlmod/other_module/BUILD.bazel +++ b/examples/bzlmod/other_module/BUILD.bazel @@ -4,7 +4,7 @@ load("@rules_python//python:pip.bzl", "compile_pip_requirements") # override in the MODULE.bazel. compile_pip_requirements( name = "requirements", - python_version = "3.11", src = "requirements.in", + python_version = "3.11", requirements_txt = "requirements_lock_3_11.txt", ) From 6a7d1d109864b685bfc0448ae21010e26f345f5b Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Tue, 21 Jan 2025 16:02:02 +0900 Subject: [PATCH 08/17] fixup --- python/private/toolchains_repo.bzl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/private/toolchains_repo.bzl b/python/private/toolchains_repo.bzl index 4140cde63e..dcfd3c1a2e 100644 --- a/python/private/toolchains_repo.bzl +++ b/python/private/toolchains_repo.bzl @@ -177,7 +177,7 @@ def py_console_script_binary(name, **kwargs): **with_deprecation( kwargs, symbol_name = "py_console_script_binary", - load_name = "entry_points:py_console_script_binary", + load_name = "/entry_points:py_console_script_binary", python_version = "{python_version}", deprecated = "@{name}//:defs.bzl", ), @@ -358,7 +358,7 @@ def py_console_script_binary(name, **kwargs): **with_deprecation( kwargs, symbol_name = "py_console_script_binary", - load_name = "entry_points:py_console_script_binary", + load_name = "/entry_points:py_console_script_binary", python_version = "{python_version}", deprecated = "@{name}//{python_version}:defs.bzl", ), From a3ef421ef1bcf23a2ca4a432c3df91bc4105a503 Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Tue, 21 Jan 2025 17:23:57 +0900 Subject: [PATCH 09/17] doc: add docstring --- python/config_settings/transition.bzl | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/python/config_settings/transition.bzl b/python/config_settings/transition.bzl index 10bd464dd5..5b406efd0f 100644 --- a/python/config_settings/transition.bzl +++ b/python/config_settings/transition.bzl @@ -38,7 +38,21 @@ load("@rules_python//python{load_name}.bzl", "{name}") """ def with_deprecation(kwargs, *, symbol_name, python_version, load_name = None, deprecated = "rules_python//python/config_settings:transition.bzl"): - """Internal function to propagate the deprecation warning.""" + """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. + python_version: {type}`str` the python version to be used. + load_name: {type}`str` the load location under `//python`. Should start + either with `/` or `:`. Defaults to `:`. + deprecated: {type}`str` the symbol import location that we are deprecating. + + Returns: + The kwargs to be used in the macro creation. + """ # TODO @aignas 2025-01-21: should we add a flag that silences this? load_name = load_name or (":" + symbol_name) From 38467c02c9eb534c298ebcecca7c460f06d9a4f2 Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Tue, 21 Jan 2025 19:57:43 +0900 Subject: [PATCH 10/17] config: deprecation warning defaults to false --- CHANGELOG.md | 3 +++ docs/environment-variables.md | 6 ++++++ python/config_settings/transition.bzl | 25 +++++++++++++------------ python/private/internal_config_repo.bzl | 7 +++++++ 4 files changed, 29 insertions(+), 12 deletions(-) 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/docs/environment-variables.md b/docs/environment-variables.md index 12c1bcf0c2..e981dd76b9 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 symbols that will +be removed in the next major `rules_python` version. Defaults to `0`. +::: + :::{envvar} RULES_PYTHON_ENABLE_PYSTAR When `1`, the rules_python Starlark implementation of the core rules is used diff --git a/python/config_settings/transition.bzl b/python/config_settings/transition.bzl index 5b406efd0f..762b7060ac 100644 --- a/python/config_settings/transition.bzl +++ b/python/config_settings/transition.bzl @@ -21,6 +21,7 @@ of them should be changed to load the regular rules directly. ::: """ +load("@rules_python_internal//:rules_python_config.bzl", "config") load("//python:py_binary.bzl", _py_binary = "py_binary") load("//python:py_test.bzl", _py_test = "py_test") @@ -54,18 +55,18 @@ def with_deprecation(kwargs, *, symbol_name, python_version, load_name = None, d The kwargs to be used in the macro creation. """ - # TODO @aignas 2025-01-21: should we add a flag that silences this? - load_name = load_name or (":" + symbol_name) - - deprecation = _DEPRECATION_MESSAGE.format( - name = symbol_name, - load_name = load_name, - python_version = python_version, - deprecated = deprecated, - ) - if kwargs.get("deprecation"): - deprecation = kwargs.get("deprecation") + "\n\n" + deprecation - kwargs["deprecation"] = deprecation + if config.enable_deprecation_warnings: + load_name = load_name or (":" + symbol_name) + + deprecation = _DEPRECATION_MESSAGE.format( + name = symbol_name, + load_name = load_name, + python_version = python_version, + deprecated = deprecated, + ) + if kwargs.get("deprecation"): + deprecation = kwargs.get("deprecation") + "\n\n" + deprecation + kwargs["deprecation"] = deprecation kwargs["python_version"] = python_version return kwargs diff --git a/python/private/internal_config_repo.bzl b/python/private/internal_config_repo.bzl index 7b6869e9a5..d8d26a85ef 100644 --- a/python/private/internal_config_repo.bzl +++ b/python/private/internal_config_repo.bzl @@ -20,10 +20,13 @@ settings for rules to later use. _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}), @@ -60,6 +63,7 @@ bzl_library( def _internal_config_repo_impl(rctx): pystar_requested = _bool_from_environ(rctx, _ENABLE_PYSTAR_ENVVAR_NAME, _ENABLE_PYSTAR_DEFAULT) + deprecation_warnings_requested = _bool_from_environ(rctx, _ENABLE_DEPRECATION_WARNINGS_ENVVAR_NAME, _ENABLE_DEPRECATION_WARNINGS_DEFAULT) # Bazel 7+ (dev and later) has native.starlark_doc_extract, and thus the # py_internal global, which are necessary for the pystar implementation. @@ -68,6 +72,8 @@ def _internal_config_repo_impl(rctx): else: enable_pystar = False + enable_deprecation_warnings = deprecation_warnings_requested + if not native.bazel_version or int(native.bazel_version.split(".")[0]) >= 8: builtin_py_info_symbol = "None" builtin_py_runtime_info_symbol = "None" @@ -79,6 +85,7 @@ def _internal_config_repo_impl(rctx): rctx.file("rules_python_config.bzl", _CONFIG_TEMPLATE.format( enable_pystar = enable_pystar, + enable_deprecation_warnings = enable_deprecation_warnings, 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, From 57037e91115ec05ebaab26bfbe06b82b9849350f Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Tue, 21 Jan 2025 09:07:20 -0800 Subject: [PATCH 11/17] improve doc of envvar --- docs/environment-variables.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/environment-variables.md b/docs/environment-variables.md index e981dd76b9..fb9971597b 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -42,8 +42,8 @@ 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 symbols that will -be removed in the next major `rules_python` version. Defaults to `0`. +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 From 6bf4281e40308ac0a7e4937b0586d9ccb67fc108 Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Wed, 22 Jan 2025 08:47:35 +0900 Subject: [PATCH 12/17] comment: inline the deprecation warnings env var --- python/private/internal_config_repo.bzl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/python/private/internal_config_repo.bzl b/python/private/internal_config_repo.bzl index d8d26a85ef..eb093e294d 100644 --- a/python/private/internal_config_repo.bzl +++ b/python/private/internal_config_repo.bzl @@ -63,7 +63,6 @@ bzl_library( def _internal_config_repo_impl(rctx): pystar_requested = _bool_from_environ(rctx, _ENABLE_PYSTAR_ENVVAR_NAME, _ENABLE_PYSTAR_DEFAULT) - deprecation_warnings_requested = _bool_from_environ(rctx, _ENABLE_DEPRECATION_WARNINGS_ENVVAR_NAME, _ENABLE_DEPRECATION_WARNINGS_DEFAULT) # Bazel 7+ (dev and later) has native.starlark_doc_extract, and thus the # py_internal global, which are necessary for the pystar implementation. @@ -72,8 +71,6 @@ def _internal_config_repo_impl(rctx): else: enable_pystar = False - enable_deprecation_warnings = deprecation_warnings_requested - if not native.bazel_version or int(native.bazel_version.split(".")[0]) >= 8: builtin_py_info_symbol = "None" builtin_py_runtime_info_symbol = "None" @@ -85,7 +82,7 @@ def _internal_config_repo_impl(rctx): rctx.file("rules_python_config.bzl", _CONFIG_TEMPLATE.format( enable_pystar = enable_pystar, - enable_deprecation_warnings = enable_deprecation_warnings, + 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, From df6f580a1fc7d695ddb48a76b97d4434cdb0d70c Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Wed, 22 Jan 2025 09:31:16 +0900 Subject: [PATCH 13/17] rework the symbol deprecation and add tests to ensure that we are still working --- python/config_settings/transition.bzl | 58 +++-------- python/private/BUILD.bazel | 8 ++ python/private/deprecation.bzl | 59 +++++++++++ python/private/internal_config_repo.bzl | 4 +- python/private/toolchains_repo.bzl | 132 ++++++++---------------- tests/deprecated/BUILD.bazel | 96 +++++++++++++++++ tests/deprecated/dummy.py | 0 tests/deprecated/requirements.in | 0 tests/deprecated/requirements.txt | 6 ++ 9 files changed, 226 insertions(+), 137 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 diff --git a/python/config_settings/transition.bzl b/python/config_settings/transition.bzl index 762b7060ac..937f33bb88 100644 --- a/python/config_settings/transition.bzl +++ b/python/config_settings/transition.bzl @@ -21,54 +21,20 @@ of them should be changed to load the regular rules directly. ::: """ -load("@rules_python_internal//:rules_python_config.bzl", "config") load("//python:py_binary.bzl", _py_binary = "py_binary") load("//python:py_test.bzl", _py_test = "py_test") +load("//python/private:deprecation.bzl", "with_deprecation") +load("//python/private:text_util.bzl", "render") -_DEPRECATION_MESSAGE = """ -The '{name}' symbol in @{deprecated} -is deprecated. It is an alias to the regular rule; use it directly instead: - -load("@rules_python//python{load_name}.bzl", "{name}") - -{name}( - # ... - python_version = "{python_version}", - # ... -) -""" - -def with_deprecation(kwargs, *, symbol_name, python_version, load_name = None, deprecated = "rules_python//python/config_settings:transition.bzl"): - """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. - python_version: {type}`str` the python version to be used. - load_name: {type}`str` the load location under `//python`. Should start - either with `/` or `:`. Defaults to `:`. - deprecated: {type}`str` the symbol import location that we are deprecating. - - Returns: - The kwargs to be used in the macro creation. - """ - - if config.enable_deprecation_warnings: - load_name = load_name or (":" + symbol_name) - - deprecation = _DEPRECATION_MESSAGE.format( - name = symbol_name, - load_name = load_name, - python_version = python_version, - deprecated = deprecated, - ) - if kwargs.get("deprecation"): - deprecation = kwargs.get("deprecation") + "\n\n" + deprecation - kwargs["deprecation"] = deprecation +def _with_deprecation(kwargs, *, name, python_version): kwargs["python_version"] = python_version - return kwargs + 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. @@ -77,7 +43,7 @@ def py_binary(**kwargs): **kwargs: keyword args forwarded onto {obj}`py_binary`. """ - _py_binary(**with_deprecation(kwargs, name = "py_binary", python_version = kwargs.get("python_version"))) + _py_binary(**_with_deprecation(kwargs, name = "py_binary", python_version = kwargs.get("python_version"))) def py_test(**kwargs): """[DEPRECATED] Deprecated alias for py_test. @@ -85,4 +51,4 @@ def py_test(**kwargs): Args: **kwargs: keyword args forwarded onto {obj}`py_binary`. """ - _py_test(**with_deprecation(kwargs, name = "py_test", python_version = kwargs.get("python_version"))) + _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 eb093e294d..a5c4787161 100644 --- a/python/private/internal_config_repo.bzl +++ b/python/private/internal_config_repo.bzl @@ -18,6 +18,8 @@ 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" @@ -116,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 dcfd3c1a2e..b4da813784 100644 --- a/python/private/toolchains_repo.bzl +++ b/python/private/toolchains_repo.bzl @@ -151,61 +151,37 @@ toolchain_aliases( rctx.file("defs.bzl", content = """\ # Generated by python/private/toolchains_repo.bzl -load("{rules_python}//python/config_settings:transition.bzl", "with_deprecation") +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(**kwargs): - return _py_binary( - **with_deprecation( - kwargs, - symbol_name = "py_binary", - python_version = "{python_version}", - deprecated = "@{name}//:defs.bzl", - ), +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, - **with_deprecation( - kwargs, - symbol_name = "py_console_script_binary", - load_name = "/entry_points:py_console_script_binary", - python_version = "{python_version}", - deprecated = "@{name}//:defs.bzl", - ), - ) +def py_binary(**kwargs): + return _py_binary(**_with_deprecation(kwargs, name = "py_binary")) -def py_test(name, **kwargs): - return _py_test( - name = name, - **with_deprecation( - kwargs, - symbol_name = "py_test", - python_version = "{python_version}", - deprecated = "@{name}//:defs.bzl", - ), - ) +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, - **with_deprecation( - kwargs, - symbol_name = "compile_pip_requirements", - load_name = "pip", - python_version = "{python_version}", - deprecated = "@{name}//:defs.bzl", - ), - ) +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, @@ -332,66 +308,42 @@ def _multi_toolchain_aliases_impl(rctx): rctx.file(file, content = """\ # Generated by python/private/toolchains_repo.bzl -load("@@{rules_python}//python/config_settings:transition.bzl", "with_deprecation") -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: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", + "{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(**kwargs): - return _py_binary( - **with_deprecation( - kwargs, - symbol_name = "py_binary", - python_version = "{python_version}", - deprecated = "@{name}//{python_version}:defs.bzl", - ), +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_console_script_binary(name, **kwargs): - return _py_console_script_binary( - name = name, - binary_rule = _py_binary, - **with_deprecation( - kwargs, - symbol_name = "py_console_script_binary", - load_name = "/entry_points:py_console_script_binary", - python_version = "{python_version}", - deprecated = "@{name}//{python_version}:defs.bzl", - ), - ) +def py_binary(**kwargs): + return _py_binary(**_with_deprecation(kwargs, name = "py_binary")) -def py_test(name, **kwargs): - return _py_test( - name = name, - **with_deprecation( - kwargs, - symbol_name = "py_test", - python_version = "{python_version}", - deprecated = "@{name}//{python_version}:defs.bzl", - ), - ) +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, - **with_deprecation( - kwargs, - symbol_name = "compile_pip_requirements", - load_name = "pip", - python_version = "{python_version}", - deprecated = "@{name}//{python_version}:defs.bzl", - ), - ) +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 = rules_python, + rules_python = "@" + rules_python, )) rctx.file("{}/BUILD.bazel".format(python_version), "") diff --git a/tests/deprecated/BUILD.bazel b/tests/deprecated/BUILD.bazel new file mode 100644 index 0000000000..d269f83e20 --- /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", + 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_versions//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/config_settings:transition.bzl", transition_py_binary = "py_binary", transition_py_test = "py_test") + +# TODO 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.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..444beb63a5 --- /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:hub_compile_pip_requirements.update +# From fa883cff6d966899a345e7eb65031702adfecb6c Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Wed, 22 Jan 2025 09:31:32 +0900 Subject: [PATCH 14/17] fixup! rework the symbol deprecation and add tests to ensure that we are still working --- tests/deprecated/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/deprecated/BUILD.bazel b/tests/deprecated/BUILD.bazel index d269f83e20..7f363aaac0 100644 --- a/tests/deprecated/BUILD.bazel +++ b/tests/deprecated/BUILD.bazel @@ -15,7 +15,7 @@ load( ) load("//python/config_settings:transition.bzl", transition_py_binary = "py_binary", transition_py_test = "py_test") -# TODO remove the referenced symbols when releasing v2 +# TODO @aignas 2025-01-22: remove the referenced symbols when releasing v2 transition_py_binary( name = "transition_py_binary", From ece6b683bce403dbedd6a0e84fe0730fe13a875d Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Wed, 22 Jan 2025 09:33:17 +0900 Subject: [PATCH 15/17] fixup tests --- tests/deprecated/BUILD.bazel | 2 +- tests/deprecated/requirements.txt | 2 +- tests/deprecated/requirements_hub.txt | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 tests/deprecated/requirements_hub.txt diff --git a/tests/deprecated/BUILD.bazel b/tests/deprecated/BUILD.bazel index 7f363aaac0..9fa543b750 100644 --- a/tests/deprecated/BUILD.bazel +++ b/tests/deprecated/BUILD.bazel @@ -76,7 +76,7 @@ hub_py_console_script_binary( hub_compile_pip_requirements( name = "hub_compile_pip_requirements", src = "requirements.in", - requirements_txt = "requirements.txt", + requirements_txt = "requirements_hub.txt", ) build_test( diff --git a/tests/deprecated/requirements.txt b/tests/deprecated/requirements.txt index 444beb63a5..4d53f7c4e3 100644 --- a/tests/deprecated/requirements.txt +++ b/tests/deprecated/requirements.txt @@ -2,5 +2,5 @@ # This file is autogenerated by pip-compile with Python 3.11 # by the following command: # -# bazel run //tests/deprecated:hub_compile_pip_requirements.update +# 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 +# From 1b835c392b72b6aa2672a8345d70abb20e637df9 Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Wed, 22 Jan 2025 09:47:16 +0900 Subject: [PATCH 16/17] reshuffle the loads to make the tests compatible with WORKSPACE --- MODULE.bazel | 7 ++++++- WORKSPACE | 4 ++-- tests/deprecated/BUILD.bazel | 14 +++++++------- tools/publish/BUILD.bazel | 8 ++------ 4 files changed, 17 insertions(+), 16 deletions(-) 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/tests/deprecated/BUILD.bazel b/tests/deprecated/BUILD.bazel index 9fa543b750..4b920679f1 100644 --- a/tests/deprecated/BUILD.bazel +++ b/tests/deprecated/BUILD.bazel @@ -1,4 +1,11 @@ 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", @@ -6,13 +13,6 @@ load( versioned_py_console_script_binary = "py_console_script_binary", versioned_py_test = "py_test", ) -load( - "@python_versions//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/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 diff --git a/tools/publish/BUILD.bazel b/tools/publish/BUILD.bazel index 0145904dc8..4cf99e4d97 100644 --- a/tools/publish/BUILD.bazel +++ b/tools/publish/BUILD.bazel @@ -1,14 +1,10 @@ -load("//python:py_binary.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", From 8803d2e1f07809977c4f5f13fb8cab26a9160cd2 Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius <240938+aignas@users.noreply.github.com> Date: Wed, 22 Jan 2025 09:59:09 +0900 Subject: [PATCH 17/17] fix the rules_python name in the other place --- python/private/toolchains_repo.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/private/toolchains_repo.bzl b/python/private/toolchains_repo.bzl index b4da813784..5082047135 100644 --- a/python/private/toolchains_repo.bzl +++ b/python/private/toolchains_repo.bzl @@ -343,7 +343,7 @@ def compile_pip_requirements(**kwargs): repository_name = repository_name, name = rctx.attr.name, python_version = python_version, - rules_python = "@" + rules_python, + rules_python = get_repository_name(rctx.attr._rules_python_workspace), )) rctx.file("{}/BUILD.bazel".format(python_version), "")