From 58e53c7984a3adf4287eb71843e3a974cb15ff45 Mon Sep 17 00:00:00 2001 From: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> Date: Sun, 19 Oct 2025 23:28:30 +0000 Subject: [PATCH] Publish bazel-contrib/rules_python@1.7.0-rc1 --- modules/rules_python/1.7.0-rc1/MODULE.bazel | 464 ++++++++++++++++++ .../patches/module_dot_bazel_version.patch | 12 + modules/rules_python/1.7.0-rc1/presubmit.yml | 32 ++ modules/rules_python/1.7.0-rc1/source.json | 9 + modules/rules_python/metadata.json | 3 +- .../1.7.0-rc1/MODULE.bazel | 47 ++ .../patches/module_dot_bazel_version.patch | 12 + .../1.7.0-rc1/presubmit.yml | 32 ++ .../1.7.0-rc1/source.json | 9 + .../rules_python_gazelle_plugin/metadata.json | 3 +- 10 files changed, 621 insertions(+), 2 deletions(-) create mode 100644 modules/rules_python/1.7.0-rc1/MODULE.bazel create mode 100644 modules/rules_python/1.7.0-rc1/patches/module_dot_bazel_version.patch create mode 100644 modules/rules_python/1.7.0-rc1/presubmit.yml create mode 100644 modules/rules_python/1.7.0-rc1/source.json create mode 100644 modules/rules_python_gazelle_plugin/1.7.0-rc1/MODULE.bazel create mode 100644 modules/rules_python_gazelle_plugin/1.7.0-rc1/patches/module_dot_bazel_version.patch create mode 100644 modules/rules_python_gazelle_plugin/1.7.0-rc1/presubmit.yml create mode 100644 modules/rules_python_gazelle_plugin/1.7.0-rc1/source.json diff --git a/modules/rules_python/1.7.0-rc1/MODULE.bazel b/modules/rules_python/1.7.0-rc1/MODULE.bazel new file mode 100644 index 00000000000..ca94eba728d --- /dev/null +++ b/modules/rules_python/1.7.0-rc1/MODULE.bazel @@ -0,0 +1,464 @@ +module( + name = "rules_python", + version = "1.7.0-rc1", + compatibility_level = 1, +) + +bazel_dep(name = "bazel_features", version = "1.21.0") +bazel_dep(name = "bazel_skylib", version = "1.8.2") +bazel_dep(name = "rules_cc", version = "0.1.5") +bazel_dep(name = "platforms", version = "0.0.11") + +# Those are loaded only when using py_proto_library +# Use py_proto_library directly from protobuf repository +bazel_dep(name = "protobuf", version = "29.0-rc2", repo_name = "com_google_protobuf") + +rules_python_config = use_extension("//python/extensions:config.bzl", "config") +use_repo( + rules_python_config, + "pypi__build", + "pypi__click", + "pypi__colorama", + "pypi__importlib_metadata", + "pypi__installer", + "pypi__more_itertools", + "pypi__packaging", + "pypi__pep517", + "pypi__pip", + "pypi__pip_tools", + "pypi__pyproject_hooks", + "pypi__setuptools", + "pypi__tomli", + "pypi__wheel", + "pypi__zipp", + "rules_python_internal", +) + +# We need to do another use_extension call to expose the "pythons_hub" +# repo. +python = use_extension("//python/extensions:python.bzl", "python") + +# The default toolchain to use if nobody configures a toolchain. +# NOTE: This is not a stable version. It is provided for convenience, but will +# change frequently to track the most recent Python version. +# NOTE: The root module can override this. +# NOTE: There must be a corresponding `python.toolchain()` call for the version +# specified here. +python.defaults( + python_version = "3.11", +) +python.toolchain( + python_version = "3.11", +) +use_repo( + python, + "python_3_11", + "pythons_hub", + python = "python_versions", +) + +# This call registers the Python toolchains. +register_toolchains("@pythons_hub//:all") + +##################### +# Install twine for our own runfiles wheel publishing and allow bzlmod users to use it. + +pip = use_extension("//python/extensions:pip.bzl", "pip") + +# NOTE @aignas 2025-07-06: we define these platforms to keep backwards compatibility with the +# current `experimental_index_url` implementation. Whilst we stabilize the API this list may be +# updated with a mention in the CHANGELOG. +[ + pip.default( + arch_name = cpu, + config_settings = [ + "@platforms//cpu:{}".format(cpu), + "@platforms//os:linux", + "//python/config_settings:_is_py_freethreaded_{}".format( + "yes" if freethreaded else "no", + ), + ], + env = {"platform_version": "0"}, + marker = "python_version >= '3.13'" if freethreaded else "", + os_name = "linux", + platform = "linux_{}{}".format(cpu, freethreaded), + whl_abi_tags = ["cp{major}{minor}t"] if freethreaded else [ + "abi3", + "cp{major}{minor}", + ], + whl_platform_tags = [ + "linux_{}".format(cpu), + "manylinux_*_{}".format(cpu), + ], + ) + for cpu in [ + "x86_64", + "aarch64", + ] + for freethreaded in [ + "", + "_freethreaded", + ] +] + +[ + pip.default( + arch_name = cpu, + config_settings = [ + "@platforms//cpu:{}".format(cpu), + "@platforms//os:osx", + "//python/config_settings:_is_py_freethreaded_{}".format( + "yes" if freethreaded else "no", + ), + ], + # We choose the oldest non-EOL version at the time when we release `rules_python`. + # See https://endoflife.date/macos + env = {"platform_version": "14.0"}, + marker = "python_version >= '3.13'" if freethreaded else "", + os_name = "osx", + platform = "osx_{}{}".format(cpu, freethreaded), + whl_abi_tags = ["cp{major}{minor}t"] if freethreaded else [ + "abi3", + "cp{major}{minor}", + ], + whl_platform_tags = [ + "macosx_*_{}".format(suffix) + for suffix in platform_tag_cpus + ], + ) + for cpu, platform_tag_cpus in { + "aarch64": [ + "universal2", + "arm64", + ], + "x86_64": [ + "universal2", + "x86_64", + ], + }.items() + for freethreaded in [ + "", + "_freethreaded", + ] +] + +[ + pip.default( + arch_name = cpu, + config_settings = [ + "@platforms//cpu:{}".format(cpu), + "@platforms//os:windows", + "//python/config_settings:_is_py_freethreaded_{}".format( + "yes" if freethreaded else "no", + ), + ], + env = {"platform_version": "0"}, + marker = "python_version >= '3.13'" if freethreaded else "", + os_name = "windows", + platform = "windows_{}{}".format(cpu, freethreaded), + whl_abi_tags = ["cp{major}{minor}t"] if freethreaded else [ + "abi3", + "cp{major}{minor}", + ], + whl_platform_tags = whl_platform_tags, + ) + for cpu, whl_platform_tags in { + "x86_64": ["win_amd64"], + }.items() + for freethreaded in [ + "", + "_freethreaded", + ] +] + +[ + pip.default( + arch_name = cpu, + config_settings = [ + "@platforms//cpu:{}".format(cpu), + "@platforms//os:windows", + "//python/config_settings:_is_py_freethreaded_{}".format( + "yes" if freethreaded else "no", + ), + ], + env = {"platform_version": "0"}, + marker = "python_version >= '3.13'" if freethreaded else "python_version >= '3.11'", + os_name = "windows", + platform = "windows_{}{}".format(cpu, freethreaded), + whl_abi_tags = ["cp{major}{minor}t"] if freethreaded else [ + "abi3", + "cp{major}{minor}", + ], + whl_platform_tags = whl_platform_tags, + ) + for cpu, whl_platform_tags in { + "aarch64": ["win_arm64"], + }.items() + for freethreaded in [ + "", + "_freethreaded", + ] +] + +pip.parse( + hub_name = "rules_python_publish_deps", + python_version = "3.11", + requirements_by_platform = { + "//tools/publish:requirements_darwin.txt": "osx_*", + "//tools/publish:requirements_linux.txt": "linux_*", + "//tools/publish:requirements_windows.txt": "windows_*", + }, +) +use_repo(pip, "rules_python_publish_deps") + +# Not a dev dependency to allow usage of //sphinxdocs code, which refers to stardoc repos. +bazel_dep(name = "stardoc", version = "0.7.2", repo_name = "io_bazel_stardoc") + +# ===== DEV ONLY DEPS AND SETUP BELOW HERE ===== +bazel_dep(name = "rules_bazel_integration_test", version = "0.27.0", dev_dependency = True) +bazel_dep(name = "rules_testing", version = "0.6.0", dev_dependency = True) +bazel_dep(name = "rules_shell", version = "0.3.0", dev_dependency = True) +bazel_dep(name = "rules_multirun", version = "0.9.0", dev_dependency = True) +bazel_dep(name = "bazel_ci_rules", version = "1.0.0", dev_dependency = True) +bazel_dep(name = "rules_pkg", version = "1.0.1", dev_dependency = True) +bazel_dep(name = "other", version = "0", dev_dependency = True) +bazel_dep(name = "another_module", version = "0", dev_dependency = True) + +# Extra gazelle plugin deps so that WORKSPACE.bzlmod can continue including it for e2e tests. +# We use `WORKSPACE.bzlmod` because it is impossible to have dev-only local overrides. +bazel_dep(name = "rules_go", version = "0.41.0", dev_dependency = True, repo_name = "io_bazel_rules_go") +bazel_dep(name = "rules_python_gazelle_plugin", version = "0", dev_dependency = True) +bazel_dep(name = "gazelle", version = "0.40.0", dev_dependency = True, repo_name = "bazel_gazelle") + +internal_dev_deps = use_extension( + "//python/private:internal_dev_deps.bzl", + "internal_dev_deps", + dev_dependency = True, +) +use_repo( + internal_dev_deps, + "buildkite_config", + "implicit_namespace_ns_sub1", + "implicit_namespace_ns_sub2", + "rules_python_runtime_env_tc_info", + "somepkg_with_build_files", + "whl_with_build_files", +) + +dev_rules_python_config = use_extension( + "//python/extensions:config.bzl", + "config", + dev_dependency = True, +) +dev_rules_python_config.add_transition_setting( + # Intentionally add a setting already present for testing + setting = "//python/config_settings:python_version", +) +dev_rules_python_config.add_transition_setting( + setting = "//tests/multi_pypi:external_deps_name", +) + +# Add gazelle plugin so that we can run the gazelle example as an e2e integration +# test and include the distribution files. +local_path_override( + module_name = "rules_python_gazelle_plugin", + path = "gazelle", +) + +local_path_override( + module_name = "other", + path = "tests/modules/other", +) + +local_path_override( + module_name = "another_module", + path = "tests/modules/another_module", +) + +dev_python = use_extension( + "//python/extensions:python.bzl", + "python", + dev_dependency = True, +) +dev_python.override( + register_all_versions = True, +) + +# For testing an arbitrary runtime triggered by a custom flag. +# See //tests/toolchains:custom_platform_toolchain_test +dev_python.single_version_platform_override( + platform = "linux-x86-install-only-stripped", + python_version = "3.13.1", + sha256 = "56817aa976e4886bec1677699c136cb01c1cdfe0495104c0d8ef546541864bbb", + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + ], + target_settings = [ + "@@//tests/support:is_custom_runtime_linux-x86-install-only-stripped", + ], + urls = ["https://github.com/astral-sh/python-build-standalone/releases/download/20250115/cpython-3.13.1+20250115-x86_64-unknown-linux-gnu-install_only_stripped.tar.gz"], +) + +dev_pip = use_extension( + "//python/extensions:pip.bzl", + "pip", + dev_dependency = True, +) + +[ + dev_pip.parse( + download_only = True, + experimental_index_url = "https://pypi.org/simple", + hub_name = "dev_pip", + parallel_download = False, + python_version = python_version, + requirements_lock = "//docs:requirements.txt", + ) + for python_version in [ + "3.9", + "3.10", + "3.11", + "3.12", + "3.13", + "3.14", + ] +] + +dev_pip.parse( + download_only = True, + experimental_index_url = "https://pypi.org/simple", + hub_name = "pypiserver", + python_version = "3.11", + requirements_lock = "//examples/wheel:requirements_server.txt", +) +dev_pip.parse( + hub_name = "pypi_alpha", + python_version = "3.11", + requirements_lock = "//tests/multi_pypi/alpha:requirements.txt", +) +dev_pip.parse( + hub_name = "pypi_beta", + python_version = "3.11", + requirements_lock = "//tests/multi_pypi/beta:requirements.txt", +) +use_repo(dev_pip, "dev_pip", "pypi_alpha", "pypi_beta", "pypiserver") + +# Bazel integration test setup below + +bazel_binaries = use_extension( + "@rules_bazel_integration_test//:extensions.bzl", + "bazel_binaries", + dev_dependency = True, +) + +# Keep in sync with //:version.bzl +bazel_binaries.local( + name = "self", + path = "tests/integration/bazel_from_env", +) +bazel_binaries.download(version = "7.4.1") +bazel_binaries.download(version = "8.0.0") + +# For now, don't test with rolling, because that's Bazel 9, which is a ways +# away. +# bazel_binaries.download(version = "rolling") +use_repo( + bazel_binaries, + "bazel_binaries", + # These don't appear necessary, but are reported as direct dependencies + # that should be use_repo()'d, so we add them as requested + "bazel_binaries_bazelisk", + "build_bazel_bazel_7_4_1", + "build_bazel_bazel_8_0_0", + # "build_bazel_bazel_rolling", + "build_bazel_bazel_self", +) + +# TODO @aignas 2025-01-27: should this be moved to `//python/extensions:uv.bzl` or should +# it stay as it is? I think I may prefer to move it. +uv = use_extension("//python/uv:uv.bzl", "uv") + +# Here is how we can define platforms for the `uv` binaries - this will affect +# all of the downstream callers because we are using the extension without +# `dev_dependency = True`. +uv.default( + base_url = "https://github.com/astral-sh/uv/releases/download", + manifest_filename = "dist-manifest.json", + version = "0.6.3", +) +uv.default( + compatible_with = [ + "@platforms//os:macos", + "@platforms//cpu:aarch64", + ], + platform = "aarch64-apple-darwin", +) +uv.default( + compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:aarch64", + ], + platform = "aarch64-unknown-linux-gnu", +) +uv.default( + compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:ppc", + ], + platform = "powerpc64-unknown-linux-gnu", +) +uv.default( + compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:ppc64le", + ], + platform = "powerpc64le-unknown-linux-gnu", +) +uv.default( + compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:s390x", + ], + platform = "s390x-unknown-linux-gnu", +) +uv.default( + compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:riscv64", + ], + platform = "riscv64-unknown-linux-gnu", +) +uv.default( + compatible_with = [ + "@platforms//os:macos", + "@platforms//cpu:x86_64", + ], + platform = "x86_64-apple-darwin", +) +uv.default( + compatible_with = [ + "@platforms//os:windows", + "@platforms//cpu:x86_64", + ], + platform = "x86_64-pc-windows-msvc", +) +uv.default( + compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + ], + platform = "x86_64-unknown-linux-gnu", +) +use_repo(uv, "uv") + +register_toolchains("@uv//:all") + +uv_dev = use_extension( + "//python/uv:uv.bzl", + "uv", + dev_dependency = True, +) +uv_dev.configure( + version = "0.6.2", +) diff --git a/modules/rules_python/1.7.0-rc1/patches/module_dot_bazel_version.patch b/modules/rules_python/1.7.0-rc1/patches/module_dot_bazel_version.patch new file mode 100644 index 00000000000..f7ff4bc33e4 --- /dev/null +++ b/modules/rules_python/1.7.0-rc1/patches/module_dot_bazel_version.patch @@ -0,0 +1,12 @@ +=================================================================== +--- a/MODULE.bazel ++++ b/MODULE.bazel +@@ -1,7 +1,7 @@ + module( + name = "rules_python", +- version = "0.0.0", ++ version = "1.7.0-rc1", + compatibility_level = 1, + ) + + bazel_dep(name = "bazel_features", version = "1.21.0") diff --git a/modules/rules_python/1.7.0-rc1/presubmit.yml b/modules/rules_python/1.7.0-rc1/presubmit.yml new file mode 100644 index 00000000000..e1ddb7a1aab --- /dev/null +++ b/modules/rules_python/1.7.0-rc1/presubmit.yml @@ -0,0 +1,32 @@ +# Copyright 2023 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +bcr_test_module: + module_path: "examples/bzlmod" + matrix: + platform: ["debian11", "macos", "ubuntu2004", "windows"] + # last_rc is to get latest 8.x release. Replace with 8.x when available. + bazel: [7.x, last_rc] + tasks: + run_tests: + name: "Run test module" + platform: ${{ platform }} + bazel: ${{ bazel }} + test_flags: + - "--keep_going" + # Without these cxxopts, BCR's Mac builds fail + - '--cxxopt=-std=c++14' + - '--host_cxxopt=-std=c++14' + test_targets: + - "//..." diff --git a/modules/rules_python/1.7.0-rc1/source.json b/modules/rules_python/1.7.0-rc1/source.json new file mode 100644 index 00000000000..fa11039f15d --- /dev/null +++ b/modules/rules_python/1.7.0-rc1/source.json @@ -0,0 +1,9 @@ +{ + "integrity": "sha256-dnGtmAeM+aBtKDrkcob8YLqxU5e4mowvBbQyqtmhApo=", + "strip_prefix": "rules_python-1.7.0-rc1", + "url": "https://github.com/bazel-contrib/rules_python/releases/download/1.7.0-rc1/rules_python-1.7.0-rc1.tar.gz", + "patches": { + "module_dot_bazel_version.patch": "sha256-COPjpfWE3KrWDVfvhLpQ0mpinI0ScMGtG3lcNQDqFiY=" + }, + "patch_strip": 1 +} diff --git a/modules/rules_python/metadata.json b/modules/rules_python/metadata.json index e3a6abb9f82..3883fdddbcd 100644 --- a/modules/rules_python/metadata.json +++ b/modules/rules_python/metadata.json @@ -94,7 +94,8 @@ "1.6.0-rc0", "1.6.0", "1.6.1", - "1.6.3" + "1.6.3", + "1.7.0-rc1" ], "yanked_versions": { "0.14.0": "rules_python 0.14.0 is broken due to https://github.com/bazelbuild/bazel-central-registry/issues/287, please upgrade to version >= 0.15.0" diff --git a/modules/rules_python_gazelle_plugin/1.7.0-rc1/MODULE.bazel b/modules/rules_python_gazelle_plugin/1.7.0-rc1/MODULE.bazel new file mode 100644 index 00000000000..7ed7b240092 --- /dev/null +++ b/modules/rules_python_gazelle_plugin/1.7.0-rc1/MODULE.bazel @@ -0,0 +1,47 @@ +module( + name = "rules_python_gazelle_plugin", + version = "1.7.0-rc1", + compatibility_level = 1, +) + +bazel_dep(name = "bazel_skylib", version = "1.8.2") +bazel_dep(name = "rules_python", version = "0.18.0") +bazel_dep(name = "rules_go", version = "0.55.1", repo_name = "io_bazel_rules_go") +bazel_dep(name = "gazelle", version = "0.36.0", repo_name = "bazel_gazelle") +bazel_dep(name = "rules_cc", version = "0.0.16") + +local_path_override( + module_name = "rules_python", + path = "..", +) + +go_deps = use_extension("@bazel_gazelle//:extensions.bzl", "go_deps") +go_deps.from_file(go_mod = "//:go.mod") +use_repo( + go_deps, + "com_github_bazelbuild_buildtools", + "com_github_bmatcuk_doublestar_v4", + "com_github_emirpasic_gods", + "com_github_ghodss_yaml", + "com_github_smacker_go_tree_sitter", + "com_github_stretchr_testify", + "in_gopkg_yaml_v2", + "org_golang_x_sync", +) + +python_stdlib_list = use_extension("//python:extensions.bzl", "python_stdlib_list") +use_repo( + python_stdlib_list, + "python_stdlib_list", +) + +internal_dev_deps = use_extension( + "//:internal_dev_deps.bzl", + "internal_dev_deps_extension", + dev_dependency = True, +) +use_repo( + internal_dev_deps, + "django-types", + "pytest", +) diff --git a/modules/rules_python_gazelle_plugin/1.7.0-rc1/patches/module_dot_bazel_version.patch b/modules/rules_python_gazelle_plugin/1.7.0-rc1/patches/module_dot_bazel_version.patch new file mode 100644 index 00000000000..0c96f7ec9b3 --- /dev/null +++ b/modules/rules_python_gazelle_plugin/1.7.0-rc1/patches/module_dot_bazel_version.patch @@ -0,0 +1,12 @@ +=================================================================== +--- a/MODULE.bazel ++++ b/MODULE.bazel +@@ -1,7 +1,7 @@ + module( + name = "rules_python_gazelle_plugin", +- version = "0.0.0", ++ version = "1.7.0-rc1", + compatibility_level = 1, + ) + + bazel_dep(name = "bazel_skylib", version = "1.8.2") diff --git a/modules/rules_python_gazelle_plugin/1.7.0-rc1/presubmit.yml b/modules/rules_python_gazelle_plugin/1.7.0-rc1/presubmit.yml new file mode 100644 index 00000000000..ff1c9e7d584 --- /dev/null +++ b/modules/rules_python_gazelle_plugin/1.7.0-rc1/presubmit.yml @@ -0,0 +1,32 @@ +# Copyright 2023 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +bcr_test_module: + module_path: "examples/bzlmod_build_file_generation" + matrix: + platform: ["debian11", "macos", "ubuntu2004", "windows"] + # last_rc is to get latest 8.x release. Replace with 8.x when available. + bazel: [7.x, last_rc] + tasks: + run_tests: + name: "Run test module" + platform: ${{ platform }} + bazel: ${{ bazel }} + shell_commands: + - "echo 'common --override_module=rules_python=' >> .bazelrc" + build_targets: + - "//..." + - ":modules_map" + test_targets: + - "//..." diff --git a/modules/rules_python_gazelle_plugin/1.7.0-rc1/source.json b/modules/rules_python_gazelle_plugin/1.7.0-rc1/source.json new file mode 100644 index 00000000000..95e444311ac --- /dev/null +++ b/modules/rules_python_gazelle_plugin/1.7.0-rc1/source.json @@ -0,0 +1,9 @@ +{ + "integrity": "sha256-dnGtmAeM+aBtKDrkcob8YLqxU5e4mowvBbQyqtmhApo=", + "strip_prefix": "rules_python-1.7.0-rc1/gazelle", + "url": "https://github.com/bazel-contrib/rules_python/releases/download/1.7.0-rc1/rules_python-1.7.0-rc1.tar.gz", + "patches": { + "module_dot_bazel_version.patch": "sha256-Kp0IQwc+cXybL7yPjFjhx0m6YkI/iolTlkWwRr6HFB4=" + }, + "patch_strip": 1 +} diff --git a/modules/rules_python_gazelle_plugin/metadata.json b/modules/rules_python_gazelle_plugin/metadata.json index de6745c357c..f4be2aceebb 100644 --- a/modules/rules_python_gazelle_plugin/metadata.json +++ b/modules/rules_python_gazelle_plugin/metadata.json @@ -77,7 +77,8 @@ "1.6.0-rc0", "1.6.0", "1.6.1", - "1.6.3" + "1.6.3", + "1.7.0-rc1" ], "yanked_versions": {} }