From c8e2270f2995cbceb0551e701637e7cdc2b7063d Mon Sep 17 00:00:00 2001 From: Reid D McKenzie Date: Tue, 27 Jan 2026 09:36:50 -0700 Subject: [PATCH 01/18] feat: uv v2 - Correct `toml` watching - Correct `extra` handling - Move to `[dependency-groups]` for configurations --- .bazelrc | 2 +- .gitignore | 20 +- BUILD.bazel | 2 +- MODULE.bazel | 21 +- docs/uv.md | 31 +- e2e/.bazelrc | 2 +- e2e/MODULE.bazel | 39 +- e2e/cases/oci/py_image_layer/BUILD.bazel | 1 + e2e/cases/oci/py_image_layer/pyproject.toml | 9 + e2e/cases/oci/py_image_layer/uv.lock | 70 + e2e/cases/oci/py_venv_image_layer/BUILD.bazel | 1 + .../oci/py_venv_image_layer/pyproject.toml | 9 + e2e/cases/oci/py_venv_image_layer/uv.lock | 70 + e2e/cases/uv-deps-650/airflow/pyproject.toml | 10 + e2e/cases/uv-deps-650/airflow/uv.lock | 498 +++- e2e/cases/uv-deps-650/crossbuild/BUILD.bazel | 13 - .../uv-deps-650/crossbuild/pyproject.toml | 9 + e2e/cases/uv-deps-650/crossbuild/uv.lock | 86 +- e2e/cases/uv-deps-650/extras/BUILD.bazel | 14 + e2e/cases/uv-deps-650/extras/__test__.py | 13 + e2e/cases/uv-deps-650/extras/pyproject.toml | 15 + e2e/cases/uv-deps-650/extras/uv.lock | 354 +++ e2e/cases/uv-deps-650/say/pyproject.toml | 7 + e2e/cases/uv-deps-650/say/uv.lock | 6 +- py/private/py_library.bzl | 2 +- py/tests/py-binary/BUILD.bazel | 52 - py/tests/py-binary/main_from_name.py | 5 - py/tests/py-binary/runfiles_from_pip.py | 14 - py/tests/py-binary/test_data.txt | 1 - pyproject.toml | 21 + uv.lock | 373 +-- uv/BUILD.bazel | 0 uv/private/BUILD.bazel | 27 - uv/private/constraints/repository.bzl | 35 + uv/private/defs.bzl | 10 + uv/private/extension.bzl | 1002 ------- uv/private/extension/BUILD.bazel | 14 + uv/private/extension/defs.bzl | 525 ++++ uv/private/extension/git_utils.bzl | 106 + uv/private/extension/graph_utils.bzl | 149 + uv/private/extension/lockfile.bzl | 265 ++ uv/private/extension/parser.bzl | 905 +++++++ uv/private/extension/projectfile.bzl | 204 ++ uv/private/extension/test_graph_utils.bzl | 382 +++ uv/private/git_archive/BUILD.bazel | 5 + uv/private/git_archive/repository.bzl | 85 + uv/private/graph/BUILD.bazel | 10 + uv/private/graph/defs.bzl | 5 + uv/private/graph/sccs.bzl | 84 + uv/private/graph/sccs_test.bzl | 2385 +++++++++++++++++ uv/private/hub/repository.bzl | 257 -- uv/private/pprint/BUILD.bazel | 5 + uv/private/pprint/defs.bzl | 80 + uv/private/pprint/test.bzl | 67 + uv/private/py_entrypoint_binary/BUILD.bazel | 5 +- uv/private/py_entrypoint_binary/defs.bzl | 61 +- .../py_entrypoint_binary/entrypoint.tmpl | 6 +- uv/private/py_entrypoint_binary/search.py | 65 + uv/private/sccs.bzl | 86 - uv/private/sdist_build/build_helper.py | 68 +- uv/private/sdist_build/repository.bzl | 42 +- uv/private/sdist_build/rule.bzl | 5 + uv/private/uv/pyproject.toml | 2 +- uv/private/uv/uv.lock.json | 106 +- uv/private/{hub => uv_hub}/BUILD.bazel | 0 uv/private/uv_hub/repository.bzl | 228 ++ .../{venv_hub => uv_project}/BUILD.bazel | 0 uv/private/uv_project/repository.bzl | 265 ++ uv/private/venv_hub/repository.bzl | 213 -- uv/private/whl_install/repository.bzl | 28 +- uv/unstable/defs.bzl | 8 + uv/unstable/extension.bzl | 2 +- v2.py | 482 ++++ 73 files changed, 7886 insertions(+), 2163 deletions(-) create mode 100644 e2e/cases/oci/py_image_layer/pyproject.toml create mode 100644 e2e/cases/oci/py_image_layer/uv.lock create mode 100644 e2e/cases/oci/py_venv_image_layer/pyproject.toml create mode 100644 e2e/cases/oci/py_venv_image_layer/uv.lock create mode 100644 e2e/cases/uv-deps-650/airflow/pyproject.toml create mode 100644 e2e/cases/uv-deps-650/crossbuild/pyproject.toml create mode 100644 e2e/cases/uv-deps-650/extras/BUILD.bazel create mode 100644 e2e/cases/uv-deps-650/extras/__test__.py create mode 100644 e2e/cases/uv-deps-650/extras/pyproject.toml create mode 100644 e2e/cases/uv-deps-650/extras/uv.lock create mode 100644 e2e/cases/uv-deps-650/say/pyproject.toml delete mode 100644 py/tests/py-binary/BUILD.bazel delete mode 100644 py/tests/py-binary/main_from_name.py delete mode 100644 py/tests/py-binary/runfiles_from_pip.py delete mode 100644 py/tests/py-binary/test_data.txt create mode 100644 pyproject.toml delete mode 100644 uv/BUILD.bazel delete mode 100644 uv/private/extension.bzl create mode 100644 uv/private/extension/BUILD.bazel create mode 100644 uv/private/extension/defs.bzl create mode 100644 uv/private/extension/git_utils.bzl create mode 100644 uv/private/extension/graph_utils.bzl create mode 100644 uv/private/extension/lockfile.bzl create mode 100644 uv/private/extension/parser.bzl create mode 100644 uv/private/extension/projectfile.bzl create mode 100644 uv/private/extension/test_graph_utils.bzl create mode 100644 uv/private/git_archive/BUILD.bazel create mode 100644 uv/private/git_archive/repository.bzl create mode 100644 uv/private/graph/BUILD.bazel create mode 100644 uv/private/graph/defs.bzl create mode 100644 uv/private/graph/sccs.bzl create mode 100644 uv/private/graph/sccs_test.bzl delete mode 100644 uv/private/hub/repository.bzl create mode 100644 uv/private/pprint/BUILD.bazel create mode 100644 uv/private/pprint/defs.bzl create mode 100644 uv/private/pprint/test.bzl create mode 100644 uv/private/py_entrypoint_binary/search.py delete mode 100644 uv/private/sccs.bzl rename uv/private/{hub => uv_hub}/BUILD.bazel (100%) create mode 100644 uv/private/uv_hub/repository.bzl rename uv/private/{venv_hub => uv_project}/BUILD.bazel (100%) create mode 100644 uv/private/uv_project/repository.bzl delete mode 100644 uv/private/venv_hub/repository.bzl create mode 100644 v2.py diff --git a/.bazelrc b/.bazelrc index 498f0cd4..9f038f21 100644 --- a/.bazelrc +++ b/.bazelrc @@ -7,7 +7,7 @@ common --incompatible_disallow_empty_glob=False common --define=SOME_VAR=SOME_VALUE # Set the default virtualenv to 'default' -common --@pypi//venv=default +common --@pypi//venv=aspect_rules_py common --incompatible_enable_cc_toolchain_resolution common --@toolchains_llvm_bootstrapped//config:experimental_stub_libgcc_s diff --git a/.gitignore b/.gitignore index 60f3e974..62c7f3a2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,15 @@ +!third_party/** +**/*.whl +**/__pycache__ **/bazel-* +**/target/ +.*.venv/ +.DS_Store +.agent* +.gemini* .bazelrc.user .idea .ijwb -.*.venv/ -**/__pycache__ -.DS_Store -**/target/ -**/*.whl .venv/ - -node_modules/ - -!third_party/** - -# TODO: enable when it is more stable, maybe Bazel 7.1 MODULE.bazel.lock +node_modules/ diff --git a/BUILD.bazel b/BUILD.bazel index efdc898c..ec56d59c 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -14,7 +14,7 @@ gazelle_python_manifest( name = "gazelle_python_manifest", hub = "pypi", venvs = [ - "default", + "aspect_rules_py", ], ) diff --git a/MODULE.bazel b/MODULE.bazel index 5ec2e226..9390f860 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -186,19 +186,20 @@ uv = use_extension("//uv/unstable:extension.bzl", "uv", dev_dependency = IS_RELE uv.declare_hub( hub_name = "pypi", ) -uv.declare_venv( - hub_name = "pypi", - venv_name = "default", -) -uv.lockfile( - src = "//:uv.lock", +uv.project( + name = "aspect_rules_py", hub_name = "pypi", - venv_name = "default", + lock = "//:uv.lock", + pyproject = "//:pyproject.toml", + default_build_dependencies = [ + "build", + "setuptools", + "maturin", + ], ) -uv.unstable_annotate_requirements( +uv.unstable_annotate_packages( + lock = "//:uv.lock", src = "//:annotations.toml", - hub_name = "pypi", - venv_name = "default", ) use_repo(uv, "pypi") diff --git a/docs/uv.md b/docs/uv.md index d61dd463..9f3a0565 100644 --- a/docs/uv.md +++ b/docs/uv.md @@ -90,29 +90,16 @@ uv = use_extension("//uv/unstable:extension.bzl", "uv") uv.declare_hub( hub_name = "pypi", # Or whatever you wish ) -uv.declare_venv( +uv.project( hub_name = "pypi", # Must be a declared hub - venv_name = "default", # Or whatever you wish -) -uv.lockfile( - hub_name = "pypi", # Must be a declared hub - venv_name = "default", # Must be a declared venv - src = "//:uv.lock", + pyproject = "//:pyproject.toml", + lock = "//:uv.lock", ) -uv.declare_venv( - hub_name = "pypi", - venv_name = "vendored_say", -) -uv.lockfile( - hub_name = "pypi", - venv_name = "vendored_say", - src = "//:uv.lock", -) -uv.override_requirement( - hub_name = "pypi", - venv_name = "vendored_say", - requirement = "cowsay", +uv.override_package( + lock = "//:uv.lock", + name = "cowsay", + # version = "", Optional but may be required for disambiguation target = "//third_party/py/cowsay:cowsay", ) @@ -121,10 +108,12 @@ use repository(uv, "pypi") ``` We can configure a default virtualenv by setting the venv configuration flag on our hub as part of the `.bazelrc`. +Each `[dependency-group]` of the `pyproject.toml` is registered as a named venv configuration. +If no dependency groups are listed, an implicit default group with the name of the project itself is created. ``` # .bazelrc -common --@pypi//venv=default +common --@pypi//venv=dummy ``` Individual targets can request different venvs if multiple venvs are configured. diff --git a/e2e/.bazelrc b/e2e/.bazelrc index bc72d0e8..060b2639 100644 --- a/e2e/.bazelrc +++ b/e2e/.bazelrc @@ -7,4 +7,4 @@ common --repo_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 common --repo_env=BAZEL_NO_APPLE_CPP_TOOLCHAIN=1 # Configure a default venv -common --@pypi//venv=say +# common --@pypi//venv=say diff --git a/e2e/MODULE.bazel b/e2e/MODULE.bazel index 436b2387..39973469 100644 --- a/e2e/MODULE.bazel +++ b/e2e/MODULE.bazel @@ -111,37 +111,30 @@ use_repo(importer, "myrepo") # For cases/uv-deps-650 uv = use_extension("@aspect_rules_py//uv/unstable:extension.bzl", "uv") uv.declare_hub(hub_name = "pypi") -uv.declare_venv( +uv.project( hub_name = "pypi", - venv_name = "say", + lock = "//cases/uv-deps-650/say:uv.lock", + pyproject = "//cases/uv-deps-650/say:pyproject.toml", ) -uv.lockfile( - src = "//cases/uv-deps-650/say:uv.lock", - hub_name = "pypi", - venv_name = "say", -) -uv.override_requirement( - hub_name = "pypi", - requirement = "cowsay", +uv.override_package( + name = "cowsay", + lock = "//cases/uv-deps-650/say:uv.lock", + # FIXME: Version annotation may be required for disambiguation target = "//cases/uv-deps-650/third_party/cowsay", - venv_name = "say", -) -uv.declare_venv( - hub_name = "pypi", - venv_name = "airflow", ) -uv.lockfile( - src = "//cases/uv-deps-650/airflow:uv.lock", +uv.project( hub_name = "pypi", - venv_name = "airflow", + lock = "//cases/uv-deps-650/airflow:uv.lock", + pyproject = "//cases/uv-deps-650/airflow:pyproject.toml", ) -uv.declare_venv( +uv.project( hub_name = "pypi", - venv_name = "psql", + lock = "//cases/uv-deps-650/crossbuild:uv.lock", + pyproject = "//cases/uv-deps-650/crossbuild:pyproject.toml", ) -uv.lockfile( - src = "//cases/uv-deps-650/crossbuild:uv.lock", +uv.project( hub_name = "pypi", - venv_name = "psql", + lock = "//cases/uv-deps-650/extras:uv.lock", + pyproject = "//cases/uv-deps-650/extras:pyproject.toml", ) use_repo(uv, "pypi") diff --git a/e2e/cases/oci/py_image_layer/BUILD.bazel b/e2e/cases/oci/py_image_layer/BUILD.bazel index bc507515..bae5f3d9 100644 --- a/e2e/cases/oci/py_image_layer/BUILD.bazel +++ b/e2e/cases/oci/py_image_layer/BUILD.bazel @@ -23,6 +23,7 @@ platform( py_binary( name = "my_app_bin", srcs = ["__main__.py"], + venv = "images", deps = [ "//cases/oci/py_image_layer/branding", "@aspect_rules_py//py/tests/internal-deps/adder", diff --git a/e2e/cases/oci/py_image_layer/pyproject.toml b/e2e/cases/oci/py_image_layer/pyproject.toml new file mode 100644 index 00000000..4242a5b5 --- /dev/null +++ b/e2e/cases/oci/py_image_layer/pyproject.toml @@ -0,0 +1,9 @@ +[project] +name = "images" +version = "0.0.0" +authors = [] +dependencies = [ + "colorama", + "setuptools", + "build", +] diff --git a/e2e/cases/oci/py_image_layer/uv.lock b/e2e/cases/oci/py_image_layer/uv.lock new file mode 100644 index 00000000..773084bb --- /dev/null +++ b/e2e/cases/oci/py_image_layer/uv.lock @@ -0,0 +1,70 @@ +version = 1 +revision = 3 +requires-python = ">=3.11" + +[[package]] +name = "build" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "os_name == 'nt'" }, + { name = "packaging" }, + { name = "pyproject-hooks" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/18/94eaffda7b329535d91f00fe605ab1f1e5cd68b2074d03f255c7d250687d/build-1.4.0.tar.gz", hash = "sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936", size = 50054, upload-time = "2026-01-08T16:41:47.696Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl", hash = "sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596", size = 24141, upload-time = "2026-01-08T16:41:46.453Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "images" +version = "0.0.0" +source = { virtual = "." } +dependencies = [ + { name = "build" }, + { name = "colorama" }, + { name = "setuptools" }, +] + +[package.metadata] +requires-dist = [ + { name = "build" }, + { name = "colorama" }, + { name = "setuptools" }, +] + +[[package]] +name = "packaging" +version = "26.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, +] + +[[package]] +name = "pyproject-hooks" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/82/28175b2414effca1cdac8dc99f76d660e7a4fb0ceefa4b4ab8f5f6742925/pyproject_hooks-1.2.0.tar.gz", hash = "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8", size = 19228, upload-time = "2024-09-29T09:24:13.293Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl", hash = "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913", size = 10216, upload-time = "2024-09-29T09:24:11.978Z" }, +] + +[[package]] +name = "setuptools" +version = "80.10.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/95/faf61eb8363f26aa7e1d762267a8d602a1b26d4f3a1e758e92cb3cb8b054/setuptools-80.10.2.tar.gz", hash = "sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70", size = 1200343, upload-time = "2026-01-25T22:38:17.252Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/b8/f1f62a5e3c0ad2ff1d189590bfa4c46b4f3b6e49cef6f26c6ee4e575394d/setuptools-80.10.2-py3-none-any.whl", hash = "sha256:95b30ddfb717250edb492926c92b5221f7ef3fbcc2b07579bcd4a27da21d0173", size = 1064234, upload-time = "2026-01-25T22:38:15.216Z" }, +] diff --git a/e2e/cases/oci/py_venv_image_layer/BUILD.bazel b/e2e/cases/oci/py_venv_image_layer/BUILD.bazel index 00376656..a616b3f2 100644 --- a/e2e/cases/oci/py_venv_image_layer/BUILD.bazel +++ b/e2e/cases/oci/py_venv_image_layer/BUILD.bazel @@ -40,6 +40,7 @@ py_venv_binary( srcs = ["__main__.py"], main = "__main__.py", tags = ["manual"], + venv = "venv_images", deps = [ "//cases/oci/py_image_layer/branding", "@aspect_rules_py//py/tests/internal-deps/adder", diff --git a/e2e/cases/oci/py_venv_image_layer/pyproject.toml b/e2e/cases/oci/py_venv_image_layer/pyproject.toml new file mode 100644 index 00000000..8737cac8 --- /dev/null +++ b/e2e/cases/oci/py_venv_image_layer/pyproject.toml @@ -0,0 +1,9 @@ +[project] +name = "venv_images" +version = "0.0.0" +authors = [] +dependencies = [ + "colorama", + "setuptools", + "build", +] diff --git a/e2e/cases/oci/py_venv_image_layer/uv.lock b/e2e/cases/oci/py_venv_image_layer/uv.lock new file mode 100644 index 00000000..e2e39b50 --- /dev/null +++ b/e2e/cases/oci/py_venv_image_layer/uv.lock @@ -0,0 +1,70 @@ +version = 1 +revision = 3 +requires-python = ">=3.11" + +[[package]] +name = "build" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "os_name == 'nt'" }, + { name = "packaging" }, + { name = "pyproject-hooks" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/18/94eaffda7b329535d91f00fe605ab1f1e5cd68b2074d03f255c7d250687d/build-1.4.0.tar.gz", hash = "sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936", size = 50054, upload-time = "2026-01-08T16:41:47.696Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl", hash = "sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596", size = 24141, upload-time = "2026-01-08T16:41:46.453Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "packaging" +version = "26.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, +] + +[[package]] +name = "pyproject-hooks" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/82/28175b2414effca1cdac8dc99f76d660e7a4fb0ceefa4b4ab8f5f6742925/pyproject_hooks-1.2.0.tar.gz", hash = "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8", size = 19228, upload-time = "2024-09-29T09:24:13.293Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl", hash = "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913", size = 10216, upload-time = "2024-09-29T09:24:11.978Z" }, +] + +[[package]] +name = "setuptools" +version = "80.10.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/95/faf61eb8363f26aa7e1d762267a8d602a1b26d4f3a1e758e92cb3cb8b054/setuptools-80.10.2.tar.gz", hash = "sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70", size = 1200343, upload-time = "2026-01-25T22:38:17.252Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/b8/f1f62a5e3c0ad2ff1d189590bfa4c46b4f3b6e49cef6f26c6ee4e575394d/setuptools-80.10.2-py3-none-any.whl", hash = "sha256:95b30ddfb717250edb492926c92b5221f7ef3fbcc2b07579bcd4a27da21d0173", size = 1064234, upload-time = "2026-01-25T22:38:15.216Z" }, +] + +[[package]] +name = "venv-images" +version = "0.0.0" +source = { virtual = "." } +dependencies = [ + { name = "build" }, + { name = "colorama" }, + { name = "setuptools" }, +] + +[package.metadata] +requires-dist = [ + { name = "build" }, + { name = "colorama" }, + { name = "setuptools" }, +] diff --git a/e2e/cases/uv-deps-650/airflow/pyproject.toml b/e2e/cases/uv-deps-650/airflow/pyproject.toml new file mode 100644 index 00000000..b695bb3b --- /dev/null +++ b/e2e/cases/uv-deps-650/airflow/pyproject.toml @@ -0,0 +1,10 @@ +[project] +name = "airflow" +version = "0.0.0" +authors = [] +dependencies = [ + "apache-airflow", + "apache-airflow-providers-sqlite", + "setuptools", + "build", +] diff --git a/e2e/cases/uv-deps-650/airflow/uv.lock b/e2e/cases/uv-deps-650/airflow/uv.lock index b609287e..ea6b40e1 100644 --- a/e2e/cases/uv-deps-650/airflow/uv.lock +++ b/e2e/cases/uv-deps-650/airflow/uv.lock @@ -1,6 +1,11 @@ version = 1 revision = 3 -requires-python = ">=3.12" +requires-python = ">=3.11" +resolution-markers = [ + "python_full_version >= '3.13'", + "python_full_version == '3.12.*'", + "python_full_version < '3.12'", +] [[package]] name = "a2wsgi" @@ -32,6 +37,25 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f5/10/6c25ed6de94c49f88a91fa5018cb4c0f3625f31d5be9f771ebe5cc7cd506/aiosqlite-0.21.0-py3-none-any.whl", hash = "sha256:2549cf4057f95f53dcba16f2b64e8e2791d7e1adedb13197dd8ed77bb226d7d0", size = 15792, upload-time = "2025-02-03T07:30:13.6Z" }, ] +[[package]] +name = "airflow" +version = "0.0.0" +source = { virtual = "." } +dependencies = [ + { name = "apache-airflow" }, + { name = "apache-airflow-providers-sqlite" }, + { name = "build" }, + { name = "setuptools" }, +] + +[package.metadata] +requires-dist = [ + { name = "apache-airflow" }, + { name = "apache-airflow-providers-sqlite" }, + { name = "build" }, + { name = "setuptools" }, +] + [[package]] name = "alembic" version = "1.16.5" @@ -62,6 +86,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "sniffio" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4", size = 219094, upload-time = "2025-09-23T09:19:12.58Z" } wheels = [ @@ -291,6 +316,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, ] +[[package]] +name = "build" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "os_name == 'nt'" }, + { name = "packaging" }, + { name = "pyproject-hooks" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/18/94eaffda7b329535d91f00fe605ab1f1e5cd68b2074d03f255c7d250687d/build-1.4.0.tar.gz", hash = "sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936", size = 50054, upload-time = "2026-01-08T16:41:47.696Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl", hash = "sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596", size = 24141, upload-time = "2026-01-08T16:41:46.453Z" }, +] + [[package]] name = "cadwyn" version = "5.4.4" @@ -326,6 +365,31 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload-time = "2025-09-08T23:22:26.456Z" }, + { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload-time = "2025-09-08T23:22:28.197Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload-time = "2025-09-08T23:22:29.475Z" }, + { url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476, upload-time = "2025-09-08T23:22:31.063Z" }, + { url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374, upload-time = "2025-09-08T23:22:32.507Z" }, + { url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597, upload-time = "2025-09-08T23:22:34.132Z" }, + { url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574, upload-time = "2025-09-08T23:22:35.443Z" }, + { url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971, upload-time = "2025-09-08T23:22:36.805Z" }, + { url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972, upload-time = "2025-09-08T23:22:38.436Z" }, + { url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078, upload-time = "2025-09-08T23:22:39.776Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload-time = "2025-09-08T23:22:40.95Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload-time = "2025-09-08T23:22:42.463Z" }, + { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload-time = "2025-09-08T23:22:43.623Z" }, + { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" }, + { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" }, + { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" }, + { url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" }, + { url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" }, + { url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" }, + { url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" }, + { url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" }, + { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" }, { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" }, { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" }, { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" }, @@ -368,6 +432,28 @@ version = "3.4.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload-time = "2025-08-09T07:57:28.46Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/b5/991245018615474a60965a7c9cd2b4efbaabd16d582a5547c47ee1c7730b/charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b", size = 204483, upload-time = "2025-08-09T07:55:53.12Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2a/ae245c41c06299ec18262825c1569c5d3298fc920e4ddf56ab011b417efd/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64", size = 145520, upload-time = "2025-08-09T07:55:54.712Z" }, + { url = "https://files.pythonhosted.org/packages/3a/a4/b3b6c76e7a635748c4421d2b92c7b8f90a432f98bda5082049af37ffc8e3/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91", size = 158876, upload-time = "2025-08-09T07:55:56.024Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e6/63bb0e10f90a8243c5def74b5b105b3bbbfb3e7bb753915fe333fb0c11ea/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f", size = 156083, upload-time = "2025-08-09T07:55:57.582Z" }, + { url = "https://files.pythonhosted.org/packages/87/df/b7737ff046c974b183ea9aa111b74185ac8c3a326c6262d413bd5a1b8c69/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07", size = 150295, upload-time = "2025-08-09T07:55:59.147Z" }, + { url = "https://files.pythonhosted.org/packages/61/f1/190d9977e0084d3f1dc169acd060d479bbbc71b90bf3e7bf7b9927dec3eb/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30", size = 148379, upload-time = "2025-08-09T07:56:00.364Z" }, + { url = "https://files.pythonhosted.org/packages/4c/92/27dbe365d34c68cfe0ca76f1edd70e8705d82b378cb54ebbaeabc2e3029d/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14", size = 160018, upload-time = "2025-08-09T07:56:01.678Z" }, + { url = "https://files.pythonhosted.org/packages/99/04/baae2a1ea1893a01635d475b9261c889a18fd48393634b6270827869fa34/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c", size = 157430, upload-time = "2025-08-09T07:56:02.87Z" }, + { url = "https://files.pythonhosted.org/packages/2f/36/77da9c6a328c54d17b960c89eccacfab8271fdaaa228305330915b88afa9/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae", size = 151600, upload-time = "2025-08-09T07:56:04.089Z" }, + { url = "https://files.pythonhosted.org/packages/64/d4/9eb4ff2c167edbbf08cdd28e19078bf195762e9bd63371689cab5ecd3d0d/charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849", size = 99616, upload-time = "2025-08-09T07:56:05.658Z" }, + { url = "https://files.pythonhosted.org/packages/f4/9c/996a4a028222e7761a96634d1820de8a744ff4327a00ada9c8942033089b/charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c", size = 107108, upload-time = "2025-08-09T07:56:07.176Z" }, + { url = "https://files.pythonhosted.org/packages/e9/5e/14c94999e418d9b87682734589404a25854d5f5d0408df68bc15b6ff54bb/charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", size = 205655, upload-time = "2025-08-09T07:56:08.475Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a8/c6ec5d389672521f644505a257f50544c074cf5fc292d5390331cd6fc9c3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", size = 146223, upload-time = "2025-08-09T07:56:09.708Z" }, + { url = "https://files.pythonhosted.org/packages/fc/eb/a2ffb08547f4e1e5415fb69eb7db25932c52a52bed371429648db4d84fb1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", size = 159366, upload-time = "2025-08-09T07:56:11.326Z" }, + { url = "https://files.pythonhosted.org/packages/82/10/0fd19f20c624b278dddaf83b8464dcddc2456cb4b02bb902a6da126b87a1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", size = 157104, upload-time = "2025-08-09T07:56:13.014Z" }, + { url = "https://files.pythonhosted.org/packages/16/ab/0233c3231af734f5dfcf0844aa9582d5a1466c985bbed6cedab85af9bfe3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", size = 151830, upload-time = "2025-08-09T07:56:14.428Z" }, + { url = "https://files.pythonhosted.org/packages/ae/02/e29e22b4e02839a0e4a06557b1999d0a47db3567e82989b5bb21f3fbbd9f/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", size = 148854, upload-time = "2025-08-09T07:56:16.051Z" }, + { url = "https://files.pythonhosted.org/packages/05/6b/e2539a0a4be302b481e8cafb5af8792da8093b486885a1ae4d15d452bcec/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", size = 160670, upload-time = "2025-08-09T07:56:17.314Z" }, + { url = "https://files.pythonhosted.org/packages/31/e7/883ee5676a2ef217a40ce0bffcc3d0dfbf9e64cbcfbdf822c52981c3304b/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", size = 158501, upload-time = "2025-08-09T07:56:18.641Z" }, + { url = "https://files.pythonhosted.org/packages/c1/35/6525b21aa0db614cf8b5792d232021dca3df7f90a1944db934efa5d20bb1/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", size = 153173, upload-time = "2025-08-09T07:56:20.289Z" }, + { url = "https://files.pythonhosted.org/packages/50/ee/f4704bad8201de513fdc8aac1cabc87e38c5818c93857140e06e772b5892/charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", size = 99822, upload-time = "2025-08-09T07:56:21.551Z" }, + { url = "https://files.pythonhosted.org/packages/39/f5/3b3836ca6064d0992c58c7561c6b6eee1b3892e9665d650c803bd5614522/charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", size = 107543, upload-time = "2025-08-09T07:56:23.115Z" }, { url = "https://files.pythonhosted.org/packages/65/ca/2135ac97709b400c7654b4b764daf5c5567c2da45a30cdd20f9eefe2d658/charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", size = 205326, upload-time = "2025-08-09T07:56:24.721Z" }, { url = "https://files.pythonhosted.org/packages/71/11/98a04c3c97dd34e49c7d247083af03645ca3730809a5509443f3c37f7c99/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", size = 146008, upload-time = "2025-08-09T07:56:26.004Z" }, { url = "https://files.pythonhosted.org/packages/60/f5/4659a4cb3c4ec146bec80c32d8bb16033752574c20b1252ee842a95d1a1e/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", size = 159196, upload-time = "2025-08-09T07:56:27.25Z" }, @@ -505,6 +591,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/68/46/753d457492d15458c7b5a653fc9a84a1c9c7a83af6ebdc94c3fc373ca6e8/cryptography-46.0.1-cp38-abi3-win32.whl", hash = "sha256:45f790934ac1018adeba46a0f7289b2b8fe76ba774a88c7f1922213a56c98bc1", size = 3043779, upload-time = "2025-09-17T00:10:08.951Z" }, { url = "https://files.pythonhosted.org/packages/2f/50/b6f3b540c2f6ee712feeb5fa780bb11fad76634e71334718568e7695cb55/cryptography-46.0.1-cp38-abi3-win_amd64.whl", hash = "sha256:7176a5ab56fac98d706921f6416a05e5aff7df0e4b91516f450f8627cda22af3", size = 3517226, upload-time = "2025-09-17T00:10:10.769Z" }, { url = "https://files.pythonhosted.org/packages/ff/e8/77d17d00981cdd27cc493e81e1749a0b8bbfb843780dbd841e30d7f50743/cryptography-46.0.1-cp38-abi3-win_arm64.whl", hash = "sha256:efc9e51c3e595267ff84adf56e9b357db89ab2279d7e375ffcaf8f678606f3d9", size = 2923149, upload-time = "2025-09-17T00:10:13.236Z" }, + { url = "https://files.pythonhosted.org/packages/27/27/077e09fd92075dd1338ea0ffaf5cfee641535545925768350ad90d8c36ca/cryptography-46.0.1-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b9c79af2c3058430d911ff1a5b2b96bbfe8da47d5ed961639ce4681886614e70", size = 3722319, upload-time = "2025-09-17T00:10:20.273Z" }, + { url = "https://files.pythonhosted.org/packages/db/32/6fc7250280920418651640d76cee34d91c1e0601d73acd44364570cf041f/cryptography-46.0.1-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:0ca4be2af48c24df689a150d9cd37404f689e2968e247b6b8ff09bff5bcd786f", size = 4249030, upload-time = "2025-09-17T00:10:22.396Z" }, + { url = "https://files.pythonhosted.org/packages/32/33/8d5398b2da15a15110b2478480ab512609f95b45ead3a105c9a9c76f9980/cryptography-46.0.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:13e67c4d3fb8b6bc4ef778a7ccdd8df4cd15b4bcc18f4239c8440891a11245cc", size = 4528009, upload-time = "2025-09-17T00:10:24.418Z" }, + { url = "https://files.pythonhosted.org/packages/fd/1c/4012edad2a8977ab386c36b6e21f5065974d37afa3eade83a9968cba4855/cryptography-46.0.1-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:15b5fd9358803b0d1cc42505a18d8bca81dabb35b5cfbfea1505092e13a9d96d", size = 4248902, upload-time = "2025-09-17T00:10:26.255Z" }, + { url = "https://files.pythonhosted.org/packages/58/a3/257cd5ae677302de8fa066fca9de37128f6729d1e63c04dd6a15555dd450/cryptography-46.0.1-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:e34da95e29daf8a71cb2841fd55df0511539a6cdf33e6f77c1e95e44006b9b46", size = 4527150, upload-time = "2025-09-17T00:10:28.28Z" }, + { url = "https://files.pythonhosted.org/packages/6a/cd/fe6b65e1117ec7631f6be8951d3db076bac3e1b096e3e12710ed071ffc3c/cryptography-46.0.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:34f04b7311174469ab3ac2647469743720f8b6c8b046f238e5cb27905695eb2a", size = 3448210, upload-time = "2025-09-17T00:10:30.145Z" }, ] [[package]] @@ -634,6 +726,28 @@ version = "3.2.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/03/b8/704d753a5a45507a7aab61f18db9509302ed3d0a27ac7e0359ec2905b1a6/greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d", size = 188260, upload-time = "2025-08-07T13:24:33.51Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/de/f28ced0a67749cac23fecb02b694f6473f47686dff6afaa211d186e2ef9c/greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2", size = 272305, upload-time = "2025-08-07T13:15:41.288Z" }, + { url = "https://files.pythonhosted.org/packages/09/16/2c3792cba130000bf2a31c5272999113f4764fd9d874fb257ff588ac779a/greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246", size = 632472, upload-time = "2025-08-07T13:42:55.044Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8f/95d48d7e3d433e6dae5b1682e4292242a53f22df82e6d3dda81b1701a960/greenlet-3.2.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:94abf90142c2a18151632371140b3dba4dee031633fe614cb592dbb6c9e17bc3", size = 644646, upload-time = "2025-08-07T13:45:26.523Z" }, + { url = "https://files.pythonhosted.org/packages/d5/5e/405965351aef8c76b8ef7ad370e5da58d57ef6068df197548b015464001a/greenlet-3.2.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:4d1378601b85e2e5171b99be8d2dc85f594c79967599328f95c1dc1a40f1c633", size = 640519, upload-time = "2025-08-07T13:53:13.928Z" }, + { url = "https://files.pythonhosted.org/packages/25/5d/382753b52006ce0218297ec1b628e048c4e64b155379331f25a7316eb749/greenlet-3.2.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0db5594dce18db94f7d1650d7489909b57afde4c580806b8d9203b6e79cdc079", size = 639707, upload-time = "2025-08-07T13:18:27.146Z" }, + { url = "https://files.pythonhosted.org/packages/1f/8e/abdd3f14d735b2929290a018ecf133c901be4874b858dd1c604b9319f064/greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8", size = 587684, upload-time = "2025-08-07T13:18:25.164Z" }, + { url = "https://files.pythonhosted.org/packages/5d/65/deb2a69c3e5996439b0176f6651e0052542bb6c8f8ec2e3fba97c9768805/greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52", size = 1116647, upload-time = "2025-08-07T13:42:38.655Z" }, + { url = "https://files.pythonhosted.org/packages/3f/cc/b07000438a29ac5cfb2194bfc128151d52f333cee74dd7dfe3fb733fc16c/greenlet-3.2.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:55e9c5affaa6775e2c6b67659f3a71684de4c549b3dd9afca3bc773533d284fa", size = 1142073, upload-time = "2025-08-07T13:18:21.737Z" }, + { url = "https://files.pythonhosted.org/packages/67/24/28a5b2fa42d12b3d7e5614145f0bd89714c34c08be6aabe39c14dd52db34/greenlet-3.2.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c9c6de1940a7d828635fbd254d69db79e54619f165ee7ce32fda763a9cb6a58c", size = 1548385, upload-time = "2025-11-04T12:42:11.067Z" }, + { url = "https://files.pythonhosted.org/packages/6a/05/03f2f0bdd0b0ff9a4f7b99333d57b53a7709c27723ec8123056b084e69cd/greenlet-3.2.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03c5136e7be905045160b1b9fdca93dd6727b180feeafda6818e6496434ed8c5", size = 1613329, upload-time = "2025-11-04T12:42:12.928Z" }, + { url = "https://files.pythonhosted.org/packages/d8/0f/30aef242fcab550b0b3520b8e3561156857c94288f0332a79928c31a52cf/greenlet-3.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:9c40adce87eaa9ddb593ccb0fa6a07caf34015a29bf8d344811665b573138db9", size = 299100, upload-time = "2025-08-07T13:44:12.287Z" }, + { url = "https://files.pythonhosted.org/packages/44/69/9b804adb5fd0671f367781560eb5eb586c4d495277c93bde4307b9e28068/greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd", size = 274079, upload-time = "2025-08-07T13:15:45.033Z" }, + { url = "https://files.pythonhosted.org/packages/46/e9/d2a80c99f19a153eff70bc451ab78615583b8dac0754cfb942223d2c1a0d/greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb", size = 640997, upload-time = "2025-08-07T13:42:56.234Z" }, + { url = "https://files.pythonhosted.org/packages/3b/16/035dcfcc48715ccd345f3a93183267167cdd162ad123cd93067d86f27ce4/greenlet-3.2.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f28588772bb5fb869a8eb331374ec06f24a83a9c25bfa1f38b6993afe9c1e968", size = 655185, upload-time = "2025-08-07T13:45:27.624Z" }, + { url = "https://files.pythonhosted.org/packages/31/da/0386695eef69ffae1ad726881571dfe28b41970173947e7c558d9998de0f/greenlet-3.2.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5c9320971821a7cb77cfab8d956fa8e39cd07ca44b6070db358ceb7f8797c8c9", size = 649926, upload-time = "2025-08-07T13:53:15.251Z" }, + { url = "https://files.pythonhosted.org/packages/68/88/69bf19fd4dc19981928ceacbc5fd4bb6bc2215d53199e367832e98d1d8fe/greenlet-3.2.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c60a6d84229b271d44b70fb6e5fa23781abb5d742af7b808ae3f6efd7c9c60f6", size = 651839, upload-time = "2025-08-07T13:18:30.281Z" }, + { url = "https://files.pythonhosted.org/packages/19/0d/6660d55f7373b2ff8152401a83e02084956da23ae58cddbfb0b330978fe9/greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0", size = 607586, upload-time = "2025-08-07T13:18:28.544Z" }, + { url = "https://files.pythonhosted.org/packages/8e/1a/c953fdedd22d81ee4629afbb38d2f9d71e37d23caace44775a3a969147d4/greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0", size = 1123281, upload-time = "2025-08-07T13:42:39.858Z" }, + { url = "https://files.pythonhosted.org/packages/3f/c7/12381b18e21aef2c6bd3a636da1088b888b97b7a0362fac2e4de92405f97/greenlet-3.2.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f", size = 1151142, upload-time = "2025-08-07T13:18:22.981Z" }, + { url = "https://files.pythonhosted.org/packages/27/45/80935968b53cfd3f33cf99ea5f08227f2646e044568c9b1555b58ffd61c2/greenlet-3.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee7a6ec486883397d70eec05059353b8e83eca9168b9f3f9a361971e77e0bcd0", size = 1564846, upload-time = "2025-11-04T12:42:15.191Z" }, + { url = "https://files.pythonhosted.org/packages/69/02/b7c30e5e04752cb4db6202a3858b149c0710e5453b71a3b2aec5d78a1aab/greenlet-3.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:326d234cbf337c9c3def0676412eb7040a35a768efc92504b947b3e9cfc7543d", size = 1633814, upload-time = "2025-11-04T12:42:17.175Z" }, + { url = "https://files.pythonhosted.org/packages/e9/08/b0814846b79399e585f974bbeebf5580fbe59e258ea7be64d9dfb253c84f/greenlet-3.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02", size = 299899, upload-time = "2025-08-07T13:38:53.448Z" }, { url = "https://files.pythonhosted.org/packages/49/e8/58c7f85958bda41dafea50497cbd59738c5c43dbbea5ee83d651234398f4/greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31", size = 272814, upload-time = "2025-08-07T13:15:50.011Z" }, { url = "https://files.pythonhosted.org/packages/62/dd/b9f59862e9e257a16e4e610480cfffd29e3fae018a68c2332090b53aac3d/greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945", size = 641073, upload-time = "2025-08-07T13:42:57.23Z" }, { url = "https://files.pythonhosted.org/packages/f7/0b/bc13f787394920b23073ca3b6c4a7a21396301ed75a655bcb47196b50e6e/greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc", size = 655191, upload-time = "2025-08-07T13:45:29.752Z" }, @@ -642,6 +756,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ee/43/3cecdc0349359e1a527cbf2e3e28e5f8f06d3343aaf82ca13437a9aa290f/greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671", size = 610497, upload-time = "2025-08-07T13:18:31.636Z" }, { url = "https://files.pythonhosted.org/packages/b8/19/06b6cf5d604e2c382a6f31cafafd6f33d5dea706f4db7bdab184bad2b21d/greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b", size = 1121662, upload-time = "2025-08-07T13:42:41.117Z" }, { url = "https://files.pythonhosted.org/packages/a2/15/0d5e4e1a66fab130d98168fe984c509249c833c1a3c16806b90f253ce7b9/greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae", size = 1149210, upload-time = "2025-08-07T13:18:24.072Z" }, + { url = "https://files.pythonhosted.org/packages/1c/53/f9c440463b3057485b8594d7a638bed53ba531165ef0ca0e6c364b5cc807/greenlet-3.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e343822feb58ac4d0a1211bd9399de2b3a04963ddeec21530fc426cc121f19b", size = 1564759, upload-time = "2025-11-04T12:42:19.395Z" }, + { url = "https://files.pythonhosted.org/packages/47/e4/3bb4240abdd0a8d23f4f88adec746a3099f0d86bfedb623f063b2e3b4df0/greenlet-3.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca7f6f1f2649b89ce02f6f229d7c19f680a6238af656f61e0115b24857917929", size = 1634288, upload-time = "2025-11-04T12:42:21.174Z" }, { url = "https://files.pythonhosted.org/packages/0b/55/2321e43595e6801e105fcfdee02b34c0f996eb71e6ddffca6b10b7e1d771/greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b", size = 299685, upload-time = "2025-08-07T13:24:38.824Z" }, { url = "https://files.pythonhosted.org/packages/22/5c/85273fd7cc388285632b0498dbbab97596e04b154933dfe0f3e68156c68c/greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0", size = 273586, upload-time = "2025-08-07T13:16:08.004Z" }, { url = "https://files.pythonhosted.org/packages/d1/75/10aeeaa3da9332c2e761e4c50d4c3556c21113ee3f0afa2cf5769946f7a3/greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f", size = 686346, upload-time = "2025-08-07T13:42:59.944Z" }, @@ -649,6 +765,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dc/8b/29aae55436521f1d6f8ff4e12fb676f3400de7fcf27fccd1d4d17fd8fecd/greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1", size = 694659, upload-time = "2025-08-07T13:53:17.759Z" }, { url = "https://files.pythonhosted.org/packages/92/2e/ea25914b1ebfde93b6fc4ff46d6864564fba59024e928bdc7de475affc25/greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735", size = 695355, upload-time = "2025-08-07T13:18:34.517Z" }, { url = "https://files.pythonhosted.org/packages/72/60/fc56c62046ec17f6b0d3060564562c64c862948c9d4bc8aa807cf5bd74f4/greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337", size = 657512, upload-time = "2025-08-07T13:18:33.969Z" }, + { url = "https://files.pythonhosted.org/packages/23/6e/74407aed965a4ab6ddd93a7ded3180b730d281c77b765788419484cdfeef/greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269", size = 1612508, upload-time = "2025-11-04T12:42:23.427Z" }, + { url = "https://files.pythonhosted.org/packages/0d/da/343cd760ab2f92bac1845ca07ee3faea9fe52bee65f7bcb19f16ad7de08b/greenlet-3.2.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:015d48959d4add5d6c9f6c5210ee3803a830dce46356e3bc326d6776bde54681", size = 1680760, upload-time = "2025-11-04T12:42:25.341Z" }, { url = "https://files.pythonhosted.org/packages/e3/a5/6ddab2b4c112be95601c13428db1d8b6608a8b6039816f2ba09c346c08fc/greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01", size = 303425, upload-time = "2025-08-07T13:32:27.59Z" }, ] @@ -661,6 +779,26 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/9d/f7/8963848164c7604efb3a3e6ee457fdb3a469653e19002bd24742473254f8/grpcio-1.75.1.tar.gz", hash = "sha256:3e81d89ece99b9ace23a6916880baca613c03a799925afb2857887efa8b1b3d2", size = 12731327, upload-time = "2025-09-26T09:03:36.887Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/3c/35ca9747473a306bfad0cee04504953f7098527cd112a4ab55c55af9e7bd/grpcio-1.75.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:573855ca2e58e35032aff30bfbd1ee103fbcf4472e4b28d4010757700918e326", size = 5709761, upload-time = "2025-09-26T09:01:28.528Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2c/ecbcb4241e4edbe85ac2663f885726fea0e947767401288b50d8fdcb9200/grpcio-1.75.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:6a4996a2c8accc37976dc142d5991adf60733e223e5c9a2219e157dc6a8fd3a2", size = 11496691, upload-time = "2025-09-26T09:01:31.214Z" }, + { url = "https://files.pythonhosted.org/packages/81/40/bc07aee2911f0d426fa53fe636216100c31a8ea65a400894f280274cb023/grpcio-1.75.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b1ea1bbe77ecbc1be00af2769f4ae4a88ce93be57a4f3eebd91087898ed749f9", size = 6296084, upload-time = "2025-09-26T09:01:34.596Z" }, + { url = "https://files.pythonhosted.org/packages/b8/d1/10c067f6c67396cbf46448b80f27583b5e8c4b46cdfbe18a2a02c2c2f290/grpcio-1.75.1-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:e5b425aee54cc5e3e3c58f00731e8a33f5567965d478d516d35ef99fd648ab68", size = 6950403, upload-time = "2025-09-26T09:01:36.736Z" }, + { url = "https://files.pythonhosted.org/packages/3f/42/5f628abe360b84dfe8dd8f32be6b0606dc31dc04d3358eef27db791ea4d5/grpcio-1.75.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0049a7bf547dafaeeb1db17079ce79596c298bfe308fc084d023c8907a845b9a", size = 6470166, upload-time = "2025-09-26T09:01:39.474Z" }, + { url = "https://files.pythonhosted.org/packages/c3/93/a24035080251324019882ee2265cfde642d6476c0cf8eb207fc693fcebdc/grpcio-1.75.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5b8ea230c7f77c0a1a3208a04a1eda164633fb0767b4cefd65a01079b65e5b1f", size = 7107828, upload-time = "2025-09-26T09:01:41.782Z" }, + { url = "https://files.pythonhosted.org/packages/e4/f8/d18b984c1c9ba0318e3628dbbeb6af77a5007f02abc378c845070f2d3edd/grpcio-1.75.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:36990d629c3c9fb41e546414e5af52d0a7af37ce7113d9682c46d7e2919e4cca", size = 8045421, upload-time = "2025-09-26T09:01:45.835Z" }, + { url = "https://files.pythonhosted.org/packages/7e/b6/4bf9aacff45deca5eac5562547ed212556b831064da77971a4e632917da3/grpcio-1.75.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b10ad908118d38c2453ade7ff790e5bce36580c3742919007a2a78e3a1e521ca", size = 7503290, upload-time = "2025-09-26T09:01:49.28Z" }, + { url = "https://files.pythonhosted.org/packages/3b/15/d8d69d10223cb54c887a2180bd29fe5fa2aec1d4995c8821f7aa6eaf72e4/grpcio-1.75.1-cp311-cp311-win32.whl", hash = "sha256:d6be2b5ee7bea656c954dcf6aa8093c6f0e6a3ef9945c99d99fcbfc88c5c0bfe", size = 3950631, upload-time = "2025-09-26T09:01:51.23Z" }, + { url = "https://files.pythonhosted.org/packages/8a/40/7b8642d45fff6f83300c24eaac0380a840e5e7fe0e8d80afd31b99d7134e/grpcio-1.75.1-cp311-cp311-win_amd64.whl", hash = "sha256:61c692fb05956b17dd6d1ab480f7f10ad0536dba3bc8fd4e3c7263dc244ed772", size = 4646131, upload-time = "2025-09-26T09:01:53.266Z" }, + { url = "https://files.pythonhosted.org/packages/3a/81/42be79e73a50aaa20af66731c2defeb0e8c9008d9935a64dd8ea8e8c44eb/grpcio-1.75.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:7b888b33cd14085d86176b1628ad2fcbff94cfbbe7809465097aa0132e58b018", size = 5668314, upload-time = "2025-09-26T09:01:55.424Z" }, + { url = "https://files.pythonhosted.org/packages/c5/a7/3686ed15822fedc58c22f82b3a7403d9faf38d7c33de46d4de6f06e49426/grpcio-1.75.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:8775036efe4ad2085975531d221535329f5dac99b6c2a854a995456098f99546", size = 11476125, upload-time = "2025-09-26T09:01:57.927Z" }, + { url = "https://files.pythonhosted.org/packages/14/85/21c71d674f03345ab183c634ecd889d3330177e27baea8d5d247a89b6442/grpcio-1.75.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb658f703468d7fbb5dcc4037c65391b7dc34f808ac46ed9136c24fc5eeb041d", size = 6246335, upload-time = "2025-09-26T09:02:00.76Z" }, + { url = "https://files.pythonhosted.org/packages/fd/db/3beb661bc56a385ae4fa6b0e70f6b91ac99d47afb726fe76aaff87ebb116/grpcio-1.75.1-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:4b7177a1cdb3c51b02b0c0a256b0a72fdab719600a693e0e9037949efffb200b", size = 6916309, upload-time = "2025-09-26T09:02:02.894Z" }, + { url = "https://files.pythonhosted.org/packages/1e/9c/eda9fe57f2b84343d44c1b66cf3831c973ba29b078b16a27d4587a1fdd47/grpcio-1.75.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7d4fa6ccc3ec2e68a04f7b883d354d7fea22a34c44ce535a2f0c0049cf626ddf", size = 6435419, upload-time = "2025-09-26T09:02:05.055Z" }, + { url = "https://files.pythonhosted.org/packages/c3/b8/090c98983e0a9d602e3f919a6e2d4e470a8b489452905f9a0fa472cac059/grpcio-1.75.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3d86880ecaeb5b2f0a8afa63824de93adb8ebe4e49d0e51442532f4e08add7d6", size = 7064893, upload-time = "2025-09-26T09:02:07.275Z" }, + { url = "https://files.pythonhosted.org/packages/ec/c0/6d53d4dbbd00f8bd81571f5478d8a95528b716e0eddb4217cc7cb45aae5f/grpcio-1.75.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a8041d2f9e8a742aeae96f4b047ee44e73619f4f9d24565e84d5446c623673b6", size = 8011922, upload-time = "2025-09-26T09:02:09.527Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7c/48455b2d0c5949678d6982c3e31ea4d89df4e16131b03f7d5c590811cbe9/grpcio-1.75.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3652516048bf4c314ce12be37423c79829f46efffb390ad64149a10c6071e8de", size = 7466181, upload-time = "2025-09-26T09:02:12.279Z" }, + { url = "https://files.pythonhosted.org/packages/fd/12/04a0e79081e3170b6124f8cba9b6275871276be06c156ef981033f691880/grpcio-1.75.1-cp312-cp312-win32.whl", hash = "sha256:44b62345d8403975513af88da2f3d5cc76f73ca538ba46596f92a127c2aea945", size = 3938543, upload-time = "2025-09-26T09:02:14.77Z" }, + { url = "https://files.pythonhosted.org/packages/5f/d7/11350d9d7fb5adc73d2b0ebf6ac1cc70135577701e607407fe6739a90021/grpcio-1.75.1-cp312-cp312-win_amd64.whl", hash = "sha256:b1e191c5c465fa777d4cafbaacf0c01e0d5278022082c0abbd2ee1d6454ed94d", size = 4641938, upload-time = "2025-09-26T09:02:16.927Z" }, { url = "https://files.pythonhosted.org/packages/46/74/bac4ab9f7722164afdf263ae31ba97b8174c667153510322a5eba4194c32/grpcio-1.75.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:3bed22e750d91d53d9e31e0af35a7b0b51367e974e14a4ff229db5b207647884", size = 5672779, upload-time = "2025-09-26T09:02:19.11Z" }, { url = "https://files.pythonhosted.org/packages/a6/52/d0483cfa667cddaa294e3ab88fd2c2a6e9dc1a1928c0e5911e2e54bd5b50/grpcio-1.75.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:5b8f381eadcd6ecaa143a21e9e80a26424c76a0a9b3d546febe6648f3a36a5ac", size = 11470623, upload-time = "2025-09-26T09:02:22.117Z" }, { url = "https://files.pythonhosted.org/packages/cf/e4/d1954dce2972e32384db6a30273275e8c8ea5a44b80347f9055589333b3f/grpcio-1.75.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5bf4001d3293e3414d0cf99ff9b1139106e57c3a66dfff0c5f60b2a6286ec133", size = 6248838, upload-time = "2025-09-26T09:02:26.426Z" }, @@ -711,6 +849,20 @@ version = "0.6.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a7/9a/ce5e1f7e131522e6d3426e8e7a490b3a01f39a6696602e1c4f33f9e94277/httptools-0.6.4.tar.gz", hash = "sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c", size = 240639, upload-time = "2024-10-16T19:45:08.902Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/26/bb526d4d14c2774fe07113ca1db7255737ffbb119315839af2065abfdac3/httptools-0.6.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f47f8ed67cc0ff862b84a1189831d1d33c963fb3ce1ee0c65d3b0cbe7b711069", size = 199029, upload-time = "2024-10-16T19:44:18.427Z" }, + { url = "https://files.pythonhosted.org/packages/a6/17/3e0d3e9b901c732987a45f4f94d4e2c62b89a041d93db89eafb262afd8d5/httptools-0.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0614154d5454c21b6410fdf5262b4a3ddb0f53f1e1721cfd59d55f32138c578a", size = 103492, upload-time = "2024-10-16T19:44:19.515Z" }, + { url = "https://files.pythonhosted.org/packages/b7/24/0fe235d7b69c42423c7698d086d4db96475f9b50b6ad26a718ef27a0bce6/httptools-0.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8787367fbdfccae38e35abf7641dafc5310310a5987b689f4c32cc8cc3ee975", size = 462891, upload-time = "2024-10-16T19:44:21.067Z" }, + { url = "https://files.pythonhosted.org/packages/b1/2f/205d1f2a190b72da6ffb5f41a3736c26d6fa7871101212b15e9b5cd8f61d/httptools-0.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40b0f7fe4fd38e6a507bdb751db0379df1e99120c65fbdc8ee6c1d044897a636", size = 459788, upload-time = "2024-10-16T19:44:22.958Z" }, + { url = "https://files.pythonhosted.org/packages/6e/4c/d09ce0eff09057a206a74575ae8f1e1e2f0364d20e2442224f9e6612c8b9/httptools-0.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40a5ec98d3f49904b9fe36827dcf1aadfef3b89e2bd05b0e35e94f97c2b14721", size = 433214, upload-time = "2024-10-16T19:44:24.513Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d2/84c9e23edbccc4a4c6f96a1b8d99dfd2350289e94f00e9ccc7aadde26fb5/httptools-0.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dacdd3d10ea1b4ca9df97a0a303cbacafc04b5cd375fa98732678151643d4988", size = 434120, upload-time = "2024-10-16T19:44:26.295Z" }, + { url = "https://files.pythonhosted.org/packages/d0/46/4d8e7ba9581416de1c425b8264e2cadd201eb709ec1584c381f3e98f51c1/httptools-0.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:288cd628406cc53f9a541cfaf06041b4c71d751856bab45e3702191f931ccd17", size = 88565, upload-time = "2024-10-16T19:44:29.188Z" }, + { url = "https://files.pythonhosted.org/packages/bb/0e/d0b71465c66b9185f90a091ab36389a7352985fe857e352801c39d6127c8/httptools-0.6.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:df017d6c780287d5c80601dafa31f17bddb170232d85c066604d8558683711a2", size = 200683, upload-time = "2024-10-16T19:44:30.175Z" }, + { url = "https://files.pythonhosted.org/packages/e2/b8/412a9bb28d0a8988de3296e01efa0bd62068b33856cdda47fe1b5e890954/httptools-0.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:85071a1e8c2d051b507161f6c3e26155b5c790e4e28d7f236422dbacc2a9cc44", size = 104337, upload-time = "2024-10-16T19:44:31.786Z" }, + { url = "https://files.pythonhosted.org/packages/9b/01/6fb20be3196ffdc8eeec4e653bc2a275eca7f36634c86302242c4fbb2760/httptools-0.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69422b7f458c5af875922cdb5bd586cc1f1033295aa9ff63ee196a87519ac8e1", size = 508796, upload-time = "2024-10-16T19:44:32.825Z" }, + { url = "https://files.pythonhosted.org/packages/f7/d8/b644c44acc1368938317d76ac991c9bba1166311880bcc0ac297cb9d6bd7/httptools-0.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16e603a3bff50db08cd578d54f07032ca1631450ceb972c2f834c2b860c28ea2", size = 510837, upload-time = "2024-10-16T19:44:33.974Z" }, + { url = "https://files.pythonhosted.org/packages/52/d8/254d16a31d543073a0e57f1c329ca7378d8924e7e292eda72d0064987486/httptools-0.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec4f178901fa1834d4a060320d2f3abc5c9e39766953d038f1458cb885f47e81", size = 485289, upload-time = "2024-10-16T19:44:35.111Z" }, + { url = "https://files.pythonhosted.org/packages/5f/3c/4aee161b4b7a971660b8be71a92c24d6c64372c1ab3ae7f366b3680df20f/httptools-0.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f9eb89ecf8b290f2e293325c646a211ff1c2493222798bb80a530c5e7502494f", size = 489779, upload-time = "2024-10-16T19:44:36.253Z" }, + { url = "https://files.pythonhosted.org/packages/12/b7/5cae71a8868e555f3f67a50ee7f673ce36eac970f029c0c5e9d584352961/httptools-0.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:db78cb9ca56b59b016e64b6031eda5653be0589dba2b1b43453f6e8b405a0970", size = 88634, upload-time = "2024-10-16T19:44:37.357Z" }, { url = "https://files.pythonhosted.org/packages/94/a3/9fe9ad23fd35f7de6b91eeb60848986058bd8b5a5c1e256f5860a160cc3e/httptools-0.6.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ade273d7e767d5fae13fa637f4d53b6e961fb7fd93c7797562663f0171c26660", size = 197214, upload-time = "2024-10-16T19:44:38.738Z" }, { url = "https://files.pythonhosted.org/packages/ea/d9/82d5e68bab783b632023f2fa31db20bebb4e89dfc4d2293945fd68484ee4/httptools-0.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:856f4bc0478ae143bad54a4242fccb1f3f86a6e1be5548fecfd4102061b3a083", size = 102431, upload-time = "2024-10-16T19:44:39.818Z" }, { url = "https://files.pythonhosted.org/packages/96/c1/cb499655cbdbfb57b577734fde02f6fa0bbc3fe9fb4d87b742b512908dff/httptools-0.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:322d20ea9cdd1fa98bd6a74b77e2ec5b818abdc3d36695ab402a0de8ef2865a3", size = 473121, upload-time = "2024-10-16T19:44:41.189Z" }, @@ -810,6 +962,18 @@ version = "1.12.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/08/a2/69df9c6ba6d316cfd81fe2381e464db3e6de5db45f8c43c6a23504abf8cb/lazy_object_proxy-1.12.0.tar.gz", hash = "sha256:1f5a462d92fd0cfb82f1fab28b51bfb209fabbe6aabf7f0d51472c0c124c0c61", size = 43681, upload-time = "2025-08-22T13:50:06.783Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/01/b3/4684b1e128a87821e485f5a901b179790e6b5bc02f89b7ee19c23be36ef3/lazy_object_proxy-1.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1cf69cd1a6c7fe2dbcc3edaa017cf010f4192e53796538cc7d5e1fedbfa4bcff", size = 26656, upload-time = "2025-08-22T13:42:30.605Z" }, + { url = "https://files.pythonhosted.org/packages/3a/03/1bdc21d9a6df9ff72d70b2ff17d8609321bea4b0d3cffd2cea92fb2ef738/lazy_object_proxy-1.12.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:efff4375a8c52f55a145dc8487a2108c2140f0bec4151ab4e1843e52eb9987ad", size = 68832, upload-time = "2025-08-22T13:42:31.675Z" }, + { url = "https://files.pythonhosted.org/packages/3d/4b/5788e5e8bd01d19af71e50077ab020bc5cce67e935066cd65e1215a09ff9/lazy_object_proxy-1.12.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1192e8c2f1031a6ff453ee40213afa01ba765b3dc861302cd91dbdb2e2660b00", size = 69148, upload-time = "2025-08-22T13:42:32.876Z" }, + { url = "https://files.pythonhosted.org/packages/79/0e/090bf070f7a0de44c61659cb7f74c2fe02309a77ca8c4b43adfe0b695f66/lazy_object_proxy-1.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3605b632e82a1cbc32a1e5034278a64db555b3496e0795723ee697006b980508", size = 67800, upload-time = "2025-08-22T13:42:34.054Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d2/b320325adbb2d119156f7c506a5fbfa37fcab15c26d13cf789a90a6de04e/lazy_object_proxy-1.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a61095f5d9d1a743e1e20ec6d6db6c2ca511961777257ebd9b288951b23b44fa", size = 68085, upload-time = "2025-08-22T13:42:35.197Z" }, + { url = "https://files.pythonhosted.org/packages/6a/48/4b718c937004bf71cd82af3713874656bcb8d0cc78600bf33bb9619adc6c/lazy_object_proxy-1.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:997b1d6e10ecc6fb6fe0f2c959791ae59599f41da61d652f6c903d1ee58b7370", size = 26535, upload-time = "2025-08-22T13:42:36.521Z" }, + { url = "https://files.pythonhosted.org/packages/0d/1b/b5f5bd6bda26f1e15cd3232b223892e4498e34ec70a7f4f11c401ac969f1/lazy_object_proxy-1.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8ee0d6027b760a11cc18281e702c0309dd92da458a74b4c15025d7fc490deede", size = 26746, upload-time = "2025-08-22T13:42:37.572Z" }, + { url = "https://files.pythonhosted.org/packages/55/64/314889b618075c2bfc19293ffa9153ce880ac6153aacfd0a52fcabf21a66/lazy_object_proxy-1.12.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4ab2c584e3cc8be0dfca422e05ad30a9abe3555ce63e9ab7a559f62f8dbc6ff9", size = 71457, upload-time = "2025-08-22T13:42:38.743Z" }, + { url = "https://files.pythonhosted.org/packages/11/53/857fc2827fc1e13fbdfc0ba2629a7d2579645a06192d5461809540b78913/lazy_object_proxy-1.12.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:14e348185adbd03ec17d051e169ec45686dcd840a3779c9d4c10aabe2ca6e1c0", size = 71036, upload-time = "2025-08-22T13:42:40.184Z" }, + { url = "https://files.pythonhosted.org/packages/2b/24/e581ffed864cd33c1b445b5763d617448ebb880f48675fc9de0471a95cbc/lazy_object_proxy-1.12.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c4fcbe74fb85df8ba7825fa05eddca764138da752904b378f0ae5ab33a36c308", size = 69329, upload-time = "2025-08-22T13:42:41.311Z" }, + { url = "https://files.pythonhosted.org/packages/78/be/15f8f5a0b0b2e668e756a152257d26370132c97f2f1943329b08f057eff0/lazy_object_proxy-1.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:563d2ec8e4d4b68ee7848c5ab4d6057a6d703cb7963b342968bb8758dda33a23", size = 70690, upload-time = "2025-08-22T13:42:42.51Z" }, + { url = "https://files.pythonhosted.org/packages/5d/aa/f02be9bbfb270e13ee608c2b28b8771f20a5f64356c6d9317b20043c6129/lazy_object_proxy-1.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:53c7fd99eb156bbb82cbc5d5188891d8fdd805ba6c1e3b92b90092da2a837073", size = 26563, upload-time = "2025-08-22T13:42:43.685Z" }, { url = "https://files.pythonhosted.org/packages/f4/26/b74c791008841f8ad896c7f293415136c66cc27e7c7577de4ee68040c110/lazy_object_proxy-1.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:86fd61cb2ba249b9f436d789d1356deae69ad3231dc3c0f17293ac535162672e", size = 26745, upload-time = "2025-08-22T13:42:44.982Z" }, { url = "https://files.pythonhosted.org/packages/9b/52/641870d309e5d1fb1ea7d462a818ca727e43bfa431d8c34b173eb090348c/lazy_object_proxy-1.12.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:81d1852fb30fab81696f93db1b1e55a5d1ff7940838191062f5f56987d5fcc3e", size = 71537, upload-time = "2025-08-22T13:42:46.141Z" }, { url = "https://files.pythonhosted.org/packages/47/b6/919118e99d51c5e76e8bf5a27df406884921c0acf2c7b8a3b38d847ab3e9/lazy_object_proxy-1.12.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be9045646d83f6c2664c1330904b245ae2371b5c57a3195e4028aedc9f999655", size = 71141, upload-time = "2025-08-22T13:42:47.375Z" }, @@ -828,6 +992,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/ac/34cbfb433a10e28c7fd830f91c5a348462ba748413cbb950c7f259e67aa7/lazy_object_proxy-1.12.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0a83c6f7a6b2bfc11ef3ed67f8cbe99f8ff500b05655d8e7df9aab993a6abc95", size = 69529, upload-time = "2025-08-22T13:49:55.29Z" }, { url = "https://files.pythonhosted.org/packages/6f/6a/11ad7e349307c3ca4c0175db7a77d60ce42a41c60bcb11800aabd6a8acb8/lazy_object_proxy-1.12.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:256262384ebd2a77b023ad02fbcc9326282bcfd16484d5531154b02bc304f4c5", size = 70391, upload-time = "2025-08-22T13:49:56.35Z" }, { url = "https://files.pythonhosted.org/packages/59/97/9b410ed8fbc6e79c1ee8b13f8777a80137d4bc189caf2c6202358e66192c/lazy_object_proxy-1.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:7601ec171c7e8584f8ff3f4e440aa2eebf93e854f04639263875b8c2971f819f", size = 26988, upload-time = "2025-08-22T13:49:57.302Z" }, + { url = "https://files.pythonhosted.org/packages/41/a0/b91504515c1f9a299fc157967ffbd2f0321bce0516a3d5b89f6f4cad0355/lazy_object_proxy-1.12.0-pp39.pp310.pp311.graalpy311-none-any.whl", hash = "sha256:c3b2e0af1f7f77c4263759c4824316ce458fabe0fceadcd24ef8ca08b2d1e402", size = 15072, upload-time = "2025-08-22T13:50:05.498Z" }, ] [[package]] @@ -835,10 +1000,27 @@ name = "libcst" version = "1.8.5" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyyaml-ft" }, + { name = "pyyaml", marker = "python_full_version < '3.13'" }, + { name = "pyyaml-ft", marker = "python_full_version >= '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/5c/55/ca4552d7fe79a91b2a7b4fa39991e8a45a17c8bfbcaf264597d95903c777/libcst-1.8.5.tar.gz", hash = "sha256:e72e1816eed63f530668e93a4c22ff1cf8b91ddce0ec53e597d3f6c53e103ec7", size = 884582, upload-time = "2025-09-26T05:29:44.101Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/a0/4efb5b33c184f72554409516c73c8900909f87de528538d194b2cb5898ac/libcst-1.8.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:dd5a292ce2b6410bc100aeac2b18ba3554fd8a8f6aa0ee6a9238bb4031c521ca", size = 2206056, upload-time = "2025-09-26T05:28:02.503Z" }, + { url = "https://files.pythonhosted.org/packages/26/b0/8b1dca00aebfc89f8e538212e5582548cedfc0b8f3aa4e73a815fe87bdfd/libcst-1.8.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f43915cd523a6967ba1dfe137627ed3804892005330c3bf53674a2ab4ff3dad", size = 2090132, upload-time = "2025-09-26T05:28:04.511Z" }, + { url = "https://files.pythonhosted.org/packages/8a/1f/78ad030ca973f2c58fa58c3f30d94c2239473d3aba6c9dd1bdedd5047ddd/libcst-1.8.5-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9a756bd314b87b87dec9f0f900672c37719645b1c8bb2b53fe37b5b5fe7ee2c2", size = 2231559, upload-time = "2025-09-26T05:28:06.492Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/2ee78c01070c919de3d6736a06d1d9ecaedcbe1f367f4eee3c34ae5f801e/libcst-1.8.5-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:26e9d5e756447873eeda78441fa7d1fe640c0b526e5be2b6b7ee0c8f03c4665f", size = 2293973, upload-time = "2025-09-26T05:28:08.456Z" }, + { url = "https://files.pythonhosted.org/packages/50/cf/ef4cb1c1b16f4bd32b0d7a5f01b18168fd833010a916bc062958dd6bcd8a/libcst-1.8.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b5b33ec61f62ff6122dc9c5bf1401bc8a9f9a2f0663ca15661d21d14d9dc4de0", size = 2297099, upload-time = "2025-09-26T05:28:10.4Z" }, + { url = "https://files.pythonhosted.org/packages/75/3e/ccd2e449f09c745ded6925804a6fe66f4c96ef82a0330de646becb8c6140/libcst-1.8.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a80e14836ecbdf5374c2c82cd5cd290abaa7290ecfafe9259d0615a1ebccb30c", size = 2398032, upload-time = "2025-09-26T05:28:12.124Z" }, + { url = "https://files.pythonhosted.org/packages/1f/16/277d0666e77d53d0061cb73327053b114f516ab7b36c9d4c71963fb5e806/libcst-1.8.5-cp311-cp311-win_amd64.whl", hash = "sha256:588acde1588544b3bfe06069c118ee731e6712f323f26a026733f0ec4512596e", size = 2106472, upload-time = "2025-09-26T05:28:13.945Z" }, + { url = "https://files.pythonhosted.org/packages/bd/25/b1594abbec644a10b61ee1c1bab935ccc992a17b3880aa50234b9b4e9b06/libcst-1.8.5-cp311-cp311-win_arm64.whl", hash = "sha256:a8146f945f1eb46406fab676f86de3b7f88aca9e5d421f6366f7a63c8a950254", size = 1991976, upload-time = "2025-09-26T05:28:15.939Z" }, + { url = "https://files.pythonhosted.org/packages/13/bb/c7abe0654fcf00292d6959256948ce4ae07785c4f65a45c3e25cc4637074/libcst-1.8.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c7733aba7b43239157661207b1e3a9f3711a7fc061a0eca6a33f0716fdfd21", size = 2196690, upload-time = "2025-09-26T05:28:17.839Z" }, + { url = "https://files.pythonhosted.org/packages/49/25/e7c02209e8ce66e7b75a66d132118f6f812a8b03cd31ee7d96de56c733a1/libcst-1.8.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b8c3cfbbf6049e3c587713652e4b3c88cfbf7df7878b2eeefaa8dd20a48dc607", size = 2082616, upload-time = "2025-09-26T05:28:19.794Z" }, + { url = "https://files.pythonhosted.org/packages/32/68/a4f49d99e3130256e225d639722440ba2682c12812a30ebd7ba64fd0fd31/libcst-1.8.5-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:31d86025d8997c853f85c4b5d494f04a157fb962e24f187b4af70c7755c9b27d", size = 2229037, upload-time = "2025-09-26T05:28:21.459Z" }, + { url = "https://files.pythonhosted.org/packages/b2/62/4fa21600a0bf3eb9f4d4f8bbb50ef120fb0b2990195eabba997b0b889566/libcst-1.8.5-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff9c535cfe99f0be79ac3024772b288570751fc69fc472b44fca12d1912d1561", size = 2292806, upload-time = "2025-09-26T05:28:23.033Z" }, + { url = "https://files.pythonhosted.org/packages/14/df/a01e8d54b62060698e37e3e28f77559ecb70c7b93ffee00d17e40221f419/libcst-1.8.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e8204607504563d3606bbaea2b9b04e0cef2b3bdc14c89171a702c1e09b9318a", size = 2294836, upload-time = "2025-09-26T05:28:24.937Z" }, + { url = "https://files.pythonhosted.org/packages/75/4f/c410e7f7ceda0558f688c1ca5dfb3a40ff8dfc527f8e6015fa749e11a650/libcst-1.8.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5e6cd3df72d47701b205fa3349ba8899566df82cef248c2fdf5f575d640419c4", size = 2396004, upload-time = "2025-09-26T05:28:26.582Z" }, + { url = "https://files.pythonhosted.org/packages/f0/07/bb77dcb94badad0ad3e5a1e992a4318dbdf40632eac3b5cf18299858ad7d/libcst-1.8.5-cp312-cp312-win_amd64.whl", hash = "sha256:197c2f86dd0ca5c6464184ddef7f6440d64c8da39b78d16fc053da6701ed1209", size = 2107301, upload-time = "2025-09-26T05:28:28.235Z" }, + { url = "https://files.pythonhosted.org/packages/79/70/e688e6d99d6920c3f97bf8bbaec33ac2c71a947730772a1d32dd899dbbf1/libcst-1.8.5-cp312-cp312-win_arm64.whl", hash = "sha256:c5ca109c9a81dff3d947dceba635a08f9c3dfeb7f61b0b824a175ef0a98ea69b", size = 1990870, upload-time = "2025-09-26T05:28:29.858Z" }, { url = "https://files.pythonhosted.org/packages/b0/77/ca1d2499881c774121ebb7c78c22f371c179f18317961e1e529dafc1af52/libcst-1.8.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9e9563dcd754b65557ba9cdff9a5af32cfa5f007be0db982429580db45bfe", size = 2196687, upload-time = "2025-09-26T05:28:31.769Z" }, { url = "https://files.pythonhosted.org/packages/ef/1c/fdb7c226ad82fcf3b1bb19c24d8e895588a0c1fd2bc81e30792d041e15bc/libcst-1.8.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:61d56839d237e9bf3310e6479ffaf6659f298940f0e0d2460ce71ee67a5375df", size = 2082639, upload-time = "2025-09-26T05:28:33.358Z" }, { url = "https://files.pythonhosted.org/packages/af/1a/c6e89455483355971d13f6d71ad717624686b50558f7e2c12393c2c8e2f1/libcst-1.8.5-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:b084769dcda2036265fc426eec5894c658af8d4b0e0d0255ab6bb78c8c9d6eb4", size = 2229202, upload-time = "2025-09-26T05:28:35.276Z" }, @@ -894,21 +1076,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c8/22/9460e311f340cb62d26a38c419b1381b8593b0bb6b5d1f056938b086d362/lockfile-0.12.2-py2.py3-none-any.whl", hash = "sha256:6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa", size = 13564, upload-time = "2015-11-25T18:29:51.462Z" }, ] -[[package]] -name = "lockfiles-b" -version = "0.1.0" -source = { virtual = "." } -dependencies = [ - { name = "apache-airflow" }, - { name = "apache-airflow-providers-sqlite" }, -] - -[package.metadata] -requires-dist = [ - { name = "apache-airflow", specifier = ">=2.10.0" }, - { name = "apache-airflow-providers-sqlite" }, -] - [[package]] name = "mako" version = "1.3.10" @@ -939,6 +1106,28 @@ version = "3.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, + { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, + { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, + { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, + { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, + { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, + { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, + { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, @@ -1021,6 +1210,20 @@ version = "0.19.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/cf/9b/95d8ce458462b8b71b8a70fa94563b2498b89933689f3a7b8911edfae3d7/msgspec-0.19.0.tar.gz", hash = "sha256:604037e7cd475345848116e89c553aa9a233259733ab51986ac924ab1b976f8e", size = 216934, upload-time = "2024-12-27T17:40:28.597Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/24/d4/2ec2567ac30dab072cce3e91fb17803c52f0a37aab6b0c24375d2b20a581/msgspec-0.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aa77046904db764b0462036bc63ef71f02b75b8f72e9c9dd4c447d6da1ed8f8e", size = 187939, upload-time = "2024-12-27T17:39:32.347Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c0/18226e4328897f4f19875cb62bb9259fe47e901eade9d9376ab5f251a929/msgspec-0.19.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:047cfa8675eb3bad68722cfe95c60e7afabf84d1bd8938979dd2b92e9e4a9551", size = 182202, upload-time = "2024-12-27T17:39:33.633Z" }, + { url = "https://files.pythonhosted.org/packages/81/25/3a4b24d468203d8af90d1d351b77ea3cffb96b29492855cf83078f16bfe4/msgspec-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e78f46ff39a427e10b4a61614a2777ad69559cc8d603a7c05681f5a595ea98f7", size = 209029, upload-time = "2024-12-27T17:39:35.023Z" }, + { url = "https://files.pythonhosted.org/packages/85/2e/db7e189b57901955239f7689b5dcd6ae9458637a9c66747326726c650523/msgspec-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c7adf191e4bd3be0e9231c3b6dc20cf1199ada2af523885efc2ed218eafd011", size = 210682, upload-time = "2024-12-27T17:39:36.384Z" }, + { url = "https://files.pythonhosted.org/packages/03/97/7c8895c9074a97052d7e4a1cc1230b7b6e2ca2486714eb12c3f08bb9d284/msgspec-0.19.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f04cad4385e20be7c7176bb8ae3dca54a08e9756cfc97bcdb4f18560c3042063", size = 214003, upload-time = "2024-12-27T17:39:39.097Z" }, + { url = "https://files.pythonhosted.org/packages/61/61/e892997bcaa289559b4d5869f066a8021b79f4bf8e955f831b095f47a4cd/msgspec-0.19.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:45c8fb410670b3b7eb884d44a75589377c341ec1392b778311acdbfa55187716", size = 216833, upload-time = "2024-12-27T17:39:41.203Z" }, + { url = "https://files.pythonhosted.org/packages/ce/3d/71b2dffd3a1c743ffe13296ff701ee503feaebc3f04d0e75613b6563c374/msgspec-0.19.0-cp311-cp311-win_amd64.whl", hash = "sha256:70eaef4934b87193a27d802534dc466778ad8d536e296ae2f9334e182ac27b6c", size = 186184, upload-time = "2024-12-27T17:39:43.702Z" }, + { url = "https://files.pythonhosted.org/packages/b2/5f/a70c24f075e3e7af2fae5414c7048b0e11389685b7f717bb55ba282a34a7/msgspec-0.19.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f98bd8962ad549c27d63845b50af3f53ec468b6318400c9f1adfe8b092d7b62f", size = 190485, upload-time = "2024-12-27T17:39:44.974Z" }, + { url = "https://files.pythonhosted.org/packages/89/b0/1b9763938cfae12acf14b682fcf05c92855974d921a5a985ecc197d1c672/msgspec-0.19.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:43bbb237feab761b815ed9df43b266114203f53596f9b6e6f00ebd79d178cdf2", size = 183910, upload-time = "2024-12-27T17:39:46.401Z" }, + { url = "https://files.pythonhosted.org/packages/87/81/0c8c93f0b92c97e326b279795f9c5b956c5a97af28ca0fbb9fd86c83737a/msgspec-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cfc033c02c3e0aec52b71710d7f84cb3ca5eb407ab2ad23d75631153fdb1f12", size = 210633, upload-time = "2024-12-27T17:39:49.099Z" }, + { url = "https://files.pythonhosted.org/packages/d0/ef/c5422ce8af73928d194a6606f8ae36e93a52fd5e8df5abd366903a5ca8da/msgspec-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d911c442571605e17658ca2b416fd8579c5050ac9adc5e00c2cb3126c97f73bc", size = 213594, upload-time = "2024-12-27T17:39:51.204Z" }, + { url = "https://files.pythonhosted.org/packages/19/2b/4137bc2ed45660444842d042be2cf5b18aa06efd2cda107cff18253b9653/msgspec-0.19.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:757b501fa57e24896cf40a831442b19a864f56d253679f34f260dcb002524a6c", size = 214053, upload-time = "2024-12-27T17:39:52.866Z" }, + { url = "https://files.pythonhosted.org/packages/9d/e6/8ad51bdc806aac1dc501e8fe43f759f9ed7284043d722b53323ea421c360/msgspec-0.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5f0f65f29b45e2816d8bded36e6b837a4bf5fb60ec4bc3c625fa2c6da4124537", size = 219081, upload-time = "2024-12-27T17:39:55.142Z" }, + { url = "https://files.pythonhosted.org/packages/b1/ef/27dd35a7049c9a4f4211c6cd6a8c9db0a50647546f003a5867827ec45391/msgspec-0.19.0-cp312-cp312-win_amd64.whl", hash = "sha256:067f0de1c33cfa0b6a8206562efdf6be5985b988b53dd244a8e06f993f27c8c0", size = 187467, upload-time = "2024-12-27T17:39:56.531Z" }, { url = "https://files.pythonhosted.org/packages/3c/cb/2842c312bbe618d8fefc8b9cedce37f773cdc8fa453306546dba2c21fd98/msgspec-0.19.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f12d30dd6266557aaaf0aa0f9580a9a8fbeadfa83699c487713e355ec5f0bd86", size = 190498, upload-time = "2024-12-27T17:40:00.427Z" }, { url = "https://files.pythonhosted.org/packages/58/95/c40b01b93465e1a5f3b6c7d91b10fb574818163740cc3acbe722d1e0e7e4/msgspec-0.19.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82b2c42c1b9ebc89e822e7e13bbe9d17ede0c23c187469fdd9505afd5a481314", size = 183950, upload-time = "2024-12-27T17:40:04.219Z" }, { url = "https://files.pythonhosted.org/packages/e8/f0/5b764e066ce9aba4b70d1db8b087ea66098c7c27d59b9dd8a3532774d48f/msgspec-0.19.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19746b50be214a54239aab822964f2ac81e38b0055cca94808359d779338c10e", size = 210647, upload-time = "2024-12-27T17:40:05.606Z" }, @@ -1192,6 +1395,26 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/23/7c/009c12b86c7cc6c403aec80f8a4308598dfc5995e5c523a5491faaa3952e/pendulum-3.1.0.tar.gz", hash = "sha256:66f96303560f41d097bee7d2dc98ffca716fbb3a832c4b3062034c2d45865015", size = 85930, upload-time = "2025-04-19T14:30:01.675Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/5e/6e/d28d3c22e6708b819a94c05bd05a3dfaed5c685379e8b6dc4b34b473b942/pendulum-3.1.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:61a03d14f8c64d13b2f7d5859e4b4053c4a7d3b02339f6c71f3e4606bfd67423", size = 338596, upload-time = "2025-04-19T14:01:11.306Z" }, + { url = "https://files.pythonhosted.org/packages/e1/e6/43324d58021d463c2eeb6146b169d2c935f2f840f9e45ac2d500453d954c/pendulum-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e674ed2d158afa5c361e60f1f67872dc55b492a10cacdaa7fcd7b7da5f158f24", size = 325854, upload-time = "2025-04-19T14:01:13.156Z" }, + { url = "https://files.pythonhosted.org/packages/b0/a7/d2ae79b960bfdea94dab67e2f118697b08bc9e98eb6bd8d32c4d99240da3/pendulum-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c75377eb16e58bbe7e03ea89eeea49be6fc5de0934a4aef0e263f8b4fa71bc2", size = 344334, upload-time = "2025-04-19T14:01:15.151Z" }, + { url = "https://files.pythonhosted.org/packages/96/94/941f071212e23c29aae7def891fb636930c648386e059ce09ea0dcd43933/pendulum-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:656b8b0ce070f0f2e5e2668247d3c783c55336534aa1f13bd0969535878955e1", size = 382259, upload-time = "2025-04-19T14:01:16.924Z" }, + { url = "https://files.pythonhosted.org/packages/51/ad/a78a701656aec00d16fee636704445c23ca11617a0bfe7c3848d1caa5157/pendulum-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48962903e6c1afe1f13548cb6252666056086c107d59e3d64795c58c9298bc2e", size = 436361, upload-time = "2025-04-19T14:01:18.796Z" }, + { url = "https://files.pythonhosted.org/packages/da/93/83f59ccbf4435c29dca8c63a6560fcbe4783079a468a5f91d9f886fd21f0/pendulum-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d364ec3f8e65010fefd4b0aaf7be5eb97e5df761b107a06f5e743b7c3f52c311", size = 353653, upload-time = "2025-04-19T14:01:20.159Z" }, + { url = "https://files.pythonhosted.org/packages/6f/0f/42d6644ec6339b41066f594e52d286162aecd2e9735aaf994d7e00c9e09d/pendulum-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dd52caffc2afb86612ec43bbeb226f204ea12ebff9f3d12f900a7d3097210fcc", size = 524567, upload-time = "2025-04-19T14:01:21.457Z" }, + { url = "https://files.pythonhosted.org/packages/de/45/d84d909202755ab9d3379e5481fdf70f53344ebefbd68d6f5803ddde98a6/pendulum-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d439fccaa35c91f686bd59d30604dab01e8b5c1d0dd66e81648c432fd3f8a539", size = 525571, upload-time = "2025-04-19T14:01:23.329Z" }, + { url = "https://files.pythonhosted.org/packages/0d/e0/4de160773ce3c2f7843c310db19dd919a0cd02cc1c0384866f63b18a6251/pendulum-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:43288773a86d9c5c0ddb645f88f615ff6bd12fd1410b34323662beccb18f3b49", size = 260259, upload-time = "2025-04-19T14:01:24.689Z" }, + { url = "https://files.pythonhosted.org/packages/c1/7f/ffa278f78112c6c6e5130a702042f52aab5c649ae2edf814df07810bbba5/pendulum-3.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:569ea5072ae0f11d625e03b36d865f8037b76e838a3b621f6967314193896a11", size = 253899, upload-time = "2025-04-19T14:01:26.442Z" }, + { url = "https://files.pythonhosted.org/packages/7a/d7/b1bfe15a742f2c2713acb1fdc7dc3594ff46ef9418ac6a96fcb12a6ba60b/pendulum-3.1.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:4dfd53e7583ccae138be86d6c0a0b324c7547df2afcec1876943c4d481cf9608", size = 336209, upload-time = "2025-04-19T14:01:27.815Z" }, + { url = "https://files.pythonhosted.org/packages/eb/87/0392da0c603c828b926d9f7097fbdddaafc01388cb8a00888635d04758c3/pendulum-3.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6a6e06a28f3a7d696546347805536f6f38be458cb79de4f80754430696bea9e6", size = 323130, upload-time = "2025-04-19T14:01:29.336Z" }, + { url = "https://files.pythonhosted.org/packages/c0/61/95f1eec25796be6dddf71440ee16ec1fd0c573fc61a73bd1ef6daacd529a/pendulum-3.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e68d6a51880708084afd8958af42dc8c5e819a70a6c6ae903b1c4bfc61e0f25", size = 341509, upload-time = "2025-04-19T14:01:31.1Z" }, + { url = "https://files.pythonhosted.org/packages/b5/7b/eb0f5e6aa87d5e1b467a1611009dbdc92f0f72425ebf07669bfadd8885a6/pendulum-3.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e3f1e5da39a7ea7119efda1dd96b529748c1566f8a983412d0908455d606942", size = 378674, upload-time = "2025-04-19T14:01:32.974Z" }, + { url = "https://files.pythonhosted.org/packages/29/68/5a4c1b5de3e54e16cab21d2ec88f9cd3f18599e96cc90a441c0b0ab6b03f/pendulum-3.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9af1e5eeddb4ebbe1b1c9afb9fd8077d73416ade42dd61264b3f3b87742e0bb", size = 436133, upload-time = "2025-04-19T14:01:34.349Z" }, + { url = "https://files.pythonhosted.org/packages/87/5d/f7a1d693e5c0f789185117d5c1d5bee104f5b0d9fbf061d715fb61c840a8/pendulum-3.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20f74aa8029a42e327bfc150472e0e4d2358fa5d795f70460160ba81b94b6945", size = 351232, upload-time = "2025-04-19T14:01:35.669Z" }, + { url = "https://files.pythonhosted.org/packages/30/77/c97617eb31f1d0554edb073201a294019b9e0a9bd2f73c68e6d8d048cd6b/pendulum-3.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:cf6229e5ee70c2660148523f46c472e677654d0097bec010d6730f08312a4931", size = 521562, upload-time = "2025-04-19T14:01:37.05Z" }, + { url = "https://files.pythonhosted.org/packages/76/22/0d0ef3393303877e757b848ecef8a9a8c7627e17e7590af82d14633b2cd1/pendulum-3.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:350cabb23bf1aec7c7694b915d3030bff53a2ad4aeabc8c8c0d807c8194113d6", size = 523221, upload-time = "2025-04-19T14:01:38.444Z" }, + { url = "https://files.pythonhosted.org/packages/99/f3/aefb579aa3cebd6f2866b205fc7a60d33e9a696e9e629024752107dc3cf5/pendulum-3.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:42959341e843077c41d47420f28c3631de054abd64da83f9b956519b5c7a06a7", size = 260502, upload-time = "2025-04-19T14:01:39.814Z" }, + { url = "https://files.pythonhosted.org/packages/02/74/4332b5d6e34c63d4df8e8eab2249e74c05513b1477757463f7fdca99e9be/pendulum-3.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:006758e2125da2e624493324dfd5d7d1b02b0c44bc39358e18bf0f66d0767f5f", size = 253089, upload-time = "2025-04-19T14:01:41.171Z" }, { url = "https://files.pythonhosted.org/packages/8e/1f/af928ba4aa403dac9569f787adcf024005e7654433d71f7a84e608716837/pendulum-3.1.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:28658b0baf4b30eb31d096a375983cfed033e60c0a7bbe94fa23f06cd779b50b", size = 336209, upload-time = "2025-04-19T14:01:42.775Z" }, { url = "https://files.pythonhosted.org/packages/b6/16/b010643007ba964c397da7fa622924423883c1bbff1a53f9d1022cd7f024/pendulum-3.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b114dcb99ce511cb8f5495c7b6f0056b2c3dba444ef1ea6e48030d7371bd531a", size = 323132, upload-time = "2025-04-19T14:01:44.577Z" }, { url = "https://files.pythonhosted.org/packages/64/19/c3c47aeecb5d9bceb0e89faafd800d39809b696c5b7bba8ec8370ad5052c/pendulum-3.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2404a6a54c80252ea393291f0b7f35525a61abae3d795407f34e118a8f133a18", size = 341509, upload-time = "2025-04-19T14:01:46.084Z" }, @@ -1277,6 +1500,34 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/8d/71db63483d518cbbf290261a1fc2839d17ff89fce7089e08cad07ccfce67/pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7", size = 2028584, upload-time = "2025-04-23T18:31:03.106Z" }, + { url = "https://files.pythonhosted.org/packages/24/2f/3cfa7244ae292dd850989f328722d2aef313f74ffc471184dc509e1e4e5a/pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246", size = 1855071, upload-time = "2025-04-23T18:31:04.621Z" }, + { url = "https://files.pythonhosted.org/packages/b3/d3/4ae42d33f5e3f50dd467761304be2fa0a9417fbf09735bc2cce003480f2a/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f", size = 1897823, upload-time = "2025-04-23T18:31:06.377Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f3/aa5976e8352b7695ff808599794b1fba2a9ae2ee954a3426855935799488/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc", size = 1983792, upload-time = "2025-04-23T18:31:07.93Z" }, + { url = "https://files.pythonhosted.org/packages/d5/7a/cda9b5a23c552037717f2b2a5257e9b2bfe45e687386df9591eff7b46d28/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de", size = 2136338, upload-time = "2025-04-23T18:31:09.283Z" }, + { url = "https://files.pythonhosted.org/packages/2b/9f/b8f9ec8dd1417eb9da784e91e1667d58a2a4a7b7b34cf4af765ef663a7e5/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a", size = 2730998, upload-time = "2025-04-23T18:31:11.7Z" }, + { url = "https://files.pythonhosted.org/packages/47/bc/cd720e078576bdb8255d5032c5d63ee5c0bf4b7173dd955185a1d658c456/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef", size = 2003200, upload-time = "2025-04-23T18:31:13.536Z" }, + { url = "https://files.pythonhosted.org/packages/ca/22/3602b895ee2cd29d11a2b349372446ae9727c32e78a94b3d588a40fdf187/pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e", size = 2113890, upload-time = "2025-04-23T18:31:15.011Z" }, + { url = "https://files.pythonhosted.org/packages/ff/e6/e3c5908c03cf00d629eb38393a98fccc38ee0ce8ecce32f69fc7d7b558a7/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d", size = 2073359, upload-time = "2025-04-23T18:31:16.393Z" }, + { url = "https://files.pythonhosted.org/packages/12/e7/6a36a07c59ebefc8777d1ffdaf5ae71b06b21952582e4b07eba88a421c79/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30", size = 2245883, upload-time = "2025-04-23T18:31:17.892Z" }, + { url = "https://files.pythonhosted.org/packages/16/3f/59b3187aaa6cc0c1e6616e8045b284de2b6a87b027cce2ffcea073adf1d2/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf", size = 2241074, upload-time = "2025-04-23T18:31:19.205Z" }, + { url = "https://files.pythonhosted.org/packages/e0/ed/55532bb88f674d5d8f67ab121a2a13c385df382de2a1677f30ad385f7438/pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51", size = 1910538, upload-time = "2025-04-23T18:31:20.541Z" }, + { url = "https://files.pythonhosted.org/packages/fe/1b/25b7cccd4519c0b23c2dd636ad39d381abf113085ce4f7bec2b0dc755eb1/pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab", size = 1952909, upload-time = "2025-04-23T18:31:22.371Z" }, + { url = "https://files.pythonhosted.org/packages/49/a9/d809358e49126438055884c4366a1f6227f0f84f635a9014e2deb9b9de54/pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65", size = 1897786, upload-time = "2025-04-23T18:31:24.161Z" }, + { url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000, upload-time = "2025-04-23T18:31:25.863Z" }, + { url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996, upload-time = "2025-04-23T18:31:27.341Z" }, + { url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957, upload-time = "2025-04-23T18:31:28.956Z" }, + { url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199, upload-time = "2025-04-23T18:31:31.025Z" }, + { url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296, upload-time = "2025-04-23T18:31:32.514Z" }, + { url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109, upload-time = "2025-04-23T18:31:33.958Z" }, + { url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028, upload-time = "2025-04-23T18:31:39.095Z" }, + { url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044, upload-time = "2025-04-23T18:31:41.034Z" }, + { url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881, upload-time = "2025-04-23T18:31:42.757Z" }, + { url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034, upload-time = "2025-04-23T18:31:44.304Z" }, + { url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187, upload-time = "2025-04-23T18:31:45.891Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628, upload-time = "2025-04-23T18:31:47.819Z" }, + { url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866, upload-time = "2025-04-23T18:31:49.635Z" }, + { url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894, upload-time = "2025-04-23T18:31:51.609Z" }, { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" }, { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" }, { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" }, @@ -1294,6 +1545,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" }, { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" }, { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" }, + { url = "https://files.pythonhosted.org/packages/7b/27/d4ae6487d73948d6f20dddcd94be4ea43e74349b56eba82e9bdee2d7494c/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8", size = 2025200, upload-time = "2025-04-23T18:33:14.199Z" }, + { url = "https://files.pythonhosted.org/packages/f1/b8/b3cb95375f05d33801024079b9392a5ab45267a63400bf1866e7ce0f0de4/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593", size = 1859123, upload-time = "2025-04-23T18:33:16.555Z" }, + { url = "https://files.pythonhosted.org/packages/05/bc/0d0b5adeda59a261cd30a1235a445bf55c7e46ae44aea28f7bd6ed46e091/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612", size = 1892852, upload-time = "2025-04-23T18:33:18.513Z" }, + { url = "https://files.pythonhosted.org/packages/3e/11/d37bdebbda2e449cb3f519f6ce950927b56d62f0b84fd9cb9e372a26a3d5/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7", size = 2067484, upload-time = "2025-04-23T18:33:20.475Z" }, + { url = "https://files.pythonhosted.org/packages/8c/55/1f95f0a05ce72ecb02a8a8a1c3be0579bbc29b1d5ab68f1378b7bebc5057/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e", size = 2108896, upload-time = "2025-04-23T18:33:22.501Z" }, + { url = "https://files.pythonhosted.org/packages/53/89/2b2de6c81fa131f423246a9109d7b2a375e83968ad0800d6e57d0574629b/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8", size = 2069475, upload-time = "2025-04-23T18:33:24.528Z" }, + { url = "https://files.pythonhosted.org/packages/b8/e9/1f7efbe20d0b2b10f6718944b5d8ece9152390904f29a78e68d4e7961159/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf", size = 2239013, upload-time = "2025-04-23T18:33:26.621Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b2/5309c905a93811524a49b4e031e9851a6b00ff0fb668794472ea7746b448/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb", size = 2238715, upload-time = "2025-04-23T18:33:28.656Z" }, + { url = "https://files.pythonhosted.org/packages/32/56/8a7ca5d2cd2cda1d245d34b1c9a942920a718082ae8e54e5f3e5a58b7add/pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1", size = 2066757, upload-time = "2025-04-23T18:33:30.645Z" }, ] [[package]] @@ -1323,6 +1583,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997, upload-time = "2024-11-28T03:43:27.893Z" }, ] +[[package]] +name = "pyproject-hooks" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/82/28175b2414effca1cdac8dc99f76d660e7a4fb0ceefa4b4ab8f5f6742925/pyproject_hooks-1.2.0.tar.gz", hash = "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8", size = 19228, upload-time = "2024-09-29T09:24:13.293Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl", hash = "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913", size = 10216, upload-time = "2024-09-29T09:24:11.978Z" }, +] + [[package]] name = "python-daemon" version = "3.1.2" @@ -1392,6 +1661,25 @@ version = "6.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, @@ -1453,6 +1741,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, { name = "rpds-py" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" } wheels = [ @@ -1535,6 +1824,36 @@ version = "0.27.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e9/dd/2c0cbe774744272b0ae725f44032c77bdcab6e8bcf544bffa3b6e70c8dba/rpds_py-0.27.1.tar.gz", hash = "sha256:26a1c73171d10b7acccbded82bf6a586ab8203601e565badc74bbbf8bc5a10f8", size = 27479, upload-time = "2025-08-27T12:16:36.024Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/c1/7907329fbef97cbd49db6f7303893bd1dd5a4a3eae415839ffdfb0762cae/rpds_py-0.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:be898f271f851f68b318872ce6ebebbc62f303b654e43bf72683dbdc25b7c881", size = 371063, upload-time = "2025-08-27T12:12:47.856Z" }, + { url = "https://files.pythonhosted.org/packages/11/94/2aab4bc86228bcf7c48760990273653a4900de89c7537ffe1b0d6097ed39/rpds_py-0.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:62ac3d4e3e07b58ee0ddecd71d6ce3b1637de2d373501412df395a0ec5f9beb5", size = 353210, upload-time = "2025-08-27T12:12:49.187Z" }, + { url = "https://files.pythonhosted.org/packages/3a/57/f5eb3ecf434342f4f1a46009530e93fd201a0b5b83379034ebdb1d7c1a58/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4708c5c0ceb2d034f9991623631d3d23cb16e65c83736ea020cdbe28d57c0a0e", size = 381636, upload-time = "2025-08-27T12:12:50.492Z" }, + { url = "https://files.pythonhosted.org/packages/ae/f4/ef95c5945e2ceb5119571b184dd5a1cc4b8541bbdf67461998cfeac9cb1e/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:abfa1171a9952d2e0002aba2ad3780820b00cc3d9c98c6630f2e93271501f66c", size = 394341, upload-time = "2025-08-27T12:12:52.024Z" }, + { url = "https://files.pythonhosted.org/packages/5a/7e/4bd610754bf492d398b61725eb9598ddd5eb86b07d7d9483dbcd810e20bc/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b507d19f817ebaca79574b16eb2ae412e5c0835542c93fe9983f1e432aca195", size = 523428, upload-time = "2025-08-27T12:12:53.779Z" }, + { url = "https://files.pythonhosted.org/packages/9f/e5/059b9f65a8c9149361a8b75094864ab83b94718344db511fd6117936ed2a/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168b025f8fd8d8d10957405f3fdcef3dc20f5982d398f90851f4abc58c566c52", size = 402923, upload-time = "2025-08-27T12:12:55.15Z" }, + { url = "https://files.pythonhosted.org/packages/f5/48/64cabb7daced2968dd08e8a1b7988bf358d7bd5bcd5dc89a652f4668543c/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb56c6210ef77caa58e16e8c17d35c63fe3f5b60fd9ba9d424470c3400bcf9ed", size = 384094, upload-time = "2025-08-27T12:12:57.194Z" }, + { url = "https://files.pythonhosted.org/packages/ae/e1/dc9094d6ff566bff87add8a510c89b9e158ad2ecd97ee26e677da29a9e1b/rpds_py-0.27.1-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:d252f2d8ca0195faa707f8eb9368955760880b2b42a8ee16d382bf5dd807f89a", size = 401093, upload-time = "2025-08-27T12:12:58.985Z" }, + { url = "https://files.pythonhosted.org/packages/37/8e/ac8577e3ecdd5593e283d46907d7011618994e1d7ab992711ae0f78b9937/rpds_py-0.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6e5e54da1e74b91dbc7996b56640f79b195d5925c2b78efaa8c5d53e1d88edde", size = 417969, upload-time = "2025-08-27T12:13:00.367Z" }, + { url = "https://files.pythonhosted.org/packages/66/6d/87507430a8f74a93556fe55c6485ba9c259949a853ce407b1e23fea5ba31/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ffce0481cc6e95e5b3f0a47ee17ffbd234399e6d532f394c8dce320c3b089c21", size = 558302, upload-time = "2025-08-27T12:13:01.737Z" }, + { url = "https://files.pythonhosted.org/packages/3a/bb/1db4781ce1dda3eecc735e3152659a27b90a02ca62bfeea17aee45cc0fbc/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a205fdfe55c90c2cd8e540ca9ceba65cbe6629b443bc05db1f590a3db8189ff9", size = 589259, upload-time = "2025-08-27T12:13:03.127Z" }, + { url = "https://files.pythonhosted.org/packages/7b/0e/ae1c8943d11a814d01b482e1f8da903f88047a962dff9bbdadf3bd6e6fd1/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:689fb5200a749db0415b092972e8eba85847c23885c8543a8b0f5c009b1a5948", size = 554983, upload-time = "2025-08-27T12:13:04.516Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d5/0b2a55415931db4f112bdab072443ff76131b5ac4f4dc98d10d2d357eb03/rpds_py-0.27.1-cp311-cp311-win32.whl", hash = "sha256:3182af66048c00a075010bc7f4860f33913528a4b6fc09094a6e7598e462fe39", size = 217154, upload-time = "2025-08-27T12:13:06.278Z" }, + { url = "https://files.pythonhosted.org/packages/24/75/3b7ffe0d50dc86a6a964af0d1cc3a4a2cdf437cb7b099a4747bbb96d1819/rpds_py-0.27.1-cp311-cp311-win_amd64.whl", hash = "sha256:b4938466c6b257b2f5c4ff98acd8128ec36b5059e5c8f8372d79316b1c36bb15", size = 228627, upload-time = "2025-08-27T12:13:07.625Z" }, + { url = "https://files.pythonhosted.org/packages/8d/3f/4fd04c32abc02c710f09a72a30c9a55ea3cc154ef8099078fd50a0596f8e/rpds_py-0.27.1-cp311-cp311-win_arm64.whl", hash = "sha256:2f57af9b4d0793e53266ee4325535a31ba48e2f875da81a9177c9926dfa60746", size = 220998, upload-time = "2025-08-27T12:13:08.972Z" }, + { url = "https://files.pythonhosted.org/packages/bd/fe/38de28dee5df58b8198c743fe2bea0c785c6d40941b9950bac4cdb71a014/rpds_py-0.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ae2775c1973e3c30316892737b91f9283f9908e3cc7625b9331271eaaed7dc90", size = 361887, upload-time = "2025-08-27T12:13:10.233Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/4b6c7eedc7dd90986bf0fab6ea2a091ec11c01b15f8ba0a14d3f80450468/rpds_py-0.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2643400120f55c8a96f7c9d858f7be0c88d383cd4653ae2cf0d0c88f668073e5", size = 345795, upload-time = "2025-08-27T12:13:11.65Z" }, + { url = "https://files.pythonhosted.org/packages/6f/0e/e650e1b81922847a09cca820237b0edee69416a01268b7754d506ade11ad/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16323f674c089b0360674a4abd28d5042947d54ba620f72514d69be4ff64845e", size = 385121, upload-time = "2025-08-27T12:13:13.008Z" }, + { url = "https://files.pythonhosted.org/packages/1b/ea/b306067a712988e2bff00dcc7c8f31d26c29b6d5931b461aa4b60a013e33/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a1f4814b65eacac94a00fc9a526e3fdafd78e439469644032032d0d63de4881", size = 398976, upload-time = "2025-08-27T12:13:14.368Z" }, + { url = "https://files.pythonhosted.org/packages/2c/0a/26dc43c8840cb8fe239fe12dbc8d8de40f2365e838f3d395835dde72f0e5/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ba32c16b064267b22f1850a34051121d423b6f7338a12b9459550eb2096e7ec", size = 525953, upload-time = "2025-08-27T12:13:15.774Z" }, + { url = "https://files.pythonhosted.org/packages/22/14/c85e8127b573aaf3a0cbd7fbb8c9c99e735a4a02180c84da2a463b766e9e/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5c20f33fd10485b80f65e800bbe5f6785af510b9f4056c5a3c612ebc83ba6cb", size = 407915, upload-time = "2025-08-27T12:13:17.379Z" }, + { url = "https://files.pythonhosted.org/packages/ed/7b/8f4fee9ba1fb5ec856eb22d725a4efa3deb47f769597c809e03578b0f9d9/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:466bfe65bd932da36ff279ddd92de56b042f2266d752719beb97b08526268ec5", size = 386883, upload-time = "2025-08-27T12:13:18.704Z" }, + { url = "https://files.pythonhosted.org/packages/86/47/28fa6d60f8b74fcdceba81b272f8d9836ac0340570f68f5df6b41838547b/rpds_py-0.27.1-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:41e532bbdcb57c92ba3be62c42e9f096431b4cf478da9bc3bc6ce5c38ab7ba7a", size = 405699, upload-time = "2025-08-27T12:13:20.089Z" }, + { url = "https://files.pythonhosted.org/packages/d0/fd/c5987b5e054548df56953a21fe2ebed51fc1ec7c8f24fd41c067b68c4a0a/rpds_py-0.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f149826d742b406579466283769a8ea448eed82a789af0ed17b0cd5770433444", size = 423713, upload-time = "2025-08-27T12:13:21.436Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ba/3c4978b54a73ed19a7d74531be37a8bcc542d917c770e14d372b8daea186/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80c60cfb5310677bd67cb1e85a1e8eb52e12529545441b43e6f14d90b878775a", size = 562324, upload-time = "2025-08-27T12:13:22.789Z" }, + { url = "https://files.pythonhosted.org/packages/b5/6c/6943a91768fec16db09a42b08644b960cff540c66aab89b74be6d4a144ba/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7ee6521b9baf06085f62ba9c7a3e5becffbc32480d2f1b351559c001c38ce4c1", size = 593646, upload-time = "2025-08-27T12:13:24.122Z" }, + { url = "https://files.pythonhosted.org/packages/11/73/9d7a8f4be5f4396f011a6bb7a19fe26303a0dac9064462f5651ced2f572f/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a512c8263249a9d68cac08b05dd59d2b3f2061d99b322813cbcc14c3c7421998", size = 558137, upload-time = "2025-08-27T12:13:25.557Z" }, + { url = "https://files.pythonhosted.org/packages/6e/96/6772cbfa0e2485bcceef8071de7821f81aeac8bb45fbfd5542a3e8108165/rpds_py-0.27.1-cp312-cp312-win32.whl", hash = "sha256:819064fa048ba01b6dadc5116f3ac48610435ac9a0058bbde98e569f9e785c39", size = 221343, upload-time = "2025-08-27T12:13:26.967Z" }, + { url = "https://files.pythonhosted.org/packages/67/b6/c82f0faa9af1c6a64669f73a17ee0eeef25aff30bb9a1c318509efe45d84/rpds_py-0.27.1-cp312-cp312-win_amd64.whl", hash = "sha256:d9199717881f13c32c4046a15f024971a3b78ad4ea029e8da6b86e5aa9cf4594", size = 232497, upload-time = "2025-08-27T12:13:28.326Z" }, + { url = "https://files.pythonhosted.org/packages/e1/96/2817b44bd2ed11aebacc9251da03689d56109b9aba5e311297b6902136e2/rpds_py-0.27.1-cp312-cp312-win_arm64.whl", hash = "sha256:33aa65b97826a0e885ef6e278fbd934e98cdcfed80b63946025f01e2f5b29502", size = 222790, upload-time = "2025-08-27T12:13:29.71Z" }, { url = "https://files.pythonhosted.org/packages/cc/77/610aeee8d41e39080c7e14afa5387138e3c9fa9756ab893d09d99e7d8e98/rpds_py-0.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e4b9fcfbc021633863a37e92571d6f91851fa656f0180246e84cbd8b3f6b329b", size = 361741, upload-time = "2025-08-27T12:13:31.039Z" }, { url = "https://files.pythonhosted.org/packages/3a/fc/c43765f201c6a1c60be2043cbdb664013def52460a4c7adace89d6682bf4/rpds_py-0.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1441811a96eadca93c517d08df75de45e5ffe68aa3089924f963c782c4b898cf", size = 345574, upload-time = "2025-08-27T12:13:32.902Z" }, { url = "https://files.pythonhosted.org/packages/20/42/ee2b2ca114294cd9847d0ef9c26d2b0851b2e7e00bf14cc4c0b581df0fc3/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55266dafa22e672f5a4f65019015f90336ed31c6383bd53f5e7826d21a0e0b83", size = 385051, upload-time = "2025-08-27T12:13:34.228Z" }, @@ -1593,6 +1912,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dd/10/6b283707780a81919f71625351182b4f98932ac89a09023cb61865136244/rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f39f58a27cc6e59f432b568ed8429c7e1641324fbe38131de852cd77b2d534b0", size = 555813, upload-time = "2025-08-27T12:15:00.334Z" }, { url = "https://files.pythonhosted.org/packages/04/2e/30b5ea18c01379da6272a92825dd7e53dc9d15c88a19e97932d35d430ef7/rpds_py-0.27.1-cp314-cp314t-win32.whl", hash = "sha256:d5fa0ee122dc09e23607a28e6d7b150da16c662e66409bbe85230e4c85bb528a", size = 217385, upload-time = "2025-08-27T12:15:01.937Z" }, { url = "https://files.pythonhosted.org/packages/32/7d/97119da51cb1dd3f2f3c0805f155a3aa4a95fa44fe7d78ae15e69edf4f34/rpds_py-0.27.1-cp314-cp314t-win_amd64.whl", hash = "sha256:6567d2bb951e21232c2f660c24cf3470bb96de56cdcb3f071a83feeaff8a2772", size = 230097, upload-time = "2025-08-27T12:15:03.961Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ed/e1fba02de17f4f76318b834425257c8ea297e415e12c68b4361f63e8ae92/rpds_py-0.27.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cdfe4bb2f9fe7458b7453ad3c33e726d6d1c7c0a72960bcc23800d77384e42df", size = 371402, upload-time = "2025-08-27T12:15:51.561Z" }, + { url = "https://files.pythonhosted.org/packages/af/7c/e16b959b316048b55585a697e94add55a4ae0d984434d279ea83442e460d/rpds_py-0.27.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:8fabb8fd848a5f75a2324e4a84501ee3a5e3c78d8603f83475441866e60b94a3", size = 354084, upload-time = "2025-08-27T12:15:53.219Z" }, + { url = "https://files.pythonhosted.org/packages/de/c1/ade645f55de76799fdd08682d51ae6724cb46f318573f18be49b1e040428/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda8719d598f2f7f3e0f885cba8646644b55a187762bec091fa14a2b819746a9", size = 383090, upload-time = "2025-08-27T12:15:55.158Z" }, + { url = "https://files.pythonhosted.org/packages/1f/27/89070ca9b856e52960da1472efcb6c20ba27cfe902f4f23ed095b9cfc61d/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c64d07e95606ec402a0a1c511fe003873fa6af630bda59bac77fac8b4318ebc", size = 394519, upload-time = "2025-08-27T12:15:57.238Z" }, + { url = "https://files.pythonhosted.org/packages/b3/28/be120586874ef906aa5aeeae95ae8df4184bc757e5b6bd1c729ccff45ed5/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93a2ed40de81bcff59aabebb626562d48332f3d028ca2036f1d23cbb52750be4", size = 523817, upload-time = "2025-08-27T12:15:59.237Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/70cc197bc11cfcde02a86f36ac1eed15c56667c2ebddbdb76a47e90306da/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:387ce8c44ae94e0ec50532d9cb0edce17311024c9794eb196b90e1058aadeb66", size = 403240, upload-time = "2025-08-27T12:16:00.923Z" }, + { url = "https://files.pythonhosted.org/packages/cf/35/46936cca449f7f518f2f4996e0e8344db4b57e2081e752441154089d2a5f/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaf94f812c95b5e60ebaf8bfb1898a7d7cb9c1af5744d4a67fa47796e0465d4e", size = 385194, upload-time = "2025-08-27T12:16:02.802Z" }, + { url = "https://files.pythonhosted.org/packages/e1/62/29c0d3e5125c3270b51415af7cbff1ec587379c84f55a5761cc9efa8cd06/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:4848ca84d6ded9b58e474dfdbad4b8bfb450344c0551ddc8d958bf4b36aa837c", size = 402086, upload-time = "2025-08-27T12:16:04.806Z" }, + { url = "https://files.pythonhosted.org/packages/8f/66/03e1087679227785474466fdd04157fb793b3b76e3fcf01cbf4c693c1949/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2bde09cbcf2248b73c7c323be49b280180ff39fadcfe04e7b6f54a678d02a7cf", size = 419272, upload-time = "2025-08-27T12:16:06.471Z" }, + { url = "https://files.pythonhosted.org/packages/6a/24/e3e72d265121e00b063aef3e3501e5b2473cf1b23511d56e529531acf01e/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:94c44ee01fd21c9058f124d2d4f0c9dc7634bec93cd4b38eefc385dabe71acbf", size = 560003, upload-time = "2025-08-27T12:16:08.06Z" }, + { url = "https://files.pythonhosted.org/packages/26/ca/f5a344c534214cc2d41118c0699fffbdc2c1bc7046f2a2b9609765ab9c92/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:df8b74962e35c9249425d90144e721eed198e6555a0e22a563d29fe4486b51f6", size = 590482, upload-time = "2025-08-27T12:16:10.137Z" }, + { url = "https://files.pythonhosted.org/packages/ce/08/4349bdd5c64d9d193c360aa9db89adeee6f6682ab8825dca0a3f535f434f/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:dc23e6820e3b40847e2f4a7726462ba0cf53089512abe9ee16318c366494c17a", size = 556523, upload-time = "2025-08-27T12:16:12.188Z" }, ] [[package]] @@ -1601,6 +1932,26 @@ version = "1.3.7" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/8d/48/49393a96a2eef1ab418b17475fb92b8fcfad83d099e678751b05472e69de/setproctitle-1.3.7.tar.gz", hash = "sha256:bc2bc917691c1537d5b9bca1468437176809c7e11e5694ca79a9ca12345dcb9e", size = 27002, upload-time = "2025-09-05T12:51:25.278Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/04/cd/1b7ba5cad635510720ce19d7122154df96a2387d2a74217be552887c93e5/setproctitle-1.3.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a600eeb4145fb0ee6c287cb82a2884bd4ec5bbb076921e287039dcc7b7cc6dd0", size = 18085, upload-time = "2025-09-05T12:49:22.183Z" }, + { url = "https://files.pythonhosted.org/packages/8f/1a/b2da0a620490aae355f9d72072ac13e901a9fec809a6a24fc6493a8f3c35/setproctitle-1.3.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:97a090fed480471bb175689859532709e28c085087e344bca45cf318034f70c4", size = 13097, upload-time = "2025-09-05T12:49:23.322Z" }, + { url = "https://files.pythonhosted.org/packages/18/2e/bd03ff02432a181c1787f6fc2a678f53b7dacdd5ded69c318fe1619556e8/setproctitle-1.3.7-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1607b963e7b53e24ec8a2cb4e0ab3ae591d7c6bf0a160feef0551da63452b37f", size = 32191, upload-time = "2025-09-05T12:49:24.567Z" }, + { url = "https://files.pythonhosted.org/packages/28/78/1e62fc0937a8549f2220445ed2175daacee9b6764c7963b16148119b016d/setproctitle-1.3.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a20fb1a3974e2dab857870cf874b325b8705605cb7e7e8bcbb915bca896f52a9", size = 33203, upload-time = "2025-09-05T12:49:25.871Z" }, + { url = "https://files.pythonhosted.org/packages/a0/3c/65edc65db3fa3df400cf13b05e9d41a3c77517b4839ce873aa6b4043184f/setproctitle-1.3.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f8d961bba676e07d77665204f36cffaa260f526e7b32d07ab3df6a2c1dfb44ba", size = 34963, upload-time = "2025-09-05T12:49:27.044Z" }, + { url = "https://files.pythonhosted.org/packages/a1/32/89157e3de997973e306e44152522385f428e16f92f3cf113461489e1e2ee/setproctitle-1.3.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:db0fd964fbd3a9f8999b502f65bd2e20883fdb5b1fae3a424e66db9a793ed307", size = 32398, upload-time = "2025-09-05T12:49:28.909Z" }, + { url = "https://files.pythonhosted.org/packages/4a/18/77a765a339ddf046844cb4513353d8e9dcd8183da9cdba6e078713e6b0b2/setproctitle-1.3.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:db116850fcf7cca19492030f8d3b4b6e231278e8fe097a043957d22ce1bdf3ee", size = 33657, upload-time = "2025-09-05T12:49:30.323Z" }, + { url = "https://files.pythonhosted.org/packages/6b/63/f0b6205c64d74d2a24a58644a38ec77bdbaa6afc13747e75973bf8904932/setproctitle-1.3.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:316664d8b24a5c91ee244460bdaf7a74a707adaa9e14fbe0dc0a53168bb9aba1", size = 31836, upload-time = "2025-09-05T12:49:32.309Z" }, + { url = "https://files.pythonhosted.org/packages/ba/51/e1277f9ba302f1a250bbd3eedbbee747a244b3cc682eb58fb9733968f6d8/setproctitle-1.3.7-cp311-cp311-win32.whl", hash = "sha256:b74774ca471c86c09b9d5037c8451fff06bb82cd320d26ae5a01c758088c0d5d", size = 12556, upload-time = "2025-09-05T12:49:33.529Z" }, + { url = "https://files.pythonhosted.org/packages/b6/7b/822a23f17e9003dfdee92cd72758441ca2a3680388da813a371b716fb07f/setproctitle-1.3.7-cp311-cp311-win_amd64.whl", hash = "sha256:acb9097213a8dd3410ed9f0dc147840e45ca9797785272928d4be3f0e69e3be4", size = 13243, upload-time = "2025-09-05T12:49:34.553Z" }, + { url = "https://files.pythonhosted.org/packages/fb/f0/2dc88e842077719d7384d86cc47403e5102810492b33680e7dadcee64cd8/setproctitle-1.3.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2dc99aec591ab6126e636b11035a70991bc1ab7a261da428491a40b84376654e", size = 18049, upload-time = "2025-09-05T12:49:36.241Z" }, + { url = "https://files.pythonhosted.org/packages/f0/b4/50940504466689cda65680c9e9a1e518e5750c10490639fa687489ac7013/setproctitle-1.3.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cdd8aa571b7aa39840fdbea620e308a19691ff595c3a10231e9ee830339dd798", size = 13079, upload-time = "2025-09-05T12:49:38.088Z" }, + { url = "https://files.pythonhosted.org/packages/d0/99/71630546b9395b095f4082be41165d1078204d1696c2d9baade3de3202d0/setproctitle-1.3.7-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2906b6c7959cdb75f46159bf0acd8cc9906cf1361c9e1ded0d065fe8f9039629", size = 32932, upload-time = "2025-09-05T12:49:39.271Z" }, + { url = "https://files.pythonhosted.org/packages/50/22/cee06af4ffcfb0e8aba047bd44f5262e644199ae7527ae2c1f672b86495c/setproctitle-1.3.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6915964a6dda07920a1159321dcd6d94fc7fc526f815ca08a8063aeca3c204f1", size = 33736, upload-time = "2025-09-05T12:49:40.565Z" }, + { url = "https://files.pythonhosted.org/packages/5c/00/a5949a8bb06ef5e7df214fc393bb2fb6aedf0479b17214e57750dfdd0f24/setproctitle-1.3.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cff72899861c765bd4021d1ff1c68d60edc129711a2fdba77f9cb69ef726a8b6", size = 35605, upload-time = "2025-09-05T12:49:42.362Z" }, + { url = "https://files.pythonhosted.org/packages/b0/3a/50caca532a9343828e3bf5778c7a84d6c737a249b1796d50dd680290594d/setproctitle-1.3.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b7cb05bd446687ff816a3aaaf831047fc4c364feff7ada94a66024f1367b448c", size = 33143, upload-time = "2025-09-05T12:49:43.515Z" }, + { url = "https://files.pythonhosted.org/packages/ca/14/b843a251296ce55e2e17c017d6b9f11ce0d3d070e9265de4ecad948b913d/setproctitle-1.3.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3a57b9a00de8cae7e2a1f7b9f0c2ac7b69372159e16a7708aa2f38f9e5cc987a", size = 34434, upload-time = "2025-09-05T12:49:45.31Z" }, + { url = "https://files.pythonhosted.org/packages/c8/b7/06145c238c0a6d2c4bc881f8be230bb9f36d2bf51aff7bddcb796d5eed67/setproctitle-1.3.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d8828b356114f6b308b04afe398ed93803d7fca4a955dd3abe84430e28d33739", size = 32795, upload-time = "2025-09-05T12:49:46.419Z" }, + { url = "https://files.pythonhosted.org/packages/ef/dc/ef76a81fac9bf27b84ed23df19c1f67391a753eed6e3c2254ebcb5133f56/setproctitle-1.3.7-cp312-cp312-win32.whl", hash = "sha256:b0304f905efc845829ac2bc791ddebb976db2885f6171f4a3de678d7ee3f7c9f", size = 12552, upload-time = "2025-09-05T12:49:47.635Z" }, + { url = "https://files.pythonhosted.org/packages/e2/5b/a9fe517912cd6e28cf43a212b80cb679ff179a91b623138a99796d7d18a0/setproctitle-1.3.7-cp312-cp312-win_amd64.whl", hash = "sha256:9888ceb4faea3116cf02a920ff00bfbc8cc899743e4b4ac914b03625bdc3c300", size = 13247, upload-time = "2025-09-05T12:49:49.16Z" }, { url = "https://files.pythonhosted.org/packages/5d/2f/fcedcade3b307a391b6e17c774c6261a7166aed641aee00ed2aad96c63ce/setproctitle-1.3.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c3736b2a423146b5e62230502e47e08e68282ff3b69bcfe08a322bee73407922", size = 18047, upload-time = "2025-09-05T12:49:50.271Z" }, { url = "https://files.pythonhosted.org/packages/23/ae/afc141ca9631350d0a80b8f287aac79a76f26b6af28fd8bf92dae70dc2c5/setproctitle-1.3.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3384e682b158d569e85a51cfbde2afd1ab57ecf93ea6651fe198d0ba451196ee", size = 13073, upload-time = "2025-09-05T12:49:51.46Z" }, { url = "https://files.pythonhosted.org/packages/87/ed/0a4f00315bc02510395b95eec3d4aa77c07192ee79f0baae77ea7b9603d8/setproctitle-1.3.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0564a936ea687cd24dffcea35903e2a20962aa6ac20e61dd3a207652401492dd", size = 33284, upload-time = "2025-09-05T12:49:52.741Z" }, @@ -1641,6 +1992,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e7/e3/54b496ac724e60e61cc3447f02690105901ca6d90da0377dffe49ff99fc7/setproctitle-1.3.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1fae595d032b30dab4d659bece20debd202229fce12b55abab978b7f30783d73", size = 33958, upload-time = "2025-09-05T12:50:39.841Z" }, { url = "https://files.pythonhosted.org/packages/ea/a8/c84bb045ebf8c6fdc7f7532319e86f8380d14bbd3084e6348df56bdfe6fd/setproctitle-1.3.7-cp314-cp314t-win32.whl", hash = "sha256:02432f26f5d1329ab22279ff863c83589894977063f59e6c4b4845804a08f8c2", size = 12745, upload-time = "2025-09-05T12:50:41.377Z" }, { url = "https://files.pythonhosted.org/packages/08/b6/3a5a4f9952972791a9114ac01dfc123f0df79903577a3e0a7a404a695586/setproctitle-1.3.7-cp314-cp314t-win_amd64.whl", hash = "sha256:cbc388e3d86da1f766d8fc2e12682e446064c01cea9f88a88647cfe7c011de6a", size = 13469, upload-time = "2025-09-05T12:50:42.67Z" }, + { url = "https://files.pythonhosted.org/packages/c3/5b/5e1c117ac84e3cefcf8d7a7f6b2461795a87e20869da065a5c087149060b/setproctitle-1.3.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:b1cac6a4b0252b8811d60b6d8d0f157c0fdfed379ac89c25a914e6346cf355a1", size = 12587, upload-time = "2025-09-05T12:51:21.195Z" }, + { url = "https://files.pythonhosted.org/packages/73/02/b9eadc226195dcfa90eed37afe56b5dd6fa2f0e5220ab8b7867b8862b926/setproctitle-1.3.7-pp311-pypy311_pp73-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f1704c9e041f2b1dc38f5be4552e141e1432fba3dd52c72eeffd5bc2db04dc65", size = 14286, upload-time = "2025-09-05T12:51:22.61Z" }, + { url = "https://files.pythonhosted.org/packages/28/26/1be1d2a53c2a91ec48fa2ff4a409b395f836798adf194d99de9c059419ea/setproctitle-1.3.7-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b08b61976ffa548bd5349ce54404bf6b2d51bd74d4f1b241ed1b0f25bce09c3a", size = 13282, upload-time = "2025-09-05T12:51:24.094Z" }, +] + +[[package]] +name = "setuptools" +version = "80.10.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/95/faf61eb8363f26aa7e1d762267a8d602a1b26d4f3a1e758e92cb3cb8b054/setuptools-80.10.2.tar.gz", hash = "sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70", size = 1200343, upload-time = "2026-01-25T22:38:17.252Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/b8/f1f62a5e3c0ad2ff1d189590bfa4c46b4f3b6e49cef6f26c6ee4e575394d/setuptools-80.10.2-py3-none-any.whl", hash = "sha256:95b30ddfb717250edb492926c92b5221f7ef3fbcc2b07579bcd4a27da21d0173", size = 1064234, upload-time = "2026-01-25T22:38:15.216Z" }, ] [[package]] @@ -1680,6 +2043,22 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/d7/bc/d59b5d97d27229b0e009bd9098cd81af71c2fa5549c580a0a67b9bed0496/sqlalchemy-2.0.43.tar.gz", hash = "sha256:788bfcef6787a7764169cfe9859fe425bf44559619e1d9f56f5bddf2ebf6f417", size = 9762949, upload-time = "2025-08-11T14:24:58.438Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/77/fa7189fe44114658002566c6fe443d3ed0ec1fa782feb72af6ef7fbe98e7/sqlalchemy-2.0.43-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:52d9b73b8fb3e9da34c2b31e6d99d60f5f99fd8c1225c9dad24aeb74a91e1d29", size = 2136472, upload-time = "2025-08-11T15:52:21.789Z" }, + { url = "https://files.pythonhosted.org/packages/99/ea/92ac27f2fbc2e6c1766bb807084ca455265707e041ba027c09c17d697867/sqlalchemy-2.0.43-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f42f23e152e4545157fa367b2435a1ace7571cab016ca26038867eb7df2c3631", size = 2126535, upload-time = "2025-08-11T15:52:23.109Z" }, + { url = "https://files.pythonhosted.org/packages/94/12/536ede80163e295dc57fff69724caf68f91bb40578b6ac6583a293534849/sqlalchemy-2.0.43-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fb1a8c5438e0c5ea51afe9c6564f951525795cf432bed0c028c1cb081276685", size = 3297521, upload-time = "2025-08-11T15:50:33.536Z" }, + { url = "https://files.pythonhosted.org/packages/03/b5/cacf432e6f1fc9d156eca0560ac61d4355d2181e751ba8c0cd9cb232c8c1/sqlalchemy-2.0.43-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db691fa174e8f7036afefe3061bc40ac2b770718be2862bfb03aabae09051aca", size = 3297343, upload-time = "2025-08-11T15:57:51.186Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ba/d4c9b526f18457667de4c024ffbc3a0920c34237b9e9dd298e44c7c00ee5/sqlalchemy-2.0.43-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe2b3b4927d0bc03d02ad883f402d5de201dbc8894ac87d2e981e7d87430e60d", size = 3232113, upload-time = "2025-08-11T15:50:34.949Z" }, + { url = "https://files.pythonhosted.org/packages/aa/79/c0121b12b1b114e2c8a10ea297a8a6d5367bc59081b2be896815154b1163/sqlalchemy-2.0.43-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4d3d9b904ad4a6b175a2de0738248822f5ac410f52c2fd389ada0b5262d6a1e3", size = 3258240, upload-time = "2025-08-11T15:57:52.983Z" }, + { url = "https://files.pythonhosted.org/packages/79/99/a2f9be96fb382f3ba027ad42f00dbe30fdb6ba28cda5f11412eee346bec5/sqlalchemy-2.0.43-cp311-cp311-win32.whl", hash = "sha256:5cda6b51faff2639296e276591808c1726c4a77929cfaa0f514f30a5f6156921", size = 2101248, upload-time = "2025-08-11T15:55:01.855Z" }, + { url = "https://files.pythonhosted.org/packages/ee/13/744a32ebe3b4a7a9c7ea4e57babae7aa22070d47acf330d8e5a1359607f1/sqlalchemy-2.0.43-cp311-cp311-win_amd64.whl", hash = "sha256:c5d1730b25d9a07727d20ad74bc1039bbbb0a6ca24e6769861c1aa5bf2c4c4a8", size = 2126109, upload-time = "2025-08-11T15:55:04.092Z" }, + { url = "https://files.pythonhosted.org/packages/61/db/20c78f1081446095450bdc6ee6cc10045fce67a8e003a5876b6eaafc5cc4/sqlalchemy-2.0.43-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:20d81fc2736509d7a2bd33292e489b056cbae543661bb7de7ce9f1c0cd6e7f24", size = 2134891, upload-time = "2025-08-11T15:51:13.019Z" }, + { url = "https://files.pythonhosted.org/packages/45/0a/3d89034ae62b200b4396f0f95319f7d86e9945ee64d2343dcad857150fa2/sqlalchemy-2.0.43-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b9fc27650ff5a2c9d490c13c14906b918b0de1f8fcbb4c992712d8caf40e83", size = 2123061, upload-time = "2025-08-11T15:51:14.319Z" }, + { url = "https://files.pythonhosted.org/packages/cb/10/2711f7ff1805919221ad5bee205971254845c069ee2e7036847103ca1e4c/sqlalchemy-2.0.43-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6772e3ca8a43a65a37c88e2f3e2adfd511b0b1da37ef11ed78dea16aeae85bd9", size = 3320384, upload-time = "2025-08-11T15:52:35.088Z" }, + { url = "https://files.pythonhosted.org/packages/6e/0e/3d155e264d2ed2778484006ef04647bc63f55b3e2d12e6a4f787747b5900/sqlalchemy-2.0.43-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a113da919c25f7f641ffbd07fbc9077abd4b3b75097c888ab818f962707eb48", size = 3329648, upload-time = "2025-08-11T15:56:34.153Z" }, + { url = "https://files.pythonhosted.org/packages/5b/81/635100fb19725c931622c673900da5efb1595c96ff5b441e07e3dd61f2be/sqlalchemy-2.0.43-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4286a1139f14b7d70141c67a8ae1582fc2b69105f1b09d9573494eb4bb4b2687", size = 3258030, upload-time = "2025-08-11T15:52:36.933Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ed/a99302716d62b4965fded12520c1cbb189f99b17a6d8cf77611d21442e47/sqlalchemy-2.0.43-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:529064085be2f4d8a6e5fab12d36ad44f1909a18848fcfbdb59cc6d4bbe48efe", size = 3294469, upload-time = "2025-08-11T15:56:35.553Z" }, + { url = "https://files.pythonhosted.org/packages/5d/a2/3a11b06715149bf3310b55a98b5c1e84a42cfb949a7b800bc75cb4e33abc/sqlalchemy-2.0.43-cp312-cp312-win32.whl", hash = "sha256:b535d35dea8bbb8195e7e2b40059e2253acb2b7579b73c1b432a35363694641d", size = 2098906, upload-time = "2025-08-11T15:55:00.645Z" }, + { url = "https://files.pythonhosted.org/packages/bc/09/405c915a974814b90aa591280623adc6ad6b322f61fd5cff80aeaef216c9/sqlalchemy-2.0.43-cp312-cp312-win_amd64.whl", hash = "sha256:1c6d85327ca688dbae7e2b06d7d84cfe4f3fffa5b5f9e21bb6ce9d0e1a0e0e0a", size = 2126260, upload-time = "2025-08-11T15:55:02.965Z" }, { url = "https://files.pythonhosted.org/packages/41/1c/a7260bd47a6fae7e03768bf66451437b36451143f36b285522b865987ced/sqlalchemy-2.0.43-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e7c08f57f75a2bb62d7ee80a89686a5e5669f199235c6d1dac75cd59374091c3", size = 2130598, upload-time = "2025-08-11T15:51:15.903Z" }, { url = "https://files.pythonhosted.org/packages/8e/84/8a337454e82388283830b3586ad7847aa9c76fdd4f1df09cdd1f94591873/sqlalchemy-2.0.43-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:14111d22c29efad445cd5021a70a8b42f7d9152d8ba7f73304c4d82460946aaa", size = 2118415, upload-time = "2025-08-11T15:51:17.256Z" }, { url = "https://files.pythonhosted.org/packages/cf/ff/22ab2328148492c4d71899d62a0e65370ea66c877aea017a244a35733685/sqlalchemy-2.0.43-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21b27b56eb2f82653168cefe6cb8e970cdaf4f3a6cb2c5e3c3c1cf3158968ff9", size = 3248707, upload-time = "2025-08-11T15:52:38.444Z" }, @@ -1735,6 +2114,7 @@ version = "0.48.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a7/a5/d6f429d43394057b67a6b5bbe6eae2f77a6bf7459d961fdb224bf206eee6/starlette-0.48.0.tar.gz", hash = "sha256:7e8cee469a8ab2352911528110ce9088fdc6a37d9876926e73da7ce4aa4c7a46", size = 2652949, upload-time = "2025-09-13T08:41:05.699Z" } wheels = [ @@ -1924,6 +2304,18 @@ version = "0.21.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/af/c0/854216d09d33c543f12a44b393c402e89a920b1a0a7dc634c42de91b9cf6/uvloop-0.21.0.tar.gz", hash = "sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3", size = 2492741, upload-time = "2024-10-14T23:38:35.489Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/57/a7/4cf0334105c1160dd6819f3297f8700fda7fc30ab4f61fbf3e725acbc7cc/uvloop-0.21.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c0f3fa6200b3108919f8bdabb9a7f87f20e7097ea3c543754cabc7d717d95cf8", size = 1447410, upload-time = "2024-10-14T23:37:33.612Z" }, + { url = "https://files.pythonhosted.org/packages/8c/7c/1517b0bbc2dbe784b563d6ab54f2ef88c890fdad77232c98ed490aa07132/uvloop-0.21.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0878c2640cf341b269b7e128b1a5fed890adc4455513ca710d77d5e93aa6d6a0", size = 805476, upload-time = "2024-10-14T23:37:36.11Z" }, + { url = "https://files.pythonhosted.org/packages/ee/ea/0bfae1aceb82a503f358d8d2fa126ca9dbdb2ba9c7866974faec1cb5875c/uvloop-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9fb766bb57b7388745d8bcc53a359b116b8a04c83a2288069809d2b3466c37e", size = 3960855, upload-time = "2024-10-14T23:37:37.683Z" }, + { url = "https://files.pythonhosted.org/packages/8a/ca/0864176a649838b838f36d44bf31c451597ab363b60dc9e09c9630619d41/uvloop-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a375441696e2eda1c43c44ccb66e04d61ceeffcd76e4929e527b7fa401b90fb", size = 3973185, upload-time = "2024-10-14T23:37:40.226Z" }, + { url = "https://files.pythonhosted.org/packages/30/bf/08ad29979a936d63787ba47a540de2132169f140d54aa25bc8c3df3e67f4/uvloop-0.21.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:baa0e6291d91649c6ba4ed4b2f982f9fa165b5bbd50a9e203c416a2797bab3c6", size = 3820256, upload-time = "2024-10-14T23:37:42.839Z" }, + { url = "https://files.pythonhosted.org/packages/da/e2/5cf6ef37e3daf2f06e651aae5ea108ad30df3cb269102678b61ebf1fdf42/uvloop-0.21.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4509360fcc4c3bd2c70d87573ad472de40c13387f5fda8cb58350a1d7475e58d", size = 3937323, upload-time = "2024-10-14T23:37:45.337Z" }, + { url = "https://files.pythonhosted.org/packages/8c/4c/03f93178830dc7ce8b4cdee1d36770d2f5ebb6f3d37d354e061eefc73545/uvloop-0.21.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:359ec2c888397b9e592a889c4d72ba3d6befba8b2bb01743f72fffbde663b59c", size = 1471284, upload-time = "2024-10-14T23:37:47.833Z" }, + { url = "https://files.pythonhosted.org/packages/43/3e/92c03f4d05e50f09251bd8b2b2b584a2a7f8fe600008bcc4523337abe676/uvloop-0.21.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f7089d2dc73179ce5ac255bdf37c236a9f914b264825fdaacaded6990a7fb4c2", size = 821349, upload-time = "2024-10-14T23:37:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/a6/ef/a02ec5da49909dbbfb1fd205a9a1ac4e88ea92dcae885e7c961847cd51e2/uvloop-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baa4dcdbd9ae0a372f2167a207cd98c9f9a1ea1188a8a526431eef2f8116cc8d", size = 4580089, upload-time = "2024-10-14T23:37:51.703Z" }, + { url = "https://files.pythonhosted.org/packages/06/a7/b4e6a19925c900be9f98bec0a75e6e8f79bb53bdeb891916609ab3958967/uvloop-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86975dca1c773a2c9864f4c52c5a55631038e387b47eaf56210f873887b6c8dc", size = 4693770, upload-time = "2024-10-14T23:37:54.122Z" }, + { url = "https://files.pythonhosted.org/packages/ce/0c/f07435a18a4b94ce6bd0677d8319cd3de61f3a9eeb1e5f8ab4e8b5edfcb3/uvloop-0.21.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:461d9ae6660fbbafedd07559c6a2e57cd553b34b0065b6550685f6653a98c1cb", size = 4451321, upload-time = "2024-10-14T23:37:55.766Z" }, + { url = "https://files.pythonhosted.org/packages/8f/eb/f7032be105877bcf924709c97b1bf3b90255b4ec251f9340cef912559f28/uvloop-0.21.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:183aef7c8730e54c9a3ee3227464daed66e37ba13040bb3f350bc2ddc040f22f", size = 4659022, upload-time = "2024-10-14T23:37:58.195Z" }, { url = "https://files.pythonhosted.org/packages/3f/8d/2cbef610ca21539f0f36e2b34da49302029e7c9f09acef0b1c3b5839412b/uvloop-0.21.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bfd55dfcc2a512316e65f16e503e9e450cab148ef11df4e4e679b5e8253a5281", size = 1468123, upload-time = "2024-10-14T23:38:00.688Z" }, { url = "https://files.pythonhosted.org/packages/93/0d/b0038d5a469f94ed8f2b2fce2434a18396d8fbfb5da85a0a9781ebbdec14/uvloop-0.21.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:787ae31ad8a2856fc4e7c095341cccc7209bd657d0e71ad0dc2ea83c4a6fa8af", size = 819325, upload-time = "2024-10-14T23:38:02.309Z" }, { url = "https://files.pythonhosted.org/packages/50/94/0a687f39e78c4c1e02e3272c6b2ccdb4e0085fda3b8352fecd0410ccf915/uvloop-0.21.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ee4d4ef48036ff6e5cfffb09dd192c7a5027153948d85b8da7ff705065bacc6", size = 4582806, upload-time = "2024-10-14T23:38:04.711Z" }, @@ -1941,6 +2333,32 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/2a/9a/d451fcc97d029f5812e898fd30a53fd8c15c7bbd058fd75cfc6beb9bd761/watchfiles-1.1.0.tar.gz", hash = "sha256:693ed7ec72cbfcee399e92c895362b6e66d63dac6b91e2c11ae03d10d503e575", size = 94406, upload-time = "2025-06-15T19:06:59.42Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/8b/78/7401154b78ab484ccaaeef970dc2af0cb88b5ba8a1b415383da444cdd8d3/watchfiles-1.1.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:c9649dfc57cc1f9835551deb17689e8d44666315f2e82d337b9f07bd76ae3aa2", size = 405751, upload-time = "2025-06-15T19:05:07.679Z" }, + { url = "https://files.pythonhosted.org/packages/76/63/e6c3dbc1f78d001589b75e56a288c47723de28c580ad715eb116639152b5/watchfiles-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:406520216186b99374cdb58bc48e34bb74535adec160c8459894884c983a149c", size = 397313, upload-time = "2025-06-15T19:05:08.764Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a2/8afa359ff52e99af1632f90cbf359da46184207e893a5f179301b0c8d6df/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb45350fd1dc75cd68d3d72c47f5b513cb0578da716df5fba02fff31c69d5f2d", size = 450792, upload-time = "2025-06-15T19:05:09.869Z" }, + { url = "https://files.pythonhosted.org/packages/1d/bf/7446b401667f5c64972a57a0233be1104157fc3abf72c4ef2666c1bd09b2/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:11ee4444250fcbeb47459a877e5e80ed994ce8e8d20283857fc128be1715dac7", size = 458196, upload-time = "2025-06-15T19:05:11.91Z" }, + { url = "https://files.pythonhosted.org/packages/58/2f/501ddbdfa3fa874ea5597c77eeea3d413579c29af26c1091b08d0c792280/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bda8136e6a80bdea23e5e74e09df0362744d24ffb8cd59c4a95a6ce3d142f79c", size = 484788, upload-time = "2025-06-15T19:05:13.373Z" }, + { url = "https://files.pythonhosted.org/packages/61/1e/9c18eb2eb5c953c96bc0e5f626f0e53cfef4bd19bd50d71d1a049c63a575/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b915daeb2d8c1f5cee4b970f2e2c988ce6514aace3c9296e58dd64dc9aa5d575", size = 597879, upload-time = "2025-06-15T19:05:14.725Z" }, + { url = "https://files.pythonhosted.org/packages/8b/6c/1467402e5185d89388b4486745af1e0325007af0017c3384cc786fff0542/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ed8fc66786de8d0376f9f913c09e963c66e90ced9aa11997f93bdb30f7c872a8", size = 477447, upload-time = "2025-06-15T19:05:15.775Z" }, + { url = "https://files.pythonhosted.org/packages/2b/a1/ec0a606bde4853d6c4a578f9391eeb3684a9aea736a8eb217e3e00aa89a1/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe4371595edf78c41ef8ac8df20df3943e13defd0efcb732b2e393b5a8a7a71f", size = 453145, upload-time = "2025-06-15T19:05:17.17Z" }, + { url = "https://files.pythonhosted.org/packages/90/b9/ef6f0c247a6a35d689fc970dc7f6734f9257451aefb30def5d100d6246a5/watchfiles-1.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b7c5f6fe273291f4d414d55b2c80d33c457b8a42677ad14b4b47ff025d0893e4", size = 626539, upload-time = "2025-06-15T19:05:18.557Z" }, + { url = "https://files.pythonhosted.org/packages/34/44/6ffda5537085106ff5aaa762b0d130ac6c75a08015dd1621376f708c94de/watchfiles-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7738027989881e70e3723c75921f1efa45225084228788fc59ea8c6d732eb30d", size = 624472, upload-time = "2025-06-15T19:05:19.588Z" }, + { url = "https://files.pythonhosted.org/packages/c3/e3/71170985c48028fa3f0a50946916a14055e741db11c2e7bc2f3b61f4d0e3/watchfiles-1.1.0-cp311-cp311-win32.whl", hash = "sha256:622d6b2c06be19f6e89b1d951485a232e3b59618def88dbeda575ed8f0d8dbf2", size = 279348, upload-time = "2025-06-15T19:05:20.856Z" }, + { url = "https://files.pythonhosted.org/packages/89/1b/3e39c68b68a7a171070f81fc2561d23ce8d6859659406842a0e4bebf3bba/watchfiles-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:48aa25e5992b61debc908a61ab4d3f216b64f44fdaa71eb082d8b2de846b7d12", size = 292607, upload-time = "2025-06-15T19:05:21.937Z" }, + { url = "https://files.pythonhosted.org/packages/61/9f/2973b7539f2bdb6ea86d2c87f70f615a71a1fc2dba2911795cea25968aea/watchfiles-1.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:00645eb79a3faa70d9cb15c8d4187bb72970b2470e938670240c7998dad9f13a", size = 285056, upload-time = "2025-06-15T19:05:23.12Z" }, + { url = "https://files.pythonhosted.org/packages/f6/b8/858957045a38a4079203a33aaa7d23ea9269ca7761c8a074af3524fbb240/watchfiles-1.1.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9dc001c3e10de4725c749d4c2f2bdc6ae24de5a88a339c4bce32300a31ede179", size = 402339, upload-time = "2025-06-15T19:05:24.516Z" }, + { url = "https://files.pythonhosted.org/packages/80/28/98b222cca751ba68e88521fabd79a4fab64005fc5976ea49b53fa205d1fa/watchfiles-1.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d9ba68ec283153dead62cbe81872d28e053745f12335d037de9cbd14bd1877f5", size = 394409, upload-time = "2025-06-15T19:05:25.469Z" }, + { url = "https://files.pythonhosted.org/packages/86/50/dee79968566c03190677c26f7f47960aff738d32087087bdf63a5473e7df/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130fc497b8ee68dce163e4254d9b0356411d1490e868bd8790028bc46c5cc297", size = 450939, upload-time = "2025-06-15T19:05:26.494Z" }, + { url = "https://files.pythonhosted.org/packages/40/45/a7b56fb129700f3cfe2594a01aa38d033b92a33dddce86c8dfdfc1247b72/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:50a51a90610d0845a5931a780d8e51d7bd7f309ebc25132ba975aca016b576a0", size = 457270, upload-time = "2025-06-15T19:05:27.466Z" }, + { url = "https://files.pythonhosted.org/packages/b5/c8/fa5ef9476b1d02dc6b5e258f515fcaaecf559037edf8b6feffcbc097c4b8/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc44678a72ac0910bac46fa6a0de6af9ba1355669b3dfaf1ce5f05ca7a74364e", size = 483370, upload-time = "2025-06-15T19:05:28.548Z" }, + { url = "https://files.pythonhosted.org/packages/98/68/42cfcdd6533ec94f0a7aab83f759ec11280f70b11bfba0b0f885e298f9bd/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a543492513a93b001975ae283a51f4b67973662a375a403ae82f420d2c7205ee", size = 598654, upload-time = "2025-06-15T19:05:29.997Z" }, + { url = "https://files.pythonhosted.org/packages/d3/74/b2a1544224118cc28df7e59008a929e711f9c68ce7d554e171b2dc531352/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ac164e20d17cc285f2b94dc31c384bc3aa3dd5e7490473b3db043dd70fbccfd", size = 478667, upload-time = "2025-06-15T19:05:31.172Z" }, + { url = "https://files.pythonhosted.org/packages/8c/77/e3362fe308358dc9f8588102481e599c83e1b91c2ae843780a7ded939a35/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7590d5a455321e53857892ab8879dce62d1f4b04748769f5adf2e707afb9d4f", size = 452213, upload-time = "2025-06-15T19:05:32.299Z" }, + { url = "https://files.pythonhosted.org/packages/6e/17/c8f1a36540c9a1558d4faf08e909399e8133599fa359bf52ec8fcee5be6f/watchfiles-1.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:37d3d3f7defb13f62ece99e9be912afe9dd8a0077b7c45ee5a57c74811d581a4", size = 626718, upload-time = "2025-06-15T19:05:33.415Z" }, + { url = "https://files.pythonhosted.org/packages/26/45/fb599be38b4bd38032643783d7496a26a6f9ae05dea1a42e58229a20ac13/watchfiles-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7080c4bb3efd70a07b1cc2df99a7aa51d98685be56be6038c3169199d0a1c69f", size = 623098, upload-time = "2025-06-15T19:05:34.534Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e7/fdf40e038475498e160cd167333c946e45d8563ae4dd65caf757e9ffe6b4/watchfiles-1.1.0-cp312-cp312-win32.whl", hash = "sha256:cbcf8630ef4afb05dc30107bfa17f16c0896bb30ee48fc24bf64c1f970f3b1fd", size = 279209, upload-time = "2025-06-15T19:05:35.577Z" }, + { url = "https://files.pythonhosted.org/packages/3f/d3/3ae9d5124ec75143bdf088d436cba39812122edc47709cd2caafeac3266f/watchfiles-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:cbd949bdd87567b0ad183d7676feb98136cde5bb9025403794a4c0db28ed3a47", size = 292786, upload-time = "2025-06-15T19:05:36.559Z" }, + { url = "https://files.pythonhosted.org/packages/26/2f/7dd4fc8b5f2b34b545e19629b4a018bfb1de23b3a496766a2c1165ca890d/watchfiles-1.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:0a7d40b77f07be87c6faa93d0951a0fcd8cbca1ddff60a1b65d741bac6f3a9f6", size = 284343, upload-time = "2025-06-15T19:05:37.5Z" }, { url = "https://files.pythonhosted.org/packages/d3/42/fae874df96595556a9089ade83be34a2e04f0f11eb53a8dbf8a8a5e562b4/watchfiles-1.1.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5007f860c7f1f8df471e4e04aaa8c43673429047d63205d1630880f7637bca30", size = 402004, upload-time = "2025-06-15T19:05:38.499Z" }, { url = "https://files.pythonhosted.org/packages/fa/55/a77e533e59c3003d9803c09c44c3651224067cbe7fb5d574ddbaa31e11ca/watchfiles-1.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:20ecc8abbd957046f1fe9562757903f5eaf57c3bce70929fda6c7711bb58074a", size = 393671, upload-time = "2025-06-15T19:05:39.52Z" }, { url = "https://files.pythonhosted.org/packages/05/68/b0afb3f79c8e832e6571022611adbdc36e35a44e14f129ba09709aa4bb7a/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2f0498b7d2a3c072766dba3274fe22a183dbea1f99d188f1c6c72209a1063dc", size = 449772, upload-time = "2025-06-15T19:05:40.897Z" }, @@ -1984,6 +2402,10 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/69/c4/088825b75489cb5b6a761a4542645718893d395d8c530b38734f19da44d2/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d05686b5487cfa2e2c28ff1aa370ea3e6c5accfe6435944ddea1e10d93872147", size = 452240, upload-time = "2025-06-15T19:06:26.552Z" }, { url = "https://files.pythonhosted.org/packages/10/8c/22b074814970eeef43b7c44df98c3e9667c1f7bf5b83e0ff0201b0bd43f9/watchfiles-1.1.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:d0e10e6f8f6dc5762adee7dece33b722282e1f59aa6a55da5d493a97282fedd8", size = 625607, upload-time = "2025-06-15T19:06:27.606Z" }, { url = "https://files.pythonhosted.org/packages/32/fa/a4f5c2046385492b2273213ef815bf71a0d4c1943b784fb904e184e30201/watchfiles-1.1.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:af06c863f152005c7592df1d6a7009c836a247c9d8adb78fef8575a5a98699db", size = 623315, upload-time = "2025-06-15T19:06:29.076Z" }, + { url = "https://files.pythonhosted.org/packages/8c/6b/686dcf5d3525ad17b384fd94708e95193529b460a1b7bf40851f1328ec6e/watchfiles-1.1.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0ece16b563b17ab26eaa2d52230c9a7ae46cf01759621f4fbbca280e438267b3", size = 406910, upload-time = "2025-06-15T19:06:49.335Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d3/71c2dcf81dc1edcf8af9f4d8d63b1316fb0a2dd90cbfd427e8d9dd584a90/watchfiles-1.1.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:51b81e55d40c4b4aa8658427a3ee7ea847c591ae9e8b81ef94a90b668999353c", size = 398816, upload-time = "2025-06-15T19:06:50.433Z" }, + { url = "https://files.pythonhosted.org/packages/b8/fa/12269467b2fc006f8fce4cd6c3acfa77491dd0777d2a747415f28ccc8c60/watchfiles-1.1.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2bcdc54ea267fe72bfc7d83c041e4eb58d7d8dc6f578dfddb52f037ce62f432", size = 451584, upload-time = "2025-06-15T19:06:51.834Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d3/254cea30f918f489db09d6a8435a7de7047f8cb68584477a515f160541d6/watchfiles-1.1.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:923fec6e5461c42bd7e3fd5ec37492c6f3468be0499bc0707b4bbbc16ac21792", size = 454009, upload-time = "2025-06-15T19:06:52.896Z" }, ] [[package]] @@ -1992,6 +2414,28 @@ version = "15.0.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/32/18fcd5919c293a398db67443acd33fde142f283853076049824fc58e6f75/websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431", size = 175423, upload-time = "2025-03-05T20:01:56.276Z" }, + { url = "https://files.pythonhosted.org/packages/76/70/ba1ad96b07869275ef42e2ce21f07a5b0148936688c2baf7e4a1f60d5058/websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57", size = 173082, upload-time = "2025-03-05T20:01:57.563Z" }, + { url = "https://files.pythonhosted.org/packages/86/f2/10b55821dd40eb696ce4704a87d57774696f9451108cff0d2824c97e0f97/websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905", size = 173330, upload-time = "2025-03-05T20:01:59.063Z" }, + { url = "https://files.pythonhosted.org/packages/a5/90/1c37ae8b8a113d3daf1065222b6af61cc44102da95388ac0018fcb7d93d9/websockets-15.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562", size = 182878, upload-time = "2025-03-05T20:02:00.305Z" }, + { url = "https://files.pythonhosted.org/packages/8e/8d/96e8e288b2a41dffafb78e8904ea7367ee4f891dafc2ab8d87e2124cb3d3/websockets-15.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792", size = 181883, upload-time = "2025-03-05T20:02:03.148Z" }, + { url = "https://files.pythonhosted.org/packages/93/1f/5d6dbf551766308f6f50f8baf8e9860be6182911e8106da7a7f73785f4c4/websockets-15.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413", size = 182252, upload-time = "2025-03-05T20:02:05.29Z" }, + { url = "https://files.pythonhosted.org/packages/d4/78/2d4fed9123e6620cbf1706c0de8a1632e1a28e7774d94346d7de1bba2ca3/websockets-15.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8", size = 182521, upload-time = "2025-03-05T20:02:07.458Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3b/66d4c1b444dd1a9823c4a81f50231b921bab54eee2f69e70319b4e21f1ca/websockets-15.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3", size = 181958, upload-time = "2025-03-05T20:02:09.842Z" }, + { url = "https://files.pythonhosted.org/packages/08/ff/e9eed2ee5fed6f76fdd6032ca5cd38c57ca9661430bb3d5fb2872dc8703c/websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf", size = 181918, upload-time = "2025-03-05T20:02:11.968Z" }, + { url = "https://files.pythonhosted.org/packages/d8/75/994634a49b7e12532be6a42103597b71098fd25900f7437d6055ed39930a/websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85", size = 176388, upload-time = "2025-03-05T20:02:13.32Z" }, + { url = "https://files.pythonhosted.org/packages/98/93/e36c73f78400a65f5e236cd376713c34182e6663f6889cd45a4a04d8f203/websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065", size = 176828, upload-time = "2025-03-05T20:02:14.585Z" }, + { url = "https://files.pythonhosted.org/packages/51/6b/4545a0d843594f5d0771e86463606a3988b5a09ca5123136f8a76580dd63/websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3", size = 175437, upload-time = "2025-03-05T20:02:16.706Z" }, + { url = "https://files.pythonhosted.org/packages/f4/71/809a0f5f6a06522af902e0f2ea2757f71ead94610010cf570ab5c98e99ed/websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665", size = 173096, upload-time = "2025-03-05T20:02:18.832Z" }, + { url = "https://files.pythonhosted.org/packages/3d/69/1a681dd6f02180916f116894181eab8b2e25b31e484c5d0eae637ec01f7c/websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2", size = 173332, upload-time = "2025-03-05T20:02:20.187Z" }, + { url = "https://files.pythonhosted.org/packages/a6/02/0073b3952f5bce97eafbb35757f8d0d54812b6174ed8dd952aa08429bcc3/websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215", size = 183152, upload-time = "2025-03-05T20:02:22.286Z" }, + { url = "https://files.pythonhosted.org/packages/74/45/c205c8480eafd114b428284840da0b1be9ffd0e4f87338dc95dc6ff961a1/websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5", size = 182096, upload-time = "2025-03-05T20:02:24.368Z" }, + { url = "https://files.pythonhosted.org/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65", size = 182523, upload-time = "2025-03-05T20:02:25.669Z" }, + { url = "https://files.pythonhosted.org/packages/ec/6d/0267396610add5bc0d0d3e77f546d4cd287200804fe02323797de77dbce9/websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe", size = 182790, upload-time = "2025-03-05T20:02:26.99Z" }, + { url = "https://files.pythonhosted.org/packages/02/05/c68c5adbf679cf610ae2f74a9b871ae84564462955d991178f95a1ddb7dd/websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4", size = 182165, upload-time = "2025-03-05T20:02:30.291Z" }, + { url = "https://files.pythonhosted.org/packages/29/93/bb672df7b2f5faac89761cb5fa34f5cec45a4026c383a4b5761c6cea5c16/websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597", size = 182160, upload-time = "2025-03-05T20:02:31.634Z" }, + { url = "https://files.pythonhosted.org/packages/ff/83/de1f7709376dc3ca9b7eeb4b9a07b4526b14876b6d372a4dc62312bebee0/websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9", size = 176395, upload-time = "2025-03-05T20:02:33.017Z" }, + { url = "https://files.pythonhosted.org/packages/7d/71/abf2ebc3bbfa40f391ce1428c7168fb20582d0ff57019b69ea20fa698043/websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7", size = 176841, upload-time = "2025-03-05T20:02:34.498Z" }, { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload-time = "2025-03-05T20:02:36.695Z" }, { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload-time = "2025-03-05T20:02:37.985Z" }, { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload-time = "2025-03-05T20:02:39.298Z" }, @@ -2024,6 +2468,26 @@ version = "1.17.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/95/8f/aeb76c5b46e273670962298c23e7ddde79916cb74db802131d49a85e4b7d/wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0", size = 55547, upload-time = "2025-08-12T05:53:21.714Z" } wheels = [ + { url = "https://files.pythonhosted.org/packages/52/db/00e2a219213856074a213503fdac0511203dceefff26e1daa15250cc01a0/wrapt-1.17.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7", size = 53482, upload-time = "2025-08-12T05:51:45.79Z" }, + { url = "https://files.pythonhosted.org/packages/5e/30/ca3c4a5eba478408572096fe9ce36e6e915994dd26a4e9e98b4f729c06d9/wrapt-1.17.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85", size = 38674, upload-time = "2025-08-12T05:51:34.629Z" }, + { url = "https://files.pythonhosted.org/packages/31/25/3e8cc2c46b5329c5957cec959cb76a10718e1a513309c31399a4dad07eb3/wrapt-1.17.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f", size = 38959, upload-time = "2025-08-12T05:51:56.074Z" }, + { url = "https://files.pythonhosted.org/packages/5d/8f/a32a99fc03e4b37e31b57cb9cefc65050ea08147a8ce12f288616b05ef54/wrapt-1.17.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311", size = 82376, upload-time = "2025-08-12T05:52:32.134Z" }, + { url = "https://files.pythonhosted.org/packages/31/57/4930cb8d9d70d59c27ee1332a318c20291749b4fba31f113c2f8ac49a72e/wrapt-1.17.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1", size = 83604, upload-time = "2025-08-12T05:52:11.663Z" }, + { url = "https://files.pythonhosted.org/packages/a8/f3/1afd48de81d63dd66e01b263a6fbb86e1b5053b419b9b33d13e1f6d0f7d0/wrapt-1.17.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5", size = 82782, upload-time = "2025-08-12T05:52:12.626Z" }, + { url = "https://files.pythonhosted.org/packages/1e/d7/4ad5327612173b144998232f98a85bb24b60c352afb73bc48e3e0d2bdc4e/wrapt-1.17.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2", size = 82076, upload-time = "2025-08-12T05:52:33.168Z" }, + { url = "https://files.pythonhosted.org/packages/bb/59/e0adfc831674a65694f18ea6dc821f9fcb9ec82c2ce7e3d73a88ba2e8718/wrapt-1.17.3-cp311-cp311-win32.whl", hash = "sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89", size = 36457, upload-time = "2025-08-12T05:53:03.936Z" }, + { url = "https://files.pythonhosted.org/packages/83/88/16b7231ba49861b6f75fc309b11012ede4d6b0a9c90969d9e0db8d991aeb/wrapt-1.17.3-cp311-cp311-win_amd64.whl", hash = "sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77", size = 38745, upload-time = "2025-08-12T05:53:02.885Z" }, + { url = "https://files.pythonhosted.org/packages/9a/1e/c4d4f3398ec073012c51d1c8d87f715f56765444e1a4b11e5180577b7e6e/wrapt-1.17.3-cp311-cp311-win_arm64.whl", hash = "sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a", size = 36806, upload-time = "2025-08-12T05:52:53.368Z" }, + { url = "https://files.pythonhosted.org/packages/9f/41/cad1aba93e752f1f9268c77270da3c469883d56e2798e7df6240dcb2287b/wrapt-1.17.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0", size = 53998, upload-time = "2025-08-12T05:51:47.138Z" }, + { url = "https://files.pythonhosted.org/packages/60/f8/096a7cc13097a1869fe44efe68dace40d2a16ecb853141394047f0780b96/wrapt-1.17.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba", size = 39020, upload-time = "2025-08-12T05:51:35.906Z" }, + { url = "https://files.pythonhosted.org/packages/33/df/bdf864b8997aab4febb96a9ae5c124f700a5abd9b5e13d2a3214ec4be705/wrapt-1.17.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd", size = 39098, upload-time = "2025-08-12T05:51:57.474Z" }, + { url = "https://files.pythonhosted.org/packages/9f/81/5d931d78d0eb732b95dc3ddaeeb71c8bb572fb01356e9133916cd729ecdd/wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828", size = 88036, upload-time = "2025-08-12T05:52:34.784Z" }, + { url = "https://files.pythonhosted.org/packages/ca/38/2e1785df03b3d72d34fc6252d91d9d12dc27a5c89caef3335a1bbb8908ca/wrapt-1.17.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9", size = 88156, upload-time = "2025-08-12T05:52:13.599Z" }, + { url = "https://files.pythonhosted.org/packages/b3/8b/48cdb60fe0603e34e05cffda0b2a4adab81fd43718e11111a4b0100fd7c1/wrapt-1.17.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396", size = 87102, upload-time = "2025-08-12T05:52:14.56Z" }, + { url = "https://files.pythonhosted.org/packages/3c/51/d81abca783b58f40a154f1b2c56db1d2d9e0d04fa2d4224e357529f57a57/wrapt-1.17.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc", size = 87732, upload-time = "2025-08-12T05:52:36.165Z" }, + { url = "https://files.pythonhosted.org/packages/9e/b1/43b286ca1392a006d5336412d41663eeef1ad57485f3e52c767376ba7e5a/wrapt-1.17.3-cp312-cp312-win32.whl", hash = "sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe", size = 36705, upload-time = "2025-08-12T05:53:07.123Z" }, + { url = "https://files.pythonhosted.org/packages/28/de/49493f962bd3c586ab4b88066e967aa2e0703d6ef2c43aa28cb83bf7b507/wrapt-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c", size = 38877, upload-time = "2025-08-12T05:53:05.436Z" }, + { url = "https://files.pythonhosted.org/packages/f1/48/0f7102fe9cb1e8a5a77f80d4f0956d62d97034bbe88d33e94699f99d181d/wrapt-1.17.3-cp312-cp312-win_arm64.whl", hash = "sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6", size = 36885, upload-time = "2025-08-12T05:52:54.367Z" }, { url = "https://files.pythonhosted.org/packages/fc/f6/759ece88472157acb55fc195e5b116e06730f1b651b5b314c66291729193/wrapt-1.17.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0", size = 54003, upload-time = "2025-08-12T05:51:48.627Z" }, { url = "https://files.pythonhosted.org/packages/4f/a9/49940b9dc6d47027dc850c116d79b4155f15c08547d04db0f07121499347/wrapt-1.17.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77", size = 39025, upload-time = "2025-08-12T05:51:37.156Z" }, { url = "https://files.pythonhosted.org/packages/45/35/6a08de0f2c96dcdd7fe464d7420ddb9a7655a6561150e5fc4da9356aeaab/wrapt-1.17.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7", size = 39108, upload-time = "2025-08-12T05:51:58.425Z" }, diff --git a/e2e/cases/uv-deps-650/crossbuild/BUILD.bazel b/e2e/cases/uv-deps-650/crossbuild/BUILD.bazel index 6c3df4f3..42eeefea 100644 --- a/e2e/cases/uv-deps-650/crossbuild/BUILD.bazel +++ b/e2e/cases/uv-deps-650/crossbuild/BUILD.bazel @@ -2,7 +2,6 @@ load("@aspect_rules_py//py:defs.bzl", "py_image_layer") load("@aspect_rules_py//py/unstable:defs.bzl", "py_venv_binary") load("@bazel_lib//lib:transitions.bzl", "platform_transition_filegroup") load("@rules_oci//oci:defs.bzl", "oci_image", "oci_image_index") -load("//cases/oci/py_image_layer:asserts.bzl", "assert_tar_listing") platform( name = "arm64_linux", @@ -56,24 +55,12 @@ platform_transition_filegroup( target_platform = ":amd64_linux", ) -assert_tar_listing( - name = "app_amd64_layers", - actual = [":amd64_layers"], - expected = ":app_amd64_layers_listing.yaml", -) - platform_transition_filegroup( name = "arm64_layers", srcs = [":app_layers"], target_platform = ":arm64_linux", ) -assert_tar_listing( - name = "app_arm64_layers", - actual = [":arm64_layers"], - expected = ":app_arm64_layers_listing.yaml", -) - oci_image( name = "image", # This is defined by an oci.pull() call in /MODULE.bazel diff --git a/e2e/cases/uv-deps-650/crossbuild/pyproject.toml b/e2e/cases/uv-deps-650/crossbuild/pyproject.toml new file mode 100644 index 00000000..7310d14c --- /dev/null +++ b/e2e/cases/uv-deps-650/crossbuild/pyproject.toml @@ -0,0 +1,9 @@ +[project] +name = "crossbuild" +version = "0.0.0" +authors = [] +dependencies = [ + "psycopg2-binary", + "setuptools", + "build", +] diff --git a/e2e/cases/uv-deps-650/crossbuild/uv.lock b/e2e/cases/uv-deps-650/crossbuild/uv.lock index ec0beb47..d1847b17 100644 --- a/e2e/cases/uv-deps-650/crossbuild/uv.lock +++ b/e2e/cases/uv-deps-650/crossbuild/uv.lock @@ -1,17 +1,55 @@ version = 1 revision = 3 -requires-python = ">=3.9" +requires-python = ">=3.11" [[package]] -name = "lockfiles-c" -version = "0.1.0" +name = "build" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "os_name == 'nt'" }, + { name = "packaging" }, + { name = "pyproject-hooks" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/18/94eaffda7b329535d91f00fe605ab1f1e5cd68b2074d03f255c7d250687d/build-1.4.0.tar.gz", hash = "sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936", size = 50054, upload-time = "2026-01-08T16:41:47.696Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl", hash = "sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596", size = 24141, upload-time = "2026-01-08T16:41:46.453Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "crossbuild" +version = "0.0.0" source = { virtual = "." } dependencies = [ + { name = "build" }, { name = "psycopg2-binary" }, + { name = "setuptools" }, ] [package.metadata] -requires-dist = [{ name = "psycopg2-binary", specifier = "~=2.9.0" }] +requires-dist = [ + { name = "build" }, + { name = "psycopg2-binary" }, + { name = "setuptools" }, +] + +[[package]] +name = "packaging" +version = "26.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, +] [[package]] name = "psycopg2-binary" @@ -19,17 +57,6 @@ version = "2.9.11" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ac/6c/8767aaa597ba424643dc87348c6f1754dd9f48e80fdc1b9f7ca5c3a7c213/psycopg2-binary-2.9.11.tar.gz", hash = "sha256:b6aed9e096bf63f9e75edf2581aa9a7e7186d97ab5c177aa6c87797cd591236c", size = 379620, upload-time = "2025-10-10T11:14:48.041Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/f2/8e377d29c2ecf99f6062d35ea606b036e8800720eccfec5fe3dd672c2b24/psycopg2_binary-2.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d6fe6b47d0b42ce1c9f1fa3e35bb365011ca22e39db37074458f27921dca40f2", size = 3756506, upload-time = "2025-10-10T11:10:30.144Z" }, - { url = "https://files.pythonhosted.org/packages/24/cc/dc143ea88e4ec9d386106cac05023b69668bd0be20794c613446eaefafe5/psycopg2_binary-2.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a6c0e4262e089516603a09474ee13eabf09cb65c332277e39af68f6233911087", size = 3863943, upload-time = "2025-10-10T11:10:34.586Z" }, - { url = "https://files.pythonhosted.org/packages/8c/df/16848771155e7c419c60afeb24950b8aaa3ab09c0a091ec3ccca26a574d0/psycopg2_binary-2.9.11-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c47676e5b485393f069b4d7a811267d3168ce46f988fa602658b8bb901e9e64d", size = 4410873, upload-time = "2025-10-10T11:10:38.951Z" }, - { url = "https://files.pythonhosted.org/packages/43/79/5ef5f32621abd5a541b89b04231fe959a9b327c874a1d41156041c75494b/psycopg2_binary-2.9.11-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:a28d8c01a7b27a1e3265b11250ba7557e5f72b5ee9e5f3a2fa8d2949c29bf5d2", size = 4468016, upload-time = "2025-10-10T11:10:43.319Z" }, - { url = "https://files.pythonhosted.org/packages/f0/9b/d7542d0f7ad78f57385971f426704776d7b310f5219ed58da5d605b1892e/psycopg2_binary-2.9.11-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5f3f2732cf504a1aa9e9609d02f79bea1067d99edf844ab92c247bbca143303b", size = 4164996, upload-time = "2025-10-10T11:10:46.705Z" }, - { url = "https://files.pythonhosted.org/packages/14/ed/e409388b537fa7414330687936917c522f6a77a13474e4238219fcfd9a84/psycopg2_binary-2.9.11-cp310-cp310-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:865f9945ed1b3950d968ec4690ce68c55019d79e4497366d36e090327ce7db14", size = 3981881, upload-time = "2025-10-30T02:54:57.182Z" }, - { url = "https://files.pythonhosted.org/packages/bf/30/50e330e63bb05efc6fa7c1447df3e08954894025ca3dcb396ecc6739bc26/psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:91537a8df2bde69b1c1db01d6d944c831ca793952e4f57892600e96cee95f2cd", size = 3650857, upload-time = "2025-10-10T11:10:50.112Z" }, - { url = "https://files.pythonhosted.org/packages/f0/e0/4026e4c12bb49dd028756c5b0bc4c572319f2d8f1c9008e0dad8cc9addd7/psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4dca1f356a67ecb68c81a7bc7809f1569ad9e152ce7fd02c2f2036862ca9f66b", size = 3296063, upload-time = "2025-10-10T11:10:54.089Z" }, - { url = "https://files.pythonhosted.org/packages/2c/34/eb172be293c886fef5299fe5c3fcf180a05478be89856067881007934a7c/psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:0da4de5c1ac69d94ed4364b6cbe7190c1a70d325f112ba783d83f8440285f152", size = 3043464, upload-time = "2025-10-30T02:55:02.483Z" }, - { url = "https://files.pythonhosted.org/packages/18/1c/532c5d2cb11986372f14b798a95f2eaafe5779334f6a80589a68b5fcf769/psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37d8412565a7267f7d79e29ab66876e55cb5e8e7b3bbf94f8206f6795f8f7e7e", size = 3345378, upload-time = "2025-10-10T11:11:01.039Z" }, - { url = "https://files.pythonhosted.org/packages/70/e7/de420e1cf16f838e1fa17b1120e83afff374c7c0130d088dba6286fcf8ea/psycopg2_binary-2.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:c665f01ec8ab273a61c62beeb8cce3014c214429ced8a308ca1fc410ecac3a39", size = 2713904, upload-time = "2025-10-10T11:11:04.81Z" }, { url = "https://files.pythonhosted.org/packages/c7/ae/8d8266f6dd183ab4d48b95b9674034e1b482a3f8619b33a0d86438694577/psycopg2_binary-2.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0e8480afd62362d0a6a27dd09e4ca2def6fa50ed3a4e7c09165266106b2ffa10", size = 3756452, upload-time = "2025-10-10T11:11:11.583Z" }, { url = "https://files.pythonhosted.org/packages/4b/34/aa03d327739c1be70e09d01182619aca8ebab5970cd0cfa50dd8b9cec2ac/psycopg2_binary-2.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:763c93ef1df3da6d1a90f86ea7f3f806dc06b21c198fa87c3c25504abec9404a", size = 3863957, upload-time = "2025-10-10T11:11:16.932Z" }, { url = "https://files.pythonhosted.org/packages/48/89/3fdb5902bdab8868bbedc1c6e6023a4e08112ceac5db97fc2012060e0c9a/psycopg2_binary-2.9.11-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2e164359396576a3cc701ba8af4751ae68a07235d7a380c631184a611220d9a4", size = 4410955, upload-time = "2025-10-10T11:11:21.21Z" }, @@ -74,15 +101,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/97/77/21b0ea2e1a73aa5fa9222b2a6b8ba325c43c3a8d54272839c991f2345656/psycopg2_binary-2.9.11-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:32770a4d666fbdafab017086655bcddab791d7cb260a16679cc5a7338b64343b", size = 3044737, upload-time = "2025-10-30T02:55:35.69Z" }, { url = "https://files.pythonhosted.org/packages/67/69/f36abe5f118c1dca6d3726ceae164b9356985805480731ac6712a63f24f0/psycopg2_binary-2.9.11-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c3cb3a676873d7506825221045bd70e0427c905b9c8ee8d6acd70cfcbd6e576d", size = 3347643, upload-time = "2025-10-10T11:13:53.499Z" }, { url = "https://files.pythonhosted.org/packages/e1/36/9c0c326fe3a4227953dfb29f5d0c8ae3b8eb8c1cd2967aa569f50cb3c61f/psycopg2_binary-2.9.11-cp314-cp314-win_amd64.whl", hash = "sha256:4012c9c954dfaccd28f94e84ab9f94e12df76b4afb22331b1f0d3154893a6316", size = 2803913, upload-time = "2025-10-10T11:13:57.058Z" }, - { url = "https://files.pythonhosted.org/packages/b2/41/cb36a61146b3afed03e980477f6dd29c0263f15e4b4844660501a774dc0b/psycopg2_binary-2.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:20e7fb94e20b03dcc783f76c0865f9da39559dcc0c28dd1a3fce0d01902a6b9c", size = 3756418, upload-time = "2025-10-10T11:14:00.728Z" }, - { url = "https://files.pythonhosted.org/packages/f4/e3/8623be505c8921727277f22753092835b559543b078e83378bb74712dbc8/psycopg2_binary-2.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4bdab48575b6f870f465b397c38f1b415520e9879fdf10a53ee4f49dcbdf8a21", size = 3863981, upload-time = "2025-10-10T11:14:05.215Z" }, - { url = "https://files.pythonhosted.org/packages/bc/86/ec3682dc3550c65eff80384f603a6a55b798e1b86ccef262d454d19f96eb/psycopg2_binary-2.9.11-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9d3a9edcfbe77a3ed4bc72836d466dfce4174beb79eda79ea155cc77237ed9e8", size = 4410882, upload-time = "2025-10-10T11:14:09.552Z" }, - { url = "https://files.pythonhosted.org/packages/41/af/540ee7d56fb33408c57240d55904c95e4a30952c096f5e1542769cadc787/psycopg2_binary-2.9.11-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:44fc5c2b8fa871ce7f0023f619f1349a0aa03a0857f2c96fbc01c657dcbbdb49", size = 4468062, upload-time = "2025-10-10T11:14:15.225Z" }, - { url = "https://files.pythonhosted.org/packages/b4/d5/b95d47b2e67b2adfaba517c803a99a1ac41e84c8201d0f3b29d77b56e357/psycopg2_binary-2.9.11-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9c55460033867b4622cda1b6872edf445809535144152e5d14941ef591980edf", size = 4165036, upload-time = "2025-10-10T11:14:21.209Z" }, - { url = "https://files.pythonhosted.org/packages/af/f9/99e39882b70d9b0cfdcbad33bea2e5823843c3a7839c1aaf89fc1337c05c/psycopg2_binary-2.9.11-cp39-cp39-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:2d11098a83cca92deaeaed3d58cfd150d49b3b06ee0d0852be466bf87596899e", size = 3981901, upload-time = "2025-10-30T02:55:39.325Z" }, - { url = "https://files.pythonhosted.org/packages/de/c3/8d2c97f1dfddedf5a06c6ad2eda83fba48555a7bc525c3150aedc6f2bedc/psycopg2_binary-2.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:691c807d94aecfbc76a14e1408847d59ff5b5906a04a23e12a89007672b9e819", size = 3650995, upload-time = "2025-10-10T11:14:27.733Z" }, - { url = "https://files.pythonhosted.org/packages/9c/89/afdf59b44b84ebb28111652485fab608429389f4051d22bc5a7bb43d5208/psycopg2_binary-2.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:8b81627b691f29c4c30a8f322546ad039c40c328373b11dff7490a3e1b517855", size = 3296106, upload-time = "2025-10-10T11:14:33.312Z" }, - { url = "https://files.pythonhosted.org/packages/94/21/851c9ecf0e9a699907d1c455dbbde7ef9b11dba28e7b7b132c7bb28391f2/psycopg2_binary-2.9.11-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:b637d6d941209e8d96a072d7977238eea128046effbf37d1d8b2c0764750017d", size = 3043491, upload-time = "2025-10-30T02:55:42.228Z" }, - { url = "https://files.pythonhosted.org/packages/9c/de/50f6eced439e7a131b268276c4b68cf8800fd55d8cef7b37109c44bf957a/psycopg2_binary-2.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:41360b01c140c2a03d346cec3280cf8a71aa07d94f3b1509fa0161c366af66b4", size = 3345816, upload-time = "2025-10-10T11:14:38.648Z" }, - { url = "https://files.pythonhosted.org/packages/45/3b/e0506f199dc8a90ff3b462f261f45d15c0703bb8c59f0da1add5f0c11a30/psycopg2_binary-2.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:875039274f8a2361e5207857899706da840768e2a775bf8c65e82f60b197df02", size = 2714968, upload-time = "2025-10-10T11:14:43.24Z" }, +] + +[[package]] +name = "pyproject-hooks" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/82/28175b2414effca1cdac8dc99f76d660e7a4fb0ceefa4b4ab8f5f6742925/pyproject_hooks-1.2.0.tar.gz", hash = "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8", size = 19228, upload-time = "2024-09-29T09:24:13.293Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl", hash = "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913", size = 10216, upload-time = "2024-09-29T09:24:11.978Z" }, +] + +[[package]] +name = "setuptools" +version = "80.10.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/95/faf61eb8363f26aa7e1d762267a8d602a1b26d4f3a1e758e92cb3cb8b054/setuptools-80.10.2.tar.gz", hash = "sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70", size = 1200343, upload-time = "2026-01-25T22:38:17.252Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/b8/f1f62a5e3c0ad2ff1d189590bfa4c46b4f3b6e49cef6f26c6ee4e575394d/setuptools-80.10.2-py3-none-any.whl", hash = "sha256:95b30ddfb717250edb492926c92b5221f7ef3fbcc2b07579bcd4a27da21d0173", size = 1064234, upload-time = "2026-01-25T22:38:15.216Z" }, ] diff --git a/e2e/cases/uv-deps-650/extras/BUILD.bazel b/e2e/cases/uv-deps-650/extras/BUILD.bazel new file mode 100644 index 00000000..9c3724d1 --- /dev/null +++ b/e2e/cases/uv-deps-650/extras/BUILD.bazel @@ -0,0 +1,14 @@ +load("@aspect_rules_py//py/unstable:defs.bzl", "py_venv_test") + +py_venv_test( + name = "extras", + srcs = [ + "__test__.py", + ], + main = "__test__.py", + python_version = "3.11", + venv = "extras", + deps = [ + "@pypi//requests", + ], +) diff --git a/e2e/cases/uv-deps-650/extras/__test__.py b/e2e/cases/uv-deps-650/extras/__test__.py new file mode 100644 index 00000000..ea05b656 --- /dev/null +++ b/e2e/cases/uv-deps-650/extras/__test__.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +# Explicit dep +import requests +print(requests.__file__) + +# Implied dep of urllib +import urllib3 +print(urllib3.__file__) + +# Implied dep via urllib3[brotli] +import brotli +print(brotli.__file__) diff --git a/e2e/cases/uv-deps-650/extras/pyproject.toml b/e2e/cases/uv-deps-650/extras/pyproject.toml new file mode 100644 index 00000000..90357f78 --- /dev/null +++ b/e2e/cases/uv-deps-650/extras/pyproject.toml @@ -0,0 +1,15 @@ +[project] +name = "extras" +version = "0.0.0" +authors = [] +dependencies = [ + "requests", + "urllib3[brotli]", # Activate an extra +] + +[dependency-groups] +extras = [ + "extras", + "build", + "setuptools", +] diff --git a/e2e/cases/uv-deps-650/extras/uv.lock b/e2e/cases/uv-deps-650/extras/uv.lock new file mode 100644 index 00000000..38319f06 --- /dev/null +++ b/e2e/cases/uv-deps-650/extras/uv.lock @@ -0,0 +1,354 @@ +version = 1 +revision = 3 +requires-python = ">=3.11" +resolution-markers = [ + "python_full_version >= '3.13'", + "python_full_version < '3.13'", +] + +[[package]] +name = "brotli" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/16/c92ca344d646e71a43b8bb353f0a6490d7f6e06210f8554c8f874e454285/brotli-1.2.0.tar.gz", hash = "sha256:e310f77e41941c13340a95976fe66a8a95b01e783d430eeaf7a2f87e0a57dd0a", size = 7388632, upload-time = "2025-11-05T18:39:42.86Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/ef/f285668811a9e1ddb47a18cb0b437d5fc2760d537a2fe8a57875ad6f8448/brotli-1.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:15b33fe93cedc4caaff8a0bd1eb7e3dab1c61bb22a0bf5bdfdfd97cd7da79744", size = 863110, upload-time = "2025-11-05T18:38:12.978Z" }, + { url = "https://files.pythonhosted.org/packages/50/62/a3b77593587010c789a9d6eaa527c79e0848b7b860402cc64bc0bc28a86c/brotli-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:898be2be399c221d2671d29eed26b6b2713a02c2119168ed914e7d00ceadb56f", size = 445438, upload-time = "2025-11-05T18:38:14.208Z" }, + { url = "https://files.pythonhosted.org/packages/cd/e1/7fadd47f40ce5549dc44493877db40292277db373da5053aff181656e16e/brotli-1.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:350c8348f0e76fff0a0fd6c26755d2653863279d086d3aa2c290a6a7251135dd", size = 1534420, upload-time = "2025-11-05T18:38:15.111Z" }, + { url = "https://files.pythonhosted.org/packages/12/8b/1ed2f64054a5a008a4ccd2f271dbba7a5fb1a3067a99f5ceadedd4c1d5a7/brotli-1.2.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e1ad3fda65ae0d93fec742a128d72e145c9c7a99ee2fcd667785d99eb25a7fe", size = 1632619, upload-time = "2025-11-05T18:38:16.094Z" }, + { url = "https://files.pythonhosted.org/packages/89/5a/7071a621eb2d052d64efd5da2ef55ecdac7c3b0c6e4f9d519e9c66d987ef/brotli-1.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:40d918bce2b427a0c4ba189df7a006ac0c7277c180aee4617d99e9ccaaf59e6a", size = 1426014, upload-time = "2025-11-05T18:38:17.177Z" }, + { url = "https://files.pythonhosted.org/packages/26/6d/0971a8ea435af5156acaaccec1a505f981c9c80227633851f2810abd252a/brotli-1.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2a7f1d03727130fc875448b65b127a9ec5d06d19d0148e7554384229706f9d1b", size = 1489661, upload-time = "2025-11-05T18:38:18.41Z" }, + { url = "https://files.pythonhosted.org/packages/f3/75/c1baca8b4ec6c96a03ef8230fab2a785e35297632f402ebb1e78a1e39116/brotli-1.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:9c79f57faa25d97900bfb119480806d783fba83cd09ee0b33c17623935b05fa3", size = 1599150, upload-time = "2025-11-05T18:38:19.792Z" }, + { url = "https://files.pythonhosted.org/packages/0d/1a/23fcfee1c324fd48a63d7ebf4bac3a4115bdb1b00e600f80f727d850b1ae/brotli-1.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:844a8ceb8483fefafc412f85c14f2aae2fb69567bf2a0de53cdb88b73e7c43ae", size = 1493505, upload-time = "2025-11-05T18:38:20.913Z" }, + { url = "https://files.pythonhosted.org/packages/36/e5/12904bbd36afeef53d45a84881a4810ae8810ad7e328a971ebbfd760a0b3/brotli-1.2.0-cp311-cp311-win32.whl", hash = "sha256:aa47441fa3026543513139cb8926a92a8e305ee9c71a6209ef7a97d91640ea03", size = 334451, upload-time = "2025-11-05T18:38:21.94Z" }, + { url = "https://files.pythonhosted.org/packages/02/8b/ecb5761b989629a4758c394b9301607a5880de61ee2ee5fe104b87149ebc/brotli-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:022426c9e99fd65d9475dce5c195526f04bb8be8907607e27e747893f6ee3e24", size = 369035, upload-time = "2025-11-05T18:38:22.941Z" }, + { url = "https://files.pythonhosted.org/packages/11/ee/b0a11ab2315c69bb9b45a2aaed022499c9c24a205c3a49c3513b541a7967/brotli-1.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:35d382625778834a7f3061b15423919aa03e4f5da34ac8e02c074e4b75ab4f84", size = 861543, upload-time = "2025-11-05T18:38:24.183Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2f/29c1459513cd35828e25531ebfcbf3e92a5e49f560b1777a9af7203eb46e/brotli-1.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7a61c06b334bd99bc5ae84f1eeb36bfe01400264b3c352f968c6e30a10f9d08b", size = 444288, upload-time = "2025-11-05T18:38:25.139Z" }, + { url = "https://files.pythonhosted.org/packages/3d/6f/feba03130d5fceadfa3a1bb102cb14650798c848b1df2a808356f939bb16/brotli-1.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:acec55bb7c90f1dfc476126f9711a8e81c9af7fb617409a9ee2953115343f08d", size = 1528071, upload-time = "2025-11-05T18:38:26.081Z" }, + { url = "https://files.pythonhosted.org/packages/2b/38/f3abb554eee089bd15471057ba85f47e53a44a462cfce265d9bf7088eb09/brotli-1.2.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:260d3692396e1895c5034f204f0db022c056f9e2ac841593a4cf9426e2a3faca", size = 1626913, upload-time = "2025-11-05T18:38:27.284Z" }, + { url = "https://files.pythonhosted.org/packages/03/a7/03aa61fbc3c5cbf99b44d158665f9b0dd3d8059be16c460208d9e385c837/brotli-1.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:072e7624b1fc4d601036ab3f4f27942ef772887e876beff0301d261210bca97f", size = 1419762, upload-time = "2025-11-05T18:38:28.295Z" }, + { url = "https://files.pythonhosted.org/packages/21/1b/0374a89ee27d152a5069c356c96b93afd1b94eae83f1e004b57eb6ce2f10/brotli-1.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:adedc4a67e15327dfdd04884873c6d5a01d3e3b6f61406f99b1ed4865a2f6d28", size = 1484494, upload-time = "2025-11-05T18:38:29.29Z" }, + { url = "https://files.pythonhosted.org/packages/cf/57/69d4fe84a67aef4f524dcd075c6eee868d7850e85bf01d778a857d8dbe0a/brotli-1.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7a47ce5c2288702e09dc22a44d0ee6152f2c7eda97b3c8482d826a1f3cfc7da7", size = 1593302, upload-time = "2025-11-05T18:38:30.639Z" }, + { url = "https://files.pythonhosted.org/packages/d5/3b/39e13ce78a8e9a621c5df3aeb5fd181fcc8caba8c48a194cd629771f6828/brotli-1.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:af43b8711a8264bb4e7d6d9a6d004c3a2019c04c01127a868709ec29962b6036", size = 1487913, upload-time = "2025-11-05T18:38:31.618Z" }, + { url = "https://files.pythonhosted.org/packages/62/28/4d00cb9bd76a6357a66fcd54b4b6d70288385584063f4b07884c1e7286ac/brotli-1.2.0-cp312-cp312-win32.whl", hash = "sha256:e99befa0b48f3cd293dafeacdd0d191804d105d279e0b387a32054c1180f3161", size = 334362, upload-time = "2025-11-05T18:38:32.939Z" }, + { url = "https://files.pythonhosted.org/packages/1c/4e/bc1dcac9498859d5e353c9b153627a3752868a9d5f05ce8dedd81a2354ab/brotli-1.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:b35c13ce241abdd44cb8ca70683f20c0c079728a36a996297adb5334adfc1c44", size = 369115, upload-time = "2025-11-05T18:38:33.765Z" }, + { url = "https://files.pythonhosted.org/packages/6c/d4/4ad5432ac98c73096159d9ce7ffeb82d151c2ac84adcc6168e476bb54674/brotli-1.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9e5825ba2c9998375530504578fd4d5d1059d09621a02065d1b6bfc41a8e05ab", size = 861523, upload-time = "2025-11-05T18:38:34.67Z" }, + { url = "https://files.pythonhosted.org/packages/91/9f/9cc5bd03ee68a85dc4bc89114f7067c056a3c14b3d95f171918c088bf88d/brotli-1.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0cf8c3b8ba93d496b2fae778039e2f5ecc7cff99df84df337ca31d8f2252896c", size = 444289, upload-time = "2025-11-05T18:38:35.6Z" }, + { url = "https://files.pythonhosted.org/packages/2e/b6/fe84227c56a865d16a6614e2c4722864b380cb14b13f3e6bef441e73a85a/brotli-1.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8565e3cdc1808b1a34714b553b262c5de5fbda202285782173ec137fd13709f", size = 1528076, upload-time = "2025-11-05T18:38:36.639Z" }, + { url = "https://files.pythonhosted.org/packages/55/de/de4ae0aaca06c790371cf6e7ee93a024f6b4bb0568727da8c3de112e726c/brotli-1.2.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:26e8d3ecb0ee458a9804f47f21b74845cc823fd1bb19f02272be70774f56e2a6", size = 1626880, upload-time = "2025-11-05T18:38:37.623Z" }, + { url = "https://files.pythonhosted.org/packages/5f/16/a1b22cbea436642e071adcaf8d4b350a2ad02f5e0ad0da879a1be16188a0/brotli-1.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67a91c5187e1eec76a61625c77a6c8c785650f5b576ca732bd33ef58b0dff49c", size = 1419737, upload-time = "2025-11-05T18:38:38.729Z" }, + { url = "https://files.pythonhosted.org/packages/46/63/c968a97cbb3bdbf7f974ef5a6ab467a2879b82afbc5ffb65b8acbb744f95/brotli-1.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4ecdb3b6dc36e6d6e14d3a1bdc6c1057c8cbf80db04031d566eb6080ce283a48", size = 1484440, upload-time = "2025-11-05T18:38:39.916Z" }, + { url = "https://files.pythonhosted.org/packages/06/9d/102c67ea5c9fc171f423e8399e585dabea29b5bc79b05572891e70013cdd/brotli-1.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3e1b35d56856f3ed326b140d3c6d9db91740f22e14b06e840fe4bb1923439a18", size = 1593313, upload-time = "2025-11-05T18:38:41.24Z" }, + { url = "https://files.pythonhosted.org/packages/9e/4a/9526d14fa6b87bc827ba1755a8440e214ff90de03095cacd78a64abe2b7d/brotli-1.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:54a50a9dad16b32136b2241ddea9e4df159b41247b2ce6aac0b3276a66a8f1e5", size = 1487945, upload-time = "2025-11-05T18:38:42.277Z" }, + { url = "https://files.pythonhosted.org/packages/5b/e8/3fe1ffed70cbef83c5236166acaed7bb9c766509b157854c80e2f766b38c/brotli-1.2.0-cp313-cp313-win32.whl", hash = "sha256:1b1d6a4efedd53671c793be6dd760fcf2107da3a52331ad9ea429edf0902f27a", size = 334368, upload-time = "2025-11-05T18:38:43.345Z" }, + { url = "https://files.pythonhosted.org/packages/ff/91/e739587be970a113b37b821eae8097aac5a48e5f0eca438c22e4c7dd8648/brotli-1.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:b63daa43d82f0cdabf98dee215b375b4058cce72871fd07934f179885aad16e8", size = 369116, upload-time = "2025-11-05T18:38:44.609Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/298c2ddf786bb7347a1cd71d63a347a79e5712a7c0cba9e3c3458ebd976f/brotli-1.2.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:6c12dad5cd04530323e723787ff762bac749a7b256a5bece32b2243dd5c27b21", size = 863080, upload-time = "2025-11-05T18:38:45.503Z" }, + { url = "https://files.pythonhosted.org/packages/84/0c/aac98e286ba66868b2b3b50338ffbd85a35c7122e9531a73a37a29763d38/brotli-1.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3219bd9e69868e57183316ee19c84e03e8f8b5a1d1f2667e1aa8c2f91cb061ac", size = 445453, upload-time = "2025-11-05T18:38:46.433Z" }, + { url = "https://files.pythonhosted.org/packages/ec/f1/0ca1f3f99ae300372635ab3fe2f7a79fa335fee3d874fa7f9e68575e0e62/brotli-1.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:963a08f3bebd8b75ac57661045402da15991468a621f014be54e50f53a58d19e", size = 1528168, upload-time = "2025-11-05T18:38:47.371Z" }, + { url = "https://files.pythonhosted.org/packages/d6/a6/2ebfc8f766d46df8d3e65b880a2e220732395e6d7dc312c1e1244b0f074a/brotli-1.2.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9322b9f8656782414b37e6af884146869d46ab85158201d82bab9abbcb971dc7", size = 1627098, upload-time = "2025-11-05T18:38:48.385Z" }, + { url = "https://files.pythonhosted.org/packages/f3/2f/0976d5b097ff8a22163b10617f76b2557f15f0f39d6a0fe1f02b1a53e92b/brotli-1.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cf9cba6f5b78a2071ec6fb1e7bd39acf35071d90a81231d67e92d637776a6a63", size = 1419861, upload-time = "2025-11-05T18:38:49.372Z" }, + { url = "https://files.pythonhosted.org/packages/9c/97/d76df7176a2ce7616ff94c1fb72d307c9a30d2189fe877f3dd99af00ea5a/brotli-1.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7547369c4392b47d30a3467fe8c3330b4f2e0f7730e45e3103d7d636678a808b", size = 1484594, upload-time = "2025-11-05T18:38:50.655Z" }, + { url = "https://files.pythonhosted.org/packages/d3/93/14cf0b1216f43df5609f5b272050b0abd219e0b54ea80b47cef9867b45e7/brotli-1.2.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:fc1530af5c3c275b8524f2e24841cbe2599d74462455e9bae5109e9ff42e9361", size = 1593455, upload-time = "2025-11-05T18:38:51.624Z" }, + { url = "https://files.pythonhosted.org/packages/b3/73/3183c9e41ca755713bdf2cc1d0810df742c09484e2e1ddd693bee53877c1/brotli-1.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d2d085ded05278d1c7f65560aae97b3160aeb2ea2c0b3e26204856beccb60888", size = 1488164, upload-time = "2025-11-05T18:38:53.079Z" }, + { url = "https://files.pythonhosted.org/packages/64/6a/0c78d8f3a582859236482fd9fa86a65a60328a00983006bcf6d83b7b2253/brotli-1.2.0-cp314-cp314-win32.whl", hash = "sha256:832c115a020e463c2f67664560449a7bea26b0c1fdd690352addad6d0a08714d", size = 339280, upload-time = "2025-11-05T18:38:54.02Z" }, + { url = "https://files.pythonhosted.org/packages/f5/10/56978295c14794b2c12007b07f3e41ba26acda9257457d7085b0bb3bb90c/brotli-1.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:e7c0af964e0b4e3412a0ebf341ea26ec767fa0b4cf81abb5e897c9338b5ad6a3", size = 375639, upload-time = "2025-11-05T18:38:55.67Z" }, +] + +[[package]] +name = "brotlicffi" +version = "1.2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/84/85/57c314a6b35336efbbdc13e5fc9ae13f6b60a0647cfa7c1221178ac6d8ae/brotlicffi-1.2.0.0.tar.gz", hash = "sha256:34345d8d1f9d534fcac2249e57a4c3c8801a33c9942ff9f8574f67a175e17adb", size = 476682, upload-time = "2025-11-21T18:17:57.334Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/df/a72b284d8c7bef0ed5756b41c2eb7d0219a1dd6ac6762f1c7bdbc31ef3af/brotlicffi-1.2.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:9458d08a7ccde8e3c0afedbf2c70a8263227a68dea5ab13590593f4c0a4fd5f4", size = 432340, upload-time = "2025-11-21T18:17:42.277Z" }, + { url = "https://files.pythonhosted.org/packages/74/2b/cc55a2d1d6fb4f5d458fba44a3d3f91fb4320aa14145799fd3a996af0686/brotlicffi-1.2.0.0-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:84e3d0020cf1bd8b8131f4a07819edee9f283721566fe044a20ec792ca8fd8b7", size = 1534002, upload-time = "2025-11-21T18:17:43.746Z" }, + { url = "https://files.pythonhosted.org/packages/e4/9c/d51486bf366fc7d6735f0e46b5b96ca58dc005b250263525a1eea3cd5d21/brotlicffi-1.2.0.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:33cfb408d0cff64cd50bef268c0fed397c46fbb53944aa37264148614a62e990", size = 1536547, upload-time = "2025-11-21T18:17:45.729Z" }, + { url = "https://files.pythonhosted.org/packages/1b/37/293a9a0a7caf17e6e657668bebb92dfe730305999fe8c0e2703b8888789c/brotlicffi-1.2.0.0-cp38-abi3-win32.whl", hash = "sha256:23e5c912fdc6fd37143203820230374d24babd078fc054e18070a647118158f6", size = 343085, upload-time = "2025-11-21T18:17:48.887Z" }, + { url = "https://files.pythonhosted.org/packages/07/6b/6e92009df3b8b7272f85a0992b306b61c34b7ea1c4776643746e61c380ac/brotlicffi-1.2.0.0-cp38-abi3-win_amd64.whl", hash = "sha256:f139a7cdfe4ae7859513067b736eb44d19fae1186f9e99370092f6915216451b", size = 378586, upload-time = "2025-11-21T18:17:50.531Z" }, + { url = "https://files.pythonhosted.org/packages/a4/ec/52488a0563f1663e2ccc75834b470650f4b8bcdea3132aef3bf67219c661/brotlicffi-1.2.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:fa102a60e50ddbd08de86a63431a722ea216d9bc903b000bf544149cc9b823dc", size = 402002, upload-time = "2025-11-21T18:17:51.76Z" }, + { url = "https://files.pythonhosted.org/packages/e4/63/d4aea4835fd97da1401d798d9b8ba77227974de565faea402f520b37b10f/brotlicffi-1.2.0.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d3c4332fc808a94e8c1035950a10d04b681b03ab585ce897ae2a360d479037c", size = 406447, upload-time = "2025-11-21T18:17:53.614Z" }, + { url = "https://files.pythonhosted.org/packages/62/4e/5554ecb2615ff035ef8678d4e419549a0f7a28b3f096b272174d656749fb/brotlicffi-1.2.0.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb4eb5830026b79a93bf503ad32b2c5257315e9ffc49e76b2715cffd07c8e3db", size = 402521, upload-time = "2025-11-21T18:17:54.875Z" }, + { url = "https://files.pythonhosted.org/packages/b5/d3/b07f8f125ac52bbee5dc00ef0d526f820f67321bf4184f915f17f50a4657/brotlicffi-1.2.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3832c66e00d6d82087f20a972b2fc03e21cd99ef22705225a6f8f418a9158ecc", size = 374730, upload-time = "2025-11-21T18:17:56.334Z" }, +] + +[[package]] +name = "build" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "os_name == 'nt'" }, + { name = "packaging" }, + { name = "pyproject-hooks" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/18/94eaffda7b329535d91f00fe605ab1f1e5cd68b2074d03f255c7d250687d/build-1.4.0.tar.gz", hash = "sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936", size = 50054, upload-time = "2026-01-08T16:41:47.696Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl", hash = "sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596", size = 24141, upload-time = "2026-01-08T16:41:46.453Z" }, +] + +[[package]] +name = "certifi" +version = "2026.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120", size = 154268, upload-time = "2026-01-04T02:42:41.825Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c", size = 152900, upload-time = "2026-01-04T02:42:40.15Z" }, +] + +[[package]] +name = "cffi" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload-time = "2025-09-08T23:22:26.456Z" }, + { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload-time = "2025-09-08T23:22:28.197Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload-time = "2025-09-08T23:22:29.475Z" }, + { url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476, upload-time = "2025-09-08T23:22:31.063Z" }, + { url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374, upload-time = "2025-09-08T23:22:32.507Z" }, + { url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597, upload-time = "2025-09-08T23:22:34.132Z" }, + { url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574, upload-time = "2025-09-08T23:22:35.443Z" }, + { url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971, upload-time = "2025-09-08T23:22:36.805Z" }, + { url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972, upload-time = "2025-09-08T23:22:38.436Z" }, + { url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078, upload-time = "2025-09-08T23:22:39.776Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload-time = "2025-09-08T23:22:40.95Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload-time = "2025-09-08T23:22:42.463Z" }, + { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload-time = "2025-09-08T23:22:43.623Z" }, + { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" }, + { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" }, + { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" }, + { url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" }, + { url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" }, + { url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" }, + { url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" }, + { url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" }, + { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" }, + { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" }, + { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" }, + { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" }, + { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" }, + { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" }, + { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" }, + { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" }, + { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" }, + { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" }, + { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" }, + { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" }, + { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" }, + { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" }, + { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" }, + { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" }, + { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" }, + { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" }, + { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" }, + { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" }, + { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" }, + { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" }, + { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" }, + { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" }, + { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" }, + { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", size = 206988, upload-time = "2025-10-14T04:40:33.79Z" }, + { url = "https://files.pythonhosted.org/packages/94/59/2e87300fe67ab820b5428580a53cad894272dbb97f38a7a814a2a1ac1011/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", size = 147324, upload-time = "2025-10-14T04:40:34.961Z" }, + { url = "https://files.pythonhosted.org/packages/07/fb/0cf61dc84b2b088391830f6274cb57c82e4da8bbc2efeac8c025edb88772/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", size = 142742, upload-time = "2025-10-14T04:40:36.105Z" }, + { url = "https://files.pythonhosted.org/packages/62/8b/171935adf2312cd745d290ed93cf16cf0dfe320863ab7cbeeae1dcd6535f/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc", size = 160863, upload-time = "2025-10-14T04:40:37.188Z" }, + { url = "https://files.pythonhosted.org/packages/09/73/ad875b192bda14f2173bfc1bc9a55e009808484a4b256748d931b6948442/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897", size = 157837, upload-time = "2025-10-14T04:40:38.435Z" }, + { url = "https://files.pythonhosted.org/packages/6d/fc/de9cce525b2c5b94b47c70a4b4fb19f871b24995c728e957ee68ab1671ea/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381", size = 151550, upload-time = "2025-10-14T04:40:40.053Z" }, + { url = "https://files.pythonhosted.org/packages/55/c2/43edd615fdfba8c6f2dfbd459b25a6b3b551f24ea21981e23fb768503ce1/charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815", size = 149162, upload-time = "2025-10-14T04:40:41.163Z" }, + { url = "https://files.pythonhosted.org/packages/03/86/bde4ad8b4d0e9429a4e82c1e8f5c659993a9a863ad62c7df05cf7b678d75/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0", size = 150019, upload-time = "2025-10-14T04:40:42.276Z" }, + { url = "https://files.pythonhosted.org/packages/1f/86/a151eb2af293a7e7bac3a739b81072585ce36ccfb4493039f49f1d3cae8c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161", size = 143310, upload-time = "2025-10-14T04:40:43.439Z" }, + { url = "https://files.pythonhosted.org/packages/b5/fe/43dae6144a7e07b87478fdfc4dbe9efd5defb0e7ec29f5f58a55aeef7bf7/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4", size = 162022, upload-time = "2025-10-14T04:40:44.547Z" }, + { url = "https://files.pythonhosted.org/packages/80/e6/7aab83774f5d2bca81f42ac58d04caf44f0cc2b65fc6db2b3b2e8a05f3b3/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89", size = 149383, upload-time = "2025-10-14T04:40:46.018Z" }, + { url = "https://files.pythonhosted.org/packages/4f/e8/b289173b4edae05c0dde07f69f8db476a0b511eac556dfe0d6bda3c43384/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569", size = 159098, upload-time = "2025-10-14T04:40:47.081Z" }, + { url = "https://files.pythonhosted.org/packages/d8/df/fe699727754cae3f8478493c7f45f777b17c3ef0600e28abfec8619eb49c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224", size = 152991, upload-time = "2025-10-14T04:40:48.246Z" }, + { url = "https://files.pythonhosted.org/packages/1a/86/584869fe4ddb6ffa3bd9f491b87a01568797fb9bd8933f557dba9771beaf/charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", size = 99456, upload-time = "2025-10-14T04:40:49.376Z" }, + { url = "https://files.pythonhosted.org/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", size = 106978, upload-time = "2025-10-14T04:40:50.844Z" }, + { url = "https://files.pythonhosted.org/packages/7a/9d/0710916e6c82948b3be62d9d398cb4fcf4e97b56d6a6aeccd66c4b2f2bd5/charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", size = 99969, upload-time = "2025-10-14T04:40:52.272Z" }, + { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, + { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, + { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, + { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, + { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, + { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, + { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, + { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, + { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, + { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, + { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, + { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, + { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, + { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, + { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, + { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, + { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, + { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, + { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, + { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, + { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, + { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, + { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, + { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "extras" +version = "0.0.0" +source = { virtual = "." } +dependencies = [ + { name = "requests" }, + { name = "urllib3", extra = ["brotli"] }, +] + +[package.dev-dependencies] +extras = [ + { name = "build" }, + { name = "extras" }, + { name = "setuptools" }, +] + +[package.metadata] +requires-dist = [ + { name = "requests" }, + { name = "urllib3", extras = ["brotli"] }, +] + +[package.metadata.requires-dev] +extras = [ + { name = "build" }, + { name = "extras" }, + { name = "setuptools" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "packaging" +version = "26.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, +] + +[[package]] +name = "pycparser" +version = "3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, +] + +[[package]] +name = "pyproject-hooks" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/82/28175b2414effca1cdac8dc99f76d660e7a4fb0ceefa4b4ab8f5f6742925/pyproject_hooks-1.2.0.tar.gz", hash = "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8", size = 19228, upload-time = "2024-09-29T09:24:13.293Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl", hash = "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913", size = 10216, upload-time = "2024-09-29T09:24:11.978Z" }, +] + +[[package]] +name = "requests" +version = "2.32.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, +] + +[[package]] +name = "setuptools" +version = "82.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/f3/748f4d6f65d1756b9ae577f329c951cda23fb900e4de9f70900ced962085/setuptools-82.0.0.tar.gz", hash = "sha256:22e0a2d69474c6ae4feb01951cb69d515ed23728cf96d05513d36e42b62b37cb", size = 1144893, upload-time = "2026-02-08T15:08:40.206Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl", hash = "sha256:70b18734b607bd1da571d097d236cfcfacaf01de45717d59e6e04b96877532e0", size = 1003468, upload-time = "2026-02-08T15:08:38.723Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, +] + +[package.optional-dependencies] +brotli = [ + { name = "brotli", marker = "platform_python_implementation == 'CPython'" }, + { name = "brotlicffi", marker = "platform_python_implementation != 'CPython'" }, +] diff --git a/e2e/cases/uv-deps-650/say/pyproject.toml b/e2e/cases/uv-deps-650/say/pyproject.toml new file mode 100644 index 00000000..d0f36973 --- /dev/null +++ b/e2e/cases/uv-deps-650/say/pyproject.toml @@ -0,0 +1,7 @@ +[project] +name = "say" +version = "0.0.0" +authors = [] +dependencies = [ + "cowsay", +] diff --git a/e2e/cases/uv-deps-650/say/uv.lock b/e2e/cases/uv-deps-650/say/uv.lock index a309b166..19e36898 100644 --- a/e2e/cases/uv-deps-650/say/uv.lock +++ b/e2e/cases/uv-deps-650/say/uv.lock @@ -1,6 +1,6 @@ version = 1 revision = 3 -requires-python = ">=3.9" +requires-python = ">=3.11" [[package]] name = "cowsay" @@ -11,7 +11,7 @@ wheels = [ ] [[package]] -name = "dummy" +name = "say" version = "0.0.0" source = { virtual = "." } dependencies = [ @@ -19,4 +19,4 @@ dependencies = [ ] [package.metadata] -requires-dist = [{ name = "cowsay", specifier = "==6.1" }] +requires-dist = [{ name = "cowsay" }] diff --git a/py/private/py_library.bzl b/py/private/py_library.bzl index ffc1abcc..3a6bb7a3 100644 --- a/py/private/py_library.bzl +++ b/py/private/py_library.bzl @@ -181,7 +181,7 @@ def _py_library_impl(ctx): return [ DefaultInfo( - files = depset(direct = ctx.files.srcs), + files = depset(direct = ctx.files.srcs, transitive = [transitive_srcs]), default_runfiles = runfiles, ), PyInfo( diff --git a/py/tests/py-binary/BUILD.bazel b/py/tests/py-binary/BUILD.bazel deleted file mode 100644 index 4104ef0c..00000000 --- a/py/tests/py-binary/BUILD.bazel +++ /dev/null @@ -1,52 +0,0 @@ -load("@bazel_lib//lib:run_binary.bzl", "run_binary") -load("@bazel_lib//lib:testing.bzl", "assert_contains") -load("@pypi//:requirements.bzl", "requirement") -load("//py:defs.bzl", "py_binary", "py_test") - -genrule( - name = "run_py_test_help", - outs = ["help.txt"], - cmd = "$(execpath @pypi//pytest/entrypoints:pytest) --help >$@", - tools = [ - "@pypi//pytest/entrypoints:pytest", - ], -) - -assert_contains( - name = "test__run_py_test_help", - actual = "help.txt", - expected = "junit_logging (string):", -) - -################# -# Case 2: -# The main property can be inferred from the target name. -py_binary( - name = "main_from_name", - srcs = ["main_from_name.py"], -) - -run_binary( - name = "run_main_from_name", - outs = ["main_from_name.out"], - args = ["$(execpath main_from_name.out)"], - tool = "main_from_name", -) - -assert_contains( - name = "test__main_from_name", - actual = "main_from_name.out", - expected = "running main_from_name", -) - -################# -# Case 3: Runfiles from pip works -py_test( - name = "runfiles_from_pip_test", - srcs = ["runfiles_from_pip.py"], - data = ["test_data.txt"], - main = "runfiles_from_pip.py", - deps = [ - requirement("bazel-runfiles"), - ], -) diff --git a/py/tests/py-binary/main_from_name.py b/py/tests/py-binary/main_from_name.py deleted file mode 100644 index 7456b53d..00000000 --- a/py/tests/py-binary/main_from_name.py +++ /dev/null @@ -1,5 +0,0 @@ -import sys - -if __name__ == '__main__': - with open(sys.argv[1], 'w') as f: - f.write("running main_from_name") diff --git a/py/tests/py-binary/runfiles_from_pip.py b/py/tests/py-binary/runfiles_from_pip.py deleted file mode 100644 index c55996e1..00000000 --- a/py/tests/py-binary/runfiles_from_pip.py +++ /dev/null @@ -1,14 +0,0 @@ -import os -import pathlib -import unittest - -import runfiles # requirement("bazel-runfiles") - -class RunfilesTest(unittest.TestCase): - def test_runfiles(self) -> None: - r = runfiles.Runfiles.Create() - path = pathlib.Path(r.Rlocation(os.getenv("BAZEL_WORKSPACE")+"/py/tests/py-binary/test_data.txt")) - self.assertEquals(path.read_text(), "42\n") - -if __name__ == "__main__": - unittest.main() diff --git a/py/tests/py-binary/test_data.txt b/py/tests/py-binary/test_data.txt deleted file mode 100644 index d81cc071..00000000 --- a/py/tests/py-binary/test_data.txt +++ /dev/null @@ -1 +0,0 @@ -42 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..f1529d60 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,21 @@ +[project] +name = "aspect_rules_py" +version = "0.0.0" +authors = [] +requires-python = ">=3.9, <3.12" +dependencies = [ + "setuptools", + "build", + "django~=4.2.7", + "colorama~=0.4.0", + "click", + "pytest", + "coverage", + "cowsay", + "snakesay", + "ftfy==6.2.0", + "neptune==1.10.2", + "six", + "bazel-runfiles", + "maturin", +] diff --git a/uv.lock b/uv.lock index 994519a6..de5c1b32 100644 --- a/uv.lock +++ b/uv.lock @@ -1,9 +1,8 @@ version = 1 revision = 3 -requires-python = ">=3.9" +requires-python = ">=3.9, <3.12" resolution-markers = [ - "python_full_version >= '3.12'", - "python_full_version == '3.11.*'", + "python_full_version >= '3.11'", "python_full_version == '3.10.*'", "python_full_version < '3.10'", ] @@ -33,6 +32,45 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/39/e3/893e8757be2612e6c266d9bb58ad2e3651524b5b40cf56761e985a28b13e/asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47", size = 23828, upload-time = "2024-03-22T14:39:34.521Z" }, ] +[[package]] +name = "aspect-rules-py" +version = "0.0.0" +source = { virtual = "." } +dependencies = [ + { name = "bazel-runfiles" }, + { name = "build" }, + { name = "click" }, + { name = "colorama" }, + { name = "coverage" }, + { name = "cowsay" }, + { name = "django" }, + { name = "ftfy" }, + { name = "maturin" }, + { name = "neptune" }, + { name = "pytest" }, + { name = "setuptools" }, + { name = "six" }, + { name = "snakesay" }, +] + +[package.metadata] +requires-dist = [ + { name = "bazel-runfiles" }, + { name = "build" }, + { name = "click" }, + { name = "colorama", specifier = "~=0.4.0" }, + { name = "coverage" }, + { name = "cowsay" }, + { name = "django", specifier = "~=4.2.7" }, + { name = "ftfy", specifier = "==6.2.0" }, + { name = "maturin" }, + { name = "neptune", specifier = "==1.10.2" }, + { name = "pytest" }, + { name = "setuptools" }, + { name = "six" }, + { name = "snakesay" }, +] + [[package]] name = "attrs" version = "23.2.0" @@ -177,21 +215,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2d/dc/9dacba68c9ac0ae781d40e1a0c0058e26302ea0660e574ddf6797a0347f7/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", size = 140859, upload-time = "2023-11-01T04:03:17.362Z" }, { url = "https://files.pythonhosted.org/packages/6c/c2/4a583f800c0708dd22096298e49f887b49d9746d0e78bfc1d7e29816614c/charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", size = 92509, upload-time = "2023-11-01T04:03:21.453Z" }, { url = "https://files.pythonhosted.org/packages/57/ec/80c8d48ac8b1741d5b963797b7c0c869335619e13d4744ca2f67fc11c6fc/charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", size = 99870, upload-time = "2023-11-01T04:03:22.723Z" }, - { url = "https://files.pythonhosted.org/packages/d1/b2/fcedc8255ec42afee97f9e6f0145c734bbe104aac28300214593eb326f1d/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", size = 192892, upload-time = "2023-11-01T04:03:24.135Z" }, - { url = "https://files.pythonhosted.org/packages/2e/7d/2259318c202f3d17f3fe6438149b3b9e706d1070fe3fcbb28049730bb25c/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", size = 122213, upload-time = "2023-11-01T04:03:25.66Z" }, - { url = "https://files.pythonhosted.org/packages/3a/52/9f9d17c3b54dc238de384c4cb5a2ef0e27985b42a0e5cc8e8a31d918d48d/charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", size = 119404, upload-time = "2023-11-01T04:03:27.04Z" }, - { url = "https://files.pythonhosted.org/packages/99/b0/9c365f6d79a9f0f3c379ddb40a256a67aa69c59609608fe7feb6235896e1/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", size = 137275, upload-time = "2023-11-01T04:03:28.466Z" }, - { url = "https://files.pythonhosted.org/packages/91/33/749df346e93d7a30cdcb90cbfdd41a06026317bfbfb62cd68307c1a3c543/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", size = 147518, upload-time = "2023-11-01T04:03:29.82Z" }, - { url = "https://files.pythonhosted.org/packages/72/1a/641d5c9f59e6af4c7b53da463d07600a695b9824e20849cb6eea8a627761/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", size = 140182, upload-time = "2023-11-01T04:03:31.511Z" }, - { url = "https://files.pythonhosted.org/packages/ee/fb/14d30eb4956408ee3ae09ad34299131fb383c47df355ddb428a7331cfa1e/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", size = 141869, upload-time = "2023-11-01T04:03:32.887Z" }, - { url = "https://files.pythonhosted.org/packages/df/3e/a06b18788ca2eb6695c9b22325b6fde7dde0f1d1838b1792a0076f58fe9d/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", size = 144042, upload-time = "2023-11-01T04:03:34.412Z" }, - { url = "https://files.pythonhosted.org/packages/45/59/3d27019d3b447a88fe7e7d004a1e04be220227760264cc41b405e863891b/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", size = 138275, upload-time = "2023-11-01T04:03:35.759Z" }, - { url = "https://files.pythonhosted.org/packages/7b/ef/5eb105530b4da8ae37d506ccfa25057961b7b63d581def6f99165ea89c7e/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", size = 144819, upload-time = "2023-11-01T04:03:37.216Z" }, - { url = "https://files.pythonhosted.org/packages/a2/51/e5023f937d7f307c948ed3e5c29c4b7a3e42ed2ee0b8cdf8f3a706089bf0/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", size = 149415, upload-time = "2023-11-01T04:03:38.694Z" }, - { url = "https://files.pythonhosted.org/packages/24/9d/2e3ef673dfd5be0154b20363c5cdcc5606f35666544381bee15af3778239/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", size = 141212, upload-time = "2023-11-01T04:03:40.07Z" }, - { url = "https://files.pythonhosted.org/packages/5b/ae/ce2c12fcac59cb3860b2e2d76dc405253a4475436b1861d95fe75bdea520/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", size = 142167, upload-time = "2023-11-01T04:03:41.491Z" }, - { url = "https://files.pythonhosted.org/packages/ed/3a/a448bf035dce5da359daf9ae8a16b8a39623cc395a2ffb1620aa1bce62b0/charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", size = 93041, upload-time = "2023-11-01T04:03:42.836Z" }, - { url = "https://files.pythonhosted.org/packages/b6/7c/8debebb4f90174074b827c63242c23851bdf00a532489fba57fef3416e40/charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", size = 100397, upload-time = "2023-11-01T04:03:44.467Z" }, { url = "https://files.pythonhosted.org/packages/f7/9d/bcf4a449a438ed6f19790eee543a86a740c77508fbc5ddab210ab3ba3a9a/charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", size = 194198, upload-time = "2023-11-01T04:04:32.328Z" }, { url = "https://files.pythonhosted.org/packages/66/fe/c7d3da40a66a6bf2920cce0f436fa1f62ee28aaf92f412f0bf3b84c8ad6c/charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", size = 122494, upload-time = "2023-11-01T04:04:33.993Z" }, { url = "https://files.pythonhosted.org/packages/2a/9d/a6d15bd1e3e2914af5955c8eb15f4071997e7078419328fee93dfd497eb7/charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", size = 120393, upload-time = "2023-11-01T04:04:35.533Z" }, @@ -257,36 +280,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ee/2d/7016f4ad9d553cabcb7333ed78ff9d27248ec4eba8dd21fa488254dff894/coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377", size = 238045, upload-time = "2024-12-26T16:57:36.952Z" }, { url = "https://files.pythonhosted.org/packages/a7/fe/45af5c82389a71e0cae4546413266d2195c3744849669b0bab4b5f2c75da/coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8", size = 210647, upload-time = "2024-12-26T16:57:39.84Z" }, { url = "https://files.pythonhosted.org/packages/db/11/3f8e803a43b79bc534c6a506674da9d614e990e37118b4506faf70d46ed6/coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609", size = 211508, upload-time = "2024-12-26T16:57:41.234Z" }, - { url = "https://files.pythonhosted.org/packages/86/77/19d09ea06f92fdf0487499283b1b7af06bc422ea94534c8fe3a4cd023641/coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853", size = 208281, upload-time = "2024-12-26T16:57:42.968Z" }, - { url = "https://files.pythonhosted.org/packages/b6/67/5479b9f2f99fcfb49c0d5cf61912a5255ef80b6e80a3cddba39c38146cf4/coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078", size = 208514, upload-time = "2024-12-26T16:57:45.747Z" }, - { url = "https://files.pythonhosted.org/packages/15/d1/febf59030ce1c83b7331c3546d7317e5120c5966471727aa7ac157729c4b/coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0", size = 241537, upload-time = "2024-12-26T16:57:48.647Z" }, - { url = "https://files.pythonhosted.org/packages/4b/7e/5ac4c90192130e7cf8b63153fe620c8bfd9068f89a6d9b5f26f1550f7a26/coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50", size = 238572, upload-time = "2024-12-26T16:57:51.668Z" }, - { url = "https://files.pythonhosted.org/packages/dc/03/0334a79b26ecf59958f2fe9dd1f5ab3e2f88db876f5071933de39af09647/coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022", size = 240639, upload-time = "2024-12-26T16:57:53.175Z" }, - { url = "https://files.pythonhosted.org/packages/d7/45/8a707f23c202208d7b286d78ad6233f50dcf929319b664b6cc18a03c1aae/coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b", size = 240072, upload-time = "2024-12-26T16:57:56.087Z" }, - { url = "https://files.pythonhosted.org/packages/66/02/603ce0ac2d02bc7b393279ef618940b4a0535b0868ee791140bda9ecfa40/coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0", size = 238386, upload-time = "2024-12-26T16:57:57.572Z" }, - { url = "https://files.pythonhosted.org/packages/04/62/4e6887e9be060f5d18f1dd58c2838b2d9646faf353232dec4e2d4b1c8644/coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852", size = 240054, upload-time = "2024-12-26T16:57:58.967Z" }, - { url = "https://files.pythonhosted.org/packages/5c/74/83ae4151c170d8bd071924f212add22a0e62a7fe2b149edf016aeecad17c/coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359", size = 210904, upload-time = "2024-12-26T16:58:00.688Z" }, - { url = "https://files.pythonhosted.org/packages/c3/54/de0893186a221478f5880283119fc40483bc460b27c4c71d1b8bba3474b9/coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247", size = 211692, upload-time = "2024-12-26T16:58:02.35Z" }, - { url = "https://files.pythonhosted.org/packages/25/6d/31883d78865529257bf847df5789e2ae80e99de8a460c3453dbfbe0db069/coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9", size = 208308, upload-time = "2024-12-26T16:58:04.487Z" }, - { url = "https://files.pythonhosted.org/packages/70/22/3f2b129cc08de00c83b0ad6252e034320946abfc3e4235c009e57cfeee05/coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b", size = 208565, upload-time = "2024-12-26T16:58:06.774Z" }, - { url = "https://files.pythonhosted.org/packages/97/0a/d89bc2d1cc61d3a8dfe9e9d75217b2be85f6c73ebf1b9e3c2f4e797f4531/coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690", size = 241083, upload-time = "2024-12-26T16:58:10.27Z" }, - { url = "https://files.pythonhosted.org/packages/4c/81/6d64b88a00c7a7aaed3a657b8eaa0931f37a6395fcef61e53ff742b49c97/coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18", size = 238235, upload-time = "2024-12-26T16:58:12.497Z" }, - { url = "https://files.pythonhosted.org/packages/9a/0b/7797d4193f5adb4b837207ed87fecf5fc38f7cc612b369a8e8e12d9fa114/coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c", size = 240220, upload-time = "2024-12-26T16:58:15.619Z" }, - { url = "https://files.pythonhosted.org/packages/65/4d/6f83ca1bddcf8e51bf8ff71572f39a1c73c34cf50e752a952c34f24d0a60/coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd", size = 239847, upload-time = "2024-12-26T16:58:17.126Z" }, - { url = "https://files.pythonhosted.org/packages/30/9d/2470df6aa146aff4c65fee0f87f58d2164a67533c771c9cc12ffcdb865d5/coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e", size = 237922, upload-time = "2024-12-26T16:58:20.198Z" }, - { url = "https://files.pythonhosted.org/packages/08/dd/723fef5d901e6a89f2507094db66c091449c8ba03272861eaefa773ad95c/coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694", size = 239783, upload-time = "2024-12-26T16:58:23.614Z" }, - { url = "https://files.pythonhosted.org/packages/3d/f7/64d3298b2baf261cb35466000628706ce20a82d42faf9b771af447cd2b76/coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6", size = 210965, upload-time = "2024-12-26T16:58:26.765Z" }, - { url = "https://files.pythonhosted.org/packages/d5/58/ec43499a7fc681212fe7742fe90b2bc361cdb72e3181ace1604247a5b24d/coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e", size = 211719, upload-time = "2024-12-26T16:58:28.781Z" }, - { url = "https://files.pythonhosted.org/packages/ab/c9/f2857a135bcff4330c1e90e7d03446b036b2363d4ad37eb5e3a47bbac8a6/coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe", size = 209050, upload-time = "2024-12-26T16:58:31.616Z" }, - { url = "https://files.pythonhosted.org/packages/aa/b3/f840e5bd777d8433caa9e4a1eb20503495709f697341ac1a8ee6a3c906ad/coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273", size = 209321, upload-time = "2024-12-26T16:58:34.509Z" }, - { url = "https://files.pythonhosted.org/packages/85/7d/125a5362180fcc1c03d91850fc020f3831d5cda09319522bcfa6b2b70be7/coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8", size = 252039, upload-time = "2024-12-26T16:58:36.072Z" }, - { url = "https://files.pythonhosted.org/packages/a9/9c/4358bf3c74baf1f9bddd2baf3756b54c07f2cfd2535f0a47f1e7757e54b3/coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098", size = 247758, upload-time = "2024-12-26T16:58:39.458Z" }, - { url = "https://files.pythonhosted.org/packages/cf/c7/de3eb6fc5263b26fab5cda3de7a0f80e317597a4bad4781859f72885f300/coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb", size = 250119, upload-time = "2024-12-26T16:58:41.018Z" }, - { url = "https://files.pythonhosted.org/packages/3e/e6/43de91f8ba2ec9140c6a4af1102141712949903dc732cf739167cfa7a3bc/coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0", size = 249597, upload-time = "2024-12-26T16:58:42.827Z" }, - { url = "https://files.pythonhosted.org/packages/08/40/61158b5499aa2adf9e37bc6d0117e8f6788625b283d51e7e0c53cf340530/coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf", size = 247473, upload-time = "2024-12-26T16:58:44.486Z" }, - { url = "https://files.pythonhosted.org/packages/50/69/b3f2416725621e9f112e74e8470793d5b5995f146f596f133678a633b77e/coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2", size = 248737, upload-time = "2024-12-26T16:58:45.919Z" }, - { url = "https://files.pythonhosted.org/packages/3c/6e/fe899fb937657db6df31cc3e61c6968cb56d36d7326361847440a430152e/coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312", size = 211611, upload-time = "2024-12-26T16:58:47.883Z" }, - { url = "https://files.pythonhosted.org/packages/1c/55/52f5e66142a9d7bc93a15192eba7a78513d2abf6b3558d77b4ca32f5f424/coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d", size = 212781, upload-time = "2024-12-26T16:58:50.822Z" }, { url = "https://files.pythonhosted.org/packages/40/41/473617aadf9a1c15bc2d56be65d90d7c29bfa50a957a67ef96462f7ebf8e/coverage-7.6.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:656c82b8a0ead8bba147de9a89bda95064874c91a3ed43a00e687f23cc19d53a", size = 207978, upload-time = "2024-12-26T16:58:52.834Z" }, { url = "https://files.pythonhosted.org/packages/10/f6/480586607768b39a30e6910a3c4522139094ac0f1677028e1f4823688957/coverage-7.6.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccc2b70a7ed475c68ceb548bf69cec1e27305c1c2606a5eb7c3afff56a1b3b27", size = 208415, upload-time = "2024-12-26T16:58:56.317Z" }, { url = "https://files.pythonhosted.org/packages/f1/af/439bb760f817deff6f4d38fe7da08d9dd7874a560241f1945bc3b4446550/coverage-7.6.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5e37dc41d57ceba70956fa2fc5b63c26dba863c946ace9705f8eca99daecdc4", size = 236452, upload-time = "2024-12-26T16:58:59.158Z" }, @@ -322,166 +315,16 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/77/86af525feb6a9951d2bc96371ae3652f11bb35933b21966abc594f777956/Django-4.2.15-py3-none-any.whl", hash = "sha256:61ee4a130efb8c451ef3467c67ca99fdce400fedd768634efc86a68c18d80d30", size = 7992797, upload-time = "2024-08-06T13:16:35.691Z" }, ] -[[package]] -name = "dummy" -version = "0.0.0" -source = { virtual = "." } -dependencies = [ - { name = "arrow" }, - { name = "asgiref" }, - { name = "attrs" }, - { name = "bazel-runfiles" }, - { name = "boto3" }, - { name = "botocore" }, - { name = "bravado" }, - { name = "bravado-core" }, - { name = "build" }, - { name = "certifi" }, - { name = "charset-normalizer" }, - { name = "click" }, - { name = "colorama" }, - { name = "coverage" }, - { name = "cowsay" }, - { name = "django" }, - { name = "exceptiongroup" }, - { name = "fqdn" }, - { name = "ftfy" }, - { name = "future" }, - { name = "gitdb" }, - { name = "gitpython" }, - { name = "idna" }, - { name = "importlib-metadata" }, - { name = "iniconfig" }, - { name = "isoduration" }, - { name = "jmespath" }, - { name = "jsonpointer" }, - { name = "jsonref" }, - { name = "jsonschema", extra = ["format-nongpl"] }, - { name = "jsonschema-specifications" }, - { name = "monotonic" }, - { name = "msgpack" }, - { name = "neptune" }, - { name = "numpy" }, - { name = "oauthlib" }, - { name = "packaging" }, - { name = "pandas" }, - { name = "pillow" }, - { name = "pluggy" }, - { name = "psutil" }, - { name = "pyjwt" }, - { name = "pyproject-hooks" }, - { name = "pytest" }, - { name = "python-dateutil" }, - { name = "pytz" }, - { name = "pyyaml" }, - { name = "referencing" }, - { name = "requests" }, - { name = "requests-oauthlib" }, - { name = "rfc3339-validator" }, - { name = "rfc3986-validator" }, - { name = "rpds-py" }, - { name = "s3transfer" }, - { name = "setuptools" }, - { name = "simplejson" }, - { name = "six" }, - { name = "smmap" }, - { name = "snakesay" }, - { name = "sqlparse" }, - { name = "swagger-spec-validator" }, - { name = "tomli" }, - { name = "types-python-dateutil" }, - { name = "typing-extensions" }, - { name = "tzdata" }, - { name = "uri-template" }, - { name = "urllib3" }, - { name = "wcwidth" }, - { name = "webcolors" }, - { name = "websocket-client" }, - { name = "zipp" }, -] - -[package.metadata] -requires-dist = [ - { name = "arrow", specifier = "==1.3.0" }, - { name = "asgiref", specifier = "==3.8.1" }, - { name = "attrs", specifier = "==23.2.0" }, - { name = "bazel-runfiles", specifier = "==1.1.0" }, - { name = "boto3", specifier = "==1.34.93" }, - { name = "botocore", specifier = "==1.34.93" }, - { name = "bravado", specifier = "==11.0.3" }, - { name = "bravado-core", specifier = "==6.1.1" }, - { name = "build", specifier = "==1.3.0" }, - { name = "certifi", specifier = "==2024.7.4" }, - { name = "charset-normalizer", specifier = "==3.3.2" }, - { name = "click", specifier = "==8.1.7" }, - { name = "colorama", specifier = "==0.4.6" }, - { name = "coverage", specifier = "==7.6.10" }, - { name = "cowsay", specifier = "==6.1" }, - { name = "django", specifier = "==4.2.15" }, - { name = "exceptiongroup", specifier = "==1.2.0" }, - { name = "fqdn", specifier = "==1.5.1" }, - { name = "ftfy", specifier = "==6.2.0" }, - { name = "future", specifier = "==1.0.0" }, - { name = "gitdb", specifier = "==4.0.12" }, - { name = "gitpython", specifier = "==3.1.43" }, - { name = "idna", specifier = "==3.7" }, - { name = "importlib-metadata", specifier = "==8.7.0" }, - { name = "iniconfig", specifier = "==2.0.0" }, - { name = "isoduration", specifier = "==20.11.0" }, - { name = "jmespath", specifier = "==1.0.1" }, - { name = "jsonpointer", specifier = "==2.4" }, - { name = "jsonref", specifier = "==1.1.0" }, - { name = "jsonschema", extras = ["format-nongpl"], specifier = "==4.21.1" }, - { name = "jsonschema-specifications", specifier = "==2023.12.1" }, - { name = "monotonic", specifier = "==1.6" }, - { name = "msgpack", specifier = "==1.0.8" }, - { name = "neptune", specifier = "==1.10.2" }, - { name = "numpy", specifier = "==1.26.4" }, - { name = "oauthlib", specifier = "==3.2.2" }, - { name = "packaging", specifier = "==24.0" }, - { name = "pandas", specifier = "==2.2.2" }, - { name = "pillow", specifier = "==10.3.0" }, - { name = "pluggy", specifier = "==1.4.0" }, - { name = "psutil", specifier = "==5.9.8" }, - { name = "pyjwt", specifier = "==2.8.0" }, - { name = "pyproject-hooks", specifier = "==1.2.0" }, - { name = "pytest", specifier = "==8.1.1" }, - { name = "python-dateutil", specifier = "==2.9.0.post0" }, - { name = "pytz", specifier = "==2024.1" }, - { name = "pyyaml", specifier = "==6.0.1" }, - { name = "referencing", specifier = "==0.35.0" }, - { name = "requests", specifier = "==2.31.0" }, - { name = "requests-oauthlib", specifier = "==2.0.0" }, - { name = "rfc3339-validator", specifier = "==0.1.4" }, - { name = "rfc3986-validator", specifier = "==0.1.1" }, - { name = "rpds-py", specifier = "==0.18.0" }, - { name = "s3transfer", specifier = "==0.10.1" }, - { name = "setuptools", specifier = "==80.9.0" }, - { name = "simplejson", specifier = "==3.19.2" }, - { name = "six", specifier = "==1.16.0" }, - { name = "smmap", specifier = "==5.0.1" }, - { name = "snakesay", specifier = "==0.10.3" }, - { name = "sqlparse", specifier = "==0.5.1" }, - { name = "swagger-spec-validator", specifier = "==3.0.3" }, - { name = "tomli", specifier = "==2.0.1" }, - { name = "types-python-dateutil", specifier = "==2.9.0.20240316" }, - { name = "typing-extensions", specifier = "==4.12.2" }, - { name = "tzdata", specifier = "==2024.1" }, - { name = "uri-template", specifier = "==1.3.0" }, - { name = "urllib3", specifier = "==1.26.19" }, - { name = "wcwidth", specifier = "==0.2.13" }, - { name = "webcolors", specifier = "==1.13" }, - { name = "websocket-client", specifier = "==1.8.0" }, - { name = "zipp", specifier = "==3.23.0" }, -] - [[package]] name = "exceptiongroup" -version = "1.2.0" +version = "1.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/1c/beef724eaf5b01bb44b6338c8c3494eff7cab376fab4904cfbbc3585dc79/exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68", size = 26264, upload-time = "2023-11-21T08:42:17.407Z" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b8/9a/5028fd52db10e600f1c4674441b968cf2ea4959085bfb5b99fb1250e5f68/exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", size = 16210, upload-time = "2023-11-21T08:42:15.525Z" }, + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] [[package]] @@ -549,14 +392,14 @@ wheels = [ [[package]] name = "importlib-metadata" -version = "8.7.0" +version = "8.7.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "zipp" }, + { name = "zipp", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload-time = "2025-04-27T15:29:01.736Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/49/3b30cad09e7771a4982d9975a8cbf64f00d4a1ececb53297f1d9a7be1b10/importlib_metadata-8.7.1.tar.gz", hash = "sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb", size = 57107, upload-time = "2025-12-21T10:00:19.278Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", size = 27656, upload-time = "2025-04-27T15:29:00.214Z" }, + { url = "https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl", hash = "sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151", size = 27865, upload-time = "2025-12-21T10:00:18.329Z" }, ] [[package]] @@ -646,6 +489,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ee/07/44bd408781594c4d0a027666ef27fab1e441b109dc3b76b4f836f8fd04fe/jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c", size = 18482, upload-time = "2023-12-25T15:16:51.997Z" }, ] +[[package]] +name = "maturin" +version = "1.11.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a4/84/bfed8cc10e2d8b6656cf0f0ca6609218e6fcb45a62929f5094e1063570f7/maturin-1.11.5.tar.gz", hash = "sha256:7579cf47640fb9595a19fe83a742cbf63203f0343055c349c1cab39045a30c29", size = 226885, upload-time = "2026-01-09T11:06:13.801Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/6c/3443d2f8c6d4eae5fc7479cd4053542aff4c1a8566d0019d0612d241b15a/maturin-1.11.5-py3-none-linux_armv6l.whl", hash = "sha256:edd1d4d35050ea2b9ef42aa01e87fe019a1e822940346b35ccb973e0aa8f6d82", size = 8845897, upload-time = "2026-01-09T11:06:17.327Z" }, + { url = "https://files.pythonhosted.org/packages/c5/03/abf1826d8aebc0d47ef6d21bdd752d98d63ac4372ad2b115db9cd5176229/maturin-1.11.5-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:2a596eab137cb3e169b97e89a739515abfa7a8755e2e5f0fc91432ef446f74f4", size = 17233855, upload-time = "2026-01-09T11:06:04.272Z" }, + { url = "https://files.pythonhosted.org/packages/90/a1/5ad62913271724035a7e4bcf796d7c95b4119317ae5f8cb034844aa99bc4/maturin-1.11.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:1c27a2eb47821edf26c75d100b3150b52dca2c1a5f074d7514af06f7a7acb9d5", size = 8881776, upload-time = "2026-01-09T11:06:10.24Z" }, + { url = "https://files.pythonhosted.org/packages/c6/66/997974b44f8d3de641281ec04fbf5b6ca821bdc8291a2fa73305978db74d/maturin-1.11.5-py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686.whl", hash = "sha256:f1320dacddcd3aa84a4bdfc77ee6fdb60e4c3835c853d7eb79c09473628b0498", size = 8870347, upload-time = "2026-01-09T11:06:12.178Z" }, + { url = "https://files.pythonhosted.org/packages/58/e0/c8fa042daf0608cc2e9a59b6df3a9e287bfc7f229136f17727f4118bac2d/maturin-1.11.5-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl", hash = "sha256:ffe7418834ff3b4a6c987187b7abb85ba033f4733e089d77d84e2de87057b4e7", size = 9291396, upload-time = "2026-01-09T11:06:02.05Z" }, + { url = "https://files.pythonhosted.org/packages/99/af/9d3edc8375efc8d435d5f24794bc4de234d4e743447592da970d53b31361/maturin-1.11.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:c739b243d012386902f112ea63a54a94848932b70ae3565fa5e121fd1c0200e0", size = 8827831, upload-time = "2026-01-09T11:06:19.523Z" }, + { url = "https://files.pythonhosted.org/packages/8a/12/cc341f6abbf9005f90935a4ee5dc7b30e2df7d1bb90b96d48b756b2c0ee7/maturin-1.11.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:8127d2cd25950bacbcdc8a2ec6daab1d4d27200f7d73964392680ad64d27f7f0", size = 8718895, upload-time = "2026-01-09T11:06:21.617Z" }, + { url = "https://files.pythonhosted.org/packages/76/17/654a59c66287e287373f2a0086e4fc8a23f0545a81c2bd6e324db26a5801/maturin-1.11.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le.whl", hash = "sha256:2a4e872fb78e77748217084ffeb59de565d08a86ccefdace054520aaa7b66db4", size = 11384741, upload-time = "2026-01-09T11:06:15.261Z" }, + { url = "https://files.pythonhosted.org/packages/2e/da/7118de648182971d723ea99d79c55007f96cdafc95f5322cc1ad15f6683e/maturin-1.11.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2079447967819b5cf615e5b5b99a406d662effdc8d6afd493dcd253c6afc3707", size = 9423814, upload-time = "2026-01-09T11:05:57.242Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8f/be14395c6e23b19ddaa0c171e68915bdcd1ef61ad1f411739c6721196903/maturin-1.11.5-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:50f6c668c1d5d4d4dc1c3ffec7b4270dab493e5b2368f8e4213f4bcde6a50eea", size = 9104378, upload-time = "2026-01-09T11:05:59.835Z" }, + { url = "https://files.pythonhosted.org/packages/77/83/53ea82a2f42a03930ea5545673d11a4ef49bb886827353a701f41a5f11c4/maturin-1.11.5-py3-none-win32.whl", hash = "sha256:49f85ce6cbe478e9743ecddd6da2964afc0ded57013aa4d054256be702d23d40", size = 7738696, upload-time = "2026-01-09T11:06:06.651Z" }, + { url = "https://files.pythonhosted.org/packages/3c/41/353a26d49aa80081c514a6354d429efbecedb90d0153ec598cece3baa607/maturin-1.11.5-py3-none-win_amd64.whl", hash = "sha256:70d3e5beffb9ef9dfae5f3c1a7eeb572091505eb8cb076e9434518df1c42a73b", size = 9029838, upload-time = "2026-01-09T11:05:54.543Z" }, + { url = "https://files.pythonhosted.org/packages/15/67/c94f8f5440bc42d54113a2d99de0d6107f06b5a33f31823e52b2715d856f/maturin-1.11.5-py3-none-win_arm64.whl", hash = "sha256:9348f7f0a346108e0c96e6719be91da4470bd43c15802435e9f4157f5cca43d4", size = 7624029, upload-time = "2026-01-09T11:06:08.728Z" }, +] + [[package]] name = "monotonic" version = "1.6" @@ -683,17 +550,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dd/06/adb6c8cdea18f9ba09b7dc1442b50ce222858ae4a85703420349784429d0/msgpack-1.0.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e2f879ab92ce502a1e65fce390eab619774dda6a6ff719718069ac94084098ce", size = 409109, upload-time = "2024-03-01T12:35:38.839Z" }, { url = "https://files.pythonhosted.org/packages/c6/d6/46eec1866b1ff58001a4be192ec43675620392de078fd4baf394f7d03552/msgpack-1.0.8-cp311-cp311-win32.whl", hash = "sha256:26ee97a8261e6e35885c2ecd2fd4a6d38252246f94a2aec23665a4e66d066305", size = 68779, upload-time = "2024-03-01T12:35:40.425Z" }, { url = "https://files.pythonhosted.org/packages/33/e9/f450b8e1243704c0ab656dcd37f6146881d11bbb68588132d8ae673c455b/msgpack-1.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:eadb9f826c138e6cf3c49d6f8de88225a3c0ab181a9b4ba792e006e5292d150e", size = 75180, upload-time = "2024-03-01T12:35:42.39Z" }, - { url = "https://files.pythonhosted.org/packages/97/73/757eeca26527ebac31d86d35bf4ba20155ee14d35c8619dd96bc80a037f3/msgpack-1.0.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:114be227f5213ef8b215c22dde19532f5da9652e56e8ce969bf0a26d7c419fee", size = 158948, upload-time = "2024-03-01T12:35:44.033Z" }, - { url = "https://files.pythonhosted.org/packages/11/df/558899a5f90d450e988484be25be0b49c6930858d6fe44ea6f1f66502fe5/msgpack-1.0.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d661dc4785affa9d0edfdd1e59ec056a58b3dbb9f196fa43587f3ddac654ac7b", size = 88696, upload-time = "2024-03-01T12:35:46.218Z" }, - { url = "https://files.pythonhosted.org/packages/99/3e/49d430df1e9abf06bb91e9824422cd6ceead2114662417286da3ddcdd295/msgpack-1.0.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d56fd9f1f1cdc8227d7b7918f55091349741904d9520c65f0139a9755952c9e8", size = 85428, upload-time = "2024-03-01T12:35:47.999Z" }, - { url = "https://files.pythonhosted.org/packages/54/f7/84828d0c6be6b7f0770777f1a7b1f76f3a78e8b6afb5e4e9c1c9350242be/msgpack-1.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0726c282d188e204281ebd8de31724b7d749adebc086873a59efb8cf7ae27df3", size = 396116, upload-time = "2024-03-01T12:35:50.114Z" }, - { url = "https://files.pythonhosted.org/packages/04/2a/c833a8503be9030083f0469e7a3c74d3622a3b4eae676c3934d3ccc01036/msgpack-1.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8db8e423192303ed77cff4dce3a4b88dbfaf43979d280181558af5e2c3c71afc", size = 408331, upload-time = "2024-03-01T12:35:52.632Z" }, - { url = "https://files.pythonhosted.org/packages/04/50/b988d0a8e8835f705e4bbcb6433845ff11dd50083c0aa43e607bb7b2ff96/msgpack-1.0.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99881222f4a8c2f641f25703963a5cefb076adffd959e0558dc9f803a52d6a58", size = 394182, upload-time = "2024-03-01T12:35:54.451Z" }, - { url = "https://files.pythonhosted.org/packages/98/e1/0d18496cbeef771db605b6a14794f9b4235d371f36b43f7223c1613969ec/msgpack-1.0.8-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b5505774ea2a73a86ea176e8a9a4a7c8bf5d521050f0f6f8426afe798689243f", size = 401226, upload-time = "2024-03-01T12:35:57.238Z" }, - { url = "https://files.pythonhosted.org/packages/03/79/ae000bde2aee4b9f0d50c1ca1ab301ade873b59dd6968c28f918d1cf8be4/msgpack-1.0.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ef254a06bcea461e65ff0373d8a0dd1ed3aa004af48839f002a0c994a6f72d04", size = 432994, upload-time = "2024-03-01T12:35:59.225Z" }, - { url = "https://files.pythonhosted.org/packages/cb/46/f97bedf3ab16d38eeea0aafa3ad93cc7b9adf898218961faaea9c3c639f1/msgpack-1.0.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e1dd7839443592d00e96db831eddb4111a2a81a46b028f0facd60a09ebbdd543", size = 410432, upload-time = "2024-03-01T12:36:01.516Z" }, - { url = "https://files.pythonhosted.org/packages/8f/59/db5b61c74341b6fdf2c8a5743bb242c395d728666cf3105ff17290eb421a/msgpack-1.0.8-cp312-cp312-win32.whl", hash = "sha256:64d0fcd436c5683fdd7c907eeae5e2cbb5eb872fafbc03a43609d7941840995c", size = 69255, upload-time = "2024-03-01T12:36:03.361Z" }, - { url = "https://files.pythonhosted.org/packages/72/5c/5facaa9b5d1b3ead831697daacf37d485af312bbe483ac6ecf43a3dd777f/msgpack-1.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:74398a4cf19de42e1498368c36eed45d9528f5fd0155241e82c4082b7e16cffd", size = 75348, upload-time = "2024-03-01T12:36:04.852Z" }, { url = "https://files.pythonhosted.org/packages/76/2f/a06b5ca0ba80aeb5f0b50449fb57a55c2c70bc495f2569442c743ed8478d/msgpack-1.0.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f51bab98d52739c50c56658cc303f190785f9a2cd97b823357e7aeae54c8f68a", size = 157945, upload-time = "2024-03-01T12:36:32.456Z" }, { url = "https://files.pythonhosted.org/packages/7a/c7/c95fe31dd0d7bf49fd3590df8e0089a8b9b18222909439d68dcc7973fd13/msgpack-1.0.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:73ee792784d48aa338bba28063e19a27e8d989344f34aad14ea6e1b9bd83f596", size = 88030, upload-time = "2024-03-01T12:36:34.051Z" }, { url = "https://files.pythonhosted.org/packages/42/fa/9379d11dd1b83570b2e9dc0d7c7e45aec2fb99d80540170f82d79f83132a/msgpack-1.0.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f9904e24646570539a8950400602d66d2b2c492b9010ea7e965025cb71d0c86d", size = 85101, upload-time = "2024-03-01T12:36:35.641Z" }, @@ -725,7 +581,6 @@ dependencies = [ { name = "pyjwt" }, { name = "requests" }, { name = "requests-oauthlib" }, - { name = "setuptools", marker = "python_full_version >= '3.12'" }, { name = "six" }, { name = "swagger-spec-validator" }, { name = "typing-extensions" }, @@ -759,14 +614,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/df/a0/4e0f14d847cfc2a633a1c8621d00724f3206cfeddeb66d35698c4e2cf3d2/numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", size = 18093567, upload-time = "2024-02-05T23:54:11.696Z" }, { url = "https://files.pythonhosted.org/packages/d2/b7/a734c733286e10a7f1a8ad1ae8c90f2d33bf604a96548e0a4a3a6739b468/numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", size = 5968812, upload-time = "2024-02-05T23:54:26.453Z" }, { url = "https://files.pythonhosted.org/packages/3f/6b/5610004206cf7f8e7ad91c5a85a8c71b2f2f8051a0c0c4d5916b76d6cbb2/numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", size = 15811913, upload-time = "2024-02-05T23:54:53.933Z" }, - { url = "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", size = 20335901, upload-time = "2024-02-05T23:55:32.801Z" }, - { url = "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", size = 13685868, upload-time = "2024-02-05T23:55:56.28Z" }, - { url = "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", size = 13925109, upload-time = "2024-02-05T23:56:20.368Z" }, - { url = "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", size = 17950613, upload-time = "2024-02-05T23:56:56.054Z" }, - { url = "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", size = 13572172, upload-time = "2024-02-05T23:57:21.56Z" }, - { url = "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", size = 17786643, upload-time = "2024-02-05T23:57:56.585Z" }, - { url = "https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", size = 5677803, upload-time = "2024-02-05T23:58:08.963Z" }, - { url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754, upload-time = "2024-02-05T23:58:36.364Z" }, { url = "https://files.pythonhosted.org/packages/7d/24/ce71dc08f06534269f66e73c04f5709ee024a1afe92a7b6e1d73f158e1f8/numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c", size = 20636301, upload-time = "2024-02-05T23:59:10.976Z" }, { url = "https://files.pythonhosted.org/packages/ae/8c/ab03a7c25741f9ebc92684a20125fbc9fc1b8e1e700beb9197d750fdff88/numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be", size = 13971216, upload-time = "2024-02-05T23:59:35.472Z" }, { url = "https://files.pythonhosted.org/packages/6d/64/c3bcdf822269421d85fe0d64ba972003f9bb4aa9a419da64b86856c9961f/numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764", size = 14226281, upload-time = "2024-02-05T23:59:59.372Z" }, @@ -824,13 +671,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/92/a2/b79c48f530673567805e607712b29814b47dcaf0d167e87145eb4b0118c6/pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db", size = 16286054, upload-time = "2024-04-10T19:44:50.51Z" }, { url = "https://files.pythonhosted.org/packages/40/c7/47e94907f1d8fdb4868d61bd6c93d57b3784a964d52691b77ebfdb062842/pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1", size = 13879507, upload-time = "2024-04-10T19:44:54.412Z" }, { url = "https://files.pythonhosted.org/packages/ab/63/966db1321a0ad55df1d1fe51505d2cdae191b84c907974873817b0a6e849/pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24", size = 11634249, upload-time = "2024-04-10T19:44:58.183Z" }, - { url = "https://files.pythonhosted.org/packages/dd/49/de869130028fb8d90e25da3b7d8fb13e40f5afa4c4af1781583eb1ff3839/pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef", size = 12500886, upload-time = "2024-04-10T19:45:01.808Z" }, - { url = "https://files.pythonhosted.org/packages/db/7c/9a60add21b96140e22465d9adf09832feade45235cd22f4cb1668a25e443/pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce", size = 11340320, upload-time = "2024-04-11T18:36:14.398Z" }, - { url = "https://files.pythonhosted.org/packages/b0/85/f95b5f322e1ae13b7ed7e97bd999160fa003424711ab4dc8344b8772c270/pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad", size = 15204346, upload-time = "2024-04-10T19:45:05.903Z" }, - { url = "https://files.pythonhosted.org/packages/40/10/79e52ef01dfeb1c1ca47a109a01a248754ebe990e159a844ece12914de83/pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad", size = 12733396, upload-time = "2024-04-10T19:45:09.282Z" }, - { url = "https://files.pythonhosted.org/packages/35/9d/208febf8c4eb5c1d9ea3314d52d8bd415fd0ef0dd66bb24cc5bdbc8fa71a/pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76", size = 15858913, upload-time = "2024-04-10T19:45:12.514Z" }, - { url = "https://files.pythonhosted.org/packages/99/d1/2d9bd05def7a9e08a92ec929b5a4c8d5556ec76fae22b0fa486cbf33ea63/pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32", size = 13417786, upload-time = "2024-04-10T19:45:16.275Z" }, - { url = "https://files.pythonhosted.org/packages/22/a5/a0b255295406ed54269814bc93723cfd1a0da63fb9aaf99e1364f07923e5/pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23", size = 11498828, upload-time = "2024-04-10T19:45:19.85Z" }, { url = "https://files.pythonhosted.org/packages/1b/cc/eb6ce83667131667c6561e009823e72aa5c76698e75552724bdfc8d1ef0b/pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2", size = 12566406, upload-time = "2024-04-10T19:45:24.254Z" }, { url = "https://files.pythonhosted.org/packages/96/08/9ad65176f854fd5eb806a27da6e8b6c12d5ddae7ef3bd80d8b3009099333/pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd", size = 11304008, upload-time = "2024-04-15T13:26:40.761Z" }, { url = "https://files.pythonhosted.org/packages/aa/30/5987c82fea318ac7d6bcd083c5b5259d4000e99dd29ae7a9357c65a1b17a/pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863", size = 15662279, upload-time = "2024-04-10T19:45:29.09Z" }, @@ -868,17 +708,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9c/f3/6e923786f2b2d167d16783fc079c003aadbcedc4995f54e8429d91aabfc4/pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09", size = 2217293, upload-time = "2024-04-01T12:17:48.292Z" }, { url = "https://files.pythonhosted.org/packages/0a/16/c83877524c47976f16703d2e05c363244bc1e60ab439e078b3cd046d07db/pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d", size = 2531332, upload-time = "2024-04-01T12:17:50.844Z" }, { url = "https://files.pythonhosted.org/packages/a8/3b/f64454549af90818774c3210b48987c3aeca5285787dbd69869d9a05b58f/pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f", size = 2229546, upload-time = "2024-04-01T12:17:53.237Z" }, - { url = "https://files.pythonhosted.org/packages/cc/5d/b7fcd38cba0f7706f64c1674fc9f018e4c64f791770598c44affadea7c2f/pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84", size = 3528535, upload-time = "2024-04-01T12:17:55.891Z" }, - { url = "https://files.pythonhosted.org/packages/5e/77/4cf407e7b033b4d8e5fcaac295b6e159cf1c70fa105d769f01ea2e1e5eca/pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19", size = 3352281, upload-time = "2024-04-01T12:17:58.527Z" }, - { url = "https://files.pythonhosted.org/packages/53/7b/4f7b153a776725a87797d744ea1c73b83ac0b723f5e379297605dee118eb/pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338", size = 4321427, upload-time = "2024-04-01T12:18:00.809Z" }, - { url = "https://files.pythonhosted.org/packages/45/08/d2cc751b790e77464f8648aa707e2327d6da5d95cf236a532e99c2e7a499/pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1", size = 4435915, upload-time = "2024-04-01T12:18:03.084Z" }, - { url = "https://files.pythonhosted.org/packages/ef/97/f69d1932cf45bf5bd9fa1e2ae57bdf716524faa4fa9fb7dc62cdb1a19113/pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462", size = 4347392, upload-time = "2024-04-01T12:18:05.319Z" }, - { url = "https://files.pythonhosted.org/packages/c6/c1/3521ddb9c1f3ac106af3e4512a98c785b6ed8a39e0f778480b8a4d340165/pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a", size = 4514536, upload-time = "2024-04-01T12:18:08.039Z" }, - { url = "https://files.pythonhosted.org/packages/c0/6f/347c241904a6514e59515284b01ba6f61765269a0d1a19fd2e6cbe331c8a/pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef", size = 4555987, upload-time = "2024-04-01T12:18:10.106Z" }, - { url = "https://files.pythonhosted.org/packages/c3/e2/3cc490c6b2e262713da82ce849c34bd8e6c31242afb53be8595d820b9877/pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3", size = 4623526, upload-time = "2024-04-01T12:18:12.172Z" }, - { url = "https://files.pythonhosted.org/packages/c1/b3/0209f70fa29b383e7618e47db95712a45788dea03bb960601753262a2883/pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d", size = 2217547, upload-time = "2024-04-01T12:18:14.188Z" }, - { url = "https://files.pythonhosted.org/packages/d3/23/3927d888481ff7c44fdbca3bc2a2e97588c933db46723bf115201377c436/pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b", size = 2531641, upload-time = "2024-04-01T12:18:16.081Z" }, - { url = "https://files.pythonhosted.org/packages/db/36/1ecaa0541d3a1b1362f937d386eeb1875847bfa06d5225f1b0e1588d1007/pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a", size = 2229746, upload-time = "2024-04-01T12:18:18.174Z" }, { url = "https://files.pythonhosted.org/packages/9b/7e/177e988989e86f57b9ac64da7dd898c53f7a663c1e14df33bb44c95132fc/pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936", size = 3528875, upload-time = "2024-04-01T12:18:42.897Z" }, { url = "https://files.pythonhosted.org/packages/45/94/af9bdb72d390001b1e9622892133b8cd90903a8cbba3a5e1eeecfe630faf/pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002", size = 3352924, upload-time = "2024-04-01T12:18:45.079Z" }, { url = "https://files.pythonhosted.org/packages/ef/cb/a3c20e6fc07bead46aa548b97dd05854424938e0544c9f788008a8c0fb77/pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60", size = 4305324, upload-time = "2024-04-01T12:18:47.357Z" }, @@ -1007,13 +836,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/03/5c/c4671451b2f1d76ebe352c0945d4cd13500adb5d05f5a51ee296d80152f7/PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", size = 748528, upload-time = "2023-08-28T18:43:23.207Z" }, { url = "https://files.pythonhosted.org/packages/73/9c/766e78d1efc0d1fca637a6b62cea1b4510a7fb93617eb805223294fef681/PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", size = 130286, upload-time = "2023-07-17T23:58:02.964Z" }, { url = "https://files.pythonhosted.org/packages/b3/34/65bb4b2d7908044963ebf614fe0fdb080773fc7030d7e39c8d3eddcd4257/PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", size = 144699, upload-time = "2023-07-17T23:58:05.586Z" }, - { url = "https://files.pythonhosted.org/packages/bc/06/1b305bf6aa704343be85444c9d011f626c763abb40c0edc1cad13bfd7f86/PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", size = 178692, upload-time = "2023-08-28T18:43:24.924Z" }, - { url = "https://files.pythonhosted.org/packages/84/02/404de95ced348b73dd84f70e15a41843d817ff8c1744516bf78358f2ffd2/PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", size = 165622, upload-time = "2023-08-28T18:43:26.54Z" }, - { url = "https://files.pythonhosted.org/packages/c7/4c/4a2908632fc980da6d918b9de9c1d9d7d7e70b2672b1ad5166ed27841ef7/PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef", size = 696937, upload-time = "2024-01-18T20:40:22.92Z" }, - { url = "https://files.pythonhosted.org/packages/b4/33/720548182ffa8344418126017aa1d4ab4aeec9a2275f04ce3f3573d8ace8/PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", size = 724969, upload-time = "2023-08-28T18:43:28.56Z" }, - { url = "https://files.pythonhosted.org/packages/4f/78/77b40157b6cb5f2d3d31a3d9b2efd1ba3505371f76730d267e8b32cf4b7f/PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", size = 712604, upload-time = "2023-08-28T18:43:30.206Z" }, - { url = "https://files.pythonhosted.org/packages/2e/97/3e0e089ee85e840f4b15bfa00e4e63d84a3691ababbfea92d6f820ea6f21/PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", size = 126098, upload-time = "2023-08-28T18:43:31.835Z" }, - { url = "https://files.pythonhosted.org/packages/2b/9f/fbade56564ad486809c27b322d0f7e6a89c01f6b4fe208402e90d4443a99/PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", size = 138675, upload-time = "2023-08-28T18:43:33.613Z" }, { url = "https://files.pythonhosted.org/packages/57/c5/5d09b66b41d549914802f482a2118d925d876dc2a35b2d127694c1345c34/PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", size = 197846, upload-time = "2023-07-17T23:59:46.424Z" }, { url = "https://files.pythonhosted.org/packages/0e/88/21b2f16cb2123c1e9375f2c93486e35fdc86e63f02e274f0e99c589ef153/PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", size = 174396, upload-time = "2023-07-17T23:59:49.538Z" }, { url = "https://files.pythonhosted.org/packages/ac/6c/967d91a8edf98d2b2b01d149bd9e51b8f9fb527c98d80ebb60c6b21d60c4/PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", size = 731824, upload-time = "2023-07-17T23:59:58.111Z" }, @@ -1118,19 +940,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/34/cc/57873b4a0f9787bab44e9cf196cfba92781b2354490ebc11a8fd0edd7c86/rpds_py-0.18.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a1ce3ba137ed54f83e56fb983a5859a27d43a40188ba798993812fed73c70836", size = 1361642, upload-time = "2024-02-13T21:52:35.482Z" }, { url = "https://files.pythonhosted.org/packages/5d/fa/9fbc98a7d75f37767952a405025acc0f02dbd708072a0375d62c826f6947/rpds_py-0.18.0-cp311-none-win32.whl", hash = "sha256:69e64831e22a6b377772e7fb337533c365085b31619005802a79242fee620bc1", size = 195062, upload-time = "2024-02-13T21:52:38.171Z" }, { url = "https://files.pythonhosted.org/packages/a8/de/68280c51afdb241111dec873dd7d457986adfd9fd5225494eee0c4a3b9a3/rpds_py-0.18.0-cp311-none-win_amd64.whl", hash = "sha256:998e33ad22dc7ec7e030b3df701c43630b5bc0d8fbc2267653577e3fec279afa", size = 206744, upload-time = "2024-02-13T21:52:40.189Z" }, - { url = "https://files.pythonhosted.org/packages/09/b6/45690f5d3f8c551bb462e063a2f336d72c8884ed26aa19beb53a374d3854/rpds_py-0.18.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7f2facbd386dd60cbbf1a794181e6aa0bd429bd78bfdf775436020172e2a23f0", size = 338820, upload-time = "2024-02-13T21:52:42.159Z" }, - { url = "https://files.pythonhosted.org/packages/7a/58/9bfc53b266df92f0515e72fd16e4890dc6b56fc3bfc216b3a2a729c866b5/rpds_py-0.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1d9a5be316c15ffb2b3c405c4ff14448c36b4435be062a7f578ccd8b01f0c4d8", size = 332988, upload-time = "2024-02-13T21:52:44.678Z" }, - { url = "https://files.pythonhosted.org/packages/5a/57/2fcfd462cc53876ac4acef69dbf4fb941da971440049ca72051da54ea60d/rpds_py-0.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd5bf1af8efe569654bbef5a3e0a56eca45f87cfcffab31dd8dde70da5982475", size = 1106717, upload-time = "2024-02-13T21:52:46.972Z" }, - { url = "https://files.pythonhosted.org/packages/a3/7e/37298d351e0b0ee6136a0663a0836c7dc22acbf4554835244aa40d9e5d43/rpds_py-0.18.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5417558f6887e9b6b65b4527232553c139b57ec42c64570569b155262ac0754f", size = 1120259, upload-time = "2024-02-13T21:52:50.37Z" }, - { url = "https://files.pythonhosted.org/packages/c9/26/285661286e0c3fe398082de9b3009cd25198f776484269f61d29f60ecbfb/rpds_py-0.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:56a737287efecafc16f6d067c2ea0117abadcd078d58721f967952db329a3e5c", size = 1219992, upload-time = "2024-02-13T21:52:52.785Z" }, - { url = "https://files.pythonhosted.org/packages/9a/8b/d446775cffcb0c07ea7183cc85e0ffd02bb25c68ce5bb248bf03ee5a2192/rpds_py-0.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8f03bccbd8586e9dd37219bce4d4e0d3ab492e6b3b533e973fa08a112cb2ffc9", size = 1276119, upload-time = "2024-02-13T21:52:54.962Z" }, - { url = "https://files.pythonhosted.org/packages/c3/96/2211a1ca4b4e259e222169074ec0fa41f0ee18665dfc68988a139dc7e6e8/rpds_py-0.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4457a94da0d5c53dc4b3e4de1158bdab077db23c53232f37a3cb7afdb053a4e3", size = 1115487, upload-time = "2024-02-13T21:52:57.657Z" }, - { url = "https://files.pythonhosted.org/packages/29/71/59074d37725cee2140cb9c3404fbfa70b2dcf037f2dcce3b7a4db3967f18/rpds_py-0.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0ab39c1ba9023914297dd88ec3b3b3c3f33671baeb6acf82ad7ce883f6e8e157", size = 1141402, upload-time = "2024-02-13T21:52:59.969Z" }, - { url = "https://files.pythonhosted.org/packages/f9/d9/355890b2273f3cbfb7666dfac80c6ac59ad8f97a7d6d4f24c444bed504ea/rpds_py-0.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9d54553c1136b50fd12cc17e5b11ad07374c316df307e4cfd6441bea5fb68496", size = 1357339, upload-time = "2024-02-13T21:53:02.852Z" }, - { url = "https://files.pythonhosted.org/packages/de/67/330d6f74a9ab37cf1597d5f7fb40437346b00dce15dc14c31aeb96762c56/rpds_py-0.18.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0af039631b6de0397ab2ba16eaf2872e9f8fca391b44d3d8cac317860a700a3f", size = 1381314, upload-time = "2024-02-13T21:53:05.995Z" }, - { url = "https://files.pythonhosted.org/packages/41/78/6be52bb734db3774c6093848774b4dd4d5866bc32bb208f2d335a6c9861b/rpds_py-0.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:84ffab12db93b5f6bad84c712c92060a2d321b35c3c9960b43d08d0f639d60d7", size = 1364328, upload-time = "2024-02-13T21:53:08.156Z" }, - { url = "https://files.pythonhosted.org/packages/55/96/3e9646719bc6a719951f32bb03069caaa873536ad6429b21b3a4059d2008/rpds_py-0.18.0-cp312-none-win32.whl", hash = "sha256:685537e07897f173abcf67258bee3c05c374fa6fff89d4c7e42fb391b0605e98", size = 195011, upload-time = "2024-02-13T21:53:11.052Z" }, - { url = "https://files.pythonhosted.org/packages/14/8c/e69f5636f4ab6ee0855aef3b16e6c97f8b636e9e04fa5a4bcc75126acb13/rpds_py-0.18.0-cp312-none-win_amd64.whl", hash = "sha256:e003b002ec72c8d5a3e3da2989c7d6065b47d9eaa70cd8808b5384fbb970f4ec", size = 206344, upload-time = "2024-02-13T21:53:13.815Z" }, { url = "https://files.pythonhosted.org/packages/58/7a/56cff95e24beb3cf1cb06fe41f60403694bf068f0dd3e8d99d2b47624f6c/rpds_py-0.18.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5307def11a35f5ae4581a0b658b0af8178c65c530e94893345bebf41cc139d33", size = 336109, upload-time = "2024-02-13T21:53:48.362Z" }, { url = "https://files.pythonhosted.org/packages/fc/82/4cc5a780f298a92ec5bfb1d7af33d16f07fe689b31a4dfc49f5ede267e88/rpds_py-0.18.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77f195baa60a54ef9d2de16fbbfd3ff8b04edc0c0140a761b56c267ac11aa467", size = 330993, upload-time = "2024-02-13T21:53:50.635Z" }, { url = "https://files.pythonhosted.org/packages/e8/3f/9b8c68d284b1a89186e73db5973c015f6f2ccdcd397e84ac472dc9ffe5d7/rpds_py-0.18.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39f5441553f1c2aed4de4377178ad8ff8f9d733723d6c66d983d75341de265ab", size = 1103983, upload-time = "2024-02-13T21:53:53.128Z" }, @@ -1221,19 +1030,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8e/75/79d7d95730716bfaf62249a60cf886a38b970178b34ca0f33f574c16f941/simplejson-3.19.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3e74355cb47e0cd399ead3477e29e2f50e1540952c22fb3504dda0184fc9819f", size = 149490, upload-time = "2023-10-06T08:33:54.893Z" }, { url = "https://files.pythonhosted.org/packages/db/d4/7dc3a98fe7bdeb508bcddfd56a3e6fa374fb969e59036d5210860e99e9ed/simplejson-3.19.2-cp311-cp311-win32.whl", hash = "sha256:1dd4f692304854352c3e396e9b5f0a9c9e666868dd0bdc784e2ac4c93092d87b", size = 73640, upload-time = "2023-10-06T08:33:56.203Z" }, { url = "https://files.pythonhosted.org/packages/b6/8e/3e12d122dfdf549a8d12eaf39954ee39f2027060aa38b63430f8ab3244e7/simplejson-3.19.2-cp311-cp311-win_amd64.whl", hash = "sha256:9300aee2a8b5992d0f4293d88deb59c218989833e3396c824b69ba330d04a589", size = 75342, upload-time = "2023-10-06T08:33:57.76Z" }, - { url = "https://files.pythonhosted.org/packages/19/2c/3f5d3c6e22cb9b7b9752bb5cc015b5e4dab07d20153fc10c3d546844b3e3/simplejson-3.19.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b8d940fd28eb34a7084877747a60873956893e377f15a32ad445fe66c972c3b8", size = 93639, upload-time = "2023-10-06T08:33:59.373Z" }, - { url = "https://files.pythonhosted.org/packages/77/8e/8ea7d30d181ef54c0db5815d4759053e7cbafd1c927d8ca56bf813c2b72c/simplejson-3.19.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4969d974d9db826a2c07671273e6b27bc48e940738d768fa8f33b577f0978378", size = 75887, upload-time = "2023-10-06T08:34:00.555Z" }, - { url = "https://files.pythonhosted.org/packages/30/21/aa7b0f14a3e1c0b5f98fff28384e7ff6adf86c8cd6de0958666e98e25200/simplejson-3.19.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c594642d6b13d225e10df5c16ee15b3398e21a35ecd6aee824f107a625690374", size = 74755, upload-time = "2023-10-06T08:34:01.727Z" }, - { url = "https://files.pythonhosted.org/packages/43/19/d171dde587cc41437720a852ee95c47fe9abc27631c3c8458ad1a5274b3a/simplejson-3.19.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2f5a398b5e77bb01b23d92872255e1bcb3c0c719a3be40b8df146570fe7781a", size = 150322, upload-time = "2023-10-06T08:34:03.385Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c2/f0aef8063535b70c27474538485797db8fec727e721f94cd6ea87ae3f962/simplejson-3.19.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:176a1b524a3bd3314ed47029a86d02d5a95cc0bee15bd3063a1e1ec62b947de6", size = 158545, upload-time = "2023-10-06T08:34:04.678Z" }, - { url = "https://files.pythonhosted.org/packages/3d/53/c37abc9b00f75b2ea03f2711382c37afe227b93813356efcd069af9e782a/simplejson-3.19.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3c7363a8cb8c5238878ec96c5eb0fc5ca2cb11fc0c7d2379863d342c6ee367a", size = 148631, upload-time = "2023-10-06T08:34:05.788Z" }, - { url = "https://files.pythonhosted.org/packages/f2/6b/ce0090a8026acc8ed027ec9471a551e02dafb7973674773fb218824130f9/simplejson-3.19.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:346820ae96aa90c7d52653539a57766f10f33dd4be609206c001432b59ddf89f", size = 152400, upload-time = "2023-10-06T08:34:07.184Z" }, - { url = "https://files.pythonhosted.org/packages/b7/c6/f605729a159b743ba5b258d7f963ed2b271c91486356b9997f6b96784843/simplejson-3.19.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de9a2792612ec6def556d1dc621fd6b2073aff015d64fba9f3e53349ad292734", size = 153636, upload-time = "2023-10-06T08:34:08.389Z" }, - { url = "https://files.pythonhosted.org/packages/cb/dd/1f65345ff1a6ba56e8de5ab62dead48cc50a5a3d01385fd8d56ead1bf163/simplejson-3.19.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1c768e7584c45094dca4b334af361e43b0aaa4844c04945ac7d43379eeda9bc2", size = 152968, upload-time = "2023-10-06T08:34:09.503Z" }, - { url = "https://files.pythonhosted.org/packages/03/ad/5465dc0560ef3f929ab6defd617a61121a3c01ddb912e1a6782a124b29ce/simplejson-3.19.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:9652e59c022e62a5b58a6f9948b104e5bb96d3b06940c6482588176f40f4914b", size = 161290, upload-time = "2023-10-06T08:34:10.636Z" }, - { url = "https://files.pythonhosted.org/packages/2d/18/d94495c7a4ec2ffd57717390c57270eb31440aef6b31abaeec668c8c89a4/simplejson-3.19.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9c1a4393242e321e344213a90a1e3bf35d2f624aa8b8f6174d43e3c6b0e8f6eb", size = 156935, upload-time = "2023-10-06T08:34:11.829Z" }, - { url = "https://files.pythonhosted.org/packages/84/9a/024fcc6b0aa26d1188dfe6333523648c3010f8758dcb19b7590d0b1ed51b/simplejson-3.19.2-cp312-cp312-win32.whl", hash = "sha256:7cb98be113911cb0ad09e5523d0e2a926c09a465c9abb0784c9269efe4f95917", size = 73667, upload-time = "2023-10-06T08:34:13.161Z" }, - { url = "https://files.pythonhosted.org/packages/e5/9f/9d53645ba325899e374633c818390d67378540ed346750b53c32e7ada34b/simplejson-3.19.2-cp312-cp312-win_amd64.whl", hash = "sha256:6779105d2fcb7fcf794a6a2a233787f6bbd4731227333a072d8513b252ed374f", size = 75443, upload-time = "2023-10-06T08:34:15.018Z" }, { url = "https://files.pythonhosted.org/packages/27/9f/76c4a2455ce3bca261e2e0351a3d9b36745a97fd0592680aefd28c3d9290/simplejson-3.19.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:445a96543948c011a3a47c8e0f9d61e9785df2544ea5be5ab3bc2be4bd8a2565", size = 94847, upload-time = "2023-10-06T08:35:00.998Z" }, { url = "https://files.pythonhosted.org/packages/fd/8d/04fe27f3b61ac4820d27a70a8531de72a813c4d33a6491b9dcc13f04ecbf/simplejson-3.19.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4a8c3cc4f9dfc33220246760358c8265dad6e1104f25f0077bbca692d616d358", size = 76394, upload-time = "2023-10-06T08:35:02.948Z" }, { url = "https://files.pythonhosted.org/packages/10/8e/e9c836c5bae09853caf64ca0d2d173d34daa46554c1a8782a7550f12c19b/simplejson-3.19.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af9c7e6669c4d0ad7362f79cb2ab6784d71147503e62b57e3d95c4a0f222c01c", size = 75455, upload-time = "2023-10-06T08:35:04.771Z" }, @@ -1302,11 +1098,20 @@ wheels = [ [[package]] name = "tomli" -version = "2.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f", size = 15164, upload-time = "2022-02-08T10:54:04.006Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", size = 12757, upload-time = "2022-02-08T10:54:02.017Z" }, +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c", size = 17477, upload-time = "2026-01-11T11:22:38.165Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867", size = 153663, upload-time = "2026-01-11T11:21:45.27Z" }, + { url = "https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9", size = 148469, upload-time = "2026-01-11T11:21:46.873Z" }, + { url = "https://files.pythonhosted.org/packages/d6/c2/506e44cce89a8b1b1e047d64bd495c22c9f71f21e05f380f1a950dd9c217/tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95", size = 236039, upload-time = "2026-01-11T11:21:48.503Z" }, + { url = "https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76", size = 243007, upload-time = "2026-01-11T11:21:49.456Z" }, + { url = "https://files.pythonhosted.org/packages/9c/6f/6e39ce66b58a5b7ae572a0f4352ff40c71e8573633deda43f6a379d56b3e/tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d", size = 240875, upload-time = "2026-01-11T11:21:50.755Z" }, + { url = "https://files.pythonhosted.org/packages/aa/ad/cb089cb190487caa80204d503c7fd0f4d443f90b95cf4ef5cf5aa0f439b0/tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576", size = 246271, upload-time = "2026-01-11T11:21:51.81Z" }, + { url = "https://files.pythonhosted.org/packages/0b/63/69125220e47fd7a3a27fd0de0c6398c89432fec41bc739823bcc66506af6/tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a", size = 96770, upload-time = "2026-01-11T11:21:52.647Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa", size = 107626, upload-time = "2026-01-11T11:21:53.459Z" }, + { url = "https://files.pythonhosted.org/packages/2f/6d/77be674a3485e75cacbf2ddba2b146911477bd887dda9d8c9dfb2f15e871/tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614", size = 94842, upload-time = "2026-01-11T11:21:54.831Z" }, + { url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a", size = 14477, upload-time = "2026-01-11T11:22:37.446Z" }, ] [[package]] diff --git a/uv/BUILD.bazel b/uv/BUILD.bazel deleted file mode 100644 index e69de29b..00000000 diff --git a/uv/private/BUILD.bazel b/uv/private/BUILD.bazel index 2b589f34..82b10616 100644 --- a/uv/private/BUILD.bazel +++ b/uv/private/BUILD.bazel @@ -5,33 +5,6 @@ package(default_visibility = [ "//uv/private:__subpackages__", ]) -bzl_library( - name = "extension", - srcs = ["extension.bzl"], - deps = [ - ":normalize_name", - ":parse_whl_name", - ":sccs", - ":sha1", - "//uv/private/constraints:repository", - "//uv/private/constraints/platform:defs", - "//uv/private/hub:repository", - "//uv/private/sdist_build:repository", - "//uv/private/tomltool:toml", - "//uv/private/venv_hub:repository", - "//uv/private/whl_install:repository", - "@bazel_tools//tools/build_defs/repo:cache.bzl", - "@bazel_tools//tools/build_defs/repo:http.bzl", - "@bazel_tools//tools/build_defs/repo:utils.bzl", - ], -) - -bzl_library( - name = "sccs", - srcs = ["sccs.bzl"], - deps = [], -) - bzl_library( name = "sha1", srcs = ["sha1.bzl"], diff --git a/uv/private/constraints/repository.bzl b/uv/private/constraints/repository.bzl index 97b760a6..48503f94 100644 --- a/uv/private/constraints/repository.bzl +++ b/uv/private/constraints/repository.bzl @@ -14,9 +14,32 @@ def _format_list(items): return "[\n" + "".join([" {},\n".format(repr(it)) for it in items]) + "]" def _constraints_hub_impl(repository_ctx): + """Generates a repository of `config_setting` targets. + + This rule materializes two kinds of `config_setting` targets into a central + repository, which are then used by other rules to implement platform-specific + logic: + + 1. Platform "triples": For each entry in the `configurations` attribute, + it creates a `config_setting_group` that represents a specific Python + platform (e.g., a combination of interpreter, platform, and ABI like + `cp39-manylinux_2_17_x86_64-cp39`). These are used by `whl_install` + to select the correct pre-built wheel. + + 2. Environment Markers: For each entry in the `markers` attribute, it + creates a `decide_marker` target. This custom rule evaluates a Python + environment marker expression (e.g., "sys_platform == 'linux'") and + creates a `config_setting` that is active when the marker evaluates + to true. These are used by `uv_lock` to handle conditional dependencies. + + Args: + repository_ctx: The repository context. + """ + ################################################################################ content = [ "load(\"@bazel_skylib//lib:selects.bzl\", \"selects\")", + "load(\"@aspect_rules_py//uv/private/markers:defs.bzl\", \"decide_marker\")", ] for name, conditions in repository_ctx.attr.configurations.items(): @@ -32,11 +55,23 @@ selects.config_setting_group( """.format(name, _format_list(conditions)), ) + for marker, id in repository_ctx.attr.markers.items(): + content.append( + """ +decide_marker( + name = {!r}, + marker = {!r}, + visibility = ["//visibility:public"], +) +""".format(id, marker), + ) + repository_ctx.file("BUILD.bazel", content = "\n".join(content)) configurations_hub = repository_rule( implementation = _constraints_hub_impl, attrs = { "configurations": attr.string_list_dict(), + "markers": attr.string_dict(), }, ) diff --git a/uv/private/defs.bzl b/uv/private/defs.bzl index 851c8a4f..f6135719 100644 --- a/uv/private/defs.bzl +++ b/uv/private/defs.bzl @@ -24,3 +24,13 @@ whl_mode_transition = transition( inputs = [], outputs = [LIB_MODE], ) + +def _whl_requirements_impl(ctx): + return [DefaultInfo(files = depset(transitive = [s.files for s in ctx.attr.srcs]))] + +whl_requirements = rule( + implementation = _whl_requirements_impl, + attrs = { + "srcs": attr.label_list(cfg = whl_mode_transition), + }, +) diff --git a/uv/private/extension.bzl b/uv/private/extension.bzl deleted file mode 100644 index 219a19a4..00000000 --- a/uv/private/extension.bzl +++ /dev/null @@ -1,1002 +0,0 @@ -""" -An implementation of fetching dependencies based on consuming UV's lockfiles. - -Follows in the footsteps of rules_js's pnpm support by consuming a lockfile -which contains enough information to produce a virtualenv without performing any -dynamic resolution. - -Relies on the lockfile to enumerate: -- Source distributions & their digests -- Prebuilt distribitons & their digests -- The dependencies of digests - -## Example - - uv = use_repo("@aspect_rules_py//uv:extension.bzl", "uv") - uv.declare_hub(hub_name = "uv") - - uv.declare_venv(hub_name = "uv", venv_name = "a") - uv.lockfile(hub_name = "uv", venv_name = "a", lockfile = "third_party/py/venvs/uv-a.lock") - - uv.declare_venv(hub_name = "uv", venv_name = "b") - uv.lockfile(hub_name = "uv", venv_name = "b", lockfile = "third_party/py/venvs/uv-b.lock") - - use_repo(uv, "uv") - -## Features - -- Supports cross-platform builds of wheels -- Supports hermetic source builds of wheels -- Automatically handles dependency cycles - -## Appendix - -[1] https://peps.python.org/pep-0751/ -[2] https://peps.python.org/pep-0751/#locking-build-requirements-for-sdists -""" - -# Note that platform constraints are specified by markers in the lockfile, they cannot be explicitly specified. - -# FIXME: Need to explicitly test a lockfile with platform-conditional deps (tensorflow cpu vs gpu mac/linux) - -load("@bazel_features//:features.bzl", features = "bazel_features") -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") -load("//uv/private/constraints:repository.bzl", "configurations_hub") -load("//uv/private/constraints/platform:defs.bzl", "supported_platform") -load("//uv/private/constraints/python:defs.bzl", "supported_python") -load("//uv/private/hub:repository.bzl", "hub_repo") -load("//uv/private/sdist_build:repository.bzl", "sdist_build") -load("//uv/private/tomltool:toml.bzl", "toml") -load("//uv/private/venv_hub:repository.bzl", "venv_hub") -load("//uv/private/whl_install:repository.bzl", "whl_install") -load(":normalize_name.bzl", "normalize_name") -load(":parse_whl_name.bzl", "parse_whl_name") -load(":sccs.bzl", "sccs") -load(":sha1.bzl", "sha1") - -def _ignored_package(package): - """ - Indicate whether the package manifest is something we're ignoring. - - This is a workaround for the lockfile package which represents the project itself. - - Args: - package (dict): A package record from a lockfile - - Returns: - bool indicating whether the package should be skipped - """ - - # Remote package sources - # - { source = { registry = "https://some.registry/..." } } - # - { source = { url = "https://ton.hosting.biz/some.whl" } } - # FIXME: Git URLs? - # FIXME: Egg URLs? - # - # These seem to be used by the package itself - # - { source = { editable = "." } } - # - { source = { virtual = "." } } - if "virtual" in package["source"] and package["source"]["virtual"] == ".": - return True - - return False - -def _parse_hubs(module_ctx): - """ - Parse hub declaration tags. - - Produces a hubs table we use to validate venv registrations. - - Args: - module_ctx (module_ctx): The Bazel module context - - Returns: - dict; parsed hub specs. - """ - - # As with `rules_python` hub names have to be globally unique :/ - hub_specs = {} - - # Collect all hubs, ensure we have no dupes - for mod in module_ctx.modules: - for hub in mod.tags.declare_hub: - hub_specs.setdefault(hub.hub_name, {}) - hub_specs[hub.hub_name][mod.name] = 1 - - # Note that we ARE NOT validating that the same hub name is registered by - # one and only one repository. This allows `@pypi` which we think should be - # the one and only conventional hub to be referenced by many modules since - # we disambiguate the build configuration on the "venv" not the hub. - - return hub_specs - -def _parse_venvs(module_ctx, hub_specs): - """ - Parse venv declaration tags. - - Validates against the parsed hub specs to produce appropriate errors. - - Produces a hub to venv table we use for validating lockfiles and overrides. - - Args: - module_ctx (module_ctx): The Bazel module context - hub_specs (dict): The previously parsed hub specs - - Returns: - dict; parsed venv specs. - """ - - venv_specs = {} - - problems = [] - - # Collect all hubs, ensure we have no dupes - for mod in module_ctx.modules: - for venv in mod.tags.declare_venv: - if venv.hub_name not in hub_specs or mod.name not in hub_specs[venv.hub_name]: - problems.append("Venv {} in {} refers to hub {} which is not configured for that module".format(venv.venv_name, venv.hub_name, mod.name)) - - venv_specs.setdefault(venv.hub_name, {}) - venv_specs[venv.hub_name][venv.venv_name] = 1 - - if problems: - fail("\n".join(problems)) - - return venv_specs - -def _parse_locks(module_ctx, venv_specs): - """ - Parse lockfile tags. - - Validates against parsed hubs and venvs to produce appropriate errors. - - Applies a bunch of package normalization here at the entrypoint before we forget. - - Produces a hub to venv to package to package descriptor mapping. - - Args: - module_ctx (module_ctx): The Bazel module context - venv_specs (dict): The previously parsed venv specs - - Returns: - dict; collected lockfiles. - """ - - lock_specs = {} - - # FIXME: Add support for setting a default venv on a venv hub - for mod in module_ctx.modules: - for lock in mod.tags.lockfile: - req_whls = {} - - if lock.hub_name not in venv_specs or lock.venv_name not in venv_specs[lock.hub_name]: - fail("Lock {} in {} refers to hub {} which is not configured for that module".format(lock.src, mod.name, lock.hub_name)) - - lock_specs.setdefault(lock.hub_name, {}) - if lock.venv_name in lock_specs[lock.hub_name]: - fail("Multiple lockfiles detected for hub %s venv %s!" % (lock.hub_name, lock.venv_name)) - - lockfile = toml.decode_file(module_ctx, lock.src) - if lockfile.get("version") != 1: - fail("Lockfile %s is an unsupported format version!" % lock.src) - - # Apply name mangling from PyPi package names to Bazel friendly - # package names here, once. - packages = lockfile.get("package", []) - for package in list(packages): - # Just remove ignored packages now rather than filtering them - # out over and over again. - if _ignored_package(package): - packages.remove(package) - continue - - package["name"] = normalize_name(package["name"]) - - # Mark that prebuilds are available for this package - req_whls[package["name"]] = package.get("wheels") - - if package["name"] == "private": - fail("Unable to parse lockfile %s due to reserved 'private' package which collides with implementation details" % lock.src) - - if "dependencies" in package: - for d in package["dependencies"]: - d["name"] = normalize_name(d["name"]) - - # Note that we also have to mangle the optional deps so they tie - # off too. We don't mangle group names because they're - # eliminated when we resolve the depgraph. - if "optional-dependencies" in package: - for _name, group in package["optional-dependencies"].items(): - for d in group: - d["name"] = normalize_name(d["name"]) - - problems = [] - has_tools = "build" in req_whls and "setuptools" in req_whls - for req, whls in req_whls.items(): - if not whls and not has_tools: - problems.append(req) - - if problems: - fail("""Error in lockfile {lockfile} - -The requirements `build` and `setuptools` are missing from, but the following requirements only provide sdists. -Please update your lockfile to provide build tools in order to enable sdist support. - -Problems: -{problems}""".format( - lockfile = lock.src, - problems = "\n".join( - [" - " + it for it in problems], - ), - )) - - # FIXME: Should validate the lockfile but for now just stash it - # Validating in starlark kinda rots anyway - lock_specs[lock.hub_name][lock.venv_name] = lockfile - - return lock_specs - -_default_annotations = struct( - per_package = {}, - default_build_deps = [ - {"name": "setuptools"}, - {"name": "build"}, - ], -) - -def _parse_annotations(module_ctx, hub_specs, venv_specs): - """ - Parse and validate requirement annotations. - - Requirement annotations allow us to attach stuff (build deps) to requirement - targets which the uv lockfile doesn't (currently) have a way to express. - - Returns a table from hub to venv to an annotations struct for that venv. - - Venv annotations structs are - - Dep = TypedDict({"name": str}) - record( - per_package=Dict[str, Annotation], - default_build_deps=List[Dep], - ) - - The annotations file is structured as follows: - - ``` - version = 0.0.0 - [[package]] - name = "foo" - native = true - build-dependencies = [ {name = "bar"} ] - ``` - - Args: - module_ctx (module_ctx): The Bazel module context - hub_specs (dict): The previously parsed hub specs - venv_specs (dict): The previously parsed venv specs - - Returns: - dict; collected requirement annotations. - """ - - annotation_specs = {} - - for mod in module_ctx.modules: - for ann in mod.tags.unstable_annotate_requirements: - if ann.hub_name not in hub_specs: - fail("Annotations file %s attaches to undefined hub %s" % (ann.src, ann.hub_name)) - - annotation_specs.setdefault(ann.hub_name, {}) - - if ann.venv_name not in venv_specs.get(ann.hub_name, {}): - fail("Annotations file %s attaches to undefined venv %s" % (ann.src, ann.venv_name)) - - # FIXME: Allow the default build deps to be changed - annotation_specs[ann.hub_name].setdefault(ann.venv_name, struct( - per_package = {}, - default_build_deps = [] + _default_annotations.default_build_deps, - )) - - ann_content = toml.decode_file(module_ctx, ann.src) - if ann_content.get("version") != "0.0.0": - fail("Annotations file %s doesn't specify a valid version= key" % ann.src) - - for package in ann_content.get("package", []): - if not "name" in package: - fail("Annotations file %s is invalid; all [[package]] entries must have a name" % ann.src) - - # Apply name normalization so we don't forget about it - package["name"] = normalize_name(package["name"]) - - if package["name"] in annotation_specs[ann.hub_name][ann.venv_name].per_package: - fail("Annotation conflict! Package %s is annotated in venv %s multiple times!" % (package["name"], ann.venv_name)) - - if "build-dependencies" in package: - for it in package["build-dependencies"]: - it["name"] = normalize_name(it["name"]) - - annotation_specs[ann.hub_name][ann.venv_name].per_package[package["name"]] = package - - return annotation_specs - -def _parse_overrides(module_ctx, lock_specs): - """ - Parse and validate override tags. - - Override tags allow users to replace a requirement's `install` target in a - venv with a different (presumably firstparty) Bazel target. - - Overridden targets will have their sdist and whl repos pruned from the build - graph, and don't have a conventional install target. - - Args: - module_ctx (module_ctx): The Bazel module context - lock_specs (dict): The previously parsed venv specs - - Returns: - dict; map of hub to venv to package to override label - - """ - - overrides = {} - - for mod in module_ctx.modules: - for override in mod.tags.override_requirement: - if override.hub_name not in lock_specs: - fail("Override %r references undeclared hub" % (override,)) - - # Insert a base mapping for the hub - overrides.setdefault(override.hub_name, {}) - - if override.venv_name not in lock_specs[override.hub_name]: - fail("Override %r references venv not in the hub" % (override,)) - - # Insert a base mapping for the venv - overrides[override.hub_name].setdefault(override.venv_name, {}) - - req = normalize_name(override.requirement) - if not any([it["name"] == req for it in lock_specs[override.hub_name][override.venv_name].get("package", [])]): - fail("Override for %r references a requirement not in venv %r of hub %r" % (req, override.venv_name, override.hub_name)) - - if req in overrides[override.hub_name][override.venv_name]: - fail("Override collision! Requirement %r of venv %r of hub %r has multiple overrides" % (req, override.venv_name, override.hub_name)) - - overrides[override.hub_name][override.venv_name][req] = override.target - - return overrides - -def _collect_configurations(_module_ctx, lock_specs): - # Set of wheel names which we're gonna do a second pass over to collect configuration names - - wheel_files = {} - - for _hub_name, venvs in lock_specs.items(): - for _venv_name, lock in venvs.items(): - for package in lock.get("package", []): - for whl in package.get("wheels", []): - url = whl["url"] - wheel_name = url.split("/")[-1] # Find the trailing file name - wheel_files[wheel_name] = 1 - - abi_tags = {} - platform_tags = {} - python_tags = {} - - # Platform definitions from groups of configs - configurations = {} - - for wheel_name in wheel_files.keys(): - parsed_wheel = parse_whl_name(wheel_name) - for python_tag in parsed_wheel.python_tags: - # Ignore configurations for unsupported interpreters - if not supported_python(python_tag): - continue - - python_tags[python_tag] = 1 - - for platform_tag in parsed_wheel.platform_tags: - # Ignore configurations for unsupported platforms - if not supported_platform(platform_tag): - continue - - platform_tags[platform_tag] = 1 - - for abi_tag in parsed_wheel.abi_tags: - abi_tags[abi_tag] = 1 - - # Note that we are NOT filtering out - # impossible/unsatisfiable python+abi tag possibilities. - # It's not aesthetic but it is simple enough. - configuration = "{}-{}-{}".format(python_tag, platform_tag, abi_tag) - - configurations[configuration] = [ - "@aspect_rules_py//uv/private/constraints/platform:{}".format(platform_tag), - "@aspect_rules_py//uv/private/constraints/abi:{}".format(abi_tag), - "@aspect_rules_py//uv/private/constraints/python:{}".format(python_tag), - ] - - return configurations - -def _sdist_repo_name(package): - """We key sdist repos strictly by their name and content hash.""" - - return "sdist__{}__{}".format( - package["name"], - package["sdist"]["hash"][len("shasum:"):][:8], - ) - -def _raw_sdist_repos(_module_ctx, lock_specs, override_specs): - # Map of hub -> venv -> requirement -> version -> repo name - repo_defs = {} - - for hub_name, venvs in lock_specs.items(): - for venv_name, lock in venvs.items(): - for package in lock.get("package", []): - # This is an overridden package, don't declare repos for it - if override_specs.get(hub_name, {}).get(venv_name, {}).get(package["name"]): - continue - - sdist = package.get("sdist") - if sdist == None: - continue - - # Note that for source=url=... packages, the URL may not be - # repeated in the sdist spec so we have to replicate it down. - url = sdist.get("url", package["source"].get("url")) - shasum = sdist["hash"][len("sha256:"):] - - # FIXME: Do we need to factor in the shasum or source her? Could - # have two or more sources for one "artifact". - # - # Assume (potentially a problem!) - name = _sdist_repo_name(package) - downloaded_file_path = url.split("/")[-1] - spec = dict( - name = name, - downloaded_file_path = downloaded_file_path, - urls = [url], - sha256 = shasum, - ) - if name not in repo_defs: - repo_defs[name] = spec - elif name in repo_defs and url not in repo_defs[name]["urls"]: - repo_defs[name]["urls"].append(url) - - # FIXME: May need to thread netrc or other credentials through to here? - for spec in repo_defs.values(): - http_file(**spec) - -def _whl_repo_name(package, whl): - """Get the repo name for a whl.""" - - return "whl__{}__{}".format( - package["name"], - whl["hash"][len("shasum:"):][:8], - ) - -def _raw_whl_repos(_module_ctx, lock_specs, override_specs): - repo_defs = {} - - for hub_name, venvs in lock_specs.items(): - for venv_name, lock in venvs.items(): - for package in lock.get("package", []): - # This is an overridden package, don't declare repos for it - if override_specs.get(hub_name, {}).get(venv_name, {}).get(package["name"]): - continue - - wheels = package.get("wheels", []) - for whl in wheels: - url = whl["url"] - shasum = whl["hash"][len("sha256:"):] - - # FIXME: Do we need to factor in the shasum or source her? Could - # have two or more sources for one "artifact". - # - # Assume (potentially a problem!) - name = _whl_repo_name(package, whl) - - # print("Creating whl repo", name) - downloaded_file_path = url.split("/")[-1] - spec = dict( - name = name, - downloaded_file_path = downloaded_file_path, - urls = [url], - sha256 = shasum, - ) - repo_defs[name] = spec - - # FIXME: May need to thread netrc or other credentials through to here? - for spec in repo_defs.values(): - http_file(**spec) - -def _sbuild_repo_name(hub, venv, package): - """Get the repo name for a sdist build.""" - - return "sbuild__{}__{}__{}".format( - hub, - venv, - package["name"], - ) - -def _venv_target(hub_name, venv, package_name): - """Get the venv hub spoke for a given package.""" - - return "{}//{}".format( - _venv_hub_name(hub_name, venv), - package_name, - ) - -def _sbuild_repos(_module_ctx, lock_specs, annotation_specs, override_specs): - """ - Lay down sdist build repos for each configured sdist. - """ - - for hub_name, venvs in lock_specs.items(): - for venv_name, lock in venvs.items(): - for package in lock.get("package", []): - # This is an overridden package, don't declare a repo for it - if override_specs.get(hub_name, {}).get(venv_name, {}).get(package["name"]): - continue - - if "sdist" not in package: - continue - - name = _sbuild_repo_name(hub_name, venv_name, package) - - venv_anns = annotation_specs.get(hub_name, {}).get(venv_name, _default_annotations) - build_deps = venv_anns.per_package.get(package["name"], {}).get("build-dependencies", []) - - # Per-package build deps, plus global defaults - build_deps = { - it["name"]: it - for it in build_deps + venv_anns.default_build_deps - } - - # TODO: Need a better native strategy. - # - # We need to decide if the sdist we're building contains native - # extensions. For now we're relying on user-provided annotations - # to do that. - # - # It would be better for the sdist_build repo rule to inspect - # the sdist's contents and search for well known file types such - # as `pyx` and `cxx`. That would also make it easier to support - # for instance Rust extensions. This would work from a phasing - # perspective because we declare sdist archives separately, so - # the repo rule for deciding whether an sdist build is native or - # not can run (prebuilt) tools to inspect downloaded archives. - is_native = ( - # Cythonized code - "cython" in build_deps or - # Mypyc code - "mypy" in build_deps or - # User has annotated the package as using C extensions or such - venv_anns.per_package.get(package["name"], {}).get("native", False) - ) - - # TODO: What if the build needs toolchains? (cc, etc.) - sdist_build( - name = name, - src = "@" + _sdist_repo_name(package) + "//file", - # FIXME: Add support for build deps and annotative build deps - deps = [ - "@" + _venv_target(hub_name, venv_name, package["name"]) - for package in build_deps.values() - ], - is_native = is_native, - ) - -def _whl_install_repo_name(hub, venv, package): - """Get the whl install repo name for a given package.""" - - return "whl_install__{}__{}__{}".format( - hub, - venv, - package["name"], - ) - -# TODO: Move this to a real library -def _parse_ini(lines): - """ - Quick and dirty INI parser - - Handles basic INI format tables of key-value pairs, returning a dict. - Ignores top level/sectionless keys. - """ - dict = {} - heading = None - for line in lines.split("\n"): - line = line.strip() - if line.startswith("[") and line.endswith("]"): - heading = line[1:-2] - dict[heading] = {} - - elif "=" in line and heading: - key, value = line.split("=", 1) - key = key.strip() - value = value.strip() - dict[heading][key] = value - - return dict - -def _collect_entrypoints(module_ctx, lock_specs, annotation_specs): - entrypoints = {} - - # Collect predeclared entrypoints - for mod in module_ctx.modules: - for it in mod.tags.declare_entrypoint: - r = normalize_name(it.requirement) - entrypoints.setdefault(r, {}) - - # FIXME: Apply normalization here? - entrypoints[r][it.name] = it.entrypoint - - # Collect entrypoints from annotation specifications - for hub_name, venvs in annotation_specs.items(): - for venv_name, venv_struct in venvs.items(): - # print(hub_name, venv_name, venv_struct) - for package_name, package in venv_struct.per_package.items(): - entrypoints.setdefault(package_name, {}) - scripts = package.get("entry-points", {}).get("console-scripts", {}) - for name, target in scripts.items(): - # FIXME: Apply normalization here? - entrypoints[package_name][name] = target - - return entrypoints - -def _whl_install_repos(module_ctx, lock_specs, override_specs): - for hub_name, venvs in lock_specs.items(): - for venv_name, lock in venvs.items(): - for package in lock.get("package", []): - # This is an overridden package, don't declare a repo for it - if override_specs.get(hub_name, {}).get(venv_name, {}).get(package["name"]): - continue - - # This is where we need to actually choose which wheel we will - # "install", and so this is where prebuild selection needs to - # happen according to constraints. - prebuilds = {} - for whl in package.get("wheels", []): - prebuilds[whl["url"].split("/")[-1]] = _whl_repo_name(package, whl) + "//file" - - # FIXME: This should accept a common constraint for when to - # choose source builds over prebuilds. - - # FIXME: Needs to explicitly mark itself as being compatible - # only with the single venv. Shouldn't be possible to force this - # target to build when the venv hub is not pointed to this venv. - name = _whl_install_repo_name(hub_name, venv_name, package) - - # print("Creating install repo", hub_name, venv_name, name) - whl_install( - name = name, - prebuilds = json.encode(prebuilds), - sbuild = "@" + _sbuild_repo_name(hub_name, venv_name, package) + "//:whl" if "sdist" in package else None, - ) - -def _venv_hub_name(hub, venv): - return "venv__{}__{}".format( - hub, - venv, - ) - -def _marker_sha(marker): - if marker: - return sha1(marker)[:8] - else: - return None - -def _group_repos(module_ctx, lock_specs, entrypoint_specs, override_specs): - # Hub -> requirement -> venv -> True - # For building hubs we need to know what venv configurations a given - - package_venvs = {} - - for hub_name, venvs in lock_specs.items(): - package_venvs[hub_name] = {} - - for venv_name, lock in venvs.items(): - # Index all the packages by name so activating extras is easy - packages = { - package["name"]: package - for package in lock.get("package", []) - } - - # Graph of {marker shasum: raw marker expr} - markers = {} - - # Build a graph {name: {dependency_name: marker shasum}} - graph = {} - - for name, package in packages.items(): - deps = {} - - if package.get("marker"): - fail("In venv %s package %s is marked which is unsupported" % (venv_name, package["name"])) - - # Enter the package into the venv internal graph - graph.setdefault(package["name"], {}) - - for d in package.get("dependencies", []): - marker = d.get("marker", "") - msha = _marker_sha(marker) - - # If a marker expr is present, intern it - if msha: - markers[msha] = marker - - # Add this dep to the set with the marker if any - graph[package["name"]][d["name"]] = msha - - # Assume all extras are activated - extras = packages[d["name"]].get("optional-dependencies", {}) - for extra in d.get("extra", []): - for extra_dep in extras.get(extra, []): - # This should never happen, but if we do have a - # reference in an extra to an inactive package we - # want to ignore it. - if extra_dep["name"] not in packages: - continue - - graph.setdefault(d["name"], {}) - marker = extra_dep.get("marker", "") - msha = _marker_sha(marker) - - # If a marker expr is present, intern it - if msha: - markers[msha] = marker - - # Add this dep to the set with the marker if any - graph[d["name"]][extra_dep["name"]] = msha - - # Enter the package into the venv hub manifest - package_venvs[hub_name].setdefault(package["name"], {}) - package_venvs[hub_name][package["name"]][venv_name] = 1 - - # So we can find sccs/clusters which need to co-occur - # Note that we're assuming ALL marker conditional deps are live. - cycle_groups = sccs({k: v.keys() for k, v in graph.items()}) - # print(hub_name, venv_name, graph, cycle_groups) - - # Now we can assign names to the sccs and collect deps. Note that - # _every_ node in the graph will be in _a_ scc, those sccs are just - # size 1 if the node isn't part of a cycle. - # - # Rather than trying to handle size-1 clusters separately which adds - # implementation complexity we handle all clusters the same. - named_sccs = {} - scc_aliases = {} - - # scc id -> requirement -> marker IDs -> 1 - scc_markers = {} - deps = {} - for scc in cycle_groups: - # Make up a deterministic name for the scc. What it is doesn't - # matter. Could be gensym-style numeric too, but this is stable - # to the cycle's content rather than the order of the lockfile. - name = sha1(repr(scc))[:8] - deps[name] = {} - scc_markers[name] = {} - named_sccs[name] = scc - - for node in scc: - # Mark scc component with an alias - scc_aliases[node] = name - - # Mark the scc as depending on this package because it does - deps[name][node] = 1 - - # We know we've never visited node before so this is an assign - scc_markers[name][node] = {} - - # FIXME: we are PURPOSEFULLY ignoring the potential that the - # dependency on this package within the scc goes through a - # dependency edge with a marker. Dependencies within the scc - # are always activated. This may cause problems. - for it in scc: - marker = markers.get(node, {}).get(it) - if marker: - fail("In venv %s package %s and %s form a cycle which may be marker-conditional! This is not supported" % (venv_name, node, it)) - - # Collect deps of the component which are not in the scc. We - # use dict-to-one as a set because there could be multiple - # members of an scc which take a dependency on the same - # thing outside the scc. - for d in graph[node]: - # Copy in the marker from node -> d if any - marker = graph[node].get(d) - if marker: - scc_markers[name].setdefault(d, {}) - scc_markers[name][d][marker] = 1 - - if d not in scc: - deps[name][d] = 1 - - # Simplify the scc markers to scc -> dep -> list[marker id] - scc_markers = { - scc_id: {dep: markers.keys() for dep, markers in deps.items()} - for scc_id, deps in scc_markers.items() - } - - # TODO: How do we plumb markers through here? The packages - # themselves may have markers. Furthermore dependencies ON the - # packages may have markers. - # - # Reviewing some (hopefully representative) markers it seems - # unlikely that cycles would activate _through_ marker/conditional - # dependencies. That is a conditional dependency edge's activation - # creates an otherwise absent cycle. The most common application of - # markers is to implement platform support and compatibility deps. - # - # On this basis we _ASSUME_ that this will never happen and all we - # need to do is implement conditionals - - # At this point we have mapped every package to an scc (possibly of - # size 1) which it participates in, named those sccs, and identified - # their direct dependencies beyond the scc. So we can just lay down - # targets. - name = _venv_hub_name(hub_name, venv_name) - - overrides = override_specs.get(hub_name, {}).get(venv_name, {}) - - # print("Creating venv hub", name) - venv_hub( - name = name, - aliases = scc_aliases, # String dict - markers = markers, # String dict - sccs = named_sccs, # List[String] dict - scc_markers = json.encode(scc_markers), # Mangle to String - deps = deps, # List[String] dict - installs = { - # Use an override symbol if one exists, otherwise use the whl install repo. - # Note that applying an override will cause the whl install to be elided. - package: str(overrides.get(package, _whl_install_repo_name(hub_name, venv_name, {"name": package}))) - for package in sorted(graph.keys()) - }, - entrypoints = json.encode(entrypoint_specs), - ) - - return package_venvs - -def _hub_repos(module_ctx, lock_specs, package_venvs, entrypoint_specs): - for hub_name, packages in package_venvs.items(): - # print("Creating uv hub", hub_name) - hub_repo( - name = hub_name, - hub_name = hub_name, - venvs = lock_specs[hub_name].keys(), - packages = { - package: venvs.keys() - for package, venvs in packages.items() - }, - entrypoints = json.encode(entrypoint_specs), - ) - -def _uv_impl(module_ctx): - """ - And now for the easy bit. - - - Collect hub configurations - - Collect venv configurations per hub - - Collect and parse lockfiles per venv per hub - - Collect annotations and overrides per venv and hub - - Generate sdist fetches for every locked package - - Generate sdist to whl builds for every locked package - - Generate whl fetches for every locked package - - Generate an install choosing between a sdist build and a prebuilt whl for every package - - For each venv generate a hub over the installs of packages in that venv - - For each hub generate a hub fanning out to the venvs which make up the hub - - Note that we also generate a config repo which is used to introspect the - host platform and establish flag default values so the default configuration - is appropriate for the host platform. - - """ - - hub_specs = _parse_hubs(module_ctx) - - venv_specs = _parse_venvs(module_ctx, hub_specs) - - lock_specs = _parse_locks(module_ctx, venv_specs) - - annotation_specs = _parse_annotations(module_ctx, hub_specs, venv_specs) - - # Roll through all the configured wheels, collect & validate the unique - # platform configurations so that we can go create an appropriate power set - # of conditions. - configurations = _collect_configurations(module_ctx, lock_specs) - - # Collect declared entrypoints for packages - entrypoints = _collect_entrypoints(module_ctx, lock_specs, annotation_specs) - - # Roll through and collect overrides of requirements with targets - override_specs = _parse_overrides(module_ctx, lock_specs) - - # Roll through and create sdist and whl repos for all configured sources - # Note that these have no deps to this point - _raw_sdist_repos(module_ctx, lock_specs, override_specs) - _raw_whl_repos(module_ctx, lock_specs, override_specs) - - # Roll through and create per-venv sdist build repos - _sbuild_repos(module_ctx, lock_specs, annotation_specs, override_specs) - - # Roll through and create per-venv whl installs - # - # Note that we handle entrypoints at the venv level NOT the install level. - # This is because we handle cycle breaking and deps at the venv level, so we - # can't just take a direct dependency on the installed whl in its - # implementation repo. - _whl_install_repos(module_ctx, lock_specs, override_specs) - - # Roll through and create per-venv group/dep layers - package_venvs = _group_repos(module_ctx, lock_specs, entrypoints, override_specs) - - # Finally the hubs themselves are fully trivialized - _hub_repos(module_ctx, lock_specs, package_venvs, entrypoints) - - configurations_hub( - name = "aspect_rules_py_pip_configurations", - configurations = configurations, - ) - - if features.external_deps.extension_metadata_has_reproducible: - return module_ctx.extension_metadata(reproducible = True) - -_hub_tag = tag_class( - attrs = { - "hub_name": attr.string(mandatory = True), - }, -) - -_venv_tag = tag_class( - attrs = { - "hub_name": attr.string(mandatory = True), - "venv_name": attr.string(mandatory = True), - }, -) - -_lockfile_tag = tag_class( - attrs = { - "hub_name": attr.string(mandatory = True), - "venv_name": attr.string(mandatory = True), - "src": attr.label(mandatory = True), - }, -) - -_annotations_tag = tag_class( - attrs = { - "hub_name": attr.string(mandatory = True), - "venv_name": attr.string(mandatory = True), - "src": attr.label(mandatory = True), - }, -) - -_declare_entrypoint = tag_class( - attrs = { - "requirement": attr.string(mandatory = True), - "name": attr.string(mandatory = True), - "entrypoint": attr.string(mandatory = True), - }, -) - -_override_requirement = tag_class( - attrs = { - "hub_name": attr.string(mandatory = True), - "venv_name": attr.string(mandatory = True), - "requirement": attr.string(mandatory = True), - "target": attr.label(mandatory = True), - }, -) - -uv = module_extension( - implementation = _uv_impl, - tag_classes = { - "declare_hub": _hub_tag, - "declare_venv": _venv_tag, - "lockfile": _lockfile_tag, - "unstable_annotate_requirements": _annotations_tag, - "declare_entrypoint": _declare_entrypoint, - "override_requirement": _override_requirement, - }, -) diff --git a/uv/private/extension/BUILD.bazel b/uv/private/extension/BUILD.bazel new file mode 100644 index 00000000..53a47575 --- /dev/null +++ b/uv/private/extension/BUILD.bazel @@ -0,0 +1,14 @@ +# TOOLCHAIN_DEPS +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +load(":test_graph_utils.bzl", "graph_utils_test_suite") + +bzl_library( + name = "defs", + srcs = [ + "defs.bzl", + ], + visibility = ["//uv:__subpackages__"], +) + +graph_utils_test_suite() diff --git a/uv/private/extension/defs.bzl b/uv/private/extension/defs.bzl new file mode 100644 index 00000000..50c109e6 --- /dev/null +++ b/uv/private/extension/defs.bzl @@ -0,0 +1,525 @@ +"""A Bazel module extension for resolving Python dependencies from a `uv.lock` file. + +This extension provides a mechanism for resolving Python dependencies declared in a +`pyproject.toml` and locked in a `uv.lock` file. It generates a dependency graph, +handles platform-specific constraints, and creates repository rules for fetching +pre-built wheels (bdists) or building wheels from source (sdists). + +The extension is designed to handle complex dependency scenarios, including: +- Cross-platform builds for different operating systems and architectures. +- Hermetic builds of source distributions. +- Dependency cycles, which are resolved by computing the strongly connected + components (SCCs) of the dependency graph. + +## Example + +The following example shows how to use the `uv` module extension in a `MODULE.bazel` +file: + +```starlark +uv = use_extension("@aspect_rules_py//uv:extension.bzl", "uv") +uv.hub(name = "uv") +uv.project( + hub_name = "uv", + name = "my_project", + pyproject = "//:pyproject.toml", + lock = "//:uv.lock", +) +use_repo(uv, "uv") +``` + +This configuration declares a `uv` hub and registers a project with its +`pyproject.toml` and `uv.lock` files. The `use_repo` directive then makes the +resolved dependencies available in the `@uv` repository. + +## Common Types + +- **Dependency:** A tuple of `(project_id, package_name, version, extra)` that + uniquely identifies a package within a lockfile. `project_id` is a unique + identifier for the lockfile, `package_name` is the normalized name of the + package, `version` is the package version, and `extra` is the optional extra + (or `__base__` for the base package). +- **Marker:** A string representing a PEP 508 marker, used to specify + environment-specific dependencies (e.g., + `"sys_platform == 'linux'"`). +- **SCC:** A Strongly Connected Component, which is a set of packages that have + cyclic dependencies on each other. + +## Appendix + +[1] https://peps.python.org/pep-0751/ +[2] https://peps.python.org/pep-0751/#locking-build-requirements-for-sdists +""" + +load("@bazel_features//:features.bzl", features = "bazel_features") +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") +load("//uv/private:normalize_name.bzl", "normalize_name") +load("//uv/private/constraints:repository.bzl", "configurations_hub") +load("//uv/private/git_archive:repository.bzl", "git_archive") +load("//uv/private/pprint:defs.bzl", "pprint") +load("//uv/private/sdist_build:repository.bzl", "sdist_build") +load("//uv/private/tomltool:toml.bzl", "toml") +load("//uv/private/uv_hub:repository.bzl", "uv_hub") +load("//uv/private/uv_project:repository.bzl", "uv_project") +load("//uv/private/whl_install:repository.bzl", "whl_install") +load(":graph_utils.bzl", "activate_extras", "collect_sccs") +load(":lockfile.bzl", "build_marker_graph", "collect_bdists", "collect_configurations", "collect_markers", "collect_sdists", "normalize_deps") +load(":projectfile.bzl", "collate_versions_by_name", "collect_activated_extras", "extract_requirement_marker_pairs") + +def _parse_hubs(module_ctx): + """Parses `uv.hub()` declarations from all modules. + + This function iterates through all the modules in the Bazel dependency graph + and collects the `uv.hub()` declarations. It produces a dictionary of hub + specifications that is used to validate project registrations. + + Args: + module_ctx: The Bazel module context. + + Returns: + A dictionary of hub specifications, where the keys are hub names and the + values are dictionaries of module names that declared the hub. + """ + + # As with `rules_python` hub names have to be globally unique :/ + hub_specs = {} + + # Collect all hubs, ensure we have no dupes + for mod in module_ctx.modules: + for hub in mod.tags.declare_hub: + hub_specs.setdefault(hub.hub_name, {}) + hub_specs[hub.hub_name][mod.name] = 1 + + # Note that we ARE NOT validating that the same hub name is registered by + # one and only one repository. This allows `@pypi` which we think should be + # the one and only conventional hub to be referenced by many modules since + # we disambiguate the build configuration on the "venv" not the hub. + + return hub_specs + +def _parse_projects(module_ctx, hub_specs): + """Parses all `uv.project()` declarations from all modules. + + This function is the core of the module extension's logic. It iterates + through all the `uv.project()` declarations, parses the `pyproject.toml` and + `uv.lock` files, and builds up the complete dependency graph. + + Args: + module_ctx: The Bazel module context. + hub_specs: A dictionary of hub specifications, as returned by + `_parse_hubs`. + + Returns: + A struct containing all the parsed information, including the dependency + graph, SCCs, and configurations for all the repository rules that need + to be generated. + """ + + hub_cfgs = {} + project_cfgs = {} + marker_specs = {} + whl_configurations = {} + + sdist_specs = {} + sdist_table = {} + + bdist_specs = {} + bdist_table = {} + + sbuild_specs = {} + + install_cfgs = {} + install_table = {} + + # FIXME: Collect build deps files/annotations + + # Collect all hubs, ensure we have no dupes + for mod in module_ctx.modules: + for project in mod.tags.project: + project_data = toml.decode_file(module_ctx, project.pyproject) + lock_data = toml.decode_file(module_ctx, project.lock) + + # This SHOULD be stable enough. + # We'll rebuild the lock hub whenever the toml changes. + # Reusing the name is fine. + # project_stamp = sha1(str(project.pyproject))[:16] + project_stamp = normalize_name(project_data["project"]["name"]) + project_id = "project__" + project_stamp + + # Read these from the project or honor the module state + project_name = project.name or project_data["project"]["name"] + + # FIXME: Error if this wasn't provided and the version is marked as dynamic + project_version = project.version or project_data["project"]["version"] + + if project.hub_name not in hub_specs: + fail("Project {} in {} refers to hub {} which is not configured for that module. Please declare it.".format(project_name, mod.name, project.hub_name)) + + default_versions, lock_data = normalize_deps(project_id, lock_data) + + def _resolve(package): + name = normalize_name(package["name"]) + if "version" in package: + return (project_id, name, package["version"].replace(".", "_"), "__base__") + elif name in default_versions: + return default_versions[name] + else: + fail("Unable to identify id for package {} for lock {}\n{}".format(package, project.lock, pprint(default_versions))) + + lock_build_dep_anns = {} + for ann in mod.tags.unstable_annotate_packages: + if ann.lock == project.lock: + annotations = toml.decode_file(module_ctx, ann.src) + for package in annotations.get("package", []): + k = _resolve(package) + deps = [] + for dep in package.get("build-dependencies", []): + deps.append(_resolve(dep)) + lock_build_dep_anns[k] = deps + + overridden_packages = {} + + # FIXME: This inner join is correct and easy, but it doesn't allow us to warn if there are annotations that don't join. + for override in mod.tags.override_package: + if override.lock == project.lock: + v = override.version or default_versions.get(normalize_name(override.name))[2] + if not v: + fail("Overridden project {} neither specifies a version nor has an implied singular version in the lockfile!".format(override.name, project.lock)) + k = (project_id, normalize_name(override.name), v, "__base__") + print("Overriding {}@{} in {} with {}".format(override.name, v, project_name, override.target)) + install_table[k] = str(override.target) + + # Lazily evaluated cache + lock_build_deps = None + + marker_graph = build_marker_graph(project_id, lock_data) + + marker_specs.update(collect_markers(marker_graph)) + + bd, bt = collect_bdists(lock_data) + bdist_specs.update(bd) + bdist_table.update(bt) + + sd, st = collect_sdists(project_stamp, lock_data) + sdist_specs.update(sd) + sdist_table.update(st) + + whl_configurations.update(collect_configurations(lock_data)) + + configuration_names, activated_extras = collect_activated_extras(project.lock, project_data, default_versions, marker_graph) + version_activations = collate_versions_by_name(activated_extras) + + # Mapping from SCC ID to marked SCC members + scc_graph = {} + + # Mapping from SCC ID to marked SCC dependencies + scc_deps = {} + + # Mapping from package to cfg to the SCC for that package in that cfg + package_cfg_sccs = {} + for cfg in configuration_names: + cfgd_marker_graph = activate_extras(marker_graph, activated_extras, cfg) + cfgd_dep_to_scc, cfgd_scc_graph, cfgd_scc_deps = collect_sccs(cfgd_marker_graph) + + # Aggregate the dependency graphs Note that this may be overly + # simplistic, since markers COULD vary per configured graph; + # ignoring that for now. + scc_graph.update(cfgd_scc_graph) + scc_deps.update(cfgd_scc_deps) + + # This one's slightly tricky + for package, scc in cfgd_dep_to_scc.items(): + package_cfg_sccs.setdefault(package, {})[cfg] = scc + + marked_package_cfg_sccs = {} + for package, cfgs in version_activations.items(): + for cfg, versions in cfgs.items(): + for version, markers in versions.items(): + # Map the version to a scc in this configuration, while collecting version conditional markers + marked_package_cfg_sccs.setdefault(package, {}).setdefault(cfg, {}).setdefault(package_cfg_sccs[version][cfg], {}).update(markers) + + # Translate the package lock into installs for this project + for package in lock_data.get("package", []): + install_key = (project_id, package["name"], package["version"], "__base__") + if install_key in install_table: + # Case of an overriden package + continue + + if "editable" in package["source"]: + # Don't generate a sdist build or anything else for the self-package + if package["name"] == normalize_name(project_name): + continue + elif install_key in install_table: + continue + else: + fail("Virtual package {} in lockfile {} doesn't have a mandatory `uv.override_package()` annotation!".format(package["name"], project.lock)) + + k = "whl_install__{}__{}__{}".format(project_stamp, package["name"], package["version"].replace(".", "_")) + install_table[install_key] = "@{}//:install".format(k) + sbuild_id = "sdist_build__{}__{}__{}".format(project_stamp, package["name"], package["version"].replace(".", "_")) + sdist = sdist_table.get(sbuild_id) + + # WARNING: Loop invariant; this flag needs to be False by + # default and set if we do a build. + has_sbuild = False + + # HACK: If there's a -none-any wheel for the package, then + # we can actually skip creating the sdist build because + # we'll never use it. This allows projects which can do + # anyarch builds from bdists to avoid providing build deps. + # + # FIXME: This condition is actually incomplete, `py2.py3` wheels + # match the same condition. + # + # FIXME: If we add support for a sdist-only mode then this is + # just wrong. + has_none_any = any(["-none-any.whl" in it["url"] for it in package.get("wheels", [])]) + if sdist and not (has_none_any and project.elide_sbuilds_with_anyarch): + # HACK: Note that we resolve these LAZILY so that + # bdist-only or fully overridden configurations don't + # have to provide the build tools. + + # FIXME: We can read the [build-system] requires= + # property if it exists for the sdist. Question is how + # to defer choosing deps until the repo rule when we + # could do pyproject.toml introspection. + build_deps = lock_build_dep_anns.get(install_key) + if build_deps == None: + if lock_build_deps == None: + lock_build_deps = [ + it[0] + for req in project.default_build_dependencies + for it in extract_requirement_marker_pairs(project.lock, req, default_versions) + ] + + build_deps = lock_build_deps + + sbuild_specs[sbuild_id] = struct( + src = sdist, + deps = ["@{0}//:{1}".format(*it) for it in build_deps], + # FIXME: Check annotations + is_native = False, + version = package["version"], + ) + + has_sbuild = True + + install_cfgs[k] = struct( + whls = {whl["url"].split("/")[-1].split("?")[0].split("#")[0]: bdist_table.get(whl["hash"]) for whl in package.get("wheels", [])}, + sbuild = "@{}//:whl".format(sbuild_id) if has_sbuild else None, + ) + + # Frustratingly we have to re-key all these structures so that they + # can be jsonified later. Note that the _key is a structured string + # which we can re-parse on the other side (sigh) so we DO NOT mangle + # them at all. Mangling will be done as needed on the other side(s). + # + # FIXME: Can we make a re-keying helper? + project_cfgs[project_id] = struct( + dep_to_scc = marked_package_cfg_sccs, + scc_deps = { + k: { + d[1]: markers + for d, markers in deps.items() + } + for k, deps in scc_deps.items() + }, + scc_graph = { + scc_id: { + install_table[m]: markers + for m, markers in members.items() + # Extras etc. have no install table presence + if m in install_table + } + for scc_id, members in scc_graph.items() + }, + ) + + hub_cfg = hub_cfgs.setdefault(project.hub_name, struct( + configurations = {}, + packages = {}, + )) + + for cfg in configuration_names.keys(): + if cfg in hub_cfg.configurations: + fail("Conflict on configuration name {} in hub {}".format(cfg, project.hub_name)) + + # Build a mapping from configurations to the project containing that configuration + hub_cfg.configurations.update({ + name: project_id + for name in configuration_names.keys() + }) + + # Build a {requirement: {cfg: target mapping}} + for package, cfgs in version_activations.items(): + for cfg in cfgs.keys(): + hub_cfg.packages.setdefault(package, {})[cfg] = "@{}//:{}".format(project_id, package) + + return struct( + project_cfgs = project_cfgs, + hub_cfgs = hub_cfgs, + install_cfgs = install_cfgs, + sbuild_cfgs = sbuild_specs, + marker_cfgs = marker_specs, + whl_cfgs = whl_configurations, + sdist_cfgs = sdist_specs, + bdist_cfgs = bdist_specs, + ) + +def _uv_impl(module_ctx): + """The implementation function for the `uv` module extension. + + This function is the main entry point for the module extension. It orchestrates + the entire dependency resolution process, which includes: + - Parsing `uv.hub()` and `uv.project()` declarations. + - Generating repository rules for fetching and building all the declared + dependencies. + - Generating a `uv_project` repository rule for each pyproject.toml, which + contains the resolved dependency graph for that project according to the + matching lockfile. + - Generating a `uv_hub` repository rule for each hub, which contains the + aggregated dependency information for all the projects in that hub. + + Args: + module_ctx: The Bazel module context. + """ + + hub_specs = _parse_hubs(module_ctx) + + cfg = _parse_projects(module_ctx, hub_specs) + + configurations_hub( + name = "aspect_rules_py_pip_configurations", + configurations = cfg.whl_cfgs, + markers = {}, + ) + + for sdist_name, sdist_cfg in cfg.sdist_cfgs.items(): + if "file" in sdist_cfg: + sdist_cfg = sdist_cfg["file"] + sha256 = None + if "hash" in sdist_cfg: + sha256 = sdist_cfg["hash"][len("sha256:"):] + + http_file( + name = sdist_name, + url = sdist_cfg["url"], + sha256 = sha256, + downloaded_file_path = sdist_cfg["url"].split("/")[-1].split("?")[0].split("#")[0], + ) + + elif "git" in sdist_cfg: + git_cfg = sdist_cfg["git"] + git_archive( + name = sdist_name, + remote = git_cfg["remote"], + commit = git_cfg.get("commit"), + ref = git_cfg.get("ref"), + ) + + else: + fail("Unsupported archive! {}".format(repr(sdist_cfg))) + + for bdist_name, bdist_cfg in cfg.bdist_cfgs.items(): + http_file( + name = bdist_name, + url = bdist_cfg["url"], + sha256 = bdist_cfg["hash"][len("sha256:"):], + downloaded_file_path = bdist_cfg["url"].split("/")[-1].split("?")[0].split("#")[0], + ) + + for sbuild_id, sbuild_cfg in cfg.sbuild_cfgs.items(): + sdist_build( + name = sbuild_id, + src = sbuild_cfg.src, + deps = sbuild_cfg.deps, + is_native = sbuild_cfg.is_native, + version = sbuild_cfg.version, + ) + + for install_id, install_cfg in cfg.install_cfgs.items(): + whl_install( + name = install_id, + sbuild = install_cfg.sbuild, + whls = json.encode(install_cfg.whls), + ) + + for project_id, project_cfg in cfg.project_cfgs.items(): + uv_project( + name = project_id, + dep_to_scc = json.encode(project_cfg.dep_to_scc), + scc_deps = json.encode(project_cfg.scc_deps), + scc_graph = json.encode(project_cfg.scc_graph), + ) + + for hub_id, hub_cfg in cfg.hub_cfgs.items(): + uv_hub( + name = hub_id, + configurations = hub_cfg.configurations, + packages = json.encode(hub_cfg.packages), + ) + + if features.external_deps.extension_metadata_has_reproducible: + return module_ctx.extension_metadata(reproducible = True) + +_hub_tag = tag_class( + attrs = { + "hub_name": attr.string(mandatory = True), + }, +) + +_project_tag = tag_class( + attrs = { + "hub_name": attr.string(mandatory = True), + "name": attr.string(mandatory = False), + "version": attr.string(mandatory = False), + "pyproject": attr.label(mandatory = True), + "lock": attr.label(mandatory = True), + "elide_sbuilds_with_anyarch": attr.bool(mandatory = False, default = True), + "default_build_dependencies": attr.string_list( + mandatory = False, + default = [ + "build", + "setuptools", + ], + ), + }, +) + +_annotations_tag = tag_class( + attrs = { + "lock": attr.label(mandatory = True), + "src": attr.label(mandatory = True), + }, +) + +_declare_entrypoint_tag = tag_class( + attrs = { + "package": attr.string(mandatory = True), + "version": attr.string(mandatory = False), + "name": attr.string(mandatory = True), + "entrypoint": attr.string(mandatory = True), + }, +) + +_override_package_tag = tag_class( + attrs = { + "lock": attr.label(mandatory = True), + "name": attr.string(mandatory = True), + "version": attr.string(mandatory = False), + "target": attr.label(mandatory = True), + }, +) + +# TODO: patch_package + +uv = module_extension( + implementation = _uv_impl, + tag_classes = { + "declare_hub": _hub_tag, + "project": _project_tag, + "unstable_annotate_packages": _annotations_tag, + "override_package": _override_package_tag, + # "declare_entrypoint": _declare_entrypoint_tag, + }, +) diff --git a/uv/private/extension/git_utils.bzl b/uv/private/extension/git_utils.bzl new file mode 100644 index 00000000..df2e4139 --- /dev/null +++ b/uv/private/extension/git_utils.bzl @@ -0,0 +1,106 @@ +""" +Utilities for parsing git URLs and converting them to http_archive. +""" + +def ensure_ref(maybe_ref): + """Ensures a git ref starts with "ref/". + + Args: + maybe_ref: The git ref string. + + Returns: + The git ref string, prefixed with "ref/" if it is not already. + """ + if maybe_ref == None: + return None + + if not maybe_ref.startswith("ref/"): + return "ref/" + maybe_ref + + return maybe_ref + +def parse_git_url(url): + """Parses a git URL into a dictionary of `git_repository` arguments. + + This function is a simplified parser for git URLs that can extract a remote + URL, a commit hash, or a ref. It supports URLs with fragments and query + + Args: + url: The git URL to parse. + + Returns: + A dictionary of `git_repository` arguments. + """ + + # 1. Handle Fragment (anything after #) + # URL: https://github.com/user/repo.git#c7076a0... + remote_and_query, hash_sep, fragment = url.partition("#") + + # 2. Handle Query Parameters (anything after ?) + # URL: https://github.com/user/repo.git?rev=refs/pull/64/head + remote_base, query_sep, query_string = remote_and_query.partition("?") + + kwargs = {"remote": remote_base} + rev = "" + ref = "" + + # 3. Extract revision from Fragment + if fragment: + rev = fragment + + # 4. Extract revision from Query String (if fragment wasn't present) + elif query_string: + params = {} + + # Manually parse query string for 'rev=' or 'ref=' + pairs = query_string.split("&") + for pair in pairs: + k, v = pair.split("=", 1) + + # FIXME: Better urldecode + params[k] = v.replace("%2F", "/").replace("%2f", "/") + + if "ref" in params: + ref = params["ref"] + + if "commit" in params: + rev = params["commit"] + + # 5. Determine if the revision is a commit, tag, or branch + if rev: + kwargs["commit"] = rev + elif ref: + kwargs["ref"] = ensure_ref(ref) # Use the public ensure_ref + + return kwargs + +def try_git_to_http_archive(git_cfg): + """Tries to convert a `git_repository` configuration to an `http_archive`. + + This function attempts to convert a `git_repository` configuration to an + `http_archive` configuration for well-known git hosting services like + GitHub. This is useful for performance, as downloading a tarball over HTTP + is generally faster than cloning a git repository. + + Args: + git_cfg: A dictionary of `git_repository` arguments. + + Returns: + A dictionary of `http_archive` arguments, or `None` if the conversion + is not possible. + """ + + if "https://github.com/" in git_cfg["remote"]: + url = git_cfg["remote"].replace("git+", "").replace(".git", "").rstrip("/") + if "commit" in git_cfg: + url = "{}/archive/{}.tar.gz".format(url, git_cfg["commit"]) + return { + "url": url, + } + elif "ref" in git_cfg: + url = "{}/archive/{}.tar.gz".format(url, git_cfg["tag"]) + return { + "url": url, + } + + # FIXME: Support gitlab, other hosts? diff --git a/uv/private/extension/graph_utils.bzl b/uv/private/extension/graph_utils.bzl new file mode 100644 index 00000000..e1976067 --- /dev/null +++ b/uv/private/extension/graph_utils.bzl @@ -0,0 +1,149 @@ +load("//uv/private:sha1.bzl", "sha1") +load("//uv/private/graph:sccs.bzl", "sccs") + +def collect_sccs(marker_graph): + """Computes Strongly Connected Components (SCCs) for a dependency marker_graph. + + This function takes a dependency marker_graph and identifies all the SCCs, which + are groups of packages that have cyclic dependencies on each other. + + Args: + marker_graph: The dependency marker_graph, as returned by `_build_marker_graph`. + {pkg: {dep: {marker: 1}}} + + Returns: + A tuple containing: + - A dictionary mapping each dependency to the ID of the SCC that + contains it. + - A dictionary representing the marker_graph of SCCs, where the keys are SCC IDs + and the values are dictionaries of member dependencies and their + markers. + - A dictionary mapping each SCC ID to its direct, non-member + dependencies. + """ + + all_nodes = set() + for pkg, deps in marker_graph.items(): + all_nodes.add(pkg) + for dep in deps.keys(): + all_nodes.add(dep) + + simplified_graph = {node: [] for node in all_nodes} + for pkg, deps in marker_graph.items(): + simplified_graph[pkg] = list(deps.keys()) + + graph_components = sccs(simplified_graph) + + # Now we need to rebuild markers for intra-scc deps + # Data structure to hold scc_members and their raw deps + scc_info_list = [] + for scc_members in graph_components: + raw_scc_deps = {} + for member in scc_members: + for dep, markers in marker_graph.get(member, {}).items(): + if dep not in scc_members: # Only consider external dependencies + raw_scc_deps.setdefault(dep, {}).update(markers) + scc_info_list.append((scc_members, raw_scc_deps)) + + new_scc_graph = {} + dep_to_scc = {} + final_scc_deps = {} # This will store the scc_deps with the new keys + + for scc_members, raw_scc_deps in scc_info_list: + # Generate the new scc_id + # We need to sort the raw_scc_deps.items() to ensure consistent hashing + sorted_raw_scc_deps_repr = repr(sorted(raw_scc_deps.items())) + new_scc_id = sha1(repr(sorted(scc_members)) + ";" + sorted_raw_scc_deps_repr)[:16] + + # Build the new scc_graph entry + new_scc_graph[new_scc_id] = {m: {} for m in scc_members} + + # Populate dep_to_scc + for member in scc_members: + dep_to_scc[member] = new_scc_id + + # Populate final_scc_deps + final_scc_deps[new_scc_id] = raw_scc_deps + + # Now, rebuild markers for intra-scc deps for the new_scc_graph + for start in scc_members: + for next in scc_members: + # Note that we DO NOT provide a default marker here because this + # is a dependency edge which may not actually exist and we don't + # want to falsely insert edges/markers. + next_marks = marker_graph.get(start, {}).get(next, {}) + new_scc_graph[new_scc_id][next].update(next_marks) + + # Ensure that everything has at least the no-op marker + for next in scc_members: + if len(new_scc_graph[new_scc_id][next].keys()) == 0: + new_scc_graph[new_scc_id][next].update({"": 1}) + + return dep_to_scc, new_scc_graph, final_scc_deps + +def combine_markers(lefts, rights): + """ + Combine two sets of markers under _and_. + + If `a[b]; m` implies some `b; n`, then `a` implies `b` IFF `m and n`. It + would be incorrect to disregard either the left or right markers, as either + case of doing so could lead to an unsatisfiable false dependency. + """ + + acc = {} + + def _and(l, r): + """ + We use "" as the empty/True marker, so if either side is true then we + need to return the other side. + """ + + if l == "": + return r + elif r == "": + return l + else: + return "({}) and ({})".format(l, r) + + for l in lefts.keys(): + for r in rights.keys(): + acc[_and(l, r)] = 1 + + return acc + +def activate_extras(marker_graph, activated_extras, cfg): + """ + Configure an unconfigured marker graph by activating extras. + + Produce a _new_ graph without modifying the original which: + - Merges all active extras into their base packages (add deps) + - Translates all deps on extras to deps on the base package + - Removes all extras pesudo-packages + """ + + acc = {} + + for pkg, marked_deps in marker_graph.items(): + # Ignore extra pseudo-packages + if pkg[3] != "__base__": + continue + + # Packages may have no deps so we have to create this here + acc.setdefault(pkg, {}) + + for dep, markers in list(marked_deps.items()): + # Normalize all deps to deps on the base package + normalized_dep = (dep[0], dep[1], dep[2], "__base__") + acc[pkg][normalized_dep] = markers + + # For the current (base!) package, look up the closure of activated + # extras and merge the _dependencies_ of those extras in. + extras = activated_extras.get(pkg, {}).get(cfg, {}) + for extra, extra_markers in extras.items(): + # Merge in deps from the requested extra + for implied_dep, implied_markers in marker_graph.get(extra, {}).items(): + # Normalize since the source graph isn't + normalized_implied_dep = (implied_dep[0], implied_dep[1], implied_dep[2], "__base__") + acc[pkg][normalized_implied_dep] = combine_markers(extra_markers, implied_markers) + + return acc diff --git a/uv/private/extension/lockfile.bzl b/uv/private/extension/lockfile.bzl new file mode 100644 index 00000000..338031f5 --- /dev/null +++ b/uv/private/extension/lockfile.bzl @@ -0,0 +1,265 @@ +""" +Machinery specific to interacting with a uv.lock +""" + +load("//uv/private:normalize_name.bzl", "normalize_name") +load("//uv/private:parse_whl_name.bzl", "parse_whl_name") +load("//uv/private:sha1.bzl", "sha1") +load("//uv/private/constraints/platform:defs.bzl", "supported_platform") +load("//uv/private/constraints/python:defs.bzl", "supported_python") +load(":git_utils.bzl", "parse_git_url", "try_git_to_http_archive") + +def normalize_deps(lock_id, lock_data): + """Normalizes dependency specifications in a lockfile. + + This function performs two main normalization steps: + 1. It computes a "default version" for each package, which is used when a + dependency specification does not include a version. The default version + is only computed for packages that have a single version in the lockfile. + 2. It updates all dependency statements within the lockfile to be + version-disambiguated, using the default versions where necessary. + + Args: + lock_id: A unique identifier for the lockfile. + lock_data: The parsed content of the `uv.lock` file. + + Returns: + A tuple containing: + - A dictionary mapping package names to their default version dependency + tuples `(lock_id, package_name, version, "__base__")`. + - The normalized `lock_data` dictionary. + """ + + package_versions = {} + for spec in lock_data.get("package", []): + # spec: RequirementSpec + spec["name"] = normalize_name(spec["name"]) + + # Collect all the versions first + package_versions.setdefault(spec["name"], {})[spec["version"]] = 1 + + default_versions = { + requirement: (lock_id, requirement, list(versions.keys())[0], "__base__") + for requirement, versions in package_versions.items() + if len(versions) == 1 + } + + def _fix_version(dep): + dep["name"] = normalize_name(dep["name"]) + if not "version" in dep: + # Note that default versions is requirement => (lock_id, name, version, "__base__") + # So we need to extract the version component here + dep["version"] = default_versions.get(dep["name"])[2] + + for spec in lock_data.get("package", []): + # Backfill the sdist URL if the source is a URL file + if "sdist" in spec and not "url" in spec["sdist"]: + spec["sdist"]["url"] = spec["source"]["url"] + + for dep in spec.get("dependencies", []): + _fix_version(dep) + + for extra_deps in spec.get("optional-dependencies", {}).values(): + for dep in extra_deps: + _fix_version(dep) + + return default_versions, lock_data + +MAGIC_ACTIVATE_BASE_MARKER = "magic_activate_base == 1" + +def build_marker_graph(lock_id, lock_data): + """Builds a dependency graph from a lockfile. + + The graph is represented as a dictionary where the keys are `Dependency` + tuples `(lock_id, package, version, extra)` and the values are dictionaries + of their dependencies. The dependency dictionaries are keyed by `Dependency` + tuples and their values are dictionaries of markers. + + This function also normalizes dependencies on extras. Dependencies without an + extra are converted to a dependency on the `__base__` extra. Each extra also + gets a synthetic dependency on the `__base__` package of the same version. + + Args: + lock_id: A unique identifier for the lockfile. + lock_data: The parsed content of the `uv.lock` file. + + Returns: + A dictionary representing the dependency graph. + """ + + graph = {} + for spec in lock_data.get("package", []): + # spec: RequirementSpec + k = (lock_id, spec["name"], spec["version"], "__base__") + graph.setdefault(k, {}) + for dep in spec.get("dependencies", []): + extras = dep.get("extra", ["__base__"]) + if "__base__" not in extras: + extras = ["__base__"] + extras + + for e in extras: + ek = (lock_id, dep["name"], dep["version"], e) + graph[k].setdefault(ek, {}) + graph[k][ek][dep.get("marker", "")] = 1 + + for extra_name, optional_deps in spec.get("optional-dependencies", {}).items(): + ek = (lock_id, spec["name"], spec["version"], extra_name) + + graph.setdefault(ek, {}) + for dep in optional_deps: + extras = dep.get("extra", ["__base__"]) + if "__base__" not in extras: + extras = ["__base__"] + extras + + for e in extras: + eek = (lock_id, dep["name"], dep["version"], e) + graph[ek].setdefault(eek, {}) + graph[ek][eek][dep.get("marker", "")] = 1 + + return graph + +def collect_configurations(lock): + """Collects all unique platform configurations from the wheels in a lockfile. + + This function identifies all the unique combinations of Python implementation, + platform, and ABI from the wheel filenames in the lockfile. + + Args: + lock: The parsed content of the `uv.lock` file. + + Returns: + A dictionary mapping configuration strings (e.g., + "cp39-manylinux_2_17_x86_64-cp39") to a list of `config_setting` + labels that define the configuration. + """ + wheel_files = {} + + for package in lock.get("package", []): + for whl in package.get("wheels", []): + url = whl["url"] + wheel_name = url.split("/")[-1] # Find the trailing file name + wheel_files[wheel_name] = 1 + + abi_tags = {} + platform_tags = {} + python_tags = {} + + # Platform definitions from groups of configs + configurations = {} + + for wheel_name in wheel_files.keys(): + parsed_wheel = parse_whl_name(wheel_name) + for python_tag in parsed_wheel.python_tags: + # Ignore configurations for unsupported interpreters + if not supported_python(python_tag): + continue + + python_tags[python_tag] = 1 + + for platform_tag in parsed_wheel.platform_tags: + # Ignore configurations for unsupported platforms + if not supported_platform(platform_tag): + continue + + platform_tags[platform_tag] = 1 + + for abi_tag in parsed_wheel.abi_tags: + abi_tags[abi_tag] = 1 + + # Note that we are NOT filtering out + # impossible/unsatisfiable python+abi tag possibilities. + # It's not aesthetic but it is simple enough. + configuration = "{}-{}-{}".format(python_tag, platform_tag, abi_tag) + + configurations[configuration] = [ + "@aspect_rules_py//uv/private/constraints/platform:{}".format(platform_tag), + "@aspect_rules_py//uv/private/constraints/abi:{}".format(abi_tag), + "@aspect_rules_py//uv/private/constraints/python:{}".format(python_tag), + ] + + return configurations + +def collect_bdists(lock_data): + """Collects all pre-built wheels (bdists) from a lockfile. + + Args: + lock_data: The parsed content of the `uv.lock` file. + + Returns: + A tuple containing: + - A dictionary mapping repository names for the wheels to their bdist + specifications. + - A dictionary mapping the hash of each wheel to its repository label. + """ + bdist_specs = {} + bdist_table = {} + for package in lock_data.get("package", []): + for bdist in package.get("wheels", []): + bdist_repo_name = "whl__{}__{}".format(package["name"], bdist["hash"].split(":")[1][:16]) + bdist_specs[bdist_repo_name] = bdist + bdist_table[bdist["hash"]] = "@{}//file".format(bdist_repo_name) + + return bdist_specs, bdist_table + +def collect_sdists( + lock_id, + lock_data, + allow_git_to_http_conversion = False): + """Collects all source distributions (sdists) from a lockfile. + + Args: + lock_id: A unique identifier for the lockfile. + lock_data: The parsed content of the `uv.lock` file. + + Returns: + A tuple containing: + - A dictionary mapping repository names for the sdists to their + specifications. + - A dictionary mapping sdist build keys to their repository labels. + """ + sdist_specs = {} + sdist_table = {} + for package in lock_data.get("package", []): + k = "sdist_build__{}__{}__{}".format(lock_id, package["name"], package["version"].replace(".", "_")) + if "sdist" in package: + sdist = package["sdist"] + sdist_repo_name = "sdist__{}__{}".format(package["name"], sdist["hash"].split(":")[1][:16]) + sdist_specs[sdist_repo_name] = {"file": sdist} + sdist_table[k] = "@{}//file".format(sdist_repo_name) + + elif "git" in package["source"]: + git_url = package["source"]["git"] + git_cfg = parse_git_url(git_url) + + # FIXME: Replace with a policy mechanism + if allow_git_to_http_conversion: + sdist_cfg = try_git_to_http_archive(git_cfg) + sdist_repo_name = "sdist_git__{}__{}".format(package["name"], sha1(git_url)[:16]) + sdist_table[k] = "@{}//file".format(sdist_repo_name) + + if sdist_cfg: + sdist_specs[sdist_repo_name] = {"file": sdist_cfg} + continue + + sdist_specs[sdist_repo_name] = {"git": git_cfg} + + return sdist_specs, sdist_table + +def collect_markers(graph): + """Collects all unique marker expressions from the dependency graph. + + Args: + graph: The dependency graph. + + Returns: + A dictionary mapping each unique marker expression to its SHA-1 hash. + """ + acc = {} + for _dep, nexts in graph.items(): + for _next, markers in nexts.items(): + for marker in markers.keys(): + # sha1 is "expensive" so we minimize it + if marker and marker not in acc: + acc[marker] = sha1(marker) + + return acc diff --git a/uv/private/extension/parser.bzl b/uv/private/extension/parser.bzl new file mode 100644 index 00000000..efecf280 --- /dev/null +++ b/uv/private/extension/parser.bzl @@ -0,0 +1,905 @@ +"Functions for parsing `uv.project()` declarations." + +load("//uv/private:parse_whl_name.bzl", "parse_whl_name") +load("//uv/private:sha1.bzl", "sha1") +load("//uv/private/constraints/platform:defs.bzl", "supported_platform") +load("//uv/private/constraints/python:defs.bzl", "supported_python") +load("//uv/private/graph:sccs.bzl", "sccs") +load("//uv/private/pprint:defs.bzl", "pprint") +load("//uv/private/tomltool:toml.bzl", "toml") +load(":normalize_name.bzl", "normalize_name") + +def _normalize_deps(lock_id, lock_data): + """Normalizes dependency specifications in a lockfile. + + This function performs two main normalization steps: + 1. It computes a "default version" for each package, which is used when a + dependency specification does not include a version. The default version + is only computed for packages that have a single version in the lockfile. + 2. It updates all dependency statements within the lockfile to be + version-disambiguated, using the default versions where necessary. + + Args: + lock_id: A unique identifier for the lockfile. + lock_data: The parsed content of the `uv.lock` file. + + Returns: + A tuple containing: + - A dictionary mapping package names to their default version dependency + tuples `(lock_id, package_name, version, "__base__")`. + - The normalized `lock_data` dictionary. + """ + + package_versions = {} + for spec in lock_data.get("package", []): + # spec: RequirementSpec + spec["name"] = normalize_name(spec["name"]) + + # Collect all the versions first + package_versions.setdefault(spec["name"], {})[spec["version"]] = 1 + + default_versions = { + requirement: (lock_id, requirement, list(versions.keys())[0], "__base__") + for requirement, versions in package_versions.items() + if len(versions) == 1 + } + + def _fix_version(dep): + dep["name"] = normalize_name(dep["name"]) + if not "version" in dep: + # Note that default versions is requirement => (lock_id, name, version, "__base__") + # So we need to extract the version component here + dep["version"] = default_versions.get(dep["name"])[2] + + for spec in lock_data.get("package", []): + # Backfill the sdist URL if the source is a URL file + if "sdist" in spec and not "url" in spec["sdist"]: + spec["sdist"]["url"] = spec["source"]["url"] + + for dep in spec.get("dependencies", []): + _fix_version(dep) + + for extra_deps in spec.get("optional-dependencies", {}).values(): + for dep in extra_deps: + _fix_version(dep) + + return default_versions, lock_data + +def _build_marker_graph(lock_id, lock_data): + """Builds a dependency graph from a lockfile. + + The graph is represented as a dictionary where the keys are `Dependency` + tuples `(lock_id, package, version, extra)` and the values are dictionaries + of their dependencies. The dependency dictionaries are keyed by `Dependency` + tuples and their values are dictionaries of markers. + + This function also normalizes dependencies on extras. Dependencies without an + extra are converted to a dependency on the `__base__` extra. Each extra also + gets a synthetic dependency on the `__base__` package of the same version. + + Args: + lock_id: A unique identifier for the lockfile. + lock_data: The parsed content of the `uv.lock` file. + + Returns: + A dictionary representing the dependency graph. + """ + + graph = {} + for spec in lock_data.get("package", []): + # spec: RequirementSpec + k = (lock_id, spec["name"], spec["version"], "__base__") + graph.setdefault(k, {}) + for dep in spec.get("dependencies", []): + extras = dep.get("extra", ["__base__"]) + for e in extras: + ek = (lock_id, dep["name"], dep["version"], e) + graph[k].setdefault(ek, {}) + graph[k][ek][dep.get("marker", "")] = 1 + + for extra_name, optional_deps in spec.get("optional-dependencies", {}).items(): + ek = (lock_id, spec["name"], spec["version"], extra_name) + + # Add a synthetic edge from the extra package to the base package + graph.setdefault(ek, {k: {"": 1}}) + for dep in optional_deps: + extras = dep.get("extra", ["__base__"]) + for e in extras: + eek = (lock_id, dep["name"], dep["version"], e) + graph[ek].setdefault(eek, {}) + graph[ek][eek][dep.get("marker", "")] = 1 + + return graph + +def _collect_sccs(graph): + """Computes Strongly Connected Components (SCCs) for a dependency graph. + + This function takes a dependency graph and identifies all the SCCs, which + are groups of packages that have cyclic dependencies on each other. + + Args: + graph: The dependency graph, as returned by `_build_marker_graph`. + + Returns: + A tuple containing: + - A dictionary mapping each dependency to the ID of the SCC that + contains it. + - A dictionary representing the graph of SCCs, where the keys are SCC IDs + and the values are dictionaries of member dependencies and their + markers. + - A dictionary mapping each SCC ID to its direct, non-member + dependencies. + """ + + simplified_graph = {pkg: deps.keys() for pkg, deps in graph.items()} + graph_components = sccs(simplified_graph) + + # Now we need to rebuild markers for intra-scc deps + scc_graph = { + sha1(repr(sorted(scc)))[:16]: {m: {} for m in scc} + for scc in graph_components + } + + for scc_id, scc in scc_graph.items(): + for start in scc.keys(): + for next in scc.keys(): + # Note that we DO NOT provide a default marker here because this + # is a dependency edge which may not actually exist and we don't + # want to falsely insert edges/markers. + next_marks = graph.get(start, {}).get(next, {}) + scc_graph[scc_id][next].update(next_marks) + + # Ensure that everything has at least the no-op marker + for next in scc.keys(): + if len(scc_graph[scc_id][next].keys()) == 0: + scc_graph[scc_id][next].update({"": 1}) + + # Compute the mapping from dependency coordinates to the SCC containing that dep + dep_to_scc = { + it: scc + for scc, deps in scc_graph.items() + for it in deps + } + + # Compute the mapping from sccs to _direct_ non-member deps for "fattening" + scc_deps = {} + for scc, members in scc_graph.items(): + for member in members: + for dep, markers in graph.get(member, {}).items(): + if dep not in members: + scc_deps.setdefault(scc, {}).setdefault(dep, {}).update(markers) + + return dep_to_scc, scc_graph, scc_deps + +def _extract_requirement_marker_pairs(req_string, version_map): + """Parses a requirement string into a list of dependency-marker pairs. + + This function parses a PEP 508 requirement string (e.g., + "requests[security]>=2.0; python_version < '3.8'") and converts it into a + list of pairs, where each pair contains a `Dependency` tuple and a `Marker` + string. + + Args: + req_string: The requirement string to parse. + version_map: A dictionary mapping package names to their default version + dependency tuples. + + Returns: + A list of tuples, where each tuple is `(Dependency, Marker)`. + """ + + # 1. Split Requirement and Marker + # Starlark split() often doesn't support maxsplit, so we use find() + slicing + semicolon_idx = req_string.find(";") + + marker = "" + if semicolon_idx != -1: + # Extract and clean the marker + marker_text = req_string[semicolon_idx + 1:].strip() + if marker_text: + marker = marker_text + + # The requirement part is everything before the semicolon + req_part = req_string[:semicolon_idx].strip() + else: + req_part = req_string.strip() + + if not req_part: + return [] + + # 2. Identify end of package name within req_part + stop_chars = { + "[": 1, + "=": 1, + ">": 1, + "<": 1, + "!": 1, + "~": 1, + " ": 1, + } + + name_end_idx = len(req_part) + + for i in range(len(req_part)): + char = req_part[i] + if char in stop_chars: + name_end_idx = i + break + + pkg_name = normalize_name(req_part[:name_end_idx]) + + # 3. Extract Extras from req_part + extras = [] + + remainder = req_part[name_end_idx:] + + if remainder.startswith("["): + close_idx = remainder.find("]") + if close_idx != -1: + content = remainder[1:close_idx] + parts = content.split(",") + for project_data in parts: + clean_p = project_data.strip() + if clean_p: + extras.append(clean_p) + + # 4. Look up version + v = version_map.get(pkg_name) + if v == None: + fail("Unable to resolve a default version for requirement {}".format(repr(req_string))) + else: + lock_id, pkg_name, version, _ = v + + # 5. Construct results + # Each result is ((name, ver, extra), marker) + results = [] + + # Base requirement + base_dep = (lock_id, pkg_name, version, "__base__") + results.append((base_dep, marker or "")) + + # Extras + for e in extras: + dep = (lock_id, pkg_name, version, e) + results.append((dep, marker or "")) + + return results + +def _collect_activated_extras(project_data, default_versions, graph): + """Collects the set of transitively activated extras for each configuration. + + This function determines the full set of extras that are activated for each + dependency group defined in the `pyproject.toml`. It performs a transitive + traversal of the dependency graph to find all extras that are pulled in by + the initial set of requirements. + + Args: + project_data: The parsed content of the `pyproject.toml` file. + default_versions: A dictionary mapping package names to their default + version dependency tuples. + graph: The dependency graph, as returned by `_build_marker_graph`. + + Returns: + A tuple containing: + - A dictionary of configuration names. + - A dictionary mapping each dependency to a dictionary of configurations + that activate it, which in turn maps to a dictionary of the extra + dependencies and their markers. The structure is: + `{dep: {cfg: {extra_dep: {marker: 1}}}}`. + """ + + dep_groups = project_data.get("dependency-groups", { + project_data["project"]["name"]: [ + project_data["project"]["name"], + ], + }) + + # Normalize dep groups to our dependency triples (graph keys) + normalized_dep_groups = {} + + # Builds up {package: {configuration: {extra: {marker: 1}}}} + activated_extras = {} + + for group_name, specs in dep_groups.items(): + normalized_dep_groups[group_name] = [] + for spec in specs: + for dep, marker in _extract_requirement_marker_pairs(spec, default_versions): + normalized_dep_groups[group_name].append(dep) + + # Note that this is the base case for the reach set walk below + # We do this here so it's easy to handle marker expressions + base = (dep[0], dep[1], dep[2], "__base__") + activated_extras.setdefault(base, {}).setdefault(group_name, {}).setdefault(dep, {}).update({marker: 1}) + + for group_name, deps in normalized_dep_groups.items(): + worklist = list(deps) + + # Worklist graph traversal to handle the reach set + visited = {} + idx = 0 + for _ in range(1000000): + if idx == len(worklist): + break + + it = worklist[idx] + visited[it] = 1 + + for next, markers in graph.get(it, {}).items(): + # Convert `next`, being a dependency potentially with marker, to its base package + base = (next[0], next[1], next[2], "__base__") + + # Upsert the base package so that under the appropriate cfg it lists next as a dep with the appropriate markers + activated_extras.setdefault(base, {}).setdefault(group_name, {}).setdefault(next, {}).update(markers) + if next not in visited: + visited[next] = 1 + worklist.append(next) + + idx += 1 + + return {it: 1 for it in dep_groups.keys()}, activated_extras + +def _collate_versions_by_name(activated_extras): + """Collates activated extras by package name, configuration, and version. + + This function transforms the `activated_extras` map into a more convenient + structure that groups different versions of the same package together. + + Args: + activated_extras: The map of activated extras, as returned by + `_collect_activated_extras`. + + Returns: + A dictionary mapping package names to configurations, versions, and + markers. The structure is: `{name: {config: {version: {marker: 1}}}}`. + """ + result = {} + + for id, configs in activated_extras.items(): + (lock_id, pkg_name, pkg_version, _) = id + for cfg, deps in configs.items(): + # Ensure path exists: result[name][cfg][version] -> {marker: 1} + # We use setdefault chain to traverse/create the nested dicts + version_markers = result.setdefault(pkg_name, {}).setdefault(cfg, {}).setdefault(id, {}) + + # deps is {dep_triple: {marker: 1}} + # We aggregate all markers for this version (from base and extras) + # into the single map for this version string. + for markers in deps.values(): + version_markers.update(markers) + + return result + +def _collect_markers(graph): + """Collects all unique marker expressions from the dependency graph. + + Args: + graph: The dependency graph. + + Returns: + A dictionary mapping each unique marker expression to its SHA-1 hash. + """ + acc = {} + for _dep, nexts in graph.items(): + for _next, markers in nexts.items(): + for marker in markers.keys(): + # sha1 is "expensive" so we minimize it + if marker and marker not in acc: + acc[marker] = sha1(marker) + + return acc + +def _collect_configurations(lock): + """Collects all unique platform configurations from the wheels in a lockfile. + + This function identifies all the unique combinations of Python implementation, + platform, and ABI from the wheel filenames in the lockfile. + + Args: + lock: The parsed content of the `uv.lock` file. + + Returns: + A dictionary mapping configuration strings (e.g., + "cp39-manylinux_2_17_x86_64-cp39") to a list of `config_setting` + labels that define the configuration. + """ + wheel_files = {} + + for package in lock.get("package", []): + for whl in package.get("wheels", []): + url = whl["url"] + wheel_name = url.split("/")[-1] # Find the trailing file name + wheel_files[wheel_name] = 1 + + abi_tags = {} + platform_tags = {} + python_tags = {} + + # Platform definitions from groups of configs + configurations = {} + + for wheel_name in wheel_files.keys(): + parsed_wheel = parse_whl_name(wheel_name) + for python_tag in parsed_wheel.python_tags: + # Ignore configurations for unsupported interpreters + if not supported_python(python_tag): + continue + + python_tags[python_tag] = 1 + + for platform_tag in parsed_wheel.platform_tags: + # Ignore configurations for unsupported platforms + if not supported_platform(platform_tag): + continue + + platform_tags[platform_tag] = 1 + + for abi_tag in parsed_wheel.abi_tags: + abi_tags[abi_tag] = 1 + + # Note that we are NOT filtering out + # impossible/unsatisfiable python+abi tag possibilities. + # It's not aesthetic but it is simple enough. + configuration = "{}-{}-{}".format(python_tag, platform_tag, abi_tag) + + configurations[configuration] = [ + "@aspect_rules_py//uv/private/constraints/platform:{}".format(platform_tag), + "@aspect_rules_py//uv/private/constraints/abi:{}".format(abi_tag), + "@aspect_rules_py//uv/private/constraints/python:{}".format(python_tag), + ] + + return configurations + +def _collect_bdists(lock_data): + """Collects all pre-built wheels (bdists) from a lockfile. + + Args: + lock_data: The parsed content of the `uv.lock` file. + + Returns: + A tuple containing: + - A dictionary mapping repository names for the wheels to their bdist + specifications. + - A dictionary mapping the hash of each wheel to its repository label. + """ + bdist_specs = {} + bdist_table = {} + for package in lock_data.get("package", []): + for bdist in package.get("wheels", []): + bdist_repo_name = "whl___{}__{}".format(package["name"], bdist["hash"].split(":")[1][:16]) + bdist_specs[bdist_repo_name] = bdist + bdist_table[bdist["hash"]] = "@{}//file".format(bdist_repo_name) + + return bdist_specs, bdist_table + +def _ensure_ref(maybe_ref): + """Ensures a git ref starts with "ref/". + + Args: + maybe_ref: The git ref string. + + Returns: + The git ref string, prefixed with "ref/" if it is not already. + """ + if maybe_ref == None: + return None + + if not maybe_ref.startswith("ref/"): + return "ref/" + maybe_ref + + return maybe_ref + +def _parse_git_url(url): + """Parses a git URL into a dictionary of `git_repository` arguments. + + This function is a simplified parser for git URLs that can extract a remote + URL, a commit hash, or a ref. It supports URLs with fragments and query + + Args: + url: The git URL to parse. + + Returns: + A dictionary of `git_repository` arguments. + """ + + # 1. Handle Fragment (anything after #) + # URL: https://github.com/user/repo.git#c7076a0... + remote_and_query, hash_sep, fragment = url.partition("#") + + # 2. Handle Query Parameters (anything after ?) + # URL: https://github.com/user/repo.git?rev=refs/pull/64/head + remote_base, query_sep, query_string = remote_and_query.partition("?") + + kwargs = {"remote": remote_base} + rev = "" + ref = "" + + # 3. Extract revision from Fragment + if fragment: + rev = fragment + + # 4. Extract revision from Query String (if fragment wasn't present) + elif query_string: + params = {} + + # Manually parse query string for 'rev=' or 'ref=' + pairs = query_string.split("&") + for pair in pairs: + k, v = pair.split("=", 1) + + # FIXME: Better urldecode + params[k] = v.replace("%2F", "/").replace("%2f", "/") + + if "ref" in params: + ref = params["ref"] + + if "commit" in params: + rev = params["commit"] + + # 5. Determine if the revision is a commit, tag, or branch + if rev: + kwargs["commit"] = rev + elif ref: + kwargs["ref"] = _ensure_ref(ref) + + return kwargs + +def _try_git_to_http_archive(git_cfg): + """Tries to convert a `git_repository` configuration to an `http_archive`. + + This function attempts to convert a `git_repository` configuration to an + `http_archive` configuration for well-known git hosting services like + GitHub. This is useful for performance, as downloading a tarball over HTTP + is generally faster than cloning a git repository. + + Args: + git_cfg: A dictionary of `git_repository` arguments. + + Returns: + A dictionary of `http_archive` arguments, or `None` if the conversion + is not possible. + """ + + if "https://github.com/" in git_cfg["remote"]: + url = git_cfg["remote"].replace("git+", "").replace(".git", "").rstrip("/") + if "commit" in git_cfg: + url = "{}/archive/{}.tar.gz".format(url, git_cfg["commit"]) + return { + "url": url, + } + elif "ref" in git_cfg: + url = "{}/archive/{}.tar.gz".format(url, git_cfg["tag"]) + return { + "url": url, + } + + # FIXME: Support gitlab, other hosts? + +def _collect_sdists(lock_id, lock_data): + """Collects all source distributions (sdists) from a lockfile. + + Args: + lock_id: A unique identifier for the lockfile. + lock_data: The parsed content of the `uv.lock` file. + + Returns: + A tuple containing: + - A dictionary mapping repository names for the sdists to their + specifications. + - A dictionary mapping sdist build keys to their repository labels. + """ + sdist_specs = {} + sdist_table = {} + for package in lock_data.get("package", []): + k = "sdist_build__{}__{}__{}".format(lock_id, package["name"], package["version"].replace(".", "_")) + if "sdist" in package: + sdist = package["sdist"] + sdist_repo_name = "sdist__{}__{}".format(package["name"], sdist["hash"].split(":")[1][:16]) + sdist_specs[sdist_repo_name] = {"file": sdist} + sdist_table[k] = "@{}//file".format(sdist_repo_name) + + elif "git" in package["source"]: + git_url = package["source"]["git"] + git_cfg = _parse_git_url(git_url) + + sdist_cfg = _try_git_to_http_archive(git_cfg) + sdist_repo_name = "sdist_git__{}__{}".format(package["name"], sha1(git_url)[:16]) + sdist_table[k] = "@{}//file".format(sdist_repo_name) + + if sdist_cfg: + sdist_specs[sdist_repo_name] = {"file": sdist_cfg} + + else: + sdist_specs[sdist_repo_name] = {"git": git_cfg} + + return sdist_specs, sdist_table + +def _resolve(package, lock_id, default_versions): + name = normalize_name(package["name"]) + if "version" in package: + return (lock_id, name, package["version"].replace(".", "_"), "__base__") + elif name in default_versions: + return default_versions[name] + else: + fail("Unable to identify id for package {} for lock {}".format(package, lock_id, pprint(default_versions))) + +def _process_overridden_packages(mod, project, lock_id, default_versions, install_table): + # FIXME: This inner join is correct and easy, but it doesn't allow us to warn if there are annotations that don't join. + for override in mod.tags.override_package: + if override.lock == project.lock: + v = override.version or default_versions.get(normalize_name(override.name)) + if not v: + fail("Overridden project {} neither specifies a version nor has an implied singular version in the lockfile!\n{}".format(override.name, project.lock)) + k = (lock_id, normalize_name(override.name), v, "__base__") + install_table[k] = str(override.target) + +def _process_lock_file(module_ctx, mod, project, lock_id, lock_data, default_versions, install_table, sdist_table, sbuild_specs, install_cfgs, project_name): + lock_build_dep_anns = {} + for ann in mod.tags.unstable_annotate_packages: + if ann.lock == project.lock: + annotations = toml.decode_file(module_ctx, ann.src) + for package in annotations.get("package", []): + k = _resolve(package, lock_id, default_versions) + deps = [] + for dep in package.get("build-dependencies", []): + deps.append(_resolve(dep, lock_id, default_versions)) + lock_build_dep_anns[k] = deps + + # Lazily evaluated cache + lock_build_deps = None + + for package in lock_data.get("package", []): + install_key = (lock_id, package["name"], package["version"], "__base__") + + if "editable" in package["source"]: + # Don't generate a sdist build or anything else for the self-package + if package["name"] == normalize_name(project_name): + continue + elif install_key in install_table: + continue + else: + fail("Virtual package {} in lockfile {} doesn't have a mandatory `uv.override_package()` annotation!".format(package["name"], project.lock)) + + k = "whl_install__{}__{}__{}".format(lock_id[:16], package["name"], package["version"].replace(".", "_")) + install_table[install_key] = "@{}//:install".format(k) + sbuild_id = "sdist_build__{}__{}__{}".format(lock_id[:16], package["name"], package["version"].replace(".", "_")) + sdist = sdist_table.get(sbuild_id) + + # WARNING: Loop invariant; this flag needs to be False by + # default and set if we do a build. + has_sbuild = False + + # HACK: If there's a -none-any wheel for the package, then + # we can actually skip creating the sdist build because + # we'll never use it. This allows projects which can do + # anyarch builds from bdists to avoid providing build deps. + has_none_any = any(["-none-any.whl" in it["url"] for it in package.get("wheels", [])]) + if sdist and not (has_none_any and project.elide_sbuilds_with_anyarch): + # HACK: Note that we resolve these LAZILY so that + # bdist-only or fully overridden configurations don't + # have to provide the build tools. + + # FIXME: We can read the [build-system] requires= + # property if it exists for the sdist. Question is how + # to defer choosing deps until the repo rule when we + # could do pyproject.toml introspection. + build_deps = lock_build_dep_anns.get(install_key) + if build_deps == None: + if lock_build_deps == None: + lock_build_deps = [ + it[0] + for req in project.default_build_dependencies + for it in _extract_requirement_marker_pairs(req, default_versions) + ] + + build_deps = lock_build_deps + + sbuild_specs[sbuild_id] = struct( + src = sdist, + deps = [ + "@{}__{}//:{}__{}".format(lock_id, bdep[1], bdep[2].replace(".", "_"), bdep[3]) + for bdep in build_deps + ], + # FIXME: Check annotations + is_native = False, + version = package["version"], + ) + + has_sbuild = True + + install_cfgs[k] = struct( + whls = {whl["url"].split("/")[-1].split("?")[0].split("#")[0]: sdist_table.get(whl["hash"]) for whl in package.get("wheels", [])}, + sbuild = "@{}//:whl".format(sbuild_id) if has_sbuild else None, + ) + +def _parse_single_project(module_ctx, mod, project, hub_specs, lock_cfgs, hub_cfgs, marker_specs, whl_configurations, sdist_specs, sdist_table, bdist_specs, bdist_table, sbuild_specs, install_cfgs, install_table, project_set): + project_data = toml.decode_file(module_ctx, project.pyproject) + lock_data = toml.decode_file(module_ctx, project.lock) + + # This SHOULD be stable enough. + # We'll rebuild the lock hub whenever the toml changes. + # Reusing the name is fine. + lock_stamp = sha1(repr(project.lock))[:16] + lock_id = "lockfile__" + lock_stamp + + def _name(k): + if k[3] == "__base__": + return "@{}//:{}__{}".format(lock_id, k[1], k[2].replace(".", "_")) + else: + return "@{}//:{}__{}__extra__{}".format(lock_id, k[1], k[2].replace(".", "_"), normalize_name(k[3])) + + # Read these from the project or honor the module state + project_name = project.name or project_data["project"]["name"] + + # FIXME: Error if this wasn't provided and the version is marked as dynamic + project_version = project.version or project_data["project"]["version"] + + project_set[project_name] = 1 + + if project.hub_name not in hub_specs: + fail("Project {} in {} refers to hub {} which is not configured for that module. Please declare it.".format(project_name, mod.name, project.hub_name)) + + if lock_id not in lock_cfgs: + default_versions, lock_data = _normalize_deps(lock_id, lock_data) + + _process_overridden_packages(mod, project, lock_id, default_versions, install_table) + + marker_graph = _build_marker_graph(lock_id, lock_data) + + marker_specs.update(_collect_markers(marker_graph)) + + bd, bt = _collect_bdists(lock_data) + bdist_specs.update(bd) + bdist_table.update(bt) + + sd, st = _collect_sdists(lock_stamp, lock_data) + sdist_specs.update(sd) + sdist_table.update(st) + + whl_configurations.update(_collect_configurations(lock_data)) + + _process_lock_file(module_ctx, mod, project, lock_id, lock_data, default_versions, install_table, sdist_table, sbuild_specs, install_cfgs, project_name) + + dep_to_scc, scc_graph, scc_deps = _collect_sccs(marker_graph) + + # Rebuild the SCC graph to point to member installs + # + # This is a bit tricky because _extras_ which have no install + # COULD be members of the SCC. We handle this by recognizing + # that an extra is a group of deps we splice in potentially + # conditionally, so all we need to do here is to recognize that + # the package is virtual (has no install) and skip it. scc_deps + # already handles the set of external edges, which will include + # the set of external edges from component extras. + scc_graph = { + scc_id: { + install_table[m]: v + for m, v in members.items() + # Extras etc. have no install table presence + if m in install_table + } + for scc_id, members in scc_graph.items() + } + + lock_cfgs[lock_id] = struct( + default_versions = { + k: _name(v) + for k, v in default_versions.items() + }, + dep_to_scc = { + _name(k).split(":")[1]: v + for k, v in dep_to_scc.items() + }, + scc_deps = { + k: { + _name(d).split("//")[1]: markers + for d, markers in deps.items() + } + for k, deps in scc_deps.items() + }, + scc_graph = scc_graph, + ) + + else: + cfg = lock_cfgs[lock_id] + default_versions = cfg.default_versions + dep_to_scc = cfg.dep_to_scc + scc_graph = cfg.scc_graph + scc_deps = cfg.scc_deps + + configuration_names, activated_extras = _collect_activated_extras(project_data, default_versions, marker_graph) + version_activations = _collate_versions_by_name(activated_extras) + + # Filter out the project itself + version_activations.pop(project_name) + + activated_extras = { + _name(pkg): { + cfg: { + _name(extra): markers + for extra, markers in extra_cfgs.items() + } + for cfg, extra_cfgs in pkg_cfgs.items() + } + for pkg, pkg_cfgs in activated_extras.items() + if pkg[1] != project_name + } + + version_activations = { + cfg: { + pkg: { + _name(version): markers + for version, markers in versions.items() + } + for pkg, versions in packages.items() + if pkg[1] != project_name + } + for cfg, packages in version_activations.items() + } + + hub_cfg = hub_cfgs.setdefault(project.hub_name, struct( + configurations = {}, + version_activations = {}, + extra_activations = {}, + )) + + for cfg in configuration_names.keys(): + if cfg in hub_cfg.configurations: + fail("Conflict on configuration name {} in hub {}".format(cfg, project.hub_name)) + + hub_cfg.configurations.update(configuration_names) + hub_cfg.version_activations.update(version_activations) + hub_cfg.extra_activations.update(activated_extras) + +def parse_projects(module_ctx, hub_specs): + """Parses all `uv.project()` declarations from all modules. + + This function is the core of the module extension's logic. It iterates + through all the `uv.project()` declarations, parses the `pyproject.toml` and + `uv.lock` files, and builds up the complete dependency graph. + + Args: + module_ctx: The Bazel module context. + hub_specs: A dictionary of hub specifications. + + Returns: + A struct containing all the parsed information, including the dependency + graph, SCCs, and configurations for all the repository rules that need + to be generated. + """ + + lock_cfgs = {} + hub_cfgs = {} + marker_specs = {} + whl_configurations = {} + + sdist_specs = {} + sdist_table = {} + + bdist_specs = {} + bdist_table = {} + + sbuild_specs = {} + + install_cfgs = {} + install_table = {} + + project_set = {} + + # FIXME: Collect build deps files/annotations + + # Collect all hubs, ensure we have no dupes + for mod in module_ctx.modules: + for project in mod.tags.project: + _parse_single_project(module_ctx, mod, project, hub_specs, lock_cfgs, hub_cfgs, marker_specs, whl_configurations, sdist_specs, sdist_table, bdist_specs, bdist_table, sbuild_specs, install_cfgs, install_table, project_set) + + return struct( + lock_cfgs = lock_cfgs, + hub_cfgs = hub_cfgs, + install_cfgs = install_cfgs, + sbuild_cfgs = sbuild_specs, + marker_cfgs = marker_specs, + whl_cfgs = whl_configurations, + sdist_cfgs = sdist_specs, + bdist_cfgs = bdist_specs, + project_set = project_set, + ) diff --git a/uv/private/extension/projectfile.bzl b/uv/private/extension/projectfile.bzl new file mode 100644 index 00000000..d3035a6f --- /dev/null +++ b/uv/private/extension/projectfile.bzl @@ -0,0 +1,204 @@ +""" +Machinery specific to interacting with a pyproject.toml +""" + +load("//uv/private:normalize_name.bzl", "normalize_name") + +def extract_requirement_marker_pairs(projectfile, req_string, version_map): + """Parses a requirement string into a list of dependency-marker pairs. + + This function parses a PEP 508 requirement string (e.g., + "requests[security]>=2.0; python_version < '3.8'") and converts it into a + list of pairs, where each pair contains a `Dependency` tuple and a `Marker` + string. + + Args: + req_string: The requirement string to parse. + version_map: A dictionary mapping package names to their default version + dependency tuples. + + Returns: + A list of tuples, where each tuple is `(Dependency, Marker)`. + """ + + # 1. Split Requirement and Marker + # Starlark split() often doesn't support maxsplit, so we use find() + slicing + semicolon_idx = req_string.find(";") + + marker = "" + if semicolon_idx != -1: + # Extract and clean the marker + marker_text = req_string[semicolon_idx + 1:].strip() + if marker_text: + marker = marker_text + + # The requirement part is everything before the semicolon + req_part = req_string[:semicolon_idx].strip() + else: + req_part = req_string.strip() + + if not req_part: + return [] + + # 2. Identify end of package name within req_part + stop_chars = { + "[": 1, + "=": 1, + ">": 1, + "<": 1, + "!": 1, + "~": 1, + " ": 1, + } + + name_end_idx = len(req_part) + + for i in range(len(req_part)): + char = req_part[i] + if char in stop_chars: + name_end_idx = i + break + + pkg_name = normalize_name(req_part[:name_end_idx]) + + # 3. Extract Extras from req_part + extras = [] + + remainder = req_part[name_end_idx:] + + if remainder.startswith("["): + close_idx = remainder.find("]") + if close_idx != -1: + content = remainder[1:close_idx] + parts = content.split(",") + for project_data in parts: + clean_p = project_data.strip() + if clean_p: + extras.append(clean_p) + + # 4. Look up version + v = version_map.get(pkg_name) + if v == None: + fail("Unable to resolve a default version for requirement {} in {}".format(repr(req_string), projectfile)) + else: + lock_id, pkg_name, version, _ = v + + # 5. Construct results + # Each result is ((name, ver, extra), marker) + results = [] + + # Base requirement + base_dep = (lock_id, pkg_name, version, "__base__") + results.append((base_dep, marker or "")) + + # Extras + for e in extras: + dep = (lock_id, pkg_name, version, e) + results.append((dep, marker or "")) + + return results + +def collect_activated_extras(projectfile, project_data, default_versions, graph): + """Collects the set of transitively activated extras for each configuration. + + This function determines the full set of extras that are activated for each + dependency group defined in the `pyproject.toml`. It performs a transitive + traversal of the dependency graph to find all extras that are pulled in by + the initial set of requirements. + + Args: + project_data: The parsed content of the `pyproject.toml` file. + default_versions: A dictionary mapping package names to their default + version dependency tuples. + graph: The dependency graph, as returned by `build_marker_graph`. + + Returns: + A tuple containing: + - A dictionary of configuration names. + - A dictionary mapping each dependency to a dictionary of configurations + that activate it, which in turn maps to a dictionary of the extra + dependencies and their markers. The structure is: + `{dep: {cfg: {extra_dep: {marker: 1}}}}`. + """ + + # If no dependency-groups are specified, create a default group + dep_groups = project_data.get("dependency-groups", { + project_data["project"]["name"]: [ + project_data["project"]["name"], + ], + }) + + # Normalize dep groups to our dependency triples (graph keys) + normalized_dep_groups = {} + + # Builds up {package: {configuration: {extra: {marker: 1}}}} + activated_extras = {} + + for group_name, specs in dep_groups.items(): + normalized_dep_groups[group_name] = [] + for spec in specs: + for dep, marker in extract_requirement_marker_pairs(projectfile, spec, default_versions): + normalized_dep_groups[group_name].append(dep) + + # Note that this is the base case for the reach set walk below + # We do this here so it's easy to handle marker expressions + base = (dep[0], dep[1], dep[2], "__base__") + activated_extras.setdefault(base, {}).setdefault(group_name, {}).setdefault(dep, {}).update({marker: 1}) + + for group_name, deps in normalized_dep_groups.items(): + worklist = list(deps) + + # Worklist graph traversal to handle the reach set + visited = {} + idx = 0 + for _ in range(1000000): + if idx == len(worklist): + break + + it = worklist[idx] + visited[it] = 1 + + for next, markers in graph.get(it, {}).items(): + # Convert `next`, being a dependency potentially with marker, to its base package + base = (next[0], next[1], next[2], "__base__") + + # Upsert the base package so that under the appropriate cfg it lists next as a dep with the appropriate markers + activated_extras.setdefault(base, {}).setdefault(group_name, {}).setdefault(next, {}).update(markers) + if next not in visited: + visited[next] = 1 + worklist.append(next) + + idx += 1 + + return {it: 1 for it in dep_groups.keys()}, activated_extras + +def collate_versions_by_name(activated_extras): + """Collates activated extras by package name, configuration, and version. + + This function transforms the `activated_extras` map into a more convenient + structure that groups different versions of the same package together. + + Args: + activated_extras: The map of activated extras, as returned by + `_collect_activated_extras`. + + Returns: + A dictionary mapping package names to configurations, versions, and + markers. The structure is: `{name: {config: {version: {marker: 1}}}}`. + """ + result = {} + + for id, configs in activated_extras.items(): + (lock_id, pkg_name, pkg_version, _) = id + for cfg, deps in configs.items(): + # Ensure path exists: result[name][cfg][version] -> {marker: 1} + # We use setdefault chain to traverse/create the nested dicts + version_markers = result.setdefault(pkg_name, {}).setdefault(cfg, {}).setdefault(id, {}) + + # deps is {dep_triple: {marker: 1}} + # We aggregate all markers for this version (from base and extras) + # into the single map for this version string. + for markers in deps.values(): + version_markers.update(markers) + + return result diff --git a/uv/private/extension/test_graph_utils.bzl b/uv/private/extension/test_graph_utils.bzl new file mode 100644 index 00000000..cd1cd7ec --- /dev/null +++ b/uv/private/extension/test_graph_utils.bzl @@ -0,0 +1,382 @@ +load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") +load(":graph_utils.bzl", "activate_extras", "collect_sccs") + +def _extras_test_impl(ctx): + env = unittest.begin(ctx) + + # Common configuration for tests + cfg = "default" + + # Test Case 1: Simple extra activation + # pkg1[__base__] depends on pkg2[foo_extra] + # pkg2[foo_extra] implies dep on pkg3[__base__] + marker_graph_1 = { + ("proj", "1.0", "pkg1", "__base__"): { + ("proj", "1.0", "pkg2", "__base__"): {"": 1}, + ("proj", "1.0", "pkg2", "foo_extra"): {"": 1}, + }, + ("proj", "1.0", "pkg2", "__base__"): {}, + ("proj", "1.0", "pkg2", "foo_extra"): { + ("proj", "1.0", "pkg3", "__base__"): {"": 1}, + }, + ("proj", "1.0", "pkg3", "__base__"): {}, + } + activated_extras_1 = { + ("proj", "1.0", "pkg2", "__base__"): { + cfg: { + ("proj", "1.0", "pkg2", "foo_extra"): {"": 1}, + }, + }, + } + expected_graph_1 = { + ("proj", "1.0", "pkg1", "__base__"): { + ("proj", "1.0", "pkg2", "__base__"): {"": 1}, + }, + ("proj", "1.0", "pkg2", "__base__"): { + ("proj", "1.0", "pkg3", "__base__"): {"": 1}, + }, + ("proj", "1.0", "pkg3", "__base__"): {}, + } + result_graph_1 = activate_extras(marker_graph_1, activated_extras_1, cfg) + asserts.equals(env, expected_graph_1, result_graph_1, "Test Case 1 Failed: Simple extra activation") + + # Test Case 2: No extras activated (dependency on extra exists, but extra not in activated_extras) + # pkg1[__base__] depends on pkg2[foo_extra] + # activated_extras is empty + marker_graph_2 = { + ("proj", "1.0", "pkg1", "__base__"): { + ("proj", "1.0", "pkg2", "foo_extra"): {"": 1}, + }, + } + activated_extras_2 = {} + + # The expected graph should still have pkg1 depending on pkg2 as base, because normalization happens + expected_graph_2 = { + ("proj", "1.0", "pkg1", "__base__"): { + ("proj", "1.0", "pkg2", "__base__"): {"": 1}, + }, + } + result_graph_2 = activate_extras(marker_graph_2, activated_extras_2, cfg) + asserts.equals(env, expected_graph_2, result_graph_2, "Test Case 2 Failed: No extras activated") + + # Test Case 3: Extra with multiple dependencies and conditional markers + # pkg1[__base__] depends on pkg2[bar_extra] + # pkg2[bar_extra] implies dep on pkg3[__base__] (marker: sys_platform=='linux') and pkg4[__base__] (no marker) + marker_graph_3 = { + ("proj", "1.0", "pkg1", "__base__"): { + ("proj", "1.0", "pkg2", "__base__"): {"": 1}, + ("proj", "1.0", "pkg2", "bar_extra"): {"": 1}, + }, + ("proj", "1.0", "pkg2", "__base__"): {}, + ("proj", "1.0", "pkg2", "bar_extra"): { + ("proj", "1.0", "pkg3", "__base__"): {"sys_platform=='linux'": 1}, + ("proj", "1.0", "pkg4", "__base__"): {"": 1}, + }, + ("proj", "1.0", "pkg3", "__base__"): {}, + ("proj", "1.0", "pkg4", "__base__"): {}, + } + activated_extras_3 = { + ("proj", "1.0", "pkg2", "__base__"): { + cfg: { + ("proj", "1.0", "pkg2", "bar_extra"): {"": 1}, + }, + }, + } + expected_graph_3 = { + ("proj", "1.0", "pkg1", "__base__"): { + ("proj", "1.0", "pkg2", "__base__"): {"": 1}, + }, + ("proj", "1.0", "pkg2", "__base__"): { + ("proj", "1.0", "pkg3", "__base__"): {"sys_platform=='linux'": 1}, + ("proj", "1.0", "pkg4", "__base__"): {"": 1}, + }, + ("proj", "1.0", "pkg3", "__base__"): {}, + ("proj", "1.0", "pkg4", "__base__"): {}, + } + result_graph_3 = activate_extras(marker_graph_3, activated_extras_3, cfg) + asserts.equals(env, expected_graph_3, result_graph_3, "Test Case 3 Failed: Extra with multiple dependencies and conditional markers") + + return unittest.end(env) + +extras_activation_test = unittest.make( + _extras_test_impl, +) + +def _collect_sccs_test_impl(ctx): + env = unittest.begin(ctx) + + # Test case: A simple marker_graph + marker_graph = { + ("pkg", "1.0", "dep1", "__base__"): { + ("pkg", "1.0", "dep2", "__base__"): {"python_version=='3.8'": 1}, + }, + ("pkg", "1.0", "dep2", "__base__"): { + ("pkg", "1.0", "dep1", "__base__"): {"python_version=='3.9'": 1}, + }, + ("pkg", "1.0", "dep3", "__base__"): { + ("pkg", "1.0", "dep1", "__base__"): {"": 1}, + ("pkg", "1.0", "dep4", "__base__"): {"": 1}, + }, + ("pkg", "1.0", "dep4", "__base__"): {}, + } + + dep_to_scc, scc_graph, scc_deps = collect_sccs(marker_graph) + + # 1. Check dep_to_scc + asserts.equals(env, len(dep_to_scc), 4) # All 4 dependencies should be mapped + asserts.equals(env, dep_to_scc[("pkg", "1.0", "dep1", "__base__")], dep_to_scc[("pkg", "1.0", "dep2", "__base__")]) + asserts.true(env, dep_to_scc[("pkg", "1.0", "dep1", "__base__")] != dep_to_scc[("pkg", "1.0", "dep3", "__base__")]) + asserts.true(env, dep_to_scc[("pkg", "1.0", "dep1", "__base__")] != dep_to_scc[("pkg", "1.0", "dep4", "__base__")]) + asserts.true(env, dep_to_scc[("pkg", "1.0", "dep3", "__base__")] != dep_to_scc[("pkg", "1.0", "dep4", "__base__")]) + + # 2. Check scc_graph + asserts.equals(env, len(scc_graph), 3) # Expect 3 SCCs + + # Find the SCC containing dep1 and dep2 + scc1_id = dep_to_scc[("pkg", "1.0", "dep1", "__base__")] + asserts.true(env, ("pkg", "1.0", "dep1", "__base__") in scc_graph[scc1_id]) + asserts.true(env, ("pkg", "1.0", "dep2", "__base__") in scc_graph[scc1_id]) + asserts.equals(env, len(scc_graph[scc1_id]), 2) # Should contain 2 members + + # Check intra-scc markers for scc1 + # dep1 -> dep2 + asserts.true(env, "python_version=='3.8'" in scc_graph[scc1_id][("pkg", "1.0", "dep2", "__base__")]) + + # dep2 -> dep1 + asserts.true(env, "python_version=='3.9'" in scc_graph[scc1_id][("pkg", "1.0", "dep1", "__base__")]) + + # Find the SCC containing dep3 + scc3_id = dep_to_scc[("pkg", "1.0", "dep3", "__base__")] + asserts.true(env, ("pkg", "1.0", "dep3", "__base__") in scc_graph[scc3_id]) + asserts.equals(env, len(scc_graph[scc3_id]), 1) + + # Find the SCC containing dep4 + scc4_id = dep_to_scc[("pkg", "1.0", "dep4", "__base__")] + asserts.true(env, ("pkg", "1.0", "dep4", "__base__") in scc_graph[scc4_id]) + asserts.equals(env, len(scc_graph[scc4_id]), 1) + + # 3. Check scc_deps (external dependencies from SCCs) + asserts.equals(env, len(scc_deps), 3) # Should be 3 SCCs with potential external deps + + # SCC containing dep3 should have external deps to dep1 and dep4 + scc3_deps = scc_deps[scc3_id] + asserts.true(env, ("pkg", "1.0", "dep1", "__base__") in scc3_deps) + asserts.true(env, ("pkg", "1.0", "dep4", "__base__") in scc3_deps) + asserts.equals(env, len(scc3_deps), 2) + asserts.true(env, "" in scc3_deps[("pkg", "1.0", "dep1", "__base__")]) + asserts.true(env, "" in scc3_deps[("pkg", "1.0", "dep4", "__base__")]) + + # SCC containing dep1/dep2 should not have external dependencies in this example + # Note: scc_deps for scc1_id should contain markers from dep1 to dep2 and vice versa, but they are internal. + # We are checking for *external* deps here. + asserts.equals(env, len(scc_deps[scc1_id]), 0) + + # SCC containing dep4 should not have external dependencies + asserts.equals(env, len(scc_deps[scc4_id]), 0) + + return unittest.end(env) + +collect_sccs_test = unittest.make( + _collect_sccs_test_impl, +) + +def _collect_sccs_empty_graph_test_impl(ctx): + env = unittest.begin(ctx) + marker_graph = {} + dep_to_scc, scc_graph, scc_deps = collect_sccs(marker_graph) + + asserts.equals(env, len(dep_to_scc), 0, "dep_to_scc should be empty for an empty graph") + asserts.equals(env, len(scc_graph), 0, "scc_graph should be empty for an empty graph") + asserts.equals(env, len(scc_deps), 0, "scc_deps should be empty for an empty graph") + + return unittest.end(env) + +collect_sccs_empty_graph_test = unittest.make( + _collect_sccs_empty_graph_test_impl, +) + +def _collect_sccs_linear_graph_test_impl(ctx): + env = unittest.begin(ctx) + marker_graph = { + ("pkg", "1.0", "A", "__base__"): {("pkg", "1.0", "B", "__base__"): {"": 1}}, + ("pkg", "1.0", "B", "__base__"): {("pkg", "1.0", "C", "__base__"): {"": 1}}, + ("pkg", "1.0", "C", "__base__"): {}, + } + + dep_to_scc, scc_graph, scc_deps = collect_sccs(marker_graph) + + # All nodes should be in separate SCCs as there are no cycles + asserts.equals(env, len(dep_to_scc), 3) + asserts.equals(env, len(scc_graph), 3) + asserts.equals(env, len(scc_deps), 3) + + scc_a_id = dep_to_scc[("pkg", "1.0", "A", "__base__")] + scc_b_id = dep_to_scc[("pkg", "1.0", "B", "__base__")] + scc_c_id = dep_to_scc[("pkg", "1.0", "C", "__base__")] + + asserts.true(env, scc_a_id != scc_b_id) + asserts.true(env, scc_b_id != scc_c_id) + asserts.true(env, scc_a_id != scc_c_id) + + asserts.equals(env, len(scc_graph[scc_a_id]), 1) + asserts.true(env, ("pkg", "1.0", "A", "__base__") in scc_graph[scc_a_id]) + + asserts.equals(env, len(scc_graph[scc_b_id]), 1) + asserts.true(env, ("pkg", "1.0", "B", "__base__") in scc_graph[scc_b_id]) + + asserts.equals(env, len(scc_graph[scc_c_id]), 1) + asserts.true(env, ("pkg", "1.0", "C", "__base__") in scc_graph[scc_c_id]) + + # Check external dependencies + asserts.true(env, ("pkg", "1.0", "B", "__base__") in scc_deps[scc_a_id]) + asserts.equals(env, len(scc_deps[scc_a_id]), 1) + + asserts.true(env, ("pkg", "1.0", "C", "__base__") in scc_deps[scc_b_id]) + asserts.equals(env, len(scc_deps[scc_b_id]), 1) + + asserts.equals(env, len(scc_deps[scc_c_id]), 0) + + return unittest.end(env) + +collect_sccs_linear_graph_test = unittest.make( + _collect_sccs_linear_graph_test_impl, +) + +def _collect_sccs_disconnected_graph_test_impl(ctx): + env = unittest.begin(ctx) + marker_graph = { + ("pkg", "1.0", "A", "__base__"): {("pkg", "1.0", "B", "__base__"): {"": 1}}, + ("pkg", "1.0", "B", "__base__"): {}, + ("pkg", "1.0", "X", "__base__"): {("pkg", "1.0", "Y", "__base__"): {"": 1}}, + ("pkg", "1.0", "Y", "__base__"): {}, + } + + dep_to_scc, scc_graph, scc_deps = collect_sccs(marker_graph) + + asserts.equals(env, len(dep_to_scc), 4) + asserts.equals(env, len(scc_graph), 4) + asserts.equals(env, len(scc_deps), 4) + + # All nodes should be in separate SCCs + scc_a_id = dep_to_scc[("pkg", "1.0", "A", "__base__")] + scc_b_id = dep_to_scc[("pkg", "1.0", "B", "__base__")] + scc_x_id = dep_to_scc[("pkg", "1.0", "X", "__base__")] + scc_y_id = dep_to_scc[("pkg", "1.0", "Y", "__base__")] + + asserts.true(env, scc_a_id != scc_b_id) + asserts.true(env, scc_x_id != scc_y_id) + asserts.true(env, scc_a_id != scc_x_id) # A, B, X, Y should all be distinct SCCs + + # Check external dependencies + asserts.true(env, ("pkg", "1.0", "B", "__base__") in scc_deps[scc_a_id]) + asserts.equals(env, len(scc_deps[scc_a_id]), 1) + asserts.equals(env, len(scc_deps[scc_b_id]), 0) + + asserts.true(env, ("pkg", "1.0", "Y", "__base__") in scc_deps[scc_x_id]) + asserts.equals(env, len(scc_deps[scc_x_id]), 1) + asserts.equals(env, len(scc_deps[scc_y_id]), 0) + + return unittest.end(env) + +collect_sccs_disconnected_graph_test = unittest.make( + _collect_sccs_disconnected_graph_test_impl, +) + +def _collect_sccs_single_node_graph_test_impl(ctx): + env = unittest.begin(ctx) + marker_graph = { + ("pkg", "1.0", "A", "__base__"): {}, + } + + dep_to_scc, scc_graph, scc_deps = collect_sccs(marker_graph) + + asserts.equals(env, len(dep_to_scc), 1) + asserts.equals(env, len(scc_graph), 1) + asserts.equals(env, len(scc_deps), 1) + + scc_a_id = dep_to_scc[("pkg", "1.0", "A", "__base__")] + asserts.true(env, ("pkg", "1.0", "A", "__base__") in scc_graph[scc_a_id]) + asserts.equals(env, len(scc_graph[scc_a_id]), 1) + asserts.equals(env, len(scc_deps[scc_a_id]), 0) + + return unittest.end(env) + +collect_sccs_single_node_graph_test = unittest.make( + _collect_sccs_single_node_graph_test_impl, +) + +def _collect_sccs_self_loop_graph_test_impl(ctx): + env = unittest.begin(ctx) + marker_graph = { + ("pkg", "1.0", "A", "__base__"): {("pkg", "1.0", "A", "__base__"): {"": 1}}, + } + + dep_to_scc, scc_graph, scc_deps = collect_sccs(marker_graph) + + asserts.equals(env, len(dep_to_scc), 1) + asserts.equals(env, len(scc_graph), 1) + asserts.equals(env, len(scc_deps), 1) + + scc_a_id = dep_to_scc[("pkg", "1.0", "A", "__base__")] + asserts.true(env, ("pkg", "1.0", "A", "__base__") in scc_graph[scc_a_id]) + asserts.equals(env, len(scc_graph[scc_a_id]), 1) + asserts.true(env, "" in scc_graph[scc_a_id][("pkg", "1.0", "A", "__base__")]) + asserts.equals(env, len(scc_deps[scc_a_id]), 0) + + return unittest.end(env) + +collect_sccs_self_loop_graph_test = unittest.make( + _collect_sccs_self_loop_graph_test_impl, +) + +def _collect_sccs_complex_cycle_test_impl(ctx): + env = unittest.begin(ctx) + marker_graph = { + ("pkg", "1.0", "A", "__base__"): {("pkg", "1.0", "B", "__base__"): {"": 1}}, + ("pkg", "1.0", "B", "__base__"): {("pkg", "1.0", "C", "__base__"): {"": 1}}, + ("pkg", "1.0", "C", "__base__"): {("pkg", "1.0", "A", "__base__"): {"": 1}}, + ("pkg", "1.0", "D", "__base__"): {("pkg", "1.0", "A", "__base__"): {"": 1}}, + } + + dep_to_scc, scc_graph, scc_deps = collect_sccs(marker_graph) + + asserts.equals(env, len(dep_to_scc), 4) + asserts.equals(env, len(scc_graph), 2) # One SCC for A, B, C; one for D + asserts.equals(env, len(scc_deps), 2) + + scc_abc_id = dep_to_scc[("pkg", "1.0", "A", "__base__")] + scc_d_id = dep_to_scc[("pkg", "1.0", "D", "__base__")] + + asserts.true(env, scc_abc_id == dep_to_scc[("pkg", "1.0", "B", "__base__")]) + asserts.true(env, scc_abc_id == dep_to_scc[("pkg", "1.0", "C", "__base__")]) + asserts.true(env, scc_abc_id != scc_d_id) + + asserts.equals(env, len(scc_graph[scc_abc_id]), 3) # A, B, C are members + asserts.equals(env, len(scc_graph[scc_d_id]), 1) # D is a member + + # Check external dependencies for SCC D -> A,B,C + asserts.true(env, ("pkg", "1.0", "A", "__base__") in scc_deps[scc_d_id]) + asserts.equals(env, len(scc_deps[scc_d_id]), 1) + asserts.equals(env, len(scc_deps[scc_abc_id]), 0) # The cycle itself has no external dependencies + + return unittest.end(env) + +collect_sccs_complex_cycle_test = unittest.make( + _collect_sccs_complex_cycle_test_impl, +) + +def graph_utils_test_suite(): + unittest.suite( + "extras_activation_tests", + extras_activation_test, + ) + unittest.suite( + "collect_sccs_tests", + collect_sccs_test, + collect_sccs_empty_graph_test, + collect_sccs_linear_graph_test, + collect_sccs_disconnected_graph_test, + collect_sccs_single_node_graph_test, + collect_sccs_self_loop_graph_test, + collect_sccs_complex_cycle_test, + ) diff --git a/uv/private/git_archive/BUILD.bazel b/uv/private/git_archive/BUILD.bazel new file mode 100644 index 00000000..bea41f60 --- /dev/null +++ b/uv/private/git_archive/BUILD.bazel @@ -0,0 +1,5 @@ +# TOOLCHAIN: Unused +# Visible to the private extension package +package(default_visibility = ["//uv/private/extension:__pkg__"]) + +exports_files(["defs.bzl"]) diff --git a/uv/private/git_archive/repository.bzl b/uv/private/git_archive/repository.bzl new file mode 100644 index 00000000..8af172fa --- /dev/null +++ b/uv/private/git_archive/repository.bzl @@ -0,0 +1,85 @@ +""" +A repository rule for creating an archive from a remote git repository. +""" + +load("@bazel_features//:features.bzl", features = "bazel_features") + +def _is_sha1(s): + """Check if a string is a 40-character hex string (SHA-1).""" + if len(s) != 40: + return False + for char in s.elems(): + if char not in "0123456789abcdefABCDEF": + return False + return True + +def _git_archive_impl(repository_ctx): + remote = repository_ctx.attr.remote + commit = repository_ctx.attr.commit + ref = repository_ctx.attr.ref + + if commit and not _is_sha1(commit): + fail("The 'commit' attribute must be a 40-character hex string. Got: {}".format(commit)) + + target_ref = ref or commit + is_reproducible = True + resolved_commit = commit + + if ref: + # Use git ls-remote to find the commit associated with the ref + result = repository_ctx.execute(["git", "ls-remote", remote, ref]) + if result.return_code == 0 and result.stdout: + # ls-remote output is: "\t" + resolved_commit = result.stdout.split()[0] + is_reproducible = False + else: + # If we can't resolve it, it's definitely not reproducible + is_reproducible = False + fail("Unable to resolve remote ref {} {}".format(remote, ref)) + + archive_path = "archive.tar" + + # Note that this implies a mkdir the execute relies on + repository_ctx.file("file/BUILD.bazel", """ +package(default_visibility = ["//visibility:public"]) +filegroup( + name = "file", + srcs = ["{}"], +) +""".format(archive_path)) + + # Execute the archive command + repository_ctx.execute( + [ + "git", + "archive", + "--format=tar", + "--remote=" + remote, + "--output=file/" + archive_path, + target_ref, + ], + ) + + if features.external_deps.extension_metadata_has_reproducible: + return repository_ctx.repository_ctx( + reproducible = is_reproducible, + attrs_for_reproducibility = {"commit": resolved_commit}, + ) + +git_archive = repository_rule( + implementation = _git_archive_impl, + attrs = { + "remote": attr.string( + doc = "The URL of the remote git repository.", + mandatory = True, + ), + "ref": attr.string( + doc = "The git ref to archive.", + mandatory = False, + ), + "commit": attr.string( + doc = "The git commit to archive.", + mandatory = False, + ), + }, +) diff --git a/uv/private/graph/BUILD.bazel b/uv/private/graph/BUILD.bazel new file mode 100644 index 00000000..86d11197 --- /dev/null +++ b/uv/private/graph/BUILD.bazel @@ -0,0 +1,10 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") +load(":sccs_test.bzl", "sccs_test_suite") + +bzl_library( + name = "sccs", + srcs = ["sccs.bzl"], + visibility = ["//visibility:public"], +) + +sccs_test_suite() diff --git a/uv/private/graph/defs.bzl b/uv/private/graph/defs.bzl new file mode 100644 index 00000000..79b6c7ff --- /dev/null +++ b/uv/private/graph/defs.bzl @@ -0,0 +1,5 @@ +load(":sccs.bzl", _sccs = "sccs") + +graph = struct( + sccs = _sccs, +) diff --git a/uv/private/graph/sccs.bzl b/uv/private/graph/sccs.bzl new file mode 100644 index 00000000..1af8dfdb --- /dev/null +++ b/uv/private/graph/sccs.bzl @@ -0,0 +1,84 @@ +""" +Strongly connected components helpers. +""" + +def sccs(graph): + """Identify strongly connected components. + + Uses Kosaraju's algorithm as the strategy. This is a non-recursive, + no-while-loop implementation suitable for Starlark. + + Args: + graph (dict): A mapping of nodes to their adjacencies. + + Returns: + A list of lists, where each inner list represents an SCC. + The components of each SCC are in lexically sorted order. + """ + nodes = list(graph.keys()) + bound = len(nodes) * len(nodes) + if not bound: + bound = 1 + + # First DFS traversal to determine finishing times (post-order traversal) + order = [] + + # visited can be 0 (unvisited), 1 (visiting), or 2 (finished) + visited = {node: 0 for node in nodes} + for node in nodes: + if visited[node] == 0: + stack = [node] + visited[node] = 1 + for _ in range(bound): + if not stack: + break + + current_node = stack[-1] + + # Find an unvisited neighbor + unvisited_neighbor = None + for neighbor in graph.get(current_node, []): + if visited[neighbor] == 0: + unvisited_neighbor = neighbor + break + + if unvisited_neighbor: + visited[unvisited_neighbor] = 1 + stack.append(unvisited_neighbor) + else: + # All neighbors visited, so we are done with this node + stack.pop() + visited[current_node] = 2 + order.append(current_node) + + # Create the transpose graph (all edges reversed) + transpose_graph = {node: [] for node in nodes} + for node in nodes: + for neighbor in graph.get(node, []): + transpose_graph.setdefault(neighbor, []).append(node) + + # Second DFS traversal on the transpose graph + sccs = [] + visited = {node: False for node in nodes} + for i in range(len(order)): + start_node = order[len(order) - 1 - i] # reversed order + if not visited[start_node]: + component = [] + stack = [start_node] + visited[start_node] = True + + for _ in range(bound): + if not stack: + break + + current_node = stack.pop() + component.append(current_node) + + for neighbor in transpose_graph.get(current_node, []): + if not visited[neighbor]: + visited[neighbor] = True + stack.append(neighbor) + + sccs.append(sorted(component)) + + return sccs diff --git a/uv/private/graph/sccs_test.bzl b/uv/private/graph/sccs_test.bzl new file mode 100644 index 00000000..580bb256 --- /dev/null +++ b/uv/private/graph/sccs_test.bzl @@ -0,0 +1,2385 @@ +"""Tests for sccs.bzl.""" + +load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") +load("//uv/private/graph:sccs.bzl", "sccs") + +def _sccs_test_impl(ctx): + """ + Some basic hand-coded graphs. + """ + + env = unittest.begin(ctx) + + # Test case 1: A simple graph with no cycles + graph1 = { + "a": ["b", "c"], + "b": ["d"], + "c": ["d"], + "d": [], + } + expected1 = [["d"], ["c"], ["b"], ["a"]] + asserts.equals(env, sorted([sorted(s) for s in sccs(graph1)]), sorted(expected1)) + + # Test case 2: A graph with a single cycle + graph2 = { + "a": ["b"], + "b": ["c"], + "c": ["a"], + } + expected2 = [["a", "b", "c"]] + asserts.equals(env, sorted([sorted(s) for s in sccs(graph2)]), sorted(expected2)) + + # Test case 3: A graph with two separate cycles + graph3 = { + "a": ["b"], + "b": ["a"], + "c": ["d"], + "d": ["c"], + } + expected3 = [["a", "b"], ["c", "d"]] + asserts.equals(env, sorted([sorted(s) for s in sccs(graph3)]), sorted(expected3)) + + # Test case 4: A more complex graph with multiple interconnected cycles + graph4 = { + "a": ["b"], + "b": ["c", "e"], + "c": ["d"], + "d": ["b"], + "e": ["f"], + "f": ["e", "g"], + "g": [], + } + expected4 = [["g"], ["e", "f"], ["b", "c", "d"], ["a"]] + asserts.equals(env, sorted([sorted(s) for s in sccs(graph4)]), sorted(expected4)) + return unittest.end(env) + +sccs_test = unittest.make( + _sccs_test_impl, +) + +def _sccs_lockfile_test_impl(ctx): + """ + A dump of a real lockfile's graph which exposed a rather nasty bug where + cycles were incorrectly analyzed resulting in erroneous graph manipulations. + Replicated here as an example test; no effort has been made to identify a + minimal reproduction. + """ + + env = unittest.begin(ctx) + graph5 = { + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "aiobotocore", "2.19.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "aiohttp", "3.13.3", "__base__"), + ("lockfile__e08ddb66104268a4", "aioitertools", "0.12.0", "__base__"), + ("lockfile__e08ddb66104268a4", "botocore", "1.36.1", "__base__"), + ("lockfile__e08ddb66104268a4", "jmespath", "1.0.1", "__base__"), + ("lockfile__e08ddb66104268a4", "multidict", "6.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "python_dateutil", "2.9.0.post0", "__base__"), + ("lockfile__e08ddb66104268a4", "urllib3", "2.3.0", "__base__"), + ("lockfile__e08ddb66104268a4", "wrapt", "1.17.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "aiofiles", "24.1.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "aiohappyeyeballs", "2.6.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "aiohttp", "3.13.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "aiohappyeyeballs", "2.6.1", "__base__"), + ("lockfile__e08ddb66104268a4", "aiosignal", "1.4.0", "__base__"), + ("lockfile__e08ddb66104268a4", "attrs", "24.3.0", "__base__"), + ("lockfile__e08ddb66104268a4", "frozenlist", "1.5.0", "__base__"), + ("lockfile__e08ddb66104268a4", "multidict", "6.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "propcache", "0.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "yarl", "1.18.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "aiohttp_cors", "0.7.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "aiohttp", "3.13.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "aioitertools", "0.12.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "aiosignal", "1.4.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "frozenlist", "1.5.0", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "aiotools", "1.8.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "alembic", "1.15.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "mako", "1.3.9", "__base__"), + ("lockfile__e08ddb66104268a4", "sqlalchemy", "2.0.45", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "altair", "5.5.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jinja2", "3.1.6", "__base__"), + ("lockfile__e08ddb66104268a4", "jsonschema", "4.23.0", "__base__"), + ("lockfile__e08ddb66104268a4", "narwhals", "1.22.0", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "annotated_types", "0.7.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "ansicon", "1.89.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "anyio", "4.8.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "idna", "3.10", "__base__"), + ("lockfile__e08ddb66104268a4", "sniffio", "1.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "anyscale", "0.26.81", "__base__"): [ + ("lockfile__e08ddb66104268a4", "aiohttp", "3.13.3", "__base__"), + ("lockfile__e08ddb66104268a4", "boto3", "1.36.1", "__base__"), + ("lockfile__e08ddb66104268a4", "botocore", "1.36.1", "__base__"), + ("lockfile__e08ddb66104268a4", "certifi", "2024.12.14", "__base__"), + ("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "colorama", "0.4.6", "__base__"), + ("lockfile__e08ddb66104268a4", "gitpython", "3.1.44", "__base__"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "humanize", "4.11.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jsonpatch", "1.33", "__base__"), + ("lockfile__e08ddb66104268a4", "jsonschema", "4.23.0", "__base__"), + ("lockfile__e08ddb66104268a4", "kubernetes", "33.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "oauth2client", "4.1.3", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pathspec", "0.12.1", "__base__"), + ("lockfile__e08ddb66104268a4", "python_dateutil", "2.9.0.post0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "rich", "13.9.4", "__base__"), + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ("lockfile__e08ddb66104268a4", "smart_open", "7.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "tabulate", "0.9.0", "__base__"), + ("lockfile__e08ddb66104268a4", "termcolor", "2.4.0", "__base__"), + ("lockfile__e08ddb66104268a4", "tqdm", "4.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ("lockfile__e08ddb66104268a4", "tzlocal", "5.2", "__base__"), + ("lockfile__e08ddb66104268a4", "urllib3", "2.3.0", "__base__"), + ("lockfile__e08ddb66104268a4", "websockets", "14.2", "__base__"), + ("lockfile__e08ddb66104268a4", "wrapt", "1.17.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "anywidget", "0.9.18", "__base__"): [ + ("lockfile__e08ddb66104268a4", "ipywidgets", "8.1.5", "__base__"), + ("lockfile__e08ddb66104268a4", "psygnal", "0.15.0", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "appnope", "0.1.4", "__base__"): [], + ("lockfile__e08ddb66104268a4", "argon2_cffi", "23.1.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "argon2_cffi_bindings", "21.2.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "argon2_cffi_bindings", "21.2.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "cffi", "1.17.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "array_record", "0.6.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "epath"), + ], + ("lockfile__e08ddb66104268a4", "arrow", "1.3.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "python_dateutil", "2.9.0.post0", "__base__"), + ("lockfile__e08ddb66104268a4", "types_python_dateutil", "2.9.0.20241206", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "asciitree", "0.3.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "asn1crypto", "1.5.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "assemblyai", "0.48.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "httpx", "0.28.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pydantic", "2.10.5", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ("lockfile__e08ddb66104268a4", "websockets", "14.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "asteval", "1.0.6", "__base__"): [], + ("lockfile__e08ddb66104268a4", "asttokens", "3.0.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "astunparse", "1.6.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ("lockfile__e08ddb66104268a4", "wheel", "0.45.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "async_lru", "2.0.4", "__base__"): [], + ("lockfile__e08ddb66104268a4", "async_timeout", "5.0.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "asynch", "0.2.5", "__base__"): [ + ("lockfile__e08ddb66104268a4", "ciso8601", "2.3.3", "__base__"), + ("lockfile__e08ddb66104268a4", "leb128", "1.0.8", "__base__"), + ("lockfile__e08ddb66104268a4", "lz4", "4.3.3", "__base__"), + ("lockfile__e08ddb66104268a4", "pytz", "2024.2", "__base__"), + ("lockfile__e08ddb66104268a4", "tzlocal", "5.2", "__base__"), + ("lockfile__e08ddb66104268a4", "zstd", "1.5.7.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "atlas_provider_sqlalchemy", "0.5.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "clickhouse_sqlalchemy", "0.3.2", "__base__"), + ("lockfile__e08ddb66104268a4", "sqlalchemy", "2.0.45", "__base__"), + ("lockfile__e08ddb66104268a4", "typer", "0.16.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "attrs", "24.3.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "augmax", "0.4.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "einops", "0.8.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jax", "0.8.1", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "autoregistry", "1.1.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "av", "14.2.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "aws_assume_role_lib", "2.10.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "boto3", "1.36.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "awscrt", "0.23.5", "__base__"): [], + ("lockfile__e08ddb66104268a4", "awsiotsdk", "1.22.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "awscrt", "0.23.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "babel", "2.17.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "bazel_runfiles", "1.1.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "bcrypt", "4.2.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "beartype", "0.19.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "beautifulsoup4", "4.13.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "soupsieve", "2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "bidict", "0.23.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "binpacking", "1.5.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "future", "1.0.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "black", "24.10.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "mypy_extensions", "1.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pathspec", "0.12.1", "__base__"), + ("lockfile__e08ddb66104268a4", "platformdirs", "4.3.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "blake3", "1.0.5", "__base__"): [], + ("lockfile__e08ddb66104268a4", "bleach", "6.2.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "webencodings", "0.5.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "bleach", "6.2.0", "css"): [ + ("lockfile__e08ddb66104268a4", "bleach", "6.2.0", "__base__"), + ("lockfile__e08ddb66104268a4", "tinycss2", "1.4.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "blessed", "1.21.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jinxed", "1.3.0", "__base__"), + ("lockfile__e08ddb66104268a4", "wcwidth", "0.2.13", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "blinker", "1.9.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "boto3", "1.36.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "botocore", "1.36.1", "__base__"), + ("lockfile__e08ddb66104268a4", "jmespath", "1.0.1", "__base__"), + ("lockfile__e08ddb66104268a4", "s3transfer", "0.11.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "botocore", "1.36.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jmespath", "1.0.1", "__base__"), + ("lockfile__e08ddb66104268a4", "python_dateutil", "2.9.0.post0", "__base__"), + ("lockfile__e08ddb66104268a4", "urllib3", "2.3.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "botocore_stubs", "1.37.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "types_awscrt", "0.23.10", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "bs4", "0.0.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "beautifulsoup4", "4.13.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "build", "1.4.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "colorama", "0.4.6", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pyproject_hooks", "1.2.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "cachelib", "0.9.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "cachetools", "6.2.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "cartesia", "1.0.14", "__base__"): [ + ("lockfile__e08ddb66104268a4", "aiohttp", "3.13.3", "__base__"), + ("lockfile__e08ddb66104268a4", "httpx", "0.28.1", "__base__"), + ("lockfile__e08ddb66104268a4", "iterators", "0.2.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pytest_asyncio", "0.23.6", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "websockets", "14.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "certifi", "2024.12.14", "__base__"): [], + ("lockfile__e08ddb66104268a4", "cffi", "1.17.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pycparser", "2.22", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "cfgv", "3.4.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "chardet", "5.2.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "charset_normalizer", "3.4.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "chex", "0.1.90", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "jax", "0.8.1", "__base__"), + ("lockfile__e08ddb66104268a4", "jaxlib", "0.8.1", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "toolz", "1.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "ciso8601", "2.3.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__"): [ + ("lockfile__e08ddb66104268a4", "colorama", "0.4.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "clickhouse_connect", "0.9.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "certifi", "2024.12.14", "__base__"), + ("lockfile__e08ddb66104268a4", "lz4", "4.3.3", "__base__"), + ("lockfile__e08ddb66104268a4", "pytz", "2024.2", "__base__"), + ("lockfile__e08ddb66104268a4", "urllib3", "2.3.0", "__base__"), + ("lockfile__e08ddb66104268a4", "zstandard", "0.23.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "clickhouse_driver", "0.2.10", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pytz", "2024.2", "__base__"), + ("lockfile__e08ddb66104268a4", "tzlocal", "5.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "clickhouse_sqlalchemy", "0.3.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "asynch", "0.2.5", "__base__"), + ("lockfile__e08ddb66104268a4", "clickhouse_driver", "0.2.10", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "sqlalchemy", "2.0.45", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "cloudpathlib", "0.21.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "cloudpathlib", "0.21.1", "gs"): [ + ("lockfile__e08ddb66104268a4", "cloudpathlib", "0.21.1", "__base__"), + ("lockfile__e08ddb66104268a4", "google_cloud_storage", "3.1.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "cloudpathlib", "0.21.1", "s3"): [ + ("lockfile__e08ddb66104268a4", "cloudpathlib", "0.21.1", "__base__"), + ("lockfile__e08ddb66104268a4", "boto3", "1.36.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "cloudpickle", "3.1.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "clu", "0.0.12", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "epath"), + ("lockfile__e08ddb66104268a4", "flax", "0.12.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jax", "0.8.1", "__base__"), + ("lockfile__e08ddb66104268a4", "jaxlib", "0.8.1", "__base__"), + ("lockfile__e08ddb66104268a4", "ml_collections", "1.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ("lockfile__e08ddb66104268a4", "wrapt", "1.17.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "cma", "4.3.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "codefind", "0.1.7", "__base__"): [], + ("lockfile__e08ddb66104268a4", "colorama", "0.4.6", "__base__"): [], + ("lockfile__e08ddb66104268a4", "coloredlogs", "15.0.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "humanfriendly", "10.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "colorful", "0.5.6", "__base__"): [ + ("lockfile__e08ddb66104268a4", "colorama", "0.4.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "colorlog", "6.10.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "colorama", "0.4.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "comm", "0.2.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "conjure_python_client", "2.13.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "contourpy", "1.3.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "coverage", "7.6.10", "__base__"): [], + ("lockfile__e08ddb66104268a4", "coverage", "7.6.10", "toml"): [ + ("lockfile__e08ddb66104268a4", "coverage", "7.6.10", "__base__"), + ("lockfile__e08ddb66104268a4", "tomli", "2.3.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "crcmod", "1.7", "__base__"): [], + ("lockfile__e08ddb66104268a4", "cryptography", "44.0.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "cffi", "1.17.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "ctranslate2", "4.5.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "setuptools", "75.8.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "cycler", "0.12.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "cyclopts", "4.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "attrs", "24.3.0", "__base__"), + ("lockfile__e08ddb66104268a4", "docstring_parser", "0.16", "__base__"), + ("lockfile__e08ddb66104268a4", "rich", "13.9.4", "__base__"), + ("lockfile__e08ddb66104268a4", "rich_rst", "1.3.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "cython", "3.2.4", "__base__"): [], + ("lockfile__e08ddb66104268a4", "daqp", "0.7.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "dash", "2.18.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "dash_core_components", "2.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "dash_html_components", "2.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "dash_table", "5.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "flask", "3.0.3", "__base__"), + ("lockfile__e08ddb66104268a4", "importlib_metadata", "8.4.0", "__base__"), + ("lockfile__e08ddb66104268a4", "nest_asyncio", "1.6.0", "__base__"), + ("lockfile__e08ddb66104268a4", "plotly", "5.24.1", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "retrying", "1.3.4", "__base__"), + ("lockfile__e08ddb66104268a4", "setuptools", "75.8.0", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ("lockfile__e08ddb66104268a4", "werkzeug", "3.0.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "dash_core_components", "2.0.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "dash_html_components", "2.0.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "dash_table", "5.0.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "dateparser", "1.2.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "python_dateutil", "2.9.0.post0", "__base__"), + ("lockfile__e08ddb66104268a4", "pytz", "2024.2", "__base__"), + ("lockfile__e08ddb66104268a4", "regex", "2024.11.6", "__base__"), + ("lockfile__e08ddb66104268a4", "tzlocal", "5.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "dds_cloudapi_sdk", "0.4.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "pillow", "11.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pydantic", "2.10.5", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "debugpy", "1.8.12", "__base__"): [], + ("lockfile__e08ddb66104268a4", "decorator", "4.4.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "deepcomparer", "0.4.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "defusedxml", "0.7.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "deprecated", "1.2.15", "__base__"): [ + ("lockfile__e08ddb66104268a4", "wrapt", "1.17.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "depthai", "2.29.0.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "dhash", "1.4", "__base__"): [], + ("lockfile__e08ddb66104268a4", "distlib", "0.3.9", "__base__"): [], + ("lockfile__e08ddb66104268a4", "distrax", "0.1.7", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "chex", "0.1.90", "__base__"), + ("lockfile__e08ddb66104268a4", "jax", "0.8.1", "__base__"), + ("lockfile__e08ddb66104268a4", "jaxlib", "0.8.1", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "tfp_nightly", "0.26.0.dev20260104", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "distro", "1.9.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "dm_control", "1.0.27", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "dm_env", "1.6", "__base__"), + ("lockfile__e08ddb66104268a4", "dm_tree", "0.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "glfw", "2.8.0", "__base__"), + ("lockfile__e08ddb66104268a4", "labmaze", "1.0.6", "__base__"), + ("lockfile__e08ddb66104268a4", "lxml", "5.3.0", "__base__"), + ("lockfile__e08ddb66104268a4", "mujoco", "3.2.7", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyopengl", "3.1.9", "__base__"), + ("lockfile__e08ddb66104268a4", "pyparsing", "3.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "scipy", "1.16.3", "__base__"), + ("lockfile__e08ddb66104268a4", "setuptools", "75.8.0", "__base__"), + ("lockfile__e08ddb66104268a4", "tqdm", "4.67.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "dm_env", "1.6", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "dm_tree", "0.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "dm_tree", "0.1.8", "__base__"): [], + ("lockfile__e08ddb66104268a4", "docker", "7.1.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pywin32", "311", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "urllib3", "2.3.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "docstring_parser", "0.16", "__base__"): [], + ("lockfile__e08ddb66104268a4", "docutils", "0.21.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "doppler_sdk", "1.3.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "http_exceptions", "0.2.10", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "dtaidistance", "2.3.12", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "durationpy", "0.9", "__base__"): [], + ("lockfile__e08ddb66104268a4", "dynamixel_sdk", "3.7.31", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pyserial", "3.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "easyhid", "0.0.10", "__base__"): [ + ("lockfile__e08ddb66104268a4", "cffi", "1.17.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "einops", "0.8.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "embreex", "2.17.7.post7", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "encord", "0.1.175", "__base__"): [ + ("lockfile__e08ddb66104268a4", "cryptography", "44.0.3", "__base__"), + ("lockfile__e08ddb66104268a4", "orjson", "3.10.15", "__base__"), + ("lockfile__e08ddb66104268a4", "pydantic", "2.10.5", "__base__"), + ("lockfile__e08ddb66104268a4", "python_dateutil", "2.9.0.post0", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "tqdm", "4.67.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "equinox", "0.12.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jax", "0.8.1", "__base__"), + ("lockfile__e08ddb66104268a4", "jaxtyping", "0.2.34", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ("lockfile__e08ddb66104268a4", "wadler_lindig", "0.1.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "edc"): [ + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "enp"): [ + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "epath"): [ + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "__base__"), + ("lockfile__e08ddb66104268a4", "fsspec", "2025.9.0", "__base__"), + ("lockfile__e08ddb66104268a4", "importlib_resources", "6.5.2", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ("lockfile__e08ddb66104268a4", "zipp", "3.21.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "epy"): [ + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "etree"): [ + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "__base__"), + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "tqdm", "4.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "evdev", "1.7.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "execnet", "2.1.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "executing", "2.1.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "expandvars", "0.12.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "fastapi", "0.115.6", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pydantic", "2.10.5", "__base__"), + ("lockfile__e08ddb66104268a4", "starlette", "0.41.3", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "fasteners", "0.19", "__base__"): [], + ("lockfile__e08ddb66104268a4", "faster_whisper", "1.1.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "av", "14.2.0", "__base__"), + ("lockfile__e08ddb66104268a4", "ctranslate2", "4.5.0", "__base__"), + ("lockfile__e08ddb66104268a4", "huggingface_hub", "0.34.4", "__base__"), + ("lockfile__e08ddb66104268a4", "onnxruntime", "1.20.1", "__base__"), + ("lockfile__e08ddb66104268a4", "tokenizers", "0.21.4", "__base__"), + ("lockfile__e08ddb66104268a4", "tqdm", "4.67.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "fastjsonschema", "2.21.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "ffmpeg_python", "0.2.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "future", "1.0.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "filelock", "3.16.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "flask", "3.0.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "blinker", "1.9.0", "__base__"), + ("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "itsdangerous", "2.2.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jinja2", "3.1.6", "__base__"), + ("lockfile__e08ddb66104268a4", "werkzeug", "3.0.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "flask_caching", "2.3.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "cachelib", "0.9.0", "__base__"), + ("lockfile__e08ddb66104268a4", "flask", "3.0.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "flask_cors", "5.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "flask", "3.0.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "flask_sock", "0.7.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "flask", "3.0.3", "__base__"), + ("lockfile__e08ddb66104268a4", "simple_websocket", "1.1.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "flatbuffers", "24.12.23", "__base__"): [], + ("lockfile__e08ddb66104268a4", "flax", "0.12.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jax", "0.8.1", "__base__"), + ("lockfile__e08ddb66104268a4", "msgpack", "1.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "optax", "0.2.2", "__base__"), + ("lockfile__e08ddb66104268a4", "orbax_checkpoint", "0.11.26", "__base__"), + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "rich", "13.9.4", "__base__"), + ("lockfile__e08ddb66104268a4", "tensorstore", "0.1.71", "__base__"), + ("lockfile__e08ddb66104268a4", "treescope", "0.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "fonttools", "4.55.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "foxglove_schemas_protobuf", "0.2.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "fqdn", "1.5.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "frozendict", "2.4.6", "__base__"): [], + ("lockfile__e08ddb66104268a4", "frozenlist", "1.5.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "fsspec", "2025.9.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "fsspec", "2025.9.0", "gcs"): [ + ("lockfile__e08ddb66104268a4", "fsspec", "2025.9.0", "__base__"), + ("lockfile__e08ddb66104268a4", "gcsfs", "2025.9.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "fsspec", "2025.9.0", "s3"): [ + ("lockfile__e08ddb66104268a4", "fsspec", "2025.9.0", "__base__"), + ("lockfile__e08ddb66104268a4", "s3fs", "2025.9.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "future", "1.0.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "gast", "0.6.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "gcsfs", "2025.9.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "aiohttp", "3.13.3", "__base__"), + ("lockfile__e08ddb66104268a4", "decorator", "4.4.2", "__base__"), + ("lockfile__e08ddb66104268a4", "fsspec", "2025.9.0", "__base__"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "google_auth_oauthlib", "1.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "google_cloud_storage", "3.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "gitdb", "4.0.12", "__base__"): [ + ("lockfile__e08ddb66104268a4", "smmap", "5.0.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "gitpython", "3.1.44", "__base__"): [ + ("lockfile__e08ddb66104268a4", "gitdb", "4.0.12", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "glfw", "2.8.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "google", "3.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "beautifulsoup4", "4.13.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "googleapis_common_protos", "1.71.0", "__base__"), + ("lockfile__e08ddb66104268a4", "proto_plus", "1.26.1", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "grpc"): [ + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "__base__"), + ("lockfile__e08ddb66104268a4", "grpcio", "1.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "grpcio_status", "1.62.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_api_python_client", "2.159.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "__base__"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "google_auth_httplib2", "0.2.0", "__base__"), + ("lockfile__e08ddb66104268a4", "httplib2", "0.22.0", "__base__"), + ("lockfile__e08ddb66104268a4", "uritemplate", "4.1.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "cachetools", "6.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pyasn1_modules", "0.4.1", "__base__"), + ("lockfile__e08ddb66104268a4", "rsa", "4.9", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_auth_httplib2", "0.2.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "httplib2", "0.22.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_auth_oauthlib", "1.2.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "requests_oauthlib", "2.0.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_cloud_appengine_logging", "1.8.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "grpc"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "grpcio", "1.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "proto_plus", "1.26.1", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_cloud_artifact_registry", "1.15.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "grpc"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "grpc_google_iam_v1", "0.14.2", "__base__"), + ("lockfile__e08ddb66104268a4", "proto_plus", "1.26.1", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_cloud_audit_log", "0.4.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "googleapis_common_protos", "1.71.0", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_cloud_container", "2.59.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "grpc"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "proto_plus", "1.26.1", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_cloud_core", "2.4.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "__base__"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_cloud_logging", "3.13.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "grpc"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "google_cloud_appengine_logging", "1.8.0", "__base__"), + ("lockfile__e08ddb66104268a4", "google_cloud_audit_log", "0.4.0", "__base__"), + ("lockfile__e08ddb66104268a4", "google_cloud_core", "2.4.3", "__base__"), + ("lockfile__e08ddb66104268a4", "grpc_google_iam_v1", "0.14.2", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_api", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "proto_plus", "1.26.1", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_cloud_mldiagnostics", "0.5.10", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "__base__"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "google_cloud_logging", "3.13.0", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "psutil", "7.0.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_cloud_pubsub", "2.34.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "grpc"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "grpc_google_iam_v1", "0.14.2", "__base__"), + ("lockfile__e08ddb66104268a4", "grpcio", "1.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "grpcio_status", "1.62.3", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_api", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_sdk", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "proto_plus", "1.26.1", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_cloud_secret_manager", "2.24.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "grpc"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "grpc_google_iam_v1", "0.14.2", "__base__"), + ("lockfile__e08ddb66104268a4", "proto_plus", "1.26.1", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_cloud_speech", "2.35.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "grpc"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "grpcio", "1.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "proto_plus", "1.26.1", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_cloud_storage", "3.1.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "__base__"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "google_cloud_core", "2.4.3", "__base__"), + ("lockfile__e08ddb66104268a4", "google_crc32c", "1.6.0", "__base__"), + ("lockfile__e08ddb66104268a4", "google_resumable_media", "2.7.2", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_cloud_storage_transfer", "1.18.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "grpc"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "grpcio", "1.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "proto_plus", "1.26.1", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_crc32c", "1.6.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "google_genai", "1.25.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "anyio", "4.8.0", "__base__"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "httpx", "0.28.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pydantic", "2.10.5", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "tenacity", "8.5.0", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ("lockfile__e08ddb66104268a4", "websockets", "14.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_pasta", "0.2.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "google_resumable_media", "2.7.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_crc32c", "1.6.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "googleapis_common_protos", "1.71.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "googleapis_common_protos", "1.71.0", "grpc"): [ + ("lockfile__e08ddb66104268a4", "googleapis_common_protos", "1.71.0", "__base__"), + ("lockfile__e08ddb66104268a4", "grpcio", "1.67.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "gpustat", "1.1.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "blessed", "1.21.0", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_ml_py", "12.570.86", "__base__"), + ("lockfile__e08ddb66104268a4", "psutil", "7.0.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "greenlet", "3.1.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "grpc_google_iam_v1", "0.14.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "googleapis_common_protos", "1.71.0", "grpc"), + ("lockfile__e08ddb66104268a4", "grpcio", "1.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "grpcio", "1.67.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "grpcio_status", "1.62.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "googleapis_common_protos", "1.71.0", "__base__"), + ("lockfile__e08ddb66104268a4", "grpcio", "1.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "grpclib", "0.4.7", "__base__"): [ + ("lockfile__e08ddb66104268a4", "h2", "4.2.0", "__base__"), + ("lockfile__e08ddb66104268a4", "multidict", "6.1.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "gunicorn", "23.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "h11", "0.14.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "h2", "4.2.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "hpack", "4.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "hyperframe", "6.1.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "h5py", "3.12.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "hf_xet", "1.1.7", "__base__"): [], + ("lockfile__e08ddb66104268a4", "hpack", "4.1.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "http_exceptions", "0.2.10", "__base__"): [], + ("lockfile__e08ddb66104268a4", "httpcore", "1.0.7", "__base__"): [ + ("lockfile__e08ddb66104268a4", "certifi", "2024.12.14", "__base__"), + ("lockfile__e08ddb66104268a4", "h11", "0.14.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "httplib2", "0.22.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pyparsing", "3.2.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "httpx", "0.28.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "anyio", "4.8.0", "__base__"), + ("lockfile__e08ddb66104268a4", "certifi", "2024.12.14", "__base__"), + ("lockfile__e08ddb66104268a4", "httpcore", "1.0.7", "__base__"), + ("lockfile__e08ddb66104268a4", "idna", "3.10", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "httpx_retries", "0.4.5", "__base__"): [ + ("lockfile__e08ddb66104268a4", "httpx", "0.28.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "httpx_ws", "0.7.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "anyio", "4.8.0", "__base__"), + ("lockfile__e08ddb66104268a4", "httpcore", "1.0.7", "__base__"), + ("lockfile__e08ddb66104268a4", "httpx", "0.28.1", "__base__"), + ("lockfile__e08ddb66104268a4", "wsproto", "1.2.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "huggingface_hub", "0.34.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "filelock", "3.16.1", "__base__"), + ("lockfile__e08ddb66104268a4", "fsspec", "2025.9.0", "__base__"), + ("lockfile__e08ddb66104268a4", "hf_xet", "1.1.7", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "tqdm", "4.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "humanfriendly", "10.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pyreadline3", "3.5.4", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "humanize", "4.11.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "hyperframe", "6.1.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "identify", "2.6.8", "__base__"): [], + ("lockfile__e08ddb66104268a4", "idna", "3.10", "__base__"): [], + ("lockfile__e08ddb66104268a4", "imageio", "2.37.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "pillow", "11.2.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "imageio", "2.37.0", "ffmpeg"): [ + ("lockfile__e08ddb66104268a4", "imageio", "2.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "imageio_ffmpeg", "0.6.0", "__base__"), + ("lockfile__e08ddb66104268a4", "psutil", "7.0.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "imageio_ffmpeg", "0.6.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "imgui_bundle", "1.92.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "glfw", "2.8.0", "__base__"), + ("lockfile__e08ddb66104268a4", "munch", "4.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "pillow", "11.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pyopengl", "3.1.9", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "immutabledict", "4.2.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "importlib_metadata", "8.4.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "zipp", "3.21.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "importlib_resources", "6.5.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "iniconfig", "2.0.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "inquirerpy", "0.3.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pfzy", "0.3.4", "__base__"), + ("lockfile__e08ddb66104268a4", "prompt_toolkit", "3.0.48", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "invoke", "2.2.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "ipykernel", "6.29.5", "__base__"): [ + ("lockfile__e08ddb66104268a4", "appnope", "0.1.4", "__base__"), + ("lockfile__e08ddb66104268a4", "comm", "0.2.2", "__base__"), + ("lockfile__e08ddb66104268a4", "debugpy", "1.8.12", "__base__"), + ("lockfile__e08ddb66104268a4", "ipython", "8.31.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_client", "8.6.3", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_core", "5.7.2", "__base__"), + ("lockfile__e08ddb66104268a4", "matplotlib_inline", "0.1.7", "__base__"), + ("lockfile__e08ddb66104268a4", "nest_asyncio", "1.6.0", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "psutil", "7.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyzmq", "26.2.0", "__base__"), + ("lockfile__e08ddb66104268a4", "tornado", "6.5.4", "__base__"), + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "ipython", "8.31.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "colorama", "0.4.6", "__base__"), + ("lockfile__e08ddb66104268a4", "decorator", "4.4.2", "__base__"), + ("lockfile__e08ddb66104268a4", "jedi", "0.19.2", "__base__"), + ("lockfile__e08ddb66104268a4", "matplotlib_inline", "0.1.7", "__base__"), + ("lockfile__e08ddb66104268a4", "pexpect", "4.9.0", "__base__"), + ("lockfile__e08ddb66104268a4", "prompt_toolkit", "3.0.48", "__base__"), + ("lockfile__e08ddb66104268a4", "pygments", "2.19.1", "__base__"), + ("lockfile__e08ddb66104268a4", "stack_data", "0.6.3", "__base__"), + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "ipywidgets", "8.1.5", "__base__"): [ + ("lockfile__e08ddb66104268a4", "comm", "0.2.2", "__base__"), + ("lockfile__e08ddb66104268a4", "ipython", "8.31.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyterlab_widgets", "3.0.13", "__base__"), + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ("lockfile__e08ddb66104268a4", "widgetsnbextension", "4.0.13", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "isoduration", "20.11.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "arrow", "1.3.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "iterators", "0.2.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "itsdangerous", "2.2.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "jax", "0.8.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jaxlib", "0.8.1", "__base__"), + ("lockfile__e08ddb66104268a4", "ml_dtypes", "0.5.1", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "opt_einsum", "3.4.0", "__base__"), + ("lockfile__e08ddb66104268a4", "scipy", "1.16.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jax_cuda12_pjrt", "0.8.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "jax_cuda12_plugin", "0.8.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jax_cuda12_pjrt", "0.8.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jax_cuda12_plugin", "0.8.1", "with-cuda"): [ + ("lockfile__e08ddb66104268a4", "jax_cuda12_plugin", "0.8.1", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_cublas_cu12", "12.8.3.14", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_cuda_cupti_cu12", "12.8.57", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_cuda_nvcc_cu12", "12.8.61", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_cuda_nvrtc_cu12", "12.9.86", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_cuda_runtime_cu12", "12.8.57", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_cudnn_cu12", "9.14.0.64", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_cufft_cu12", "11.3.3.41", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_cusolver_cu12", "11.7.2.55", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_cusparse_cu12", "12.5.7.53", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_nccl_cu12", "2.25.1", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_nvjitlink_cu12", "12.8.61", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_nvshmem_cu12", "3.4.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jax_triton", "0.3.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "jax", "0.8.1", "__base__"), + ("lockfile__e08ddb66104268a4", "triton", "3.3.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jaxlib", "0.8.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "ml_dtypes", "0.5.1", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "scipy", "1.16.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jaxtyping", "0.2.34", "__base__"): [ + ("lockfile__e08ddb66104268a4", "typeguard", "2.13.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jedi", "0.19.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "parso", "0.8.4", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jinja2", "3.1.6", "__base__"): [ + ("lockfile__e08ddb66104268a4", "markupsafe", "3.0.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jinxed", "1.3.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "ansicon", "1.89.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jiter", "0.8.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "jmespath", "1.0.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "joblib", "1.4.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "jq", "1.10.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "json_numpy", "2.1.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "json_repair", "0.52.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "json5", "0.10.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "jsonpatch", "1.33", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jsonpointer", "3.0.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jsonpointer", "3.0.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "jsonschema", "4.23.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "attrs", "24.3.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jsonschema_specifications", "2024.10.1", "__base__"), + ("lockfile__e08ddb66104268a4", "referencing", "0.36.1", "__base__"), + ("lockfile__e08ddb66104268a4", "rpds_py", "0.22.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jsonschema", "4.23.0", "format-nongpl"): [ + ("lockfile__e08ddb66104268a4", "jsonschema", "4.23.0", "__base__"), + ("lockfile__e08ddb66104268a4", "fqdn", "1.5.1", "__base__"), + ("lockfile__e08ddb66104268a4", "idna", "3.10", "__base__"), + ("lockfile__e08ddb66104268a4", "isoduration", "20.11.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jsonpointer", "3.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "rfc3339_validator", "0.1.4", "__base__"), + ("lockfile__e08ddb66104268a4", "rfc3986_validator", "0.1.1", "__base__"), + ("lockfile__e08ddb66104268a4", "uri_template", "1.3.0", "__base__"), + ("lockfile__e08ddb66104268a4", "webcolors", "24.11.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jsonschema_specifications", "2024.10.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "referencing", "0.36.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jupyter", "1.1.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "ipykernel", "6.29.5", "__base__"), + ("lockfile__e08ddb66104268a4", "ipywidgets", "8.1.5", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_console", "6.6.3", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyterlab", "4.3.5", "__base__"), + ("lockfile__e08ddb66104268a4", "nbconvert", "7.16.6", "__base__"), + ("lockfile__e08ddb66104268a4", "notebook", "7.3.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jupyter_client", "8.6.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jupyter_core", "5.7.2", "__base__"), + ("lockfile__e08ddb66104268a4", "python_dateutil", "2.9.0.post0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyzmq", "26.2.0", "__base__"), + ("lockfile__e08ddb66104268a4", "tornado", "6.5.4", "__base__"), + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jupyter_console", "6.6.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "ipykernel", "6.29.5", "__base__"), + ("lockfile__e08ddb66104268a4", "ipython", "8.31.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_client", "8.6.3", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_core", "5.7.2", "__base__"), + ("lockfile__e08ddb66104268a4", "prompt_toolkit", "3.0.48", "__base__"), + ("lockfile__e08ddb66104268a4", "pygments", "2.19.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pyzmq", "26.2.0", "__base__"), + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jupyter_core", "5.7.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "platformdirs", "4.3.6", "__base__"), + ("lockfile__e08ddb66104268a4", "pywin32", "311", "__base__"), + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jupyter_events", "0.11.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jsonschema", "4.23.0", "format-nongpl"), + ("lockfile__e08ddb66104268a4", "python_json_logger", "3.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "referencing", "0.36.1", "__base__"), + ("lockfile__e08ddb66104268a4", "rfc3339_validator", "0.1.4", "__base__"), + ("lockfile__e08ddb66104268a4", "rfc3986_validator", "0.1.1", "__base__"), + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jupyter_lsp", "2.2.5", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jupyter_server", "2.15.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jupyter_server", "2.15.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "anyio", "4.8.0", "__base__"), + ("lockfile__e08ddb66104268a4", "argon2_cffi", "23.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jinja2", "3.1.6", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_client", "8.6.3", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_core", "5.7.2", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_events", "0.11.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_server_terminals", "0.5.3", "__base__"), + ("lockfile__e08ddb66104268a4", "nbconvert", "7.16.6", "__base__"), + ("lockfile__e08ddb66104268a4", "nbformat", "5.10.4", "__base__"), + ("lockfile__e08ddb66104268a4", "overrides", "7.7.0", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "prometheus_client", "0.21.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pywinpty", "3.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pyzmq", "26.2.0", "__base__"), + ("lockfile__e08ddb66104268a4", "send2trash", "1.8.3", "__base__"), + ("lockfile__e08ddb66104268a4", "terminado", "0.18.1", "__base__"), + ("lockfile__e08ddb66104268a4", "tornado", "6.5.4", "__base__"), + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ("lockfile__e08ddb66104268a4", "websocket_client", "1.8.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jupyter_server_terminals", "0.5.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pywinpty", "3.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "terminado", "0.18.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jupyter_ui_poll", "1.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "ipython", "8.31.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jupyterlab", "4.3.5", "__base__"): [ + ("lockfile__e08ddb66104268a4", "async_lru", "2.0.4", "__base__"), + ("lockfile__e08ddb66104268a4", "httpx", "0.28.1", "__base__"), + ("lockfile__e08ddb66104268a4", "ipykernel", "6.29.5", "__base__"), + ("lockfile__e08ddb66104268a4", "jinja2", "3.1.6", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_core", "5.7.2", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_lsp", "2.2.5", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_server", "2.15.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyterlab_server", "2.27.3", "__base__"), + ("lockfile__e08ddb66104268a4", "notebook_shim", "0.2.4", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "setuptools", "75.8.0", "__base__"), + ("lockfile__e08ddb66104268a4", "tornado", "6.5.4", "__base__"), + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jupyterlab_pygments", "0.3.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "jupyterlab_server", "2.27.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "babel", "2.17.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jinja2", "3.1.6", "__base__"), + ("lockfile__e08ddb66104268a4", "json5", "0.10.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jsonschema", "4.23.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_server", "2.15.0", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "jupyterlab_widgets", "3.0.13", "__base__"): [], + ("lockfile__e08ddb66104268a4", "jurigged", "0.6.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "blessed", "1.21.0", "__base__"), + ("lockfile__e08ddb66104268a4", "codefind", "0.1.7", "__base__"), + ("lockfile__e08ddb66104268a4", "ovld", "0.4.6", "__base__"), + ("lockfile__e08ddb66104268a4", "watchdog", "4.0.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "k3d", "2.17.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "deepcomparer", "0.4.0", "__base__"), + ("lockfile__e08ddb66104268a4", "ipywidgets", "8.1.5", "__base__"), + ("lockfile__e08ddb66104268a4", "msgpack", "1.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ("lockfile__e08ddb66104268a4", "traittypes", "0.2.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "keras", "3.12.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "h5py", "3.12.1", "__base__"), + ("lockfile__e08ddb66104268a4", "ml_dtypes", "0.5.1", "__base__"), + ("lockfile__e08ddb66104268a4", "namex", "0.0.8", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "optree", "0.14.0", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "rich", "13.9.4", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "kiwisolver", "1.4.8", "__base__"): [], + ("lockfile__e08ddb66104268a4", "kubernetes", "33.1.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "certifi", "2024.12.14", "__base__"), + ("lockfile__e08ddb66104268a4", "durationpy", "0.9", "__base__"), + ("lockfile__e08ddb66104268a4", "google_auth", "2.42.0", "__base__"), + ("lockfile__e08ddb66104268a4", "oauthlib", "3.2.2", "__base__"), + ("lockfile__e08ddb66104268a4", "python_dateutil", "2.9.0.post0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "requests_oauthlib", "2.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ("lockfile__e08ddb66104268a4", "urllib3", "2.3.0", "__base__"), + ("lockfile__e08ddb66104268a4", "websocket_client", "1.8.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "labmaze", "1.0.6", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "setuptools", "75.8.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "lazy_loader", "0.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "leb128", "1.0.8", "__base__"): [], + ("lockfile__e08ddb66104268a4", "lerobot_dataset_validator", "0.1.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jsonschema", "4.23.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pandas", "2.2.3", "__base__"), + ("lockfile__e08ddb66104268a4", "tyro", "0.8.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "libclang", "18.1.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "libcst", "1.8.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "libtpu", "0.0.30", "__base__"): [], + ("lockfile__e08ddb66104268a4", "line_profiler", "4.2.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "linkify_it_py", "2.0.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "uc_micro_py", "1.0.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "linuxpy", "0.20.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "loguru", "0.7.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "colorama", "0.4.6", "__base__"), + ("lockfile__e08ddb66104268a4", "win32_setctime", "1.2.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "lxml", "5.3.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "lz4", "4.3.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "mako", "1.3.9", "__base__"): [ + ("lockfile__e08ddb66104268a4", "markupsafe", "3.0.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "manifold3d", "3.2.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "mapbox_earcut", "1.0.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "markdown", "3.7", "__base__"): [], + ("lockfile__e08ddb66104268a4", "markdown_it_py", "3.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "mdurl", "0.1.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "markdown_it_py", "3.0.0", "linkify"): [ + ("lockfile__e08ddb66104268a4", "markdown_it_py", "3.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "linkify_it_py", "2.0.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "markdown_it_py", "3.0.0", "plugins"): [ + ("lockfile__e08ddb66104268a4", "markdown_it_py", "3.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "mdit_py_plugins", "0.4.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "markupsafe", "3.0.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "matplotlib", "3.10.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "contourpy", "1.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "cycler", "0.12.1", "__base__"), + ("lockfile__e08ddb66104268a4", "fonttools", "4.55.3", "__base__"), + ("lockfile__e08ddb66104268a4", "kiwisolver", "1.4.8", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pillow", "11.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pyparsing", "3.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "python_dateutil", "2.9.0.post0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "matplotlib_inline", "0.1.7", "__base__"): [ + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "maturin", "1.8.7", "__base__"): [], + ("lockfile__e08ddb66104268a4", "mcap", "1.2.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "lz4", "4.3.3", "__base__"), + ("lockfile__e08ddb66104268a4", "zstandard", "0.23.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "mcap_protobuf_support", "0.5.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "mcap", "1.2.2", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "mdit_py_plugins", "0.4.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "markdown_it_py", "3.0.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "mdurl", "0.1.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "mediapy", "1.2.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "ipython", "8.31.0", "__base__"), + ("lockfile__e08ddb66104268a4", "matplotlib", "3.10.0", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "pillow", "11.2.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "memray", "1.15.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jinja2", "3.1.6", "__base__"), + ("lockfile__e08ddb66104268a4", "rich", "13.9.4", "__base__"), + ("lockfile__e08ddb66104268a4", "textual", "1.0.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "meshcat", "0.3.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "ipython", "8.31.0", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "pillow", "11.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pyngrok", "7.5.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyzmq", "26.2.0", "__base__"), + ("lockfile__e08ddb66104268a4", "tornado", "6.5.4", "__base__"), + ("lockfile__e08ddb66104268a4", "u_msgpack_python", "2.8.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "mink", "0.0.10", "__base__"): [ + ("lockfile__e08ddb66104268a4", "mujoco", "3.2.7", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "qpsolvers", "4.4.0", "daqp"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "mirakuru", "2.5.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "psutil", "7.0.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "mistune", "3.1.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "ml_collections", "1.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "ml_dtypes", "0.5.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "modal", "1.1.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "aiohttp", "3.13.3", "__base__"), + ("lockfile__e08ddb66104268a4", "certifi", "2024.12.14", "__base__"), + ("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "grpclib", "0.4.7", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ("lockfile__e08ddb66104268a4", "rich", "13.9.4", "__base__"), + ("lockfile__e08ddb66104268a4", "synchronicity", "0.10.2", "__base__"), + ("lockfile__e08ddb66104268a4", "toml", "0.10.2", "__base__"), + ("lockfile__e08ddb66104268a4", "typer", "0.16.0", "__base__"), + ("lockfile__e08ddb66104268a4", "types_certifi", "2021.10.8.3", "__base__"), + ("lockfile__e08ddb66104268a4", "types_toml", "0.10.8.20240310", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ("lockfile__e08ddb66104268a4", "watchfiles", "0.19.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "moviepy", "1.0.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "decorator", "4.4.2", "__base__"), + ("lockfile__e08ddb66104268a4", "imageio", "2.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "imageio_ffmpeg", "0.6.0", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "proglog", "0.1.10", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "tqdm", "4.67.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "mpmath", "1.3.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "msgpack", "1.1.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "mujoco", "3.2.7", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "epath"), + ("lockfile__e08ddb66104268a4", "glfw", "2.8.0", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "pyopengl", "3.1.9", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "multidict", "6.1.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "munch", "4.0.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "mypy", "1.15.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "mypy_extensions", "1.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "mypy_extensions", "1.0.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "namex", "0.0.8", "__base__"): [], + ("lockfile__e08ddb66104268a4", "narwhals", "1.22.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "natsort", "8.4.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "nbclient", "0.10.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jupyter_client", "8.6.3", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_core", "5.7.2", "__base__"), + ("lockfile__e08ddb66104268a4", "nbformat", "5.10.4", "__base__"), + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "nbconvert", "7.16.6", "__base__"): [ + ("lockfile__e08ddb66104268a4", "beautifulsoup4", "4.13.3", "__base__"), + ("lockfile__e08ddb66104268a4", "bleach", "6.2.0", "css"), + ("lockfile__e08ddb66104268a4", "defusedxml", "0.7.1", "__base__"), + ("lockfile__e08ddb66104268a4", "jinja2", "3.1.6", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_core", "5.7.2", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyterlab_pygments", "0.3.0", "__base__"), + ("lockfile__e08ddb66104268a4", "markupsafe", "3.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "mistune", "3.1.1", "__base__"), + ("lockfile__e08ddb66104268a4", "nbclient", "0.10.2", "__base__"), + ("lockfile__e08ddb66104268a4", "nbformat", "5.10.4", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pandocfilters", "1.5.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pygments", "2.19.1", "__base__"), + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "nbformat", "5.10.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "fastjsonschema", "2.21.1", "__base__"), + ("lockfile__e08ddb66104268a4", "jsonschema", "4.23.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_core", "5.7.2", "__base__"), + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "nest_asyncio", "1.6.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "networkx", "3.4.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "nltk", "3.9.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "joblib", "1.4.2", "__base__"), + ("lockfile__e08ddb66104268a4", "regex", "2024.11.6", "__base__"), + ("lockfile__e08ddb66104268a4", "tqdm", "4.67.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "nodeenv", "1.9.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "nominal", "1.87.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "cachetools", "6.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "conjure_python_client", "2.13.0", "__base__"), + ("lockfile__e08ddb66104268a4", "ffmpeg_python", "0.2.0", "__base__"), + ("lockfile__e08ddb66104268a4", "nominal_api", "0.931.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pandas", "2.2.3", "__base__"), + ("lockfile__e08ddb66104268a4", "python_dateutil", "2.9.0.post0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "tabulate", "0.9.0", "__base__"), + ("lockfile__e08ddb66104268a4", "types_cachetools", "6.2.0.20251022", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "nominal_api", "0.931.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "conjure_python_client", "2.13.0", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "notebook", "7.3.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jupyter_server", "2.15.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyterlab", "4.3.5", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyterlab_server", "2.27.3", "__base__"), + ("lockfile__e08ddb66104268a4", "notebook_shim", "0.2.4", "__base__"), + ("lockfile__e08ddb66104268a4", "tornado", "6.5.4", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "notebook_shim", "0.2.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jupyter_server", "2.15.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "numcodecs", "0.15.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "deprecated", "1.2.15", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"): [], + ("lockfile__e08ddb66104268a4", "numpydantic", "1.6.9", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "pydantic", "2.10.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "nvidia_cublas_cu12", "12.8.3.14", "__base__"): [], + ("lockfile__e08ddb66104268a4", "nvidia_cuda_cupti_cu12", "12.8.57", "__base__"): [], + ("lockfile__e08ddb66104268a4", "nvidia_cuda_nvcc_cu12", "12.8.61", "__base__"): [], + ("lockfile__e08ddb66104268a4", "nvidia_cuda_nvrtc_cu12", "12.9.86", "__base__"): [], + ("lockfile__e08ddb66104268a4", "nvidia_cuda_runtime_cu12", "12.8.57", "__base__"): [], + ("lockfile__e08ddb66104268a4", "nvidia_cudnn_cu12", "9.14.0.64", "__base__"): [ + ("lockfile__e08ddb66104268a4", "nvidia_cublas_cu12", "12.8.3.14", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "nvidia_cufft_cu12", "11.3.3.41", "__base__"): [ + ("lockfile__e08ddb66104268a4", "nvidia_nvjitlink_cu12", "12.8.61", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "nvidia_cusolver_cu12", "11.7.2.55", "__base__"): [ + ("lockfile__e08ddb66104268a4", "nvidia_cublas_cu12", "12.8.3.14", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_cusparse_cu12", "12.5.7.53", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_nvjitlink_cu12", "12.8.61", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "nvidia_cusparse_cu12", "12.5.7.53", "__base__"): [ + ("lockfile__e08ddb66104268a4", "nvidia_nvjitlink_cu12", "12.8.61", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "nvidia_dali_cuda120", "1.47.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "astunparse", "1.6.3", "__base__"), + ("lockfile__e08ddb66104268a4", "dm_tree", "0.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "gast", "0.6.0", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_nvimgcodec_cu12", "0.4.1.21", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_nvjpeg2k_cu12", "0.8.1.40", "__base__"), + ("lockfile__e08ddb66104268a4", "nvidia_nvtiff_cu12", "0.4.0.62", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "nvidia_ml_py", "12.570.86", "__base__"): [], + ("lockfile__e08ddb66104268a4", "nvidia_nccl_cu12", "2.25.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "nvidia_nvimgcodec_cu12", "0.4.1.21", "__base__"): [], + ("lockfile__e08ddb66104268a4", "nvidia_nvjitlink_cu12", "12.8.61", "__base__"): [], + ("lockfile__e08ddb66104268a4", "nvidia_nvjpeg_cu12", "12.3.5.57", "__base__"): [], + ("lockfile__e08ddb66104268a4", "nvidia_nvjpeg2k_cu12", "0.8.1.40", "__base__"): [], + ("lockfile__e08ddb66104268a4", "nvidia_nvshmem_cu12", "3.4.5", "__base__"): [], + ("lockfile__e08ddb66104268a4", "nvidia_nvtiff_cu12", "0.4.0.62", "__base__"): [], + ("lockfile__e08ddb66104268a4", "oauth2client", "4.1.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "httplib2", "0.22.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyasn1", "0.6.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pyasn1_modules", "0.4.1", "__base__"), + ("lockfile__e08ddb66104268a4", "rsa", "4.9", "__base__"), + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "oauthlib", "3.2.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "onnxruntime", "1.20.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "coloredlogs", "15.0.1", "__base__"), + ("lockfile__e08ddb66104268a4", "flatbuffers", "24.12.23", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ("lockfile__e08ddb66104268a4", "sympy", "1.13.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "openai", "1.95.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "anyio", "4.8.0", "__base__"), + ("lockfile__e08ddb66104268a4", "distro", "1.9.0", "__base__"), + ("lockfile__e08ddb66104268a4", "httpx", "0.28.1", "__base__"), + ("lockfile__e08ddb66104268a4", "jiter", "0.8.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pydantic", "2.10.5", "__base__"), + ("lockfile__e08ddb66104268a4", "sniffio", "1.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "tqdm", "4.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "opencensus", "0.11.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "google_api_core", "2.28.1", "__base__"), + ("lockfile__e08ddb66104268a4", "opencensus_context", "0.1.3", "__base__"), + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "opencensus_context", "0.1.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "opencv_python", "4.12.0.88", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "opentelemetry_api", "1.37.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "importlib_metadata", "8.4.0", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "opentelemetry_distro", "0.58b0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "opentelemetry_api", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_instrumentation", "0.58b0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_sdk", "1.37.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "opentelemetry_exporter_otlp", "1.37.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "opentelemetry_exporter_otlp_proto_grpc", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_exporter_otlp_proto_http", "1.37.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "opentelemetry_exporter_otlp_proto_common", "1.37.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "opentelemetry_proto", "1.37.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "opentelemetry_exporter_otlp_proto_grpc", "1.37.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "googleapis_common_protos", "1.71.0", "__base__"), + ("lockfile__e08ddb66104268a4", "grpcio", "1.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_api", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_exporter_otlp_proto_common", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_proto", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_sdk", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "opentelemetry_exporter_otlp_proto_http", "1.37.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "googleapis_common_protos", "1.71.0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_api", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_exporter_otlp_proto_common", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_proto", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_sdk", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "opentelemetry_exporter_prometheus", "0.58b0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "opentelemetry_api", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_sdk", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "prometheus_client", "0.21.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "opentelemetry_instrumentation", "0.58b0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "opentelemetry_api", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_semantic_conventions", "0.58b0", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "wrapt", "1.17.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "opentelemetry_proto", "1.37.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "opentelemetry_sdk", "1.37.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "opentelemetry_api", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_semantic_conventions", "0.58b0", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "opentelemetry_semantic_conventions", "0.58b0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "opentelemetry_api", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "opt_einsum", "3.4.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "optax", "0.2.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "chex", "0.1.90", "__base__"), + ("lockfile__e08ddb66104268a4", "jax", "0.8.1", "__base__"), + ("lockfile__e08ddb66104268a4", "jaxlib", "0.8.1", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "optree", "0.14.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "orbax_checkpoint", "0.11.26", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "aiofiles", "24.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "epath"), + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "epy"), + ("lockfile__e08ddb66104268a4", "humanize", "4.11.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jax", "0.8.1", "__base__"), + ("lockfile__e08ddb66104268a4", "msgpack", "1.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "nest_asyncio", "1.6.0", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ("lockfile__e08ddb66104268a4", "psutil", "7.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "simplejson", "3.19.3", "__base__"), + ("lockfile__e08ddb66104268a4", "tensorstore", "0.1.71", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "orjson", "3.10.15", "__base__"): [], + ("lockfile__e08ddb66104268a4", "overrides", "7.7.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "ovld", "0.4.6", "__base__"): [], + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pandas", "2.2.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "python_dateutil", "2.9.0.post0", "__base__"), + ("lockfile__e08ddb66104268a4", "pytz", "2024.2", "__base__"), + ("lockfile__e08ddb66104268a4", "tzdata", "2024.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pandocfilters", "1.5.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "paramiko", "4.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "bcrypt", "4.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "cryptography", "44.0.3", "__base__"), + ("lockfile__e08ddb66104268a4", "invoke", "2.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pynacl", "1.5.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "parso", "0.8.4", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pathspec", "0.12.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pexpect", "4.9.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "ptyprocess", "0.7.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pfzy", "0.3.4", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pg8000", "1.31.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "python_dateutil", "2.9.0.post0", "__base__"), + ("lockfile__e08ddb66104268a4", "scramp", "1.4.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pgvector", "0.3.6", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pillow", "11.2.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "ping3", "5.1.5", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pip", "25.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "platformdirs", "4.3.6", "__base__"): [], + ("lockfile__e08ddb66104268a4", "playwright", "1.55.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "greenlet", "3.1.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pyee", "13.0.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "plotly", "5.24.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "tenacity", "8.5.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pluggy", "1.5.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "polars", "1.33.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "port_for", "0.7.4", "__base__"): [], + ("lockfile__e08ddb66104268a4", "posix_ipc", "1.1.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pre_commit", "4.1.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "cfgv", "3.4.0", "__base__"), + ("lockfile__e08ddb66104268a4", "identify", "2.6.8", "__base__"), + ("lockfile__e08ddb66104268a4", "nodeenv", "1.9.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "virtualenv", "20.29.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "proglog", "0.1.10", "__base__"): [ + ("lockfile__e08ddb66104268a4", "tqdm", "4.67.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "projectaria_tools", "2.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "rerun_sdk", "0.22.1", "__base__"), + ("lockfile__e08ddb66104268a4", "tqdm", "4.67.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "projectaria_tools", "2.0.0", "all"): [ + ("lockfile__e08ddb66104268a4", "projectaria_tools", "2.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter", "1.1.1", "__base__"), + ("lockfile__e08ddb66104268a4", "matplotlib", "3.10.0", "__base__"), + ("lockfile__e08ddb66104268a4", "moviepy", "1.0.3", "__base__"), + ("lockfile__e08ddb66104268a4", "pandas", "2.2.3", "__base__"), + ("lockfile__e08ddb66104268a4", "pillow", "11.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "plotly", "5.24.1", "__base__"), + ("lockfile__e08ddb66104268a4", "rerun_notebook", "0.22.1", "__base__"), + ("lockfile__e08ddb66104268a4", "scipy", "1.16.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "prometheus_client", "0.21.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "promise", "2.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "prompt_toolkit", "3.0.48", "__base__"): [ + ("lockfile__e08ddb66104268a4", "wcwidth", "0.2.13", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "propcache", "0.2.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "proto_plus", "1.26.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "psutil", "7.0.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "psycopg", "3.2.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ("lockfile__e08ddb66104268a4", "tzdata", "2024.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "psycopg", "3.2.4", "binary"): [ + ("lockfile__e08ddb66104268a4", "psycopg", "3.2.4", "__base__"), + ("lockfile__e08ddb66104268a4", "psycopg_binary", "3.2.4", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "psycopg", "3.2.4", "pool"): [ + ("lockfile__e08ddb66104268a4", "psycopg", "3.2.4", "__base__"), + ("lockfile__e08ddb66104268a4", "psycopg_pool", "3.2.4", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "psycopg_binary", "3.2.4", "__base__"): [], + ("lockfile__e08ddb66104268a4", "psycopg_pool", "3.2.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "psycopg2_binary", "2.9.10", "__base__"): [], + ("lockfile__e08ddb66104268a4", "psygnal", "0.15.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "ptyprocess", "0.7.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pure_eval", "0.2.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pure_python_adb", "0.3.0.dev0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "py", "1.11.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "py_cpuinfo", "9.0.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "py_spy", "0.4.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyarrow", "21.0.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyasn1", "0.6.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyasn1_modules", "0.4.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pyasn1", "0.6.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pyaudio", "0.2.14", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pychromedevtools", "1.0.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "websocket_client", "1.8.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pycocotools", "2.0.10", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pycollada", "0.9.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "python_dateutil", "2.9.0.post0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pycparser", "2.22", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pycryptodome", "3.23.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pydantic", "2.10.5", "__base__"): [ + ("lockfile__e08ddb66104268a4", "annotated_types", "0.7.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pydantic_core", "2.27.2", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pydantic_core", "2.27.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pydeck", "0.9.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "jinja2", "3.1.6", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pydub", "0.25.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyee", "13.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pygame", "2.6.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pygments", "2.19.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyinstrument", "5.0.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyjoystick", "1.2.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pysdl2", "0.9.17", "__base__"), + ("lockfile__e08ddb66104268a4", "resource_man", "2.2.8", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pyjwt", "2.10.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyjwt", "2.10.1", "crypto"): [ + ("lockfile__e08ddb66104268a4", "pyjwt", "2.10.1", "__base__"), + ("lockfile__e08ddb66104268a4", "cryptography", "44.0.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pymediainfo", "7.0.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pynacl", "1.5.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "cffi", "1.17.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pyngrok", "7.5.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pynput", "1.7.7", "__base__"): [ + ("lockfile__e08ddb66104268a4", "evdev", "1.7.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pyobjc_framework_applicationservices", "12.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyobjc_framework_quartz", "12.0", "__base__"), + ("lockfile__e08ddb66104268a4", "python_xlib", "0.33", "__base__"), + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pyobjc_core", "12.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyobjc_framework_applicationservices", "12.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pyobjc_core", "12.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyobjc_framework_cocoa", "12.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyobjc_framework_coretext", "12.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyobjc_framework_quartz", "12.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pyobjc_framework_cocoa", "12.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pyobjc_core", "12.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pyobjc_framework_coretext", "12.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pyobjc_core", "12.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyobjc_framework_cocoa", "12.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyobjc_framework_quartz", "12.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pyobjc_framework_quartz", "12.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pyobjc_core", "12.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyobjc_framework_cocoa", "12.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pyopengl", "3.1.9", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyopenssl", "24.3.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "cryptography", "44.0.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pyparsing", "3.2.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyproject_hooks", "1.2.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pypylon", "4.1.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyquaternion", "0.9.9", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pyreadline3", "3.5.4", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyrealsense2", "2.56.5.9235", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pysdl2", "0.9.17", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyserial", "3.5", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyspacemouse", "1.1.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "easyhid", "0.0.10", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pytest", "8.3.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "colorama", "0.4.6", "__base__"), + ("lockfile__e08ddb66104268a4", "iniconfig", "2.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pluggy", "1.5.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pytest_asyncio", "0.23.6", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pytest", "8.3.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pytest_benchmark", "4.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "py_cpuinfo", "9.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pytest", "8.3.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pytest_cov", "5.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "coverage", "7.6.10", "toml"), + ("lockfile__e08ddb66104268a4", "pytest", "8.3.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pytest_mock", "3.14.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pytest", "8.3.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pytest_postgresql", "6.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "mirakuru", "2.5.3", "__base__"), + ("lockfile__e08ddb66104268a4", "port_for", "0.7.4", "__base__"), + ("lockfile__e08ddb66104268a4", "psycopg", "3.2.4", "__base__"), + ("lockfile__e08ddb66104268a4", "pytest", "8.3.3", "__base__"), + ("lockfile__e08ddb66104268a4", "setuptools", "75.8.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pytest_rerunfailures", "14.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pytest", "8.3.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pytest_split", "0.8.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pytest", "8.3.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pytest_timeout", "2.3.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pytest", "8.3.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pytest_xdist", "3.5.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "execnet", "2.1.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pytest", "8.3.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "python_can", "4.6.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ("lockfile__e08ddb66104268a4", "wrapt", "1.17.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "python_dateutil", "2.9.0.post0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "python_dotenv", "1.0.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "python_json_logger", "3.2.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "python_on_whales", "0.78.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pydantic", "2.10.5", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "python_xlib", "0.33", "__base__"): [ + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pytz", "2024.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyusb", "1.3.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pywin32", "311", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pywinpty", "3.0.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "pyzed", "1.3.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "durationpy", "0.9", "__base__"), + ("lockfile__e08ddb66104268a4", "python_dateutil", "2.9.0.post0", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "pyzmq", "26.2.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "cffi", "1.17.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "qpsolvers", "4.4.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "scipy", "1.16.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "qpsolvers", "4.4.0", "daqp"): [ + ("lockfile__e08ddb66104268a4", "qpsolvers", "4.4.0", "__base__"), + ("lockfile__e08ddb66104268a4", "daqp", "0.7.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "quic_portal", "0.1.13", "__base__"): [], + ("lockfile__e08ddb66104268a4", "rapidfuzz", "3.12.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "ray", "2.52.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "filelock", "3.16.1", "__base__"), + ("lockfile__e08ddb66104268a4", "jsonschema", "4.23.0", "__base__"), + ("lockfile__e08ddb66104268a4", "msgpack", "1.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "ray", "2.52.0", "default"): [ + ("lockfile__e08ddb66104268a4", "ray", "2.52.0", "__base__"), + ("lockfile__e08ddb66104268a4", "aiohttp", "3.13.3", "__base__"), + ("lockfile__e08ddb66104268a4", "aiohttp_cors", "0.7.0", "__base__"), + ("lockfile__e08ddb66104268a4", "colorful", "0.5.6", "__base__"), + ("lockfile__e08ddb66104268a4", "grpcio", "1.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "opencensus", "0.11.4", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_exporter_prometheus", "0.58b0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_proto", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_sdk", "1.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "prometheus_client", "0.21.1", "__base__"), + ("lockfile__e08ddb66104268a4", "py_spy", "0.4.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pydantic", "2.10.5", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "smart_open", "7.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "virtualenv", "20.29.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "readchar", "4.2.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "redis", "5.2.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "async_timeout", "5.0.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "referencing", "0.36.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "attrs", "24.3.0", "__base__"), + ("lockfile__e08ddb66104268a4", "rpds_py", "0.22.3", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "regex", "2024.11.6", "__base__"): [], + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"): [ + ("lockfile__e08ddb66104268a4", "certifi", "2024.12.14", "__base__"), + ("lockfile__e08ddb66104268a4", "charset_normalizer", "3.4.1", "__base__"), + ("lockfile__e08ddb66104268a4", "idna", "3.10", "__base__"), + ("lockfile__e08ddb66104268a4", "urllib3", "2.3.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "requests_mock", "1.12.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "requests_oauthlib", "2.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "oauthlib", "3.2.2", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "rerun_notebook", "0.22.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "anywidget", "0.9.18", "__base__"), + ("lockfile__e08ddb66104268a4", "jupyter_ui_poll", "1.0.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "rerun_sdk", "0.22.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "attrs", "24.3.0", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "pillow", "11.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pyarrow", "21.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "resource_man", "2.2.8", "__base__"): [], + ("lockfile__e08ddb66104268a4", "retry", "0.9.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "decorator", "4.4.2", "__base__"), + ("lockfile__e08ddb66104268a4", "py", "1.11.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "retrying", "1.3.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "rfc3339_validator", "0.1.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "rfc3986_validator", "0.1.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "rich", "13.9.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "markdown_it_py", "3.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pygments", "2.19.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "rich_click", "1.8.9", "__base__"): [ + ("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "rich", "13.9.4", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "rich_rst", "1.3.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "docutils", "0.21.2", "__base__"), + ("lockfile__e08ddb66104268a4", "rich", "13.9.4", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "rpds_py", "0.22.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "rsa", "4.9", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pyasn1", "0.6.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "rtree", "1.4.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "ruamel_yaml", "0.18.10", "__base__"): [ + ("lockfile__e08ddb66104268a4", "ruamel_yaml_clib", "0.2.12", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "ruamel_yaml_clib", "0.2.12", "__base__"): [], + ("lockfile__e08ddb66104268a4", "ruff", "0.7.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "s3fs", "2025.9.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "aiobotocore", "2.19.0", "__base__"), + ("lockfile__e08ddb66104268a4", "aiohttp", "3.13.3", "__base__"), + ("lockfile__e08ddb66104268a4", "fsspec", "2025.9.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "s3transfer", "0.11.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "botocore", "1.36.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "safetensors", "0.5.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "scaleapi", "2.15.14", "__base__"): [ + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "urllib3", "2.3.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "scikit_image", "0.25.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "imageio", "2.37.0", "__base__"), + ("lockfile__e08ddb66104268a4", "lazy_loader", "0.4", "__base__"), + ("lockfile__e08ddb66104268a4", "networkx", "3.4.2", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pillow", "11.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "scipy", "1.16.3", "__base__"), + ("lockfile__e08ddb66104268a4", "tifffile", "2025.1.10", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "scikit_learn", "1.6.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "joblib", "1.4.2", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "scipy", "1.16.3", "__base__"), + ("lockfile__e08ddb66104268a4", "threadpoolctl", "3.6.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "scipy", "1.16.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "scramp", "1.4.5", "__base__"): [ + ("lockfile__e08ddb66104268a4", "asn1crypto", "1.5.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "send2trash", "1.8.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "sentencepiece", "0.2.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "sentry_sdk", "2.20.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "certifi", "2024.12.14", "__base__"), + ("lockfile__e08ddb66104268a4", "urllib3", "2.3.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "sentry_sdk", "2.20.0", "opentelemetry"): [ + ("lockfile__e08ddb66104268a4", "sentry_sdk", "2.20.0", "__base__"), + ("lockfile__e08ddb66104268a4", "opentelemetry_distro", "0.58b0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "setuptools", "75.8.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "setuptools_scm", "9.2.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "setuptools", "75.8.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "shapely", "2.0.7", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "shellingham", "1.5.4", "__base__"): [], + ("lockfile__e08ddb66104268a4", "shtab", "1.7.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "sigtools", "4.0.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "attrs", "24.3.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "simple_parsing", "0.1.7", "__base__"): [ + ("lockfile__e08ddb66104268a4", "docstring_parser", "0.16", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "simple_term_menu", "1.6.6", "__base__"): [], + ("lockfile__e08ddb66104268a4", "simple_websocket", "1.1.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "wsproto", "1.2.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "simplejpeg", "1.9.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "simplejson", "3.19.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "slack_sdk", "3.34.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "smart_open", "7.1.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "wrapt", "1.17.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "smmap", "5.0.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "sniffio", "1.3.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "soupsieve", "2.6", "__base__"): [], + ("lockfile__e08ddb66104268a4", "speechrecognition", "3.14.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "sqlalchemy", "2.0.45", "__base__"): [ + ("lockfile__e08ddb66104268a4", "greenlet", "3.1.1", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "sqlalchemy_utils", "0.41.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "sqlalchemy", "2.0.45", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "sqlmodel", "0.0.22", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pydantic", "2.10.5", "__base__"), + ("lockfile__e08ddb66104268a4", "sqlalchemy", "2.0.45", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "sshkeyboard", "2.3.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "stack_data", "0.6.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "asttokens", "3.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "executing", "2.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pure_eval", "0.2.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "starlette", "0.41.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "anyio", "4.8.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "statsig_python_core", "0.14.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "stl", "0.0.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "streamlit", "1.46.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "altair", "5.5.0", "__base__"), + ("lockfile__e08ddb66104268a4", "blinker", "1.9.0", "__base__"), + ("lockfile__e08ddb66104268a4", "cachetools", "6.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "gitpython", "3.1.44", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pandas", "2.2.3", "__base__"), + ("lockfile__e08ddb66104268a4", "pillow", "11.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyarrow", "21.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pydeck", "0.9.1", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "tenacity", "8.5.0", "__base__"), + ("lockfile__e08ddb66104268a4", "toml", "0.10.2", "__base__"), + ("lockfile__e08ddb66104268a4", "tornado", "6.5.4", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ("lockfile__e08ddb66104268a4", "watchdog", "4.0.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "structlog", "25.1.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "svg_path", "7.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "sympy", "1.13.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "mpmath", "1.3.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "synchronicity", "0.10.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "sigtools", "4.0.1", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "tabulate", "0.9.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "tblib", "3.1.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "temporalio", "1.9.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ("lockfile__e08ddb66104268a4", "types_protobuf", "5.29.1.20241207", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "tenacity", "8.5.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "tensorboard", "2.20.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "grpcio", "1.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "markdown", "3.7", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pillow", "11.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ("lockfile__e08ddb66104268a4", "setuptools", "75.8.0", "__base__"), + ("lockfile__e08ddb66104268a4", "tensorboard_data_server", "0.7.2", "__base__"), + ("lockfile__e08ddb66104268a4", "werkzeug", "3.0.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "tensorboard_data_server", "0.7.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "tensorflow", "2.20.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "astunparse", "1.6.3", "__base__"), + ("lockfile__e08ddb66104268a4", "flatbuffers", "24.12.23", "__base__"), + ("lockfile__e08ddb66104268a4", "gast", "0.6.0", "__base__"), + ("lockfile__e08ddb66104268a4", "google_pasta", "0.2.0", "__base__"), + ("lockfile__e08ddb66104268a4", "grpcio", "1.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "h5py", "3.12.1", "__base__"), + ("lockfile__e08ddb66104268a4", "keras", "3.12.0", "__base__"), + ("lockfile__e08ddb66104268a4", "libclang", "18.1.1", "__base__"), + ("lockfile__e08ddb66104268a4", "ml_dtypes", "0.5.1", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "opt_einsum", "3.4.0", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "setuptools", "75.8.0", "__base__"), + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ("lockfile__e08ddb66104268a4", "tensorboard", "2.20.0", "__base__"), + ("lockfile__e08ddb66104268a4", "termcolor", "2.4.0", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ("lockfile__e08ddb66104268a4", "wrapt", "1.17.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "tensorflow_datasets", "4.9.7", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "array_record", "0.6.0", "__base__"), + ("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "dm_tree", "0.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "edc"), + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "enp"), + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "epath"), + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "epy"), + ("lockfile__e08ddb66104268a4", "etils", "1.11.0", "etree"), + ("lockfile__e08ddb66104268a4", "immutabledict", "4.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "promise", "2.3", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ("lockfile__e08ddb66104268a4", "psutil", "7.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyarrow", "21.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "simple_parsing", "0.1.7", "__base__"), + ("lockfile__e08ddb66104268a4", "tensorflow_metadata", "1.17.2", "__base__"), + ("lockfile__e08ddb66104268a4", "termcolor", "2.4.0", "__base__"), + ("lockfile__e08ddb66104268a4", "toml", "0.10.2", "__base__"), + ("lockfile__e08ddb66104268a4", "tqdm", "4.67.1", "__base__"), + ("lockfile__e08ddb66104268a4", "wrapt", "1.17.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "tensorflow_io", "0.37.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "tensorflow_io_gcs_filesystem", "0.37.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "tensorflow_io_gcs_filesystem", "0.37.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "tensorflow_metadata", "1.17.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "googleapis_common_protos", "1.71.0", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "tensorstore", "0.1.71", "__base__"): [ + ("lockfile__e08ddb66104268a4", "ml_dtypes", "0.5.1", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "termcolor", "2.4.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "terminado", "0.18.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "ptyprocess", "0.7.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pywinpty", "3.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "tornado", "6.5.4", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "testing_common_database", "2.0.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "testing_postgresql", "1.3.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pg8000", "1.31.2", "__base__"), + ("lockfile__e08ddb66104268a4", "testing_common_database", "2.0.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "textual", "1.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "markdown_it_py", "3.0.0", "linkify"), + ("lockfile__e08ddb66104268a4", "markdown_it_py", "3.0.0", "plugins"), + ("lockfile__e08ddb66104268a4", "platformdirs", "4.3.6", "__base__"), + ("lockfile__e08ddb66104268a4", "rich", "13.9.4", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "tf_keras", "2.20.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "tensorflow", "2.20.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "tfp_nightly", "0.26.0.dev20260104", "__base__"): [ + ("lockfile__e08ddb66104268a4", "absl_py", "2.3.1", "__base__"), + ("lockfile__e08ddb66104268a4", "cloudpickle", "3.1.1", "__base__"), + ("lockfile__e08ddb66104268a4", "decorator", "4.4.2", "__base__"), + ("lockfile__e08ddb66104268a4", "dm_tree", "0.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "gast", "0.6.0", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "threadpoolctl", "3.6.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "tifffile", "2025.1.10", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "tinycss2", "1.4.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "webencodings", "0.5.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "tokenizers", "0.21.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "huggingface_hub", "0.34.4", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "toml", "0.10.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "tomli", "2.3.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "tomlkit", "0.13.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "toolz", "1.0.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "tornado", "6.5.4", "__base__"): [], + ("lockfile__e08ddb66104268a4", "tqdm", "4.67.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "colorama", "0.4.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "traittypes", "0.2.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "traitlets", "5.14.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "transformers", "4.55.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "filelock", "3.16.1", "__base__"), + ("lockfile__e08ddb66104268a4", "huggingface_hub", "0.34.4", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "regex", "2024.11.6", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "safetensors", "0.5.2", "__base__"), + ("lockfile__e08ddb66104268a4", "tokenizers", "0.21.4", "__base__"), + ("lockfile__e08ddb66104268a4", "tqdm", "4.67.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "transforms3d", "0.4.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "transitions", "0.9.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "treescope", "0.1.8", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "trimesh", "4.9.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "trimesh", "4.9.0", "easy"): [ + ("lockfile__e08ddb66104268a4", "trimesh", "4.9.0", "__base__"), + ("lockfile__e08ddb66104268a4", "charset_normalizer", "3.4.1", "__base__"), + ("lockfile__e08ddb66104268a4", "colorlog", "6.10.1", "__base__"), + ("lockfile__e08ddb66104268a4", "embreex", "2.17.7.post7", "__base__"), + ("lockfile__e08ddb66104268a4", "httpx", "0.28.1", "__base__"), + ("lockfile__e08ddb66104268a4", "jsonschema", "4.23.0", "__base__"), + ("lockfile__e08ddb66104268a4", "lxml", "5.3.0", "__base__"), + ("lockfile__e08ddb66104268a4", "manifold3d", "3.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "mapbox_earcut", "1.0.3", "__base__"), + ("lockfile__e08ddb66104268a4", "networkx", "3.4.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pillow", "11.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "pycollada", "0.9.2", "__base__"), + ("lockfile__e08ddb66104268a4", "rtree", "1.4.1", "__base__"), + ("lockfile__e08ddb66104268a4", "scipy", "1.16.3", "__base__"), + ("lockfile__e08ddb66104268a4", "shapely", "2.0.7", "__base__"), + ("lockfile__e08ddb66104268a4", "svg_path", "7.0", "__base__"), + ("lockfile__e08ddb66104268a4", "vhacdx", "0.0.9", "__base__"), + ("lockfile__e08ddb66104268a4", "xxhash", "3.6.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "triton", "3.3.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "setuptools", "75.8.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "trueskill", "0.4.5", "__base__"): [ + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "truss", "0.9.113", "__base__"): [ + ("lockfile__e08ddb66104268a4", "aiofiles", "24.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "blake3", "1.0.5", "__base__"), + ("lockfile__e08ddb66104268a4", "boto3", "1.36.1", "__base__"), + ("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "google_cloud_storage", "3.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "httpx", "0.28.1", "__base__"), + ("lockfile__e08ddb66104268a4", "httpx_ws", "0.7.2", "__base__"), + ("lockfile__e08ddb66104268a4", "huggingface_hub", "0.34.4", "__base__"), + ("lockfile__e08ddb66104268a4", "inquirerpy", "0.3.4", "__base__"), + ("lockfile__e08ddb66104268a4", "jinja2", "3.1.6", "__base__"), + ("lockfile__e08ddb66104268a4", "libcst", "1.8.2", "__base__"), + ("lockfile__e08ddb66104268a4", "loguru", "0.7.3", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "pathspec", "0.12.1", "__base__"), + ("lockfile__e08ddb66104268a4", "psutil", "7.0.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pydantic", "2.10.5", "__base__"), + ("lockfile__e08ddb66104268a4", "python_json_logger", "3.2.1", "__base__"), + ("lockfile__e08ddb66104268a4", "python_on_whales", "0.78.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "rich", "13.9.4", "__base__"), + ("lockfile__e08ddb66104268a4", "rich_click", "1.8.9", "__base__"), + ("lockfile__e08ddb66104268a4", "ruff", "0.7.1", "__base__"), + ("lockfile__e08ddb66104268a4", "tenacity", "8.5.0", "__base__"), + ("lockfile__e08ddb66104268a4", "tomlkit", "0.13.3", "__base__"), + ("lockfile__e08ddb66104268a4", "watchfiles", "0.19.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "tuna", "0.5.11", "__base__"): [], + ("lockfile__e08ddb66104268a4", "typeguard", "2.13.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "typer", "0.16.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "rich", "13.9.4", "__base__"), + ("lockfile__e08ddb66104268a4", "shellingham", "1.5.4", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "types_awscrt", "0.23.10", "__base__"): [], + ("lockfile__e08ddb66104268a4", "types_boto3", "1.37.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "botocore_stubs", "1.37.1", "__base__"), + ("lockfile__e08ddb66104268a4", "types_s3transfer", "0.11.3", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "types_cachetools", "6.2.0.20251022", "__base__"): [], + ("lockfile__e08ddb66104268a4", "types_certifi", "2021.10.8.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "types_dateparser", "1.2.0.20240420", "__base__"): [], + ("lockfile__e08ddb66104268a4", "types_docker", "7.1.0.20241229", "__base__"): [ + ("lockfile__e08ddb66104268a4", "types_requests", "2.32.0.20241016", "__base__"), + ("lockfile__e08ddb66104268a4", "urllib3", "2.3.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "types_paramiko", "3.5.0.20240928", "__base__"): [ + ("lockfile__e08ddb66104268a4", "cryptography", "44.0.3", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "types_protobuf", "5.29.1.20241207", "__base__"): [], + ("lockfile__e08ddb66104268a4", "types_psutil", "6.1.0.20241221", "__base__"): [], + ("lockfile__e08ddb66104268a4", "types_python_dateutil", "2.9.0.20241206", "__base__"): [], + ("lockfile__e08ddb66104268a4", "types_pyyaml", "6.0.12.20241230", "__base__"): [], + ("lockfile__e08ddb66104268a4", "types_requests", "2.32.0.20241016", "__base__"): [ + ("lockfile__e08ddb66104268a4", "urllib3", "2.3.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "types_s3transfer", "0.11.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "types_toml", "0.10.8.20240310", "__base__"): [], + ("lockfile__e08ddb66104268a4", "types_tqdm", "4.67.0.20241221", "__base__"): [ + ("lockfile__e08ddb66104268a4", "types_requests", "2.32.0.20241016", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "tyro", "0.8.5", "__base__"): [ + ("lockfile__e08ddb66104268a4", "colorama", "0.4.6", "__base__"), + ("lockfile__e08ddb66104268a4", "docstring_parser", "0.16", "__base__"), + ("lockfile__e08ddb66104268a4", "rich", "13.9.4", "__base__"), + ("lockfile__e08ddb66104268a4", "shtab", "1.7.1", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "tzdata", "2024.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "tzlocal", "5.2", "__base__"): [ + ("lockfile__e08ddb66104268a4", "tzdata", "2024.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "u_msgpack_python", "2.8.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "uc_micro_py", "1.0.3", "__base__"): [], + ("lockfile__e08ddb66104268a4", "uniplot", "0.21.4", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "readchar", "4.2.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "ur_rtde", "1.6.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "uri_template", "1.3.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "uritemplate", "4.1.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "urllib3", "2.3.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "uvicorn", "0.34.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "h11", "0.14.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "uvloop", "0.21.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "vhacdx", "0.0.9", "__base__"): [ + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "virtualenv", "20.29.1", "__base__"): [ + ("lockfile__e08ddb66104268a4", "distlib", "0.3.9", "__base__"), + ("lockfile__e08ddb66104268a4", "filelock", "3.16.1", "__base__"), + ("lockfile__e08ddb66104268a4", "platformdirs", "4.3.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "vit_jax", "0.0.8", "__base__"): [], + ("lockfile__e08ddb66104268a4", "wadler_lindig", "0.1.6", "__base__"): [], + ("lockfile__e08ddb66104268a4", "wandb", "0.24.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__"), + ("lockfile__e08ddb66104268a4", "gitpython", "3.1.44", "__base__"), + ("lockfile__e08ddb66104268a4", "packaging", "24.2", "__base__"), + ("lockfile__e08ddb66104268a4", "platformdirs", "4.3.6", "__base__"), + ("lockfile__e08ddb66104268a4", "protobuf", "6.33.0", "__base__"), + ("lockfile__e08ddb66104268a4", "pydantic", "2.10.5", "__base__"), + ("lockfile__e08ddb66104268a4", "pyyaml", "6.0.2", "__base__"), + ("lockfile__e08ddb66104268a4", "requests", "2.32.5", "__base__"), + ("lockfile__e08ddb66104268a4", "sentry_sdk", "2.20.0", "__base__"), + ("lockfile__e08ddb66104268a4", "typing_extensions", "4.12.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "watchdog", "4.0.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "watchfiles", "0.19.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "anyio", "4.8.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "wcwidth", "0.2.13", "__base__"): [], + ("lockfile__e08ddb66104268a4", "webcolors", "24.11.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "webencodings", "0.5.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "websocket_client", "1.8.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "websockets", "14.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "werkzeug", "3.0.6", "__base__"): [ + ("lockfile__e08ddb66104268a4", "markupsafe", "3.0.2", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "wheel", "0.45.1", "__base__"): [], + ("lockfile__e08ddb66104268a4", "widgetsnbextension", "4.0.13", "__base__"): [], + ("lockfile__e08ddb66104268a4", "win32_setctime", "1.2.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "wrapt", "1.17.2", "__base__"): [], + ("lockfile__e08ddb66104268a4", "wsproto", "1.2.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "h11", "0.14.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "xxhash", "3.6.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "yarl", "1.18.3", "__base__"): [ + ("lockfile__e08ddb66104268a4", "idna", "3.10", "__base__"), + ("lockfile__e08ddb66104268a4", "multidict", "6.1.0", "__base__"), + ("lockfile__e08ddb66104268a4", "propcache", "0.2.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "yourdfpy", "0.0.58", "__base__"): [ + ("lockfile__e08ddb66104268a4", "lxml", "5.3.0", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ("lockfile__e08ddb66104268a4", "six", "1.16.0", "__base__"), + ("lockfile__e08ddb66104268a4", "trimesh", "4.9.0", "easy"), + ], + ("lockfile__e08ddb66104268a4", "zarr", "2.18.7", "__base__"): [ + ("lockfile__e08ddb66104268a4", "asciitree", "0.3.3", "__base__"), + ("lockfile__e08ddb66104268a4", "fasteners", "0.19", "__base__"), + ("lockfile__e08ddb66104268a4", "numcodecs", "0.15.0", "__base__"), + ("lockfile__e08ddb66104268a4", "numpy", "2.2.6", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "zipp", "3.21.0", "__base__"): [], + ("lockfile__e08ddb66104268a4", "zmq", "0.0.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "pyzmq", "26.2.0", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "zstandard", "0.23.0", "__base__"): [ + ("lockfile__e08ddb66104268a4", "cffi", "1.17.1", "__base__"), + ], + ("lockfile__e08ddb66104268a4", "zstd", "1.5.7.2", "__base__"): [], + } + + graph5_components = sccs(graph5) + asserts.true(env, [("lockfile__e08ddb66104268a4", "colorama", "0.4.6", "__base__")] in graph5_components) + asserts.true(env, [("lockfile__e08ddb66104268a4", "click", "8.1.8", "__base__")] in graph5_components) + + return unittest.end(env) + +lockfile_test = unittest.make( + _sccs_lockfile_test_impl, +) + +def sccs_test_suite(): + unittest.suite( + "sccs_tests", + sccs_test, + ) + + unittest.suite( + "lockfile_test", + lockfile_test, + ) diff --git a/uv/private/hub/repository.bzl b/uv/private/hub/repository.bzl deleted file mode 100644 index b48ac3c9..00000000 --- a/uv/private/hub/repository.bzl +++ /dev/null @@ -1,257 +0,0 @@ -""" - -""" - -def _hub_impl(repository_ctx): - # We get packages as {package: venvs} - # Need to invert that - venv_packages = {} - for package, venvs in repository_ctx.attr.packages.items(): - for venv in venvs: - venv_packages.setdefault(venv, []) - venv_packages[venv].append("//{0}:{0}".format(package)) - - # Build up a single target which depends on _all_ the packages in a given - # venv configuration. - # - # TODO: Some packages in a venv configuration may be incompatible; figure - # out how to make this take "soft" rather than "hard" dependencies. - repository_ctx.file("BUILD.bazel", """\ -load("@aspect_rules_py//py:defs.bzl", "py_library") -load("@aspect_rules_py//uv/private:defs.bzl", "py_whl_library") - -py_library( - name = "all_requirements", - deps = select({lib_arms}), - visibility = ["//visibility:private"], -) -py_whl_library( - name = "all_whl_requirements", - deps = [":all_requirements"], - visibility = ["//visibility:public"], -) -""".format(lib_arms = { - "//venv:{}".format(venv): pkgs - for venv, pkgs in venv_packages.items() - })) - - ################################################################################ - content = [ - "load(\"@bazel_skylib//lib:selects.bzl\", \"selects\")", - ] - - for name, conditions in repository_ctx.attr.configurations.items(): - content.append( - """\ -selects.config_setting_group( - name = "{}", - match_all = {}, -) -""".format(name, repr(conditions)), - ) - - repository_ctx.file("configuration/BUILD.bazel", content = "\n".join(content)) - - ################################################################################ - content = [ - """\ -# FIXME - -alias( - name = "venv", - actual = "@aspect_rules_py//uv/private/constraints/venv:venv" -) -""", - ] - - # Lay down the venv config settings - for name in repository_ctx.attr.venvs: - content.append( - """ -config_setting( - name = "{0}", - flag_values = {{ - "@aspect_rules_py//uv/private/constraints/venv:venv": "{0}", - }}, - visibility = ["//visibility:public"], # So that compatible_with is usable from other repos -) -""".format(name), - ) - repository_ctx.file("venv/BUILD.bazel", content = "\n".join(content)) - - ################################################################################ - # Lay down some new-style stuff - content = [ - "# FIXME ", - ] - - content.append( - """ -VIRTUALENVS = {venvs} - -PACKAGES = {venv_packages} - -_repo = {repo_name} - -def compatible_with(venvs, extra_constraints = []): - for v in venvs: - if v not in VIRTUALENVS: - fail("Errant virtualenv reference %r" % v) - - return {{ - Label("//venv:" + it): extra_constraints - for it in venvs - }} | {{ - "//conditions:default": ["@platforms//:incompatible"], - }} - -def incompatible_with(venvs, extra_constraints = []): - for v in venvs: - if v not in VIRTUALENVS: - fail("Errant virtualenv reference %r" % v) - - return {{ - Label("//venv:" + it): ["@platforms//:incompatible"] - for it in venvs - }} | {{ - "//conditions:default": extra_constraints, - }} -""".format( - venvs = repr(repository_ctx.attr.venvs), - venv_packages = repr(venv_packages), - repo_name = repr(repository_ctx.name), - ), - ) - - repository_ctx.file("defs.bzl", content = "\n".join(content)) - - ################################################################################ - # Lay down a requirements.bzl for compatibility with rules_python - content = [] - content.append(""" -load("@rules_python//python:pip.bzl", "pip_utils") - -# We arne't compatible with this because it isn't constant over venvs. -# all_requirements = [] - -# We aren't compatible with this because it isn't constant over venvs. -# all_whl_requirements_by_package = {{}} - -# We aren't compatible with this because it isn't constant over venvs. -# all_whl_requirements = all_whl_requirements_by_package.values() - -# We aren't compatible with this because we don't offer separate data targets -# all_data_requirements = [] - -def requirement(name): - return "@@{repo_name}//{{0}}:{{0}}".format(pip_utils.normalize_name(name)) -""".format( - repo_name = repository_ctx.name, - )) - repository_ctx.file("requirements.bzl", content = "\n".join(content)) - - ################################################################################ - # Lay down the hub aliases - - entrypoints = json.decode(repository_ctx.attr.entrypoints) - - # FIXME: since we're creating a package per target, we may have to implement - # name mangling to ensure that the pip packages become valid Bazel packages. - for name, spec in repository_ctx.attr.packages.items(): - content = [ - """ -load("//:defs.bzl", "compatible_with") -""", - ] - - select_spec = { - "//venv:{}".format(it): "@venv__{0}__{1}//{2}:{2}".format(repository_ctx.attr.hub_name, it, name) - for it in spec - } - error = "Available only in venvs " + ", ".join([it.split(":")[1][1:] for it in select_spec.keys()]) - - # TODO: Find a way to add a dist-info target here - # TODO: Find a way to add entrypoint targets here? - # TODO: Add a way to take a "soft" dependency here? - content.append( - """ -# This target is for a "hard" dependency. -# Dependencies on this target will cause build failures if it's unavailable. -alias( - name = "lib", - actual = "{name}", - visibility = ["//visibility:public"], -) -alias( - name = "{name}", - actual = select( - {lib_select}, - no_match_error = "{error}", - ), - target_compatible_with = select(compatible_with({compat})), - visibility = ["//visibility:public"], -) -alias( - name = "whl", - actual = select( - {whl_select}, - no_match_error = "{error}", - ), - target_compatible_with = select(compatible_with({compat})), - visibility = ["//visibility:public"], -) -""".format( - name = name, - lib_select = repr(select_spec), - whl_select = repr({k: v.split(":")[0] + ":whl" for k, v in select_spec.items()}), - compat = repr(spec), - error = error, - ), - ) - - repository_ctx.file(name + "/BUILD.bazel", content = "\n".join(content)) - - content = [ - """load("//:defs.bzl", "compatible_with")""", - ] - for entrypoint_name, _entrypoint_coordinate in entrypoints.get(name, {}).items(): - select_spec = { - "//venv:{}".format(it): "@venv__{0}__{1}//{2}/entrypoints:{3}".format(repository_ctx.attr.hub_name, it, name, entrypoint_name) - for it in spec - } - - content.append( - """ -alias( - name = "{name}", - actual = select( - {select}, - no_match_error = "{error}", - ), - target_compatible_with = select(compatible_with({compat})), - visibility = ["//visibility:public"], -) -""".format( - name = entrypoint_name, - select = repr(select_spec), - compat = repr(spec), - error = error, - ), - ) - - repository_ctx.file(name + "/entrypoints/BUILD.bazel", content = "\n".join(content)) - -hub_repo = repository_rule( - implementation = _hub_impl, - attrs = { - "hub_name": attr.string(), - "venvs": attr.string_list(), - "packages": attr.string_list_dict(), - "configurations": attr.string_list_dict(), - "entrypoints": attr.string( - doc = """ - JSON encoded map of pkg -> entrypoint -> coordinate - """, - ), - }, -) diff --git a/uv/private/pprint/BUILD.bazel b/uv/private/pprint/BUILD.bazel new file mode 100644 index 00000000..41026fbc --- /dev/null +++ b/uv/private/pprint/BUILD.bazel @@ -0,0 +1,5 @@ +load(":test.bzl", "pprint_test_suite") + +exports_files(["defs.bzl"]) + +pprint_test_suite() diff --git a/uv/private/pprint/defs.bzl b/uv/private/pprint/defs.bzl new file mode 100644 index 00000000..fb1a1c91 --- /dev/null +++ b/uv/private/pprint/defs.bzl @@ -0,0 +1,80 @@ +def pprint(val, indent = " "): + # Each entry: [object, indent_level, state, optional_data] + # States: + # 0: Dispatch (determine if leaf or container) + # 1: Container Closer (print ] or } or )) + # 2: List Item (indent_count + process value + comma) + # 3: Dict Item (indent_count + key + process value + comma) + # 4: Struct Item (indent_count + key + = + process value + comma) + # 5: Post-Value (just prints the comma and newline) + + worklist = [[val, 0, 0]] + output = [] + + # Use a large range to simulate a while loop + for _ in range(100000): + if not worklist: + break + + curr = worklist.pop() + obj, indent_count, state = curr[0], curr[1], curr[2] + + if state == 0: + t = type(obj) + if t == "list": + if not obj: + output.append("[]") + else: + output.append("[\n") + worklist.append([obj, indent_count, 1]) # Add closer + for i in range(len(obj) - 1, -1, -1): + worklist.append([obj[i], indent_count + 1, 2]) + elif t == "dict": + if not obj: + output.append("{}") + else: + output.append("{\n") + worklist.append([obj, indent_count, 1]) # Add closer + keys = obj.keys() + for i in range(len(keys) - 1, -1, -1): + worklist.append([obj[keys[i]], indent_count + 1, 3, keys[i]]) + elif t == "struct": + output.append("struct(\n") + worklist.append([obj, indent_count, 1]) # Add closer + keys = dir(obj) + for i in range(len(keys) - 1, -1, -1): + k = keys[i] + worklist.append([getattr(obj, k), indent_count + 1, 4, k]) + else: + output.append(repr(obj)) + + elif state == 1: # Closer + t = type(obj) + char = "]" if t == "list" else "}" if t == "dict" else ")" + output.append(indent * indent_count + char) + + elif state == 2: # List Item + output.append(indent * indent_count) + + # Add the comma to happen AFTER the value is processed + worklist.append([None, 0, 5]) + + # Process the value + worklist.append([obj, indent_count, 0]) + + elif state == 3: # Dict Item + key = curr[3] + output.append(indent * indent_count + repr(key) + ": ") + worklist.append([None, 0, 5]) + worklist.append([obj, indent_count, 0]) + + elif state == 4: # Struct Item + key = curr[3] + output.append(indent * indent_count + key + " = ") + worklist.append([None, 0, 5]) + worklist.append([obj, indent_count, 0]) + + elif state == 5: # Comma + Newline + output.append(",\n") + + return "".join(output) diff --git a/uv/private/pprint/test.bzl b/uv/private/pprint/test.bzl new file mode 100644 index 00000000..8bb5d7c8 --- /dev/null +++ b/uv/private/pprint/test.bzl @@ -0,0 +1,67 @@ +load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") +load(":defs.bzl", "pprint") + +def _test_pprint_dict(ctx): + env = unittest.begin(ctx) + test_dict = {"a": 1, "b": 2} + expected = """{ + "a": 1, + "b": 2, +}""" + asserts.equals(env, expected, pprint(test_dict)) + return unittest.end(env) + +pprint_dict_test = unittest.make(_test_pprint_dict) + +def _test_pprint_list(ctx): + env = unittest.begin(ctx) + test_list = [1, "foo", True] + expected = """[ + 1, + "foo", + True, +]""" + asserts.equals(env, expected, pprint(test_list)) + return unittest.end(env) + +pprint_list_test = unittest.make(_test_pprint_list) + +def _test_pprint_struct(ctx): + env = unittest.begin(ctx) + test_struct = struct(a = 1, b = "foo") + expected = """struct( + a = 1, + b = "foo", +)""" + asserts.equals(env, expected, pprint(test_struct)) + return unittest.end(env) + +pprint_struct_test = unittest.make(_test_pprint_struct) + +def _test_pprint_nested(ctx): + env = unittest.begin(ctx) + test_nested = {"a": [1, 2], "b": struct(c = {"d": 3})} + expected = """{ + "a": [ + 1, + 2, + ], + "b": struct( + c = { + "d": 3, + }, + ), +}""" + asserts.equals(env, expected, pprint(test_nested)) + return unittest.end(env) + +pprint_nested_test = unittest.make(_test_pprint_nested) + +def pprint_test_suite(): + unittest.suite( + "pprint_tests", + pprint_dict_test, + pprint_list_test, + pprint_struct_test, + pprint_nested_test, + ) diff --git a/uv/private/py_entrypoint_binary/BUILD.bazel b/uv/private/py_entrypoint_binary/BUILD.bazel index 0f43e7b0..e7d7a698 100644 --- a/uv/private/py_entrypoint_binary/BUILD.bazel +++ b/uv/private/py_entrypoint_binary/BUILD.bazel @@ -1 +1,4 @@ -exports_files(["entrypoint.tmpl"]) +exports_files([ + "entrypoint.tmpl", + "search.py", +]) diff --git a/uv/private/py_entrypoint_binary/defs.bzl b/uv/private/py_entrypoint_binary/defs.bzl index 0d37138a..fc24471f 100644 --- a/uv/private/py_entrypoint_binary/defs.bzl +++ b/uv/private/py_entrypoint_binary/defs.bzl @@ -3,13 +3,17 @@ load("//py/unstable:defs.bzl", "py_venv_binary") def py_entrypoint_binary( name, - coordinate, - deps, + entrypoint, + pkg, visibility = ["//visibility:public"]): main = "_{}_entrypoint".format(name) + tmpl = Label("@aspect_rules_py//uv/private/py_entrypoint_binary:entrypoint.tmpl") + + if ":" not in entrypoint: + fail("Invalid entrypoint coordinate") # = [:[.[.]*]] - package, symbol = coordinate.split(":") + package, symbol = entrypoint.split(":") if "." in symbol: fn, tail = symbol.split(".", 1) @@ -21,12 +25,12 @@ def py_entrypoint_binary( expand_template( name = main, - template = Label("@aspect_rules_py//uv/private/py_entrypoint_binary:entrypoint.tmpl"), + template = tmpl, out = main + ".py", substitutions = { - "{{package}}": package, - "{{fn}}": fn, - "{{alias}}": alias, + "{package}": package, + "{fn}": fn, + "{alias}": alias, }, ) @@ -34,6 +38,47 @@ def py_entrypoint_binary( name = name, main = main + ".py", srcs = [main], - deps = deps, + deps = [pkg], + visibility = visibility, + ) + +def py_console_script_binary( + name, + script, + pkg, + visibility = ["//visibility:public"]): + main = "_{}_entrypoint".format(name) + tmpl = Label("@aspect_rules_py//uv/private/py_entrypoint_binary:entrypoint.tmpl") + + search_tool = "_{}_search_binary".format(name) + search_py = Label("@aspect_rules_py//uv/private/py_entrypoint_binary:search.py") + search = "_{}_search".format(name) + + py_venv_binary( + name = search_tool, + deps = [pkg], + main = search_py, + srcs = [search_py], + ) + + native.genrule( + name = search, + tools = [ + search_tool, + ], + outs = [ + main + ".py", + ], + srcs = [ + tmpl, + ], + cmd = "$(location {}) --template=\"$(location {})\" --script=\"{}\" >\"$@\"".format(search_tool, tmpl, script), + ) + + py_venv_binary( + name = name, + main = search, + srcs = [search], + deps = [pkg], visibility = visibility, ) diff --git a/uv/private/py_entrypoint_binary/entrypoint.tmpl b/uv/private/py_entrypoint_binary/entrypoint.tmpl index e7c051a1..81fd8307 100644 --- a/uv/private/py_entrypoint_binary/entrypoint.tmpl +++ b/uv/private/py_entrypoint_binary/entrypoint.tmpl @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -from {{package}} import {{fn}} -{{alias}} +from {package} import {fn} +{alias} if __name__ == '__main__': - {{fn}}() + {fn}() diff --git a/uv/private/py_entrypoint_binary/search.py b/uv/private/py_entrypoint_binary/search.py new file mode 100644 index 00000000..31432ccb --- /dev/null +++ b/uv/private/py_entrypoint_binary/search.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 + +""" +Search installed packages for entrypoints and expand the entrypoint template. +""" + +import argparse +import configparser +from pathlib import Path +import sys + + +class CaseSensitiveConfigParser(configparser.ConfigParser): + optionxform = staticmethod(str) + +# Quick and dirty re-implementaiton of the setuptools search. + +PARSER = argparse.ArgumentParser() +PARSER.add_argument("--template") +PARSER.add_argument("--script") +opts, args = PARSER.parse_known_args() + +print(repr(opts), file=sys.stderr) + +entrypoint = None +for e in sys.path: + if entrypoint: + break + + print("{}:".format(e), file=sys.stderr) + for entrypoints in Path(e).glob("*.dist-info/entry_points.txt"): + cp = CaseSensitiveConfigParser(delimiters=('=',)) + cp.read([entrypoints]) + + if "console_scripts" in cp: + for e in cp["console_scripts"]: + print(entrypoints, e, cp["console_scripts"][e], file=sys.stderr) + if e == opts.script: + entrypoint = cp["console_scripts"][e] + break + +if not entrypoint: + print("Failed to identify the requested entrpoint script!", file=sys.stderr) + exit(1) + +# = [:[.[.]*]] +package, symbol = entrypoint.split(":") + +if "." in symbol: + fn, tail = symbol.split(".", 1) + alias = "{fn} = {fn}.{tail}\n".format(fn = fn, tail = tail) +else: + fn = symbol + tail = "" + alias = "" + +with open(opts.template, "r") as fp: + template = fp.read() + + +print(template.format( + package = package, + fn = fn, + alias = alias, +)) diff --git a/uv/private/sccs.bzl b/uv/private/sccs.bzl deleted file mode 100644 index 1c19b795..00000000 --- a/uv/private/sccs.bzl +++ /dev/null @@ -1,86 +0,0 @@ -""" -Strongly connected components helpers. -""" - -def sccs(graph): - """Identify strongly connected components. - - Uses Kosaraju's algorithm as the strategy. - - Args: - graph (dict): A mapping of nodes to their adjacencies. - - Returns: - A list of lists, where each inner list represents an SCC. - The components of each SCC are in lexically sorted order. - """ - nodes = list(graph.keys()) - visited = {node: False for node in nodes} - order = [] - - # An upper bound for the number of steps we'll need on each pass. The - # algorithm is actually linear time and the precise bound would be nodes + - # edges, but this is simple and safe. - # - # Starlark doesn't have `**`. Oh well. - bound = len(nodes) * len(nodes) - - # First DFS traversal to determine finishing times (post-order traversal) - # The outer loop ensures we start a traversal for all unvisited nodes. - for start_node in nodes: - if not visited[start_node]: - stack = [start_node] - temp_order = [] - - for _ in range(bound): - if not stack: - break - - current_node = stack.pop() - temp_order.append(current_node) - visited[current_node] = True - - neighbors = graph.get(current_node, []) - for neighbor in neighbors: - if not visited[neighbor]: - stack.append(neighbor) - - order = order + reversed(temp_order) - - # Create the transpose graph (all edges reversed) - transpose_graph = {node: [] for node in nodes} - for node in nodes: - for neighbor in graph.get(node, []): - transpose_graph[neighbor].append(node) - - # Reset visited flags for the second traversal - visited = {node: False for node in nodes} - sccs = [] - - # Second DFS traversal on the transpose graph - # We process nodes in the reverse of their finishing time order. - # Each traversal finds a new SCC. - for start_node in reversed(order): - if not visited[start_node]: - current_scc = [] - stack = [start_node] - visited[start_node] = True - - for _ in range(bound): - if not stack: - break - - current_node = stack.pop() - current_scc.append(current_node) - - for neighbor in transpose_graph.get(current_node, []): - if not visited[neighbor]: - visited[neighbor] = True - stack.append(neighbor) - - sccs.append(current_scc) - - return [ - sorted(scc) - for scc in sccs - ] diff --git a/uv/private/sdist_build/build_helper.py b/uv/private/sdist_build/build_helper.py index ef40cf51..a8eab5f9 100644 --- a/uv/private/sdist_build/build_helper.py +++ b/uv/private/sdist_build/build_helper.py @@ -9,7 +9,7 @@ from argparse import ArgumentParser import shutil import sys -from os import listdir, path +from os import listdir, mkdir, path from subprocess import CalledProcessError, check_call from tempfile import TemporaryDirectory @@ -17,38 +17,60 @@ PARSER.add_argument("srcarchive") PARSER.add_argument("outdir") PARSER.add_argument("--validate-anyarch", action="store_true") -PARSER.add_argument("--sandbox", action="store_true") opts, args = PARSER.parse_known_args() -with TemporaryDirectory() as t: - # Extract the source archive - shutil.unpack_archive(opts.srcarchive, t) +tmp_root = opts.outdir.lstrip("/") + ".tmp" +mkdir(tmp_root) - # Annoyingly, unpack_archive creates a subdir in the target. Update t - # accordingly. Not worth the eng effort to prevent creating this dir. - t = path.join(t, listdir(t)[0]) +t = path.join(tmp_root, "worktree") - # Get a path to the outdir which will be valid after we cd - outdir = path.abspath(opts.outdir) +shutil.unpack_archive(opts.srcarchive, t) - try: - check_call([ +# Annoyingly, unpack_archive creates a subdir in the target. Update t +# accordingly. Not worth the eng effort to prevent creating this dir. +t = path.join(t, listdir(t)[0]) + +# Get a path to the outdir which will be valid after we cd +outdir = path.abspath(opts.outdir) + +try: + if path.exists(path.join(t, "pyproject.toml")): + cmd = [ sys.executable, "-m", "build", "--wheel", "--no-isolation", "--outdir", outdir, - ], cwd=t) - except CalledProcessError: - print("Error: Build failed!\nSee {} for the sandbox".format(t), file=sys.stderr) - exit(1) + ] + elif path.exists(path.join(t, "setup.py")): + cmd = [ + sys.executable, + path.realpath(path.join(t, "setup.py")), + "bdist_wheel", + "--dist-dir", + outdir, + ] + else: + print("Error: Unable to detect build command! Neither pyproject nor setup.py found!", file=sys.stderr) + exit(1) + + check_call(cmd, + cwd=t, + env={ + "TMP": tmp_root, + "TEMP": tmp_root, + "TEMPDIR": tmp_root, + }) +except CalledProcessError: + print("Error: Build failed!\nSee {} for the sandbox".format(t), file=sys.stderr) + exit(1) - inventory = listdir(outdir) +inventory = listdir(outdir) - if len(inventory) > 1: - print("Error: Built more than one wheel!\nSee {} for the sandbox".format(t), file=sys.stderr) - exit(1) +if len(inventory) > 1: + print("Error: Built more than one wheel!\nSee {} for the sandbox".format(t), file=sys.stderr) + exit(1) - if opts.validate_anyarch and not inventory[0].endswith("-none-any.whl"): - print("Error: Target was anyarch but built a none-any wheel!\nSee {} for the sandbox".format(t), file=sys.stderr) - exit(1) +if opts.validate_anyarch and not inventory[0].endswith("-none-any.whl"): + print("Error: Target was anyarch but built a none-any wheel!\nSee {} for the sandbox".format(t), file=sys.stderr) + exit(1) diff --git a/uv/private/sdist_build/repository.bzl b/uv/private/sdist_build/repository.bzl index ea5dba63..cb0fce72 100644 --- a/uv/private/sdist_build/repository.bzl +++ b/uv/private/sdist_build/repository.bzl @@ -6,7 +6,45 @@ Consues a given src (.tar.gz or other artifact) and deps. Produces a sibling `rule.bzl` file for the implementation of `sdist_build`. """ +# TODO: Use tar.bzl to inspect sdist contents. We can probably do a good enough +# job of detecting whether a given sdist contains C-extensions by looking at the +# inventory of the sdist using an archive extractor during this repo rule and +# applying some heuristics; +# +# - Does it contain .h .hpp .hxx .c .cxx .cpp files +# - Does it contain .pyx files +# - Does it contain .for .f90 .f95 files (fortran) +# - Does it contain .rs files +# +# Fully generally we need something like prebuilt Gazelle which we can run here +# at repo phase to try and generate a real buildfile for all the many and varied +# things which a wheel COULD need to do at install time. +# +# For now we're cheating in that there's only two build rules, and we're using +# user annotations flowed through from the user's MODULE.bazel configurations to +# provide this metadata. + def _sdist_build_impl(repository_ctx): + """Prepares a repository for building a wheel from a source distribution (sdist). + + This rule does not perform the build itself, but generates the `BUILD.bazel` + file that defines the necessary targets to do so. + + It creates: + 1. A `py_venv` target named `build_venv`, which contains the build-time + dependencies (e.g., `build`, `setuptools`, `wheel`) specified in the + `deps` attribute. + 2. A target (either `sdist_build` or `sdist_native_build` from `rule.bzl`) + named `whl`. When this target is built, it executes the wheel build process + for the given `src` sdist within the `build_venv`. + + The `is_native` attribute determines whether the build is for a pure-Python + wheel or one that may contain C-extensions, which controls which underlying + build rule is used. + + Args: + repository_ctx: The repository context. + """ repository_ctx.file("BUILD.bazel", content = """ load("@aspect_rules_py//uv/private/sdist_build:rule.bzl", "{rule}") load("@aspect_rules_py//py/unstable:defs.bzl", "py_venv") @@ -20,14 +58,15 @@ py_venv( name = "whl", src = "{src}", venv = ":build_venv", + version = "{version}", args = [], visibility = ["//visibility:public"], ) """.format( src = repository_ctx.attr.src, deps = repr([str(it) for it in repository_ctx.attr.deps]), - # FIXME: This should probably be inferred by looking at the inventory of the sdist rule = "sdist_native_build" if repository_ctx.attr.is_native else "sdist_build", + version = repository_ctx.attr.version, )) sdist_build = repository_rule( @@ -36,5 +75,6 @@ sdist_build = repository_rule( "src": attr.label(), "deps": attr.label_list(), "is_native": attr.bool(), + "version": attr.string(), }, ) diff --git a/uv/private/sdist_build/rule.bzl b/uv/private/sdist_build/rule.bzl index cdd214bf..16ae561b 100644 --- a/uv/private/sdist_build/rule.bzl +++ b/uv/private/sdist_build/rule.bzl @@ -50,6 +50,9 @@ def _sdist_build(ctx): outputs = [ wheel_dir, ], + env = { + "SETUPTOOLS_SCM_PRETEND_VERSION": ctx.attr.version, + }, exec_group = "target", ) @@ -72,6 +75,7 @@ specified Python dependencies under the configured Python toochain. attrs = { "src": attr.label(), "venv": attr.label(), + "version": attr.string(), "args": attr.string_list(default = ["--validate-anyarch"]), "_helper": attr.label(allow_single_file = True, default = Label(":build_helper.py")), }, @@ -101,6 +105,7 @@ constraints of the target platform. attrs = { "src": attr.label(), "venv": attr.label(), + "version": attr.string(), "args": attr.string_list(), "_helper": attr.label(allow_single_file = True, default = Label(":build_helper.py")), }, diff --git a/uv/private/uv/pyproject.toml b/uv/private/uv/pyproject.toml index abf7be27..7a9c5745 100644 --- a/uv/private/uv/pyproject.toml +++ b/uv/private/uv/pyproject.toml @@ -1,5 +1,5 @@ [project] name = "dummy" version = "0.0.0" -requires-python = ">= 3.9" +requires - python = ">= 3.9" dependencies = [] diff --git a/uv/private/uv/uv.lock.json b/uv/private/uv/uv.lock.json index 8f4b98b6..cdaf7f16 100644 --- a/uv/private/uv/uv.lock.json +++ b/uv/private/uv/uv.lock.json @@ -1,55 +1,55 @@ { - "$schema": "https://raw.githubusercontent.com/theoremlp/rules_multitool/main/lockfile.schema.json", - "uv": { - "binaries": [ - { - "kind": "archive", - "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-aarch64-unknown-linux-musl.tar.gz", - "file": "uv-aarch64-unknown-linux-musl/uv", - "sha256": "de85bafc3e238a4fce87eb6a4e584c9c04721475abb9e5f6fe186bdce650763f", - "os": "linux", - "cpu": "arm64" - }, - { - "kind": "archive", - "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-x86_64-unknown-linux-gnu.tar.gz", - "file": "uv-x86_64-unknown-linux-gnu/uv", - "sha256": "f976ebdc612e71209f46664ab6c0325fa0090059b4474e047edd39eb9395373b", - "os": "linux", - "cpu": "x86_64" - }, - { - "kind": "archive", - "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-aarch64-apple-darwin.tar.gz", - "file": "uv-aarch64-apple-darwin/uv", - "sha256": "a3f78d20465c6d18f7072f118ce1c61b164b98698fdc37357e72958c7d1b68fd", - "os": "macos", - "cpu": "arm64" - }, - { - "kind": "archive", - "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-x86_64-apple-darwin.tar.gz", - "file": "uv-x86_64-apple-darwin/uv", - "sha256": "467b462e854bc750fcad8e3ad35e2aca0d301c9287f2365afad8c17b7672b6a8", - "os": "macos", - "cpu": "x86_64" - }, - { - "kind": "archive", - "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-aarch64-pc-windows-msvc.zip", - "file": "uv.exe", - "sha256": "eb0c7e47411d11cbc3990eef51a5e10215a1fc9d5f5058fd8e952da94be16512", - "os": "windows", - "cpu": "arm64" - }, - { - "kind": "archive", - "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-x86_64-pc-windows-msvc.zip", - "file": "uv.exe", - "sha256": "3fb92ce0860db7cb094ddeeb1ac521532fdd3e61d0a130f7bbc6be54caca7c2e", - "os": "windows", - "cpu": "x86_64" - } - ] - } + "$schema": "https://raw.githubusercontent.com/theoremlp/rules_multitool/main/lockfile.schema.json", + "uv": { + "binaries": [ + { + "kind": "archive", + "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-aarch64-unknown-linux-musl.tar.gz", + "file": "uv-aarch64-unknown-linux-musl/uv", + "sha256": "de85bafc3e238a4fce87eb6a4e584c9c04721475abb9e5f6fe186bdce650763f", + "os": "linux", + "cpu": "arm64", + }, + { + "kind": "archive", + "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-x86_64-unknown-linux-gnu.tar.gz", + "file": "uv-x86_64-unknown-linux-gnu/uv", + "sha256": "f976ebdc612e71209f46664ab6c0325fa0090059b4474e047edd39eb9395373b", + "os": "linux", + "cpu": "x86_64", + }, + { + "kind": "archive", + "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-aarch64-apple-darwin.tar.gz", + "file": "uv-aarch64-apple-darwin/uv", + "sha256": "a3f78d20465c6d18f7072f118ce1c61b164b98698fdc37357e72958c7d1b68fd", + "os": "macos", + "cpu": "arm64", + }, + { + "kind": "archive", + "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-x86_64-apple-darwin.tar.gz", + "file": "uv-x86_64-apple-darwin/uv", + "sha256": "467b462e854bc750fcad8e3ad35e2aca0d301c9287f2365afad8c17b7672b6a8", + "os": "macos", + "cpu": "x86_64", + }, + { + "kind": "archive", + "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-aarch64-pc-windows-msvc.zip", + "file": "uv.exe", + "sha256": "eb0c7e47411d11cbc3990eef51a5e10215a1fc9d5f5058fd8e952da94be16512", + "os": "windows", + "cpu": "arm64", + }, + { + "kind": "archive", + "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-x86_64-pc-windows-msvc.zip", + "file": "uv.exe", + "sha256": "3fb92ce0860db7cb094ddeeb1ac521532fdd3e61d0a130f7bbc6be54caca7c2e", + "os": "windows", + "cpu": "x86_64", + }, + ], + }, } diff --git a/uv/private/hub/BUILD.bazel b/uv/private/uv_hub/BUILD.bazel similarity index 100% rename from uv/private/hub/BUILD.bazel rename to uv/private/uv_hub/BUILD.bazel diff --git a/uv/private/uv_hub/repository.bzl b/uv/private/uv_hub/repository.bzl new file mode 100644 index 00000000..cb6eabd3 --- /dev/null +++ b/uv/private/uv_hub/repository.bzl @@ -0,0 +1,228 @@ +""" + +""" + +load("//uv/private/pprint:defs.bzl", "pprint") + +def indent(text, space = " "): + return "\n".join(["{}{}".format(space, l) for l in text.splitlines()]) + +def _hub_impl(repository_ctx): + """Generates the central hub repository that exposes resolved dependencies to the build. + + - Defines a helper alias for configuring the active [dependency-group] + - Defines aliases for every package in any component project + + This "surface" hub is dead easy, as it just wraps up project hubs which are + responsible for all the heavy lifting. + + Args: + repository_ctx: The repository context. + """ + + # {requirement: {cfg: target}} + packages = json.decode(repository_ctx.attr.packages) + + ################################################################################ + # Lay down the //venv:BUILD.bazel file with config flags + # + # We do this first because everything else hangs off of these config_settings. + content = [ + """\ +alias( + name = "venv", + actual = "@aspect_rules_py//uv/private/constraints/venv:venv", + visibility = ["//visibility:public"], +) +""", + ] + + # Lay down the venv config settings + for name in repository_ctx.attr.configurations: + content.append( + """ +config_setting( + name = "{name}", + flag_values = {{ + "@aspect_rules_py//uv/private/constraints/venv:venv": "{name}", + }}, + visibility = ["//visibility:public"], +) +""".format(name = name), + ) + repository_ctx.file("venv/BUILD.bazel", content = "\n".join(content)) + + ################################################################################ + # Lay down the //:BUILD.bazel file + content = [ + """\ +load("@aspect_rules_py//py:defs.bzl", "py_library") +load("@aspect_rules_py//uv/private:defs.bzl", "py_whl_library", "whl_requirements") +""", + ] + + select_clauses = { + "//venv:" + cfg: ["@{}//:all_requirements".format(project_id)] + for cfg, project_id in repository_ctx.attr.configurations.items() + } + + content.append(""" +filegroup( + name = "all_requirements", + srcs = select({select_clauses}, + ), + visibility = ["//visibility:public"], +) + +whl_requirements( + name = "all_whl_requirements", + srcs = [":all_requirements"], + visibility = ["//visibility:public"], +) +""".format(select_clauses = indent(pprint(select_clauses), " ").lstrip())) + + repository_ctx.file("BUILD.bazel", "\n".join(content)) + + ################################################################################ + # Lay down the hub aliases + entrypoints = {} + + for package_name, specs in packages.items(): + content = [ + """\ +load("@aspect_rules_py//py:defs.bzl", "py_library") +load("@aspect_rules_py//uv/private:defs.bzl", "py_whl_library") +load("//:defs.bzl", "compatible_with") +""", + ] + + select_spec = { + "//venv:{}".format(cfg): l + for cfg, l in specs.items() + } + + error = "Available only in venvs: " + ", ".join(specs.keys()) # Simplified error string + + # FIXME: Add support for entrypoints? + # FIXME: Create a narrower dist-info rule + content.append( + """ +# This target is for a "hard" dependency. +# Dependencies on this target will cause build failures if it's unavailable. +alias( + name = "lib", + actual = "{name}", + visibility = ["//visibility:public"], +) +py_whl_library( + name = "whl", + srcs = [":{name}"], + visibility = ["//visibility:public"], +) +filegroup( + name = "dist_info", + srcs = [":{name}"], + visibility = ["//visibility:public"], +) +alias( + name = "{name}", + actual = select({lib_select}, + no_match_error = "{error}", + ), + target_compatible_with = select(compatible_with({compat})), + visibility = ["//visibility:public"], +) +""".format( + name = package_name, + lib_select = indent(pprint(select_spec), " ").lstrip(), + compat = repr(specs.keys()), + error = error, + ), + ) + + repository_ctx.file(package_name + "/BUILD.bazel", content = "\n".join(content)) + + ################################################################################ + # Lay down //:defs.bzl + content = [ + """ +VIRTUALENVS = {configurations} +_repo = {repo_name} + +def compatible_with(venvs, extra_constraints = []): + for v in venvs: + if v not in VIRTUALENVS: + fail("Errant virtualenv reference %r" % v) + + return {{ + Label("//venv:" + it): extra_constraints + for it in venvs + }} | {{ + "//conditions:default": ["@platforms//:incompatible"], + }} + +def incompatible_with(venvs, extra_constraints = []): + for v in venvs: + if v not in VIRTUALENVS: + fail("Errant virtualenv reference %r" % v) + + return {{ + Label("//venv:" + it): ["@platforms//:incompatible"] + for it in venvs + }} | {{ + "//conditions:default": extra_constraints, + }} +""".format( + configurations = pprint(repository_ctx.attr.configurations.keys()), + repo_name = repr(repository_ctx.name), + ), + ] + + repository_ctx.file("defs.bzl", content = "\n".join(content)) + + ################################################################################ + # Lay down a requirements.bzl for compatibility with rules_python + content = [] + content.append(""" +load("@rules_python//python:pip.bzl", "pip_utils") + +# We arne't compatible with this because it isn't constant over venvs. +# all_requirements = [] + +# We aren't compatible with this because it isn't constant over venvs. +# all_whl_requirements_by_package = {{}} + +# We aren't compatible with this because it isn't constant over venvs. +# all_whl_requirements = all_whl_requirements_by_package.values() + +# We aren't compatible with this because we don't offer separate data targets +# all_data_requirements = [] + +def requirement(name): + return "@@{repo_name}//{{0}}:{{0}}".format(pip_utils.normalize_name(name)) +""".format( + repo_name = repository_ctx.name, + )) + repository_ctx.file("requirements.bzl", content = "\n".join(content)) + + ################################################################################ + # Lay down the hub aliases + entrypoints = {} + +uv_hub = repository_rule( + doc = """ + """, + implementation = _hub_impl, + attrs = { + "configurations": attr.string_dict( + doc = """ + Mapping of configuration name to a project _containing_ that configuraiton. + """, + ), + "packages": attr.string( + doc = """ + JSON blob mapping packages to configurations to projects. + """, + ), + }, +) diff --git a/uv/private/venv_hub/BUILD.bazel b/uv/private/uv_project/BUILD.bazel similarity index 100% rename from uv/private/venv_hub/BUILD.bazel rename to uv/private/uv_project/BUILD.bazel diff --git a/uv/private/uv_project/repository.bzl b/uv/private/uv_project/repository.bzl new file mode 100644 index 00000000..c62514b7 --- /dev/null +++ b/uv/private/uv_project/repository.bzl @@ -0,0 +1,265 @@ +""" + +""" + +load("//uv/private:sha1.bzl", "sha1") +load("//uv/private/pprint:defs.bzl", "pprint") + +def indent(text, space = " "): + return "\n".join(["{}{}".format(space, l) for l in text.splitlines()]) + +def name(quad): + _lock, package_name, package_version, package_extra = quad.split(",") + if package_extra == "__base__": + return "{}__{}".format(package_name, package_version) + else: + return "{}__{}__extra__{}".format(package_name, package_version, package_extra) + +def _project_impl(repository_ctx): + """Materializes the dependency graph for a single project. + + Attrs: + dep_to_scc: {package: {cfg: {scc: {marker: 1}}}} + scc_deps: {scc: {package: {marker: 1}}} + scc_graph: {scc: {install: {marker: 1}}} + """ + + # Styleguide; string append via `+=` is inefficient. Prefer to use a list as + # a pseudo string builder buffer and a single final "\n".join(content) to + # materialize the buffer to a final writable string. + + # Styleguide: Address each layer of aliases sequentially. Each layer should + # begin with a comment explaining what faimily of BUILD.bazel files will be + # generated, and end with the required `repository_ctx.file(path, content)` + # call. + + # These are provided as JSON strings and must be decoded. + dep_to_scc = json.decode(repository_ctx.attr.dep_to_scc) + scc_deps = json.decode(repository_ctx.attr.scc_deps) + scc_graph = json.decode(repository_ctx.attr.scc_graph) + + # As we go for simplicity we collect markers + marker_table = {} + + def _marker(expr): + """ + Given a marker expression, get a label for it. + Interns the marker expression into the marker table as needed. + """ + if expr not in marker_table: + marker_table[expr] = sha1(expr) + marker_id = marker_table[expr] + return "//private/markers:" + marker_id + + def _conditionalize(it, markers, cond_id_thunk, no_match = None): + if "" in markers: + return it + else: + # This is a dep which is conditional + cases = {} + for marker in markers.keys(): + cases[_marker(marker)] = it + + if no_match: + cases["//conditions:default"] = no_match + + cond_id = cond_id_thunk() + content.append(""" +alias( + name = "{name}", + actual = select({arms}), + visibility = ["//:__subpackages__"], +) +""".format( + name = cond_id, + arms = indent(pprint(cases), " " * 4).lstrip(), + )) + return ":" + cond_id + + ################################################################################ + # Lay down the //private/venv:BUILD.bazel file with config flags + # + # This mirrors the uv_hub's venv, but is internal to the project. + venv_content = [] + + # Collect all unique cfgs first + all_cfgs = set() + for dep, cfgs in dep_to_scc.items(): + for cfg in cfgs.keys(): + all_cfgs.add(cfg) + + for cfg_name in all_cfgs: + venv_content.append( + """ +config_setting( + name = "{name}", + flag_values = {{ + "@aspect_rules_py//uv/private/constraints/venv:venv": "{name}", + }}, + visibility = ["//visibility:public"], +) +""".format(name = cfg_name), + ) + repository_ctx.file("private/venv/BUILD.bazel", content = "\n".join(venv_content)) + + ################################################################################ + # Lay down the surface-level targets + content = ["""\ +load("@aspect_rules_py//py:defs.bzl", "py_library") + +"""] + for package, cfgs in dep_to_scc.items(): + content.append(""" +# {} +{} +""".format(package, indent(pprint(cfgs), "# "))) + main_arms = {} + + # FIXME: Handle markers for distinct versions + for cfg, scc_cfgs in cfgs.items(): + cfg_name = "_package_{}_{}".format(package, cfg) + main_arms["//private/venv:" + cfg] = ":" + cfg_name + + cfg_arms = {} + + # This is a bit tricky. We're doing choice between several different + # SCCs possibly encoding different verisons or extra specializations + # of a package "at once" depending on the venv + marker set. + # Consequently this second-level choice is actually the MERGE + # between the individual cases under which specific markers evaluate + # to true. It's a configuraiton and locking failure for there to be + # more than one package which resolves at this point. So we just jam all the configurations into a single select. + for scc, markers in scc_cfgs.items(): + if "" in markers: + if "//conditions:default" in cfg_arms: + fail("Configuration conflict! Package {} specifies two or more default package states!\n{}".format(package, pprint(cfgs))) + + cfg_arms["//conditions:default"] = "//private/sccs:" + scc + + else: + for marker in markers.keys(): + marker = _marker(marker) + if marker in cfg_arms: + fail("Configuration conflict! Package {} specifies two or more configurations for the same marker!\n{}".format(package, pprint(cfgs))) + + cfg_arms[marker] = "//private/sccs:" + scc + + # Now we can just build one big choice alias from that arm set. + content.append(""" +alias( + name = "{name}", + actual = select({arms}), + visibility = ["//visibility:private"], +) +""".format(name = cfg_name, arms = indent(pprint(cfg_arms), " " * 4).lstrip())) + + # Finally we can render the wrapper over all the component arms + content.append(""" +alias( + name = "{name}", + actual = select({arms}), + visibility = ["//visibility:public"], +) +""".format( + name = package, + arms = indent(pprint(main_arms), " " * 4).lstrip(), + )) + + # As part of this root repo we also lay down :all_requirements which is slightly tricky because we have to + all_requirements = {} + for package, cfgs in dep_to_scc.items(): + for cfg in cfgs.keys(): + all_requirements.setdefault("//private/venv:" + cfg, []).append("//:" + package) + + content.append(""" +py_library( + name = "all_requirements", + srcs = select({arms}), + visibility = ["//visibility:public"], +) +""".format(arms = indent(pprint(all_requirements), " " * 4).lstrip())) + repository_ctx.file("BUILD.bazel", "\n".join(content)) + + ################################0################################################ + # Now the slightly harder bit -- lay down the SCCs + + content = ["""\ +load("@aspect_rules_py//py:defs.bzl", "py_library") + +# A dummy target so we can select to nothing when no markers match. +py_library( + name = "empty", + srcs = [], + deps = [], + imports = [], + visibility = ["//visibility:private"], +) +"""] + + for scc_id, members in scc_graph.items(): + this_scc_deps = scc_deps.get(scc_id, {}) + deps = [] + content.append(""" +# scc: {} +# members: +{} +# deps: +{} +""".format(scc_id, indent(pprint(members), "# "), indent(pprint(this_scc_deps), "# "))) + + for member, markers in members.items(): + deps.append(_conditionalize( + member, + markers, + lambda: "_maybe__{}__{}".format(scc_id, sha1(member)[:16]), + no_match = ":empty", + )) + + for dep, markers in this_scc_deps.items(): + deps.append(_conditionalize( + # Note that we map these back to surface packages + "//:" + dep, + markers, + lambda: "_maybe__{}__{}".format(scc_id, sha1(dep)[:16]), + no_match = ":empty", + )) + + content.append(""" +py_library( + name = "{name}", + deps = {deps}, + visibility = ["//:__subpackages__"], +) +""".format( + name = scc_id, + deps = indent(pprint(deps), " " * 4).lstrip(), + )) + + repository_ctx.file("private/sccs/BUILD.bazel", "\n".join(content)) + + ################################################################################ + # Finally lay down the collected markers + content = [""" +load("@aspect_rules_py//uv/private/markers:defs.bzl", "decide_marker") + +"""] + + for marker_expr, marker_id in marker_table.items(): + content.append(""" +decide_marker( + name = "{name}", + marker = {marker}, + visibility = ["//:__subpackages__"], +) +""".format(name = marker_id, marker = repr(marker_expr))) + + repository_ctx.file("private/markers/BUILD.bazel", "\n".join(content)) + +uv_project = repository_rule( + implementation = _project_impl, + attrs = { + "dep_to_scc": attr.string(), + "scc_deps": attr.string(), + "scc_graph": attr.string(), + }, +) diff --git a/uv/private/venv_hub/repository.bzl b/uv/private/venv_hub/repository.bzl deleted file mode 100644 index 485673cd..00000000 --- a/uv/private/venv_hub/repository.bzl +++ /dev/null @@ -1,213 +0,0 @@ -""" - -""" - -def _venv_hub_impl(repository_ctx): - # Lay down an alias from every nominal package to the scc containing it. - # - # TODO: If packages had markers, those markers would have to go here. - - entrypoints = json.decode(repository_ctx.attr.entrypoints) - - for pkg, group in repository_ctx.attr.aliases.items(): - content = [ - """load("@aspect_rules_py//uv/private:defs.bzl", "py_whl_library")""", - ] - content.append( - """ -alias( - name = "lib", - actual = ":{pkg}", - visibility = ["//visibility:public"], -) -alias( - name = "{pkg}", - actual = "//private/sccs:{scc}_lib", - visibility = ["//visibility:public"], -) -py_whl_library( - name = "whl", - deps = [":{pkg}"], - visibility = ["//visibility:public"], -) -""".format( - pkg = pkg, - scc = group, - ), - ) - repository_ctx.file("{}/BUILD.bazel".format(pkg), content = "\n".join(content)) - - content = [ - """load("@aspect_rules_py//uv/private/py_entrypoint_binary:defs.bzl", "py_entrypoint_binary")""", - ] - for entrypoint_name, entrypoint_coordinate in entrypoints.get(pkg, {}).items(): - content.append( - """ -py_entrypoint_binary( - name = "{name}", - deps = ["//{pkg}:{pkg}"], - coordinate = "{coordinate}", - visibility = ["//visibility:public"], -) -""".format( - name = entrypoint_name, - pkg = pkg, - coordinate = entrypoint_coordinate, - ), - ) - - repository_ctx.file("{}/entrypoints/BUILD.bazel".format(pkg), content = "\n".join(content)) - - # Lay down a package full of marker conditions which we'll reuse as we - # evaluate the groups' dependencies. - content = [ - "# FIXME", - """load("@aspect_rules_py//uv/private/markers:defs.bzl", "decide_marker")""", - ] - for name, marker in repository_ctx.attr.markers.items(): - content.append( - """ -decide_marker( - name = "{name}", - marker = "{marker}", - visibility = ["//private:__subpackages__"], -) -""".format( - name = name, - marker = marker, - ), - ) - - repository_ctx.file("private/markers/BUILD.bazel", content = "\n".join(content)) - - # So the strategy here is that we need to go through sccs, create each scc - # and depend on the members of the scc by their _install_ directly rather - # than by their alias/group. - # - # Deps are added to the scc group by their _alias_. - - # JSON decode the marker mapping so we can use it - scc_markers = json.decode(repository_ctx.attr.scc_markers) - - content = [ - "# FIXME", - """load("@aspect_rules_py//py:defs.bzl", "py_library")""", - "load(\"@bazel_skylib//lib:selects.bzl\", \"selects\")", - """ -# A placeholder library which allows us to select to nothing -py_library( - name = "_empty_lib", - srcs = [], - imports = [], - visibility = ["//visibility:private"] -) -""", - ] - - for group, members in repository_ctx.attr.sccs.items(): - installs = repository_ctx.attr.installs - member_installs = [ - "\"@{}//:install\"".format(installs[it]) if not installs[it].startswith("@") else repr(installs[it]) - for it in members - ] - - deps = repository_ctx.attr.deps[group] - if group not in scc_markers: - fail("Configuration error! Configured dep groups reference reference non-existent scc!") - - dep_labels = [] - for d in deps: - if d in members: - # Easy case of dependency edges within the group - continue - - markers = scc_markers[group].get(d, []) - if not markers: - # Easy case of non-conditional external dep - dep_labels.append("\"//%s\"" % d) - - else: - # Hard case of generating a conditional dep - content.append( - """ -# All of the markers under which {group} depends on {d} -selects.config_setting_group( - name = "_maybe_{group}_{d}", - match_any = {markers}, - visibility = ["//visibility:private"], -) - -# Depend on {d} of any of the {group} markers is active -alias( - name = "_{group}_{d}_lib", - actual = select({{ - ":_maybe_{group}_{d}": "//{d}", - "//conditions:default": ":_empty_lib", - }}), -) -""".format( - group = group, - d = d, - markers = ["//private/markers:%s" % it for it in markers], - ), - ) - dep_labels.append("\":_{}_{}_lib\"".format(group, d)) - - content.append( - """ -py_library( - name = "{name}_lib", - srcs = [], - deps = [ -{lib_deps} - ], - visibility = ["//:__subpackages__"], -) -""".format( - name = group, - lib_deps = ",\n".join([((" " * 8) + it) for it in (member_installs + dep_labels)]), - ), - ) - - repository_ctx.file("private/sccs/BUILD.bazel", content = "\n".join(content)) - -venv_hub = repository_rule( - implementation = _venv_hub_impl, - attrs = { - "aliases": attr.string_dict( - doc = """ - """, - ), - "markers": attr.string_dict( - doc = """ - """, - ), - "sccs": attr.string_list_dict( - doc = """ - """, - ), - "scc_markers": attr.string( - doc = """ - Graph of pkg -> dep -> Option[marker ID] - """, - ), - "deps": attr.string_list_dict( - doc = """ - """, - ), - "installs": attr.string_dict( - doc = """ - """, - ), - "entrypoints": attr.string( - doc = """ - JSON encoded map of pkg -> entrypoint -> coordinate - """, - ), - }, - doc = """ -Create a hub repository containing all the package(s) for all configuration(s) of a venv. - -TODO: Need to figure out where compatibility selection lives in here. -""", -) diff --git a/uv/private/whl_install/repository.bzl b/uv/private/whl_install/repository.bzl index ac01ef88..56000708 100644 --- a/uv/private/whl_install/repository.bzl +++ b/uv/private/whl_install/repository.bzl @@ -54,7 +54,29 @@ def _sort_select_arms(arms): return {a: b for a, b in pairs} def _whl_install_impl(repository_ctx): - prebuilds = json.decode(repository_ctx.attr.prebuilds) + """Selects a compatible wheel for the host platform and defines its installation. + + This rule takes a dictionary of available pre-built wheels and an optional + wheel built from source (`sbuild`). It is responsible for generating the + logic to select the single, most appropriate wheel for the current target + platform. + + It generates a `BUILD.bazel` file that: + 1. Uses a custom `select_chain` rule to create a sequence of `select` + statements. This chain checks the current platform against the + compatibility triples of the available wheels (using the `config_setting`s + generated by `configurations_hub`) and picks the first, most specific match. + 2. If an `sbuild` target is provided, it is used as the default fallback in + the selection chain, for when no pre-built wheel is compatible. + 3. Feeds the selected wheel file into a `whl_install` build rule, which is + responsible for unpacking the wheel into a directory. + 4. Provides a final `install` alias that represents the installed content of + the chosen wheel. + + Args: + repository_ctx: The repository context. + """ + prebuilds = json.decode(repository_ctx.attr.whls) # Prebuilds is a mapping from whl file name to repo labels which contain # that file. We need to take these wheel files and parse out compatibility. # @@ -87,7 +109,7 @@ def _whl_install_impl(repository_ctx): continue for abi_tag in parsed.abi_tags: - select_arms[(python_tag, platform_tag, abi_tag)] = "@" + target + select_arms[(python_tag, platform_tag, abi_tag)] = target # Unfortunately the way that Bazel decides ambiguous selects is explicitly # NOT designed to allow for the implementation of ranges. Because that would @@ -175,7 +197,7 @@ alias( whl_install = repository_rule( implementation = _whl_install_impl, attrs = { - "prebuilds": attr.string(), + "whls": attr.string(), "sbuild": attr.label(), }, ) diff --git a/uv/unstable/defs.bzl b/uv/unstable/defs.bzl index e69de29b..c2b5cc43 100644 --- a/uv/unstable/defs.bzl +++ b/uv/unstable/defs.bzl @@ -0,0 +1,8 @@ +load( + "//uv/private/py_entrypoint_binary:defs.bzl", + _py_console_script_binary = "py_console_script_binary", + _py_entrypoint_binary = "py_entrypoint_binary", +) + +py_entrypoint_binary = _py_entrypoint_binary +py_console_script_binary = _py_console_script_binary diff --git a/uv/unstable/extension.bzl b/uv/unstable/extension.bzl index 66a89e17..26dc5dd0 100644 --- a/uv/unstable/extension.bzl +++ b/uv/unstable/extension.bzl @@ -1,5 +1,5 @@ """""" -load("//uv/private:extension.bzl", _uv = "uv") +load("//uv/private/extension:defs.bzl", _uv = "uv") uv = _uv diff --git a/v2.py b/v2.py new file mode 100644 index 00000000..e1c4afdf --- /dev/null +++ b/v2.py @@ -0,0 +1,482 @@ +#!/usr/bin/env python3 + +from typing import List, Optional, TypedDict +import tomllib +import sys +from pprint import pprint +from hashlib import sha1 as _sha1 + +SdistSpec = dict +WheelSpec = dict + +class DependencySpec(TypedDict): + name: str + version: Optional[str] + marker: Optional[str] + +class RequirementSpec(TypedDict): + name: str + sdist: Optional[SdistSpec] + source: dict + wheels: List[WheelSpec] + version: str + dependency: List[DependencySpec] + + +# Copying Bazel's struct +def struct(**kwargs): + return type('struct', (object,), kwargs) + + +def fail(msg): + raise ValueError(msg) + +# Bridge to our sha1's signature +def sha1(txt): + return _sha1(txt.encode()).hexdigest() + +# from sccs.bzl +def sccs(graph): + """Identify strongly connected components. + + Uses Kosaraju's algorithm as the strategy. + + Args: + graph (dict): A mapping of nodes to their adjacencies. + + Returns: + A list of lists, where each inner list represents an SCC. + The components of each SCC are in lexically sorted order. + """ + nodes = list(graph.keys()) + visited = {node: False for node in nodes} + order = [] + + # An upper bound for the number of steps we'll need on each pass. The + # algorithm is actually linear time and the precise bound would be nodes + + # edges, but this is simple and safe. + # + # Starlark doesn't have `**`. Oh well. + bound = len(nodes) * len(nodes) + + # First DFS traversal to determine finishing times (post-order traversal) + # The outer loop ensures we start a traversal for all unvisited nodes. + for start_node in nodes: + if not visited[start_node]: + stack = [start_node] + temp_order = [] + + for _ in range(bound): + if not stack: + break + + current_node = stack.pop() + temp_order.append(current_node) + visited[current_node] = True + + neighbors = graph.get(current_node, []) + for neighbor in neighbors: + if not visited[neighbor]: + stack.append(neighbor) + + order = order + list(reversed(temp_order)) + + # Create the transpose graph (all edges reversed) + transpose_graph = {node: [] for node in nodes} + for node in nodes: + for neighbor in graph.get(node, []): + transpose_graph[neighbor].append(node) + + # Reset visited flags for the second traversal + visited = {node: False for node in nodes} + sccs = [] + + # Second DFS traversal on the transpose graph + # We process nodes in the reverse of their finishing time order. + # Each traversal finds a new SCC. + for start_node in reversed(order): + if not visited[start_node]: + current_scc = [] + stack = [start_node] + visited[start_node] = True + + for _ in range(bound): + if not stack: + break + + current_node = stack.pop() + current_scc.append(current_node) + + for neighbor in transpose_graph.get(current_node, []): + if not visited[neighbor]: + visited[neighbor] = True + stack.append(neighbor) + + sccs.append(current_scc) + + return [ + sorted(scc) + for scc in sccs + ] + +#################################################################################################### + +def _normalize_deps(lock_data): + """ + Normalize the lockfile. + 1. Compute the "default version" mapping + 2. Update all the dependency statements within the lockfile so they're version disambiguated + """ + + package_versions = {} + for spec in lock_data.get("package", []): + # spec: RequirementSpec + + # Collect all the versions first + package_versions.setdefault(spec["name"], {})[spec["version"]] = 1 + + default_versions = { + requirement: list(versions.keys())[0] + for requirement, versions in package_versions.items() if len(versions) == 1 + } + + def _fix_version(dep): + if not "version" in dep: + dep["version"] = default_versions.get(dep["name"]) + + for spec in lock_data.get("package", []): + for dep in spec.get("dependencies", []): + _fix_version(dep) + for extra_deps in spec.get("optional-dependencies", {}).values(): + for dep in extra_deps: + _fix_version(dep) + + return package_versions, default_versions, lock_data + +def _build_marker_graph(lock_data): + """The graph is {(package, version, extra): {(package, version, extra): {marker: 1}}}. + + We convert dependencies which no extra list to dependencies on ["__base__"]. + We also ensure that every extra depends on the "__base__" configuration if itself. + + + So writing `requests` is understood to be `requests[__base__]`, and + `requests[foo]` is `requests[__foo__] -> requests[__base__]` which allows is + to capture the same graph without having do splice in dependencies. + + At this point we also HAVE NOT done extras activation. + """ + + graph = {} + for spec in lock_data.get("package", []): + # spec: RequirementSpec + k = (spec["name"], spec["version"], "__base__") + pkg_deps = graph.setdefault(k, {}) + for dep in spec.get("dependencies", []): + extras = dep.get("extra", ["__base__"]) + for e in extras: + pkg_deps.setdefault((dep["name"], dep["version"], e), {})[dep.get("marker")] = 1 + + for extra_name, optional_deps in spec.get("optional-dependencies", {}).items(): + ek = (spec["name"], spec["version"], extra_name) + # Add a synthetic edge from the extra package to the base package + pkg_deps = graph.setdefault(ek, {}).setdefault(k, {None: 1}) + for dep in optional_deps: + extras = dep.get("extra", ["__base__"]) + for e in extras: + graph[ek].setdefault((dep["name"], dep["version"], e), {})[dep.get("marker")] = 1 + + return graph + +def _collect_sccs(graph): + """Given the internal dependency graph, compute strongly connected + components and the mapping from each dependency to the strongly connected + component which contains that dependency. + + Returns: + - A mapping from dependency to scc ID + - A mapping from scc id to the dependencies which are members of the scc + - A mapping from scc id to the dependencies which are directs of the scc + + """ + + simplified_graph = {dep: nexts.keys() for dep, nexts in graph.items()} + graph_components = sccs(simplified_graph) + scc_graph = { + sha1(repr(sorted(scc)))[:16]: scc + for scc in graph_components + } + + # Compute the mapping from dependency coordinates to the SCC containing that dep + dep_to_scc = { + it: scc + for scc, deps in scc_graph.items() + for it in deps + } + + # Compute the mapping from sccs to _direct_ non-member deps for "fattening" + scc_deps = {} + for scc, members in scc_graph.items(): + for member in members: + for dep, markers in graph.get(member, {}).items(): + if dep not in members: + scc_deps.setdefault(scc, {}).setdefault(dep, {}).update(markers) + + return dep_to_scc, scc_graph, scc_deps + + +def _extract_requirement_marker_pairs(req_string, version_map): + """ + Parses a requirement string into a list of ((name, version, extra), marker) pairs. + + Args: + req_string: The requirement string (e.g., "foo[bar]>=1.0; sys_platform == 'linux'"). + version_map: A dict mapping package names to default version strings. + + Returns: + A list of tuples [((name, version, extra), marker), ...]. + The marker is a string or None. + """ + # 1. Split Requirement and Marker + # Starlark split() often doesn't support maxsplit, so we use find() + slicing + semicolon_idx = req_string.find(";") + + marker = None + if semicolon_idx != -1: + # Extract and clean the marker + marker_text = req_string[semicolon_idx + 1:].strip() + if marker_text: + marker = marker_text + # The requirement part is everything before the semicolon + req_part = req_string[:semicolon_idx].strip() + else: + req_part = req_string.strip() + + if not req_part: + return [] + + # 2. Identify end of package name within req_part + stop_chars = { + "[": 1, + "=": 1, + ">": 1, + "<": 1, + "!": 1, + "~": 1, + " ": 1 + } + + name_end_idx = len(req_part) + + for i in range(len(req_part)): + char = req_part[i] + if char in stop_chars: + name_end_idx = i + break + + pkg_name = req_part[:name_end_idx] + + # 3. Extract Extras from req_part + extras = [] + + remainder = req_part[name_end_idx:] + + if remainder.startswith("["): + close_idx = remainder.find("]") + if close_idx != -1: + content = remainder[1:close_idx] + parts = content.split(",") + for p in parts: + clean_p = p.strip() + if clean_p: + extras.append(clean_p) + + # 4. Look up version + version = version_map.get(pkg_name) + + # 5. Construct results + # Each result is ((name, ver, extra), marker) + results = [] + + # Base requirement + base_dep = (pkg_name, version, "__base__") + results.append((base_dep, marker)) + + # Extras + for e in extras: + dep = (pkg_name, version, e) + results.append((dep, marker)) + + return results + +def _collect_activated_extras(project_data, default_versions, graph): + """ + Collect the set of extras which are directly or transitively activated in the given configuration. + Assumes all marker expressions are live. + + Returns + - {cfg: 1} + - {dep: {cfg: {extra_dep: {marker: 1}}}} + """ + + dep_groups = project_data.get("dependency-groups", { + project_data["project"]["name"]: [ + project_data["project"]["name"], + ], + }) + + # Normalize dep groups to our dependency triples (graph keys) + normalized_dep_groups = {} + + # Builds up {package: {configuration: {extra: {marker: 1}}}} + activated_extras = {} + + for group_name, specs in dep_groups.items(): + normalized_dep_groups[group_name] = [] + for spec in specs: + for dep, marker in _extract_requirement_marker_pairs(spec, default_versions): + normalized_dep_groups[group_name].append(dep) + + # Note that this is the base case for the reach set walk below + # We do this here so it's easy to handle marker expressions + base = (dep[0], dep[1], "__base__") + activated_extras.setdefault(base, {}).setdefault(group_name, {}).setdefault(dep, {}).update({marker: 1}) + + for group_name, deps in normalized_dep_groups.items(): + worklist = list(deps) + + # Worklist graph traversal to handle the reach set + visited = {} + idx = 0 + for _ in range(2**31): + if idx == len(worklist): + break + + it = worklist[idx] + visited[it] = 1 + + for next, markers in graph.get(it, {}).items(): + # Convert `next`, being a dependency potentially with marker, to its base package + base = (next[0], next[1], "__base__") + # Upsert the base package so that under the appropriate cfg it lists next as a dep with the appropriate markers + activated_extras.setdefault(base, {}).setdefault(group_name, {}).setdefault(next, {}).update(markers) + if next not in visited: + visited[next] = 1 + worklist.append(next) + + idx += 1 + + return {it: 1 for it in dep_groups.keys()}, activated_extras + +def _dump_cfg(activated_extras, cfg): + """Convert an activation state to a `uv export` + + Specifically, this should match to + + ``` + $ uv export \\ + --format=requirements.txt \\ + --no-default-groups \\ + --no-hashes \\ + --no-annotate \\ + --only-group=$cfg + ``` + + For the given lockfile. Differences in comments and source/URL installed + packages are expected. + + """ + lines = [] + for dep, cfgs in activated_extras.items(): + if cfg in cfgs: + l = f"{dep[0]}=={dep[1]}" + markers = cfgs[cfg][dep] + marker_exprs = [it for it in markers.keys() if it is not None] + if len(marker_exprs) > 1: + marker_exprs = [f"({it})" for it in marker_exprs] + marker_expr = ' or '.join(marker_exprs) + if marker_expr and None not in markers: + l = l + " ; " + marker_expr + lines.append(l) + return '\n'.join(sorted(lines, key = lambda l: l.split("==")[0])) + +def _collate_versions_by_name(activated_extras): + """ + Transforms the activated extras map into a mapping of names to configs to + versions to markers. This groups different versions of the same package + together under the package name. + + Returns: + {name: {config: {version: {marker: 1}}}} + """ + result = {} + + for (pkg_name, pkg_version, _), configs in activated_extras.items(): + for cfg, deps in configs.items(): + # Ensure path exists: result[name][cfg][version] -> {marker: 1} + # We use setdefault chain to traverse/create the nested dicts + version_markers = result.setdefault(pkg_name, {}).setdefault(cfg, {}).setdefault(pkg_version, {}) + + # deps is {dep_triple: {marker: 1}} + # We aggregate all markers for this version (from base and extras) + # into the single map for this version string. + for markers in deps.values(): + version_markers.update(markers) + + return result + +def _collect_markers(graph): + """ + Return a mapping of marker -> sha1, containing all markers in the graph + """ + acc = {} + for _dep, nexts in graph.items(): + for _next, markers in nexts.items(): + for marker in markers.keys(): + # sha1 is "expensive" so we minimize it + if marker is not None and marker not in acc: + acc[marker] = sha1(marker) + + return acc + +def _process_project(project_data, lock_data, hub_name="pypi"): + """Build up the build graph components for implementing a given pyproject in + Bazel according to the parameters of the lockfile. + + Arguments: + project_data: the content of a pyproject.toml as a dict + lock_data: the content of a uv.lock as a dict + + """ + + # package_versions: {requirement: {version: 1}} (set of versions per req.) + # default_versions: {requirement: version} the single version where only one + package_versions, default_versions, lock_data = _normalize_deps(lock_data) + graph = _build_marker_graph(lock_data) + + dep_to_scc, scc_members, scc_deps = _collect_sccs(graph) + + # This is also our hub keys + # configuration_names: {cfg: 1} + # activated_extras: {dep: {cfg: {extra: {marker: 1}}}} + configuration_names, activated_extras = _collect_activated_extras(project_data, default_versions, graph) + + markers = _collect_markers(graph) + + version_activations = _collate_versions_by_name(activated_extras) + + pprint(version_activations) + +if __name__ == "__main__": + # pyproject.toml + proj = sys.argv[1] + # uv.lock + lock = sys.argv[2] + + with open(proj, 'rb') as fp: + proj_data = tomllib.load(fp) + + with open(lock, 'rb') as fp: + lock_data = tomllib.load(fp) + + _process_project(proj_data, lock_data) From ea3f4ab95cb9f725e8efa841c10f482fb9aa6a42 Mon Sep 17 00:00:00 2001 From: Reid D McKenzie Date: Wed, 18 Feb 2026 00:14:52 -0700 Subject: [PATCH 02/18] Don't vc that --- v2.py | 482 ---------------------------------------------------------- 1 file changed, 482 deletions(-) delete mode 100644 v2.py diff --git a/v2.py b/v2.py deleted file mode 100644 index e1c4afdf..00000000 --- a/v2.py +++ /dev/null @@ -1,482 +0,0 @@ -#!/usr/bin/env python3 - -from typing import List, Optional, TypedDict -import tomllib -import sys -from pprint import pprint -from hashlib import sha1 as _sha1 - -SdistSpec = dict -WheelSpec = dict - -class DependencySpec(TypedDict): - name: str - version: Optional[str] - marker: Optional[str] - -class RequirementSpec(TypedDict): - name: str - sdist: Optional[SdistSpec] - source: dict - wheels: List[WheelSpec] - version: str - dependency: List[DependencySpec] - - -# Copying Bazel's struct -def struct(**kwargs): - return type('struct', (object,), kwargs) - - -def fail(msg): - raise ValueError(msg) - -# Bridge to our sha1's signature -def sha1(txt): - return _sha1(txt.encode()).hexdigest() - -# from sccs.bzl -def sccs(graph): - """Identify strongly connected components. - - Uses Kosaraju's algorithm as the strategy. - - Args: - graph (dict): A mapping of nodes to their adjacencies. - - Returns: - A list of lists, where each inner list represents an SCC. - The components of each SCC are in lexically sorted order. - """ - nodes = list(graph.keys()) - visited = {node: False for node in nodes} - order = [] - - # An upper bound for the number of steps we'll need on each pass. The - # algorithm is actually linear time and the precise bound would be nodes + - # edges, but this is simple and safe. - # - # Starlark doesn't have `**`. Oh well. - bound = len(nodes) * len(nodes) - - # First DFS traversal to determine finishing times (post-order traversal) - # The outer loop ensures we start a traversal for all unvisited nodes. - for start_node in nodes: - if not visited[start_node]: - stack = [start_node] - temp_order = [] - - for _ in range(bound): - if not stack: - break - - current_node = stack.pop() - temp_order.append(current_node) - visited[current_node] = True - - neighbors = graph.get(current_node, []) - for neighbor in neighbors: - if not visited[neighbor]: - stack.append(neighbor) - - order = order + list(reversed(temp_order)) - - # Create the transpose graph (all edges reversed) - transpose_graph = {node: [] for node in nodes} - for node in nodes: - for neighbor in graph.get(node, []): - transpose_graph[neighbor].append(node) - - # Reset visited flags for the second traversal - visited = {node: False for node in nodes} - sccs = [] - - # Second DFS traversal on the transpose graph - # We process nodes in the reverse of their finishing time order. - # Each traversal finds a new SCC. - for start_node in reversed(order): - if not visited[start_node]: - current_scc = [] - stack = [start_node] - visited[start_node] = True - - for _ in range(bound): - if not stack: - break - - current_node = stack.pop() - current_scc.append(current_node) - - for neighbor in transpose_graph.get(current_node, []): - if not visited[neighbor]: - visited[neighbor] = True - stack.append(neighbor) - - sccs.append(current_scc) - - return [ - sorted(scc) - for scc in sccs - ] - -#################################################################################################### - -def _normalize_deps(lock_data): - """ - Normalize the lockfile. - 1. Compute the "default version" mapping - 2. Update all the dependency statements within the lockfile so they're version disambiguated - """ - - package_versions = {} - for spec in lock_data.get("package", []): - # spec: RequirementSpec - - # Collect all the versions first - package_versions.setdefault(spec["name"], {})[spec["version"]] = 1 - - default_versions = { - requirement: list(versions.keys())[0] - for requirement, versions in package_versions.items() if len(versions) == 1 - } - - def _fix_version(dep): - if not "version" in dep: - dep["version"] = default_versions.get(dep["name"]) - - for spec in lock_data.get("package", []): - for dep in spec.get("dependencies", []): - _fix_version(dep) - for extra_deps in spec.get("optional-dependencies", {}).values(): - for dep in extra_deps: - _fix_version(dep) - - return package_versions, default_versions, lock_data - -def _build_marker_graph(lock_data): - """The graph is {(package, version, extra): {(package, version, extra): {marker: 1}}}. - - We convert dependencies which no extra list to dependencies on ["__base__"]. - We also ensure that every extra depends on the "__base__" configuration if itself. - - - So writing `requests` is understood to be `requests[__base__]`, and - `requests[foo]` is `requests[__foo__] -> requests[__base__]` which allows is - to capture the same graph without having do splice in dependencies. - - At this point we also HAVE NOT done extras activation. - """ - - graph = {} - for spec in lock_data.get("package", []): - # spec: RequirementSpec - k = (spec["name"], spec["version"], "__base__") - pkg_deps = graph.setdefault(k, {}) - for dep in spec.get("dependencies", []): - extras = dep.get("extra", ["__base__"]) - for e in extras: - pkg_deps.setdefault((dep["name"], dep["version"], e), {})[dep.get("marker")] = 1 - - for extra_name, optional_deps in spec.get("optional-dependencies", {}).items(): - ek = (spec["name"], spec["version"], extra_name) - # Add a synthetic edge from the extra package to the base package - pkg_deps = graph.setdefault(ek, {}).setdefault(k, {None: 1}) - for dep in optional_deps: - extras = dep.get("extra", ["__base__"]) - for e in extras: - graph[ek].setdefault((dep["name"], dep["version"], e), {})[dep.get("marker")] = 1 - - return graph - -def _collect_sccs(graph): - """Given the internal dependency graph, compute strongly connected - components and the mapping from each dependency to the strongly connected - component which contains that dependency. - - Returns: - - A mapping from dependency to scc ID - - A mapping from scc id to the dependencies which are members of the scc - - A mapping from scc id to the dependencies which are directs of the scc - - """ - - simplified_graph = {dep: nexts.keys() for dep, nexts in graph.items()} - graph_components = sccs(simplified_graph) - scc_graph = { - sha1(repr(sorted(scc)))[:16]: scc - for scc in graph_components - } - - # Compute the mapping from dependency coordinates to the SCC containing that dep - dep_to_scc = { - it: scc - for scc, deps in scc_graph.items() - for it in deps - } - - # Compute the mapping from sccs to _direct_ non-member deps for "fattening" - scc_deps = {} - for scc, members in scc_graph.items(): - for member in members: - for dep, markers in graph.get(member, {}).items(): - if dep not in members: - scc_deps.setdefault(scc, {}).setdefault(dep, {}).update(markers) - - return dep_to_scc, scc_graph, scc_deps - - -def _extract_requirement_marker_pairs(req_string, version_map): - """ - Parses a requirement string into a list of ((name, version, extra), marker) pairs. - - Args: - req_string: The requirement string (e.g., "foo[bar]>=1.0; sys_platform == 'linux'"). - version_map: A dict mapping package names to default version strings. - - Returns: - A list of tuples [((name, version, extra), marker), ...]. - The marker is a string or None. - """ - # 1. Split Requirement and Marker - # Starlark split() often doesn't support maxsplit, so we use find() + slicing - semicolon_idx = req_string.find(";") - - marker = None - if semicolon_idx != -1: - # Extract and clean the marker - marker_text = req_string[semicolon_idx + 1:].strip() - if marker_text: - marker = marker_text - # The requirement part is everything before the semicolon - req_part = req_string[:semicolon_idx].strip() - else: - req_part = req_string.strip() - - if not req_part: - return [] - - # 2. Identify end of package name within req_part - stop_chars = { - "[": 1, - "=": 1, - ">": 1, - "<": 1, - "!": 1, - "~": 1, - " ": 1 - } - - name_end_idx = len(req_part) - - for i in range(len(req_part)): - char = req_part[i] - if char in stop_chars: - name_end_idx = i - break - - pkg_name = req_part[:name_end_idx] - - # 3. Extract Extras from req_part - extras = [] - - remainder = req_part[name_end_idx:] - - if remainder.startswith("["): - close_idx = remainder.find("]") - if close_idx != -1: - content = remainder[1:close_idx] - parts = content.split(",") - for p in parts: - clean_p = p.strip() - if clean_p: - extras.append(clean_p) - - # 4. Look up version - version = version_map.get(pkg_name) - - # 5. Construct results - # Each result is ((name, ver, extra), marker) - results = [] - - # Base requirement - base_dep = (pkg_name, version, "__base__") - results.append((base_dep, marker)) - - # Extras - for e in extras: - dep = (pkg_name, version, e) - results.append((dep, marker)) - - return results - -def _collect_activated_extras(project_data, default_versions, graph): - """ - Collect the set of extras which are directly or transitively activated in the given configuration. - Assumes all marker expressions are live. - - Returns - - {cfg: 1} - - {dep: {cfg: {extra_dep: {marker: 1}}}} - """ - - dep_groups = project_data.get("dependency-groups", { - project_data["project"]["name"]: [ - project_data["project"]["name"], - ], - }) - - # Normalize dep groups to our dependency triples (graph keys) - normalized_dep_groups = {} - - # Builds up {package: {configuration: {extra: {marker: 1}}}} - activated_extras = {} - - for group_name, specs in dep_groups.items(): - normalized_dep_groups[group_name] = [] - for spec in specs: - for dep, marker in _extract_requirement_marker_pairs(spec, default_versions): - normalized_dep_groups[group_name].append(dep) - - # Note that this is the base case for the reach set walk below - # We do this here so it's easy to handle marker expressions - base = (dep[0], dep[1], "__base__") - activated_extras.setdefault(base, {}).setdefault(group_name, {}).setdefault(dep, {}).update({marker: 1}) - - for group_name, deps in normalized_dep_groups.items(): - worklist = list(deps) - - # Worklist graph traversal to handle the reach set - visited = {} - idx = 0 - for _ in range(2**31): - if idx == len(worklist): - break - - it = worklist[idx] - visited[it] = 1 - - for next, markers in graph.get(it, {}).items(): - # Convert `next`, being a dependency potentially with marker, to its base package - base = (next[0], next[1], "__base__") - # Upsert the base package so that under the appropriate cfg it lists next as a dep with the appropriate markers - activated_extras.setdefault(base, {}).setdefault(group_name, {}).setdefault(next, {}).update(markers) - if next not in visited: - visited[next] = 1 - worklist.append(next) - - idx += 1 - - return {it: 1 for it in dep_groups.keys()}, activated_extras - -def _dump_cfg(activated_extras, cfg): - """Convert an activation state to a `uv export` - - Specifically, this should match to - - ``` - $ uv export \\ - --format=requirements.txt \\ - --no-default-groups \\ - --no-hashes \\ - --no-annotate \\ - --only-group=$cfg - ``` - - For the given lockfile. Differences in comments and source/URL installed - packages are expected. - - """ - lines = [] - for dep, cfgs in activated_extras.items(): - if cfg in cfgs: - l = f"{dep[0]}=={dep[1]}" - markers = cfgs[cfg][dep] - marker_exprs = [it for it in markers.keys() if it is not None] - if len(marker_exprs) > 1: - marker_exprs = [f"({it})" for it in marker_exprs] - marker_expr = ' or '.join(marker_exprs) - if marker_expr and None not in markers: - l = l + " ; " + marker_expr - lines.append(l) - return '\n'.join(sorted(lines, key = lambda l: l.split("==")[0])) - -def _collate_versions_by_name(activated_extras): - """ - Transforms the activated extras map into a mapping of names to configs to - versions to markers. This groups different versions of the same package - together under the package name. - - Returns: - {name: {config: {version: {marker: 1}}}} - """ - result = {} - - for (pkg_name, pkg_version, _), configs in activated_extras.items(): - for cfg, deps in configs.items(): - # Ensure path exists: result[name][cfg][version] -> {marker: 1} - # We use setdefault chain to traverse/create the nested dicts - version_markers = result.setdefault(pkg_name, {}).setdefault(cfg, {}).setdefault(pkg_version, {}) - - # deps is {dep_triple: {marker: 1}} - # We aggregate all markers for this version (from base and extras) - # into the single map for this version string. - for markers in deps.values(): - version_markers.update(markers) - - return result - -def _collect_markers(graph): - """ - Return a mapping of marker -> sha1, containing all markers in the graph - """ - acc = {} - for _dep, nexts in graph.items(): - for _next, markers in nexts.items(): - for marker in markers.keys(): - # sha1 is "expensive" so we minimize it - if marker is not None and marker not in acc: - acc[marker] = sha1(marker) - - return acc - -def _process_project(project_data, lock_data, hub_name="pypi"): - """Build up the build graph components for implementing a given pyproject in - Bazel according to the parameters of the lockfile. - - Arguments: - project_data: the content of a pyproject.toml as a dict - lock_data: the content of a uv.lock as a dict - - """ - - # package_versions: {requirement: {version: 1}} (set of versions per req.) - # default_versions: {requirement: version} the single version where only one - package_versions, default_versions, lock_data = _normalize_deps(lock_data) - graph = _build_marker_graph(lock_data) - - dep_to_scc, scc_members, scc_deps = _collect_sccs(graph) - - # This is also our hub keys - # configuration_names: {cfg: 1} - # activated_extras: {dep: {cfg: {extra: {marker: 1}}}} - configuration_names, activated_extras = _collect_activated_extras(project_data, default_versions, graph) - - markers = _collect_markers(graph) - - version_activations = _collate_versions_by_name(activated_extras) - - pprint(version_activations) - -if __name__ == "__main__": - # pyproject.toml - proj = sys.argv[1] - # uv.lock - lock = sys.argv[2] - - with open(proj, 'rb') as fp: - proj_data = tomllib.load(fp) - - with open(lock, 'rb') as fp: - lock_data = tomllib.load(fp) - - _process_project(proj_data, lock_data) From c6ec34ef129a4b147891e1aed5fad11d01bbf6a0 Mon Sep 17 00:00:00 2001 From: "aspect-marvin[bot]" Date: Wed, 18 Feb 2026 07:16:50 +0000 Subject: [PATCH 03/18] Pre-commit changes --- MODULE.bazel | 8 +- uv/private/extension/BUILD.bazel | 1 - uv/private/py_entrypoint_binary/search.py | 2 +- uv/private/uv/uv.lock.json | 106 +++++++++++----------- uv/private/uv_project/repository.bzl | 4 +- 5 files changed, 60 insertions(+), 61 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 9390f860..3e16fa43 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -188,18 +188,18 @@ uv.declare_hub( ) uv.project( name = "aspect_rules_py", - hub_name = "pypi", - lock = "//:uv.lock", - pyproject = "//:pyproject.toml", default_build_dependencies = [ "build", "setuptools", "maturin", ], + hub_name = "pypi", + lock = "//:uv.lock", + pyproject = "//:pyproject.toml", ) uv.unstable_annotate_packages( - lock = "//:uv.lock", src = "//:annotations.toml", + lock = "//:uv.lock", ) use_repo(uv, "pypi") diff --git a/uv/private/extension/BUILD.bazel b/uv/private/extension/BUILD.bazel index 53a47575..bc00ddc9 100644 --- a/uv/private/extension/BUILD.bazel +++ b/uv/private/extension/BUILD.bazel @@ -1,6 +1,5 @@ # TOOLCHAIN_DEPS load("@bazel_skylib//:bzl_library.bzl", "bzl_library") - load(":test_graph_utils.bzl", "graph_utils_test_suite") bzl_library( diff --git a/uv/private/py_entrypoint_binary/search.py b/uv/private/py_entrypoint_binary/search.py index 31432ccb..f6dcf52f 100644 --- a/uv/private/py_entrypoint_binary/search.py +++ b/uv/private/py_entrypoint_binary/search.py @@ -13,7 +13,7 @@ class CaseSensitiveConfigParser(configparser.ConfigParser): optionxform = staticmethod(str) -# Quick and dirty re-implementaiton of the setuptools search. +# Quick and dirty re-implementation of the setuptools search. PARSER = argparse.ArgumentParser() PARSER.add_argument("--template") diff --git a/uv/private/uv/uv.lock.json b/uv/private/uv/uv.lock.json index cdaf7f16..8f4b98b6 100644 --- a/uv/private/uv/uv.lock.json +++ b/uv/private/uv/uv.lock.json @@ -1,55 +1,55 @@ { - "$schema": "https://raw.githubusercontent.com/theoremlp/rules_multitool/main/lockfile.schema.json", - "uv": { - "binaries": [ - { - "kind": "archive", - "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-aarch64-unknown-linux-musl.tar.gz", - "file": "uv-aarch64-unknown-linux-musl/uv", - "sha256": "de85bafc3e238a4fce87eb6a4e584c9c04721475abb9e5f6fe186bdce650763f", - "os": "linux", - "cpu": "arm64", - }, - { - "kind": "archive", - "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-x86_64-unknown-linux-gnu.tar.gz", - "file": "uv-x86_64-unknown-linux-gnu/uv", - "sha256": "f976ebdc612e71209f46664ab6c0325fa0090059b4474e047edd39eb9395373b", - "os": "linux", - "cpu": "x86_64", - }, - { - "kind": "archive", - "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-aarch64-apple-darwin.tar.gz", - "file": "uv-aarch64-apple-darwin/uv", - "sha256": "a3f78d20465c6d18f7072f118ce1c61b164b98698fdc37357e72958c7d1b68fd", - "os": "macos", - "cpu": "arm64", - }, - { - "kind": "archive", - "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-x86_64-apple-darwin.tar.gz", - "file": "uv-x86_64-apple-darwin/uv", - "sha256": "467b462e854bc750fcad8e3ad35e2aca0d301c9287f2365afad8c17b7672b6a8", - "os": "macos", - "cpu": "x86_64", - }, - { - "kind": "archive", - "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-aarch64-pc-windows-msvc.zip", - "file": "uv.exe", - "sha256": "eb0c7e47411d11cbc3990eef51a5e10215a1fc9d5f5058fd8e952da94be16512", - "os": "windows", - "cpu": "arm64", - }, - { - "kind": "archive", - "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-x86_64-pc-windows-msvc.zip", - "file": "uv.exe", - "sha256": "3fb92ce0860db7cb094ddeeb1ac521532fdd3e61d0a130f7bbc6be54caca7c2e", - "os": "windows", - "cpu": "x86_64", - }, - ], - }, + "$schema": "https://raw.githubusercontent.com/theoremlp/rules_multitool/main/lockfile.schema.json", + "uv": { + "binaries": [ + { + "kind": "archive", + "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-aarch64-unknown-linux-musl.tar.gz", + "file": "uv-aarch64-unknown-linux-musl/uv", + "sha256": "de85bafc3e238a4fce87eb6a4e584c9c04721475abb9e5f6fe186bdce650763f", + "os": "linux", + "cpu": "arm64" + }, + { + "kind": "archive", + "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-x86_64-unknown-linux-gnu.tar.gz", + "file": "uv-x86_64-unknown-linux-gnu/uv", + "sha256": "f976ebdc612e71209f46664ab6c0325fa0090059b4474e047edd39eb9395373b", + "os": "linux", + "cpu": "x86_64" + }, + { + "kind": "archive", + "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-aarch64-apple-darwin.tar.gz", + "file": "uv-aarch64-apple-darwin/uv", + "sha256": "a3f78d20465c6d18f7072f118ce1c61b164b98698fdc37357e72958c7d1b68fd", + "os": "macos", + "cpu": "arm64" + }, + { + "kind": "archive", + "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-x86_64-apple-darwin.tar.gz", + "file": "uv-x86_64-apple-darwin/uv", + "sha256": "467b462e854bc750fcad8e3ad35e2aca0d301c9287f2365afad8c17b7672b6a8", + "os": "macos", + "cpu": "x86_64" + }, + { + "kind": "archive", + "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-aarch64-pc-windows-msvc.zip", + "file": "uv.exe", + "sha256": "eb0c7e47411d11cbc3990eef51a5e10215a1fc9d5f5058fd8e952da94be16512", + "os": "windows", + "cpu": "arm64" + }, + { + "kind": "archive", + "url": "https://github.com/astral-sh/uv/releases/download/0.8.12/uv-x86_64-pc-windows-msvc.zip", + "file": "uv.exe", + "sha256": "3fb92ce0860db7cb094ddeeb1ac521532fdd3e61d0a130f7bbc6be54caca7c2e", + "os": "windows", + "cpu": "x86_64" + } + ] + } } diff --git a/uv/private/uv_project/repository.bzl b/uv/private/uv_project/repository.bzl index c62514b7..2cda9526 100644 --- a/uv/private/uv_project/repository.bzl +++ b/uv/private/uv_project/repository.bzl @@ -123,11 +123,11 @@ load("@aspect_rules_py//py:defs.bzl", "py_library") cfg_arms = {} # This is a bit tricky. We're doing choice between several different - # SCCs possibly encoding different verisons or extra specializations + # SCCs possibly encoding different versions or extra specializations # of a package "at once" depending on the venv + marker set. # Consequently this second-level choice is actually the MERGE # between the individual cases under which specific markers evaluate - # to true. It's a configuraiton and locking failure for there to be + # to true. It's a configuration and locking failure for there to be # more than one package which resolves at this point. So we just jam all the configurations into a single select. for scc, markers in scc_cfgs.items(): if "" in markers: From 15043e2bd656301df1ba76a28184302d3d55e9a1 Mon Sep 17 00:00:00 2001 From: "Reid D. McKenzie" Date: Wed, 18 Feb 2026 18:13:29 -0700 Subject: [PATCH 04/18] Repair the Gazelle manifest generation --- BUILD.bazel | 2 +- gazelle_python.yaml | 2 + .../BUILD.bazel | 0 .../{manifest => gazelle_manifest}/defs.bzl | 4 +- .../generate.py | 46 +++++++++++-------- .../{manifest => gazelle_manifest}/update.sh | 0 uv/private/uv_project/repository.bzl | 2 +- uv/private/whl_install/repository.bzl | 5 +- 8 files changed, 38 insertions(+), 23 deletions(-) rename uv/private/{manifest => gazelle_manifest}/BUILD.bazel (100%) rename uv/private/{manifest => gazelle_manifest}/defs.bzl (95%) rename uv/private/{manifest => gazelle_manifest}/generate.py (95%) rename uv/private/{manifest => gazelle_manifest}/update.sh (100%) diff --git a/BUILD.bazel b/BUILD.bazel index ec56d59c..b93b1bb2 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -2,7 +2,7 @@ load("@gazelle//:def.bzl", "gazelle") load("@rules_python//python/pip_install:requirements.bzl", "compile_pip_requirements") # buildifier: disable=bzl-visibility -load("//uv/private/manifest:defs.bzl", "gazelle_python_manifest") +load("//uv/private/gazelle_manifest:defs.bzl", "gazelle_python_manifest") # gazelle:exclude internal_python_deps.bzl # gazelle:exclude internal_deps.bzl diff --git a/gazelle_python.yaml b/gazelle_python.yaml index 95d0414a..929a27af 100644 --- a/gazelle_python.yaml +++ b/gazelle_python.yaml @@ -1546,6 +1546,8 @@ manifest: libpasteurize.fixes.fix_throw: future libpasteurize.fixes.fix_unpacking: future libpasteurize.main: future + maturin: maturin + maturin.bootstrap: maturin monotonic: monotonic msgpack: msgpack msgpack.exceptions: msgpack diff --git a/uv/private/manifest/BUILD.bazel b/uv/private/gazelle_manifest/BUILD.bazel similarity index 100% rename from uv/private/manifest/BUILD.bazel rename to uv/private/gazelle_manifest/BUILD.bazel diff --git a/uv/private/manifest/defs.bzl b/uv/private/gazelle_manifest/defs.bzl similarity index 95% rename from uv/private/manifest/defs.bzl rename to uv/private/gazelle_manifest/defs.bzl index e085e512..31be1006 100644 --- a/uv/private/manifest/defs.bzl +++ b/uv/private/gazelle_manifest/defs.bzl @@ -1,12 +1,14 @@ load("@bazel_lib//lib:transitions.bzl", "platform_transition_filegroup") load("@rules_shell//shell:sh_binary.bzl", "sh_binary") +load("//uv/private/pprint:defs.bzl", "pprint") def _modules_mapping_impl(ctx): out = ctx.actions.declare_file(ctx.label.name + ".yaml") whl_file_deps = [] for target in ctx.attr.wheels: - files_depset = target[DefaultInfo].default_runfiles.files + print(pprint(target[DefaultInfo])) + files_depset = target[DefaultInfo].files whl_file_deps.append(files_depset) whl_depset = depset( diff --git a/uv/private/manifest/generate.py b/uv/private/gazelle_manifest/generate.py similarity index 95% rename from uv/private/manifest/generate.py rename to uv/private/gazelle_manifest/generate.py index ab74eb59..c2d3a6b4 100644 --- a/uv/private/manifest/generate.py +++ b/uv/private/gazelle_manifest/generate.py @@ -5,7 +5,7 @@ # be overkill and take more work. # # The strategy is simple. -# - Accept an args file containing paths to wheel (.whl) files +# - Accept an args file containing paths to wheel (.whl) files or directories containing .whl files # - A path to a lockfile # - A path to a file containing an integrity shasum # @@ -18,7 +18,6 @@ # - Write a YAML format manifest file {manifest: {modules_mapping: , pip_repository: }, integrity: } import argparse -import re import sys from zipfile import ZipFile from pathlib import Path @@ -73,12 +72,12 @@ def extract_package_name(whl_path: Path) -> Optional[str]: # Use email.parser (standard library) to reliably parse RFC 822 headers parser = Parser() msg = parser.parse(StringIO(metadata_content)) - + package_name = msg.get('Name') if not package_name: print(f"Warning: 'Name' field missing from METADATA in {whl_path}", file=sys.stderr) return None - + return normalize_name(package_name.strip()) except Exception as e: @@ -99,11 +98,11 @@ def get_importable_module_name(filepath: str) -> Optional[str]: # 2. Split into path segments segments = filepath.split('/') - + # 3. Filter out single-underscore prefixed segments (e.g., requests/_internal) # Exclude '__init__' from the underscore check filtered_segments = [s for s in segments if not (s.startswith('_') and s != '__init__')] - + # If any segment was filtered out, we exclude the entire path if len(filtered_segments) != len(segments): return None @@ -133,7 +132,7 @@ def identify_modules(whl_path: Path, package_name: str) -> dict[str, str]: A dictionary mapping importable module names to the requirement name. """ module_mapping = {} - + # Normalize package name for use as requirement name (Gazelle convention) requirement_name = package_name.lower().replace('-', '_') @@ -153,7 +152,7 @@ def identify_modules(whl_path: Path, package_name: str) -> dict[str, str]: if module_name not in module_mapping: module_mapping[module_name] = requirement_name # else: module already found, perhaps via a different path, skip - + except Exception as e: print(f"Error identifying modules in {whl_path}: {e}", file=sys.stderr) @@ -186,7 +185,7 @@ def write_manifest(module_mapping: dict[str, str], pip_repository: {pip_repository_name} integrity: "{integrity_value}" """ - + try: with open(output_path, 'w') as f: f.write(yaml_content) @@ -203,7 +202,7 @@ def main(): parser = argparse.ArgumentParser( description="A tool for generating Gazelle manifests from Python wheel files." ) - + # Args file containing paths to wheel (.whl) files parser.add_argument( '--whl_paths_file', @@ -211,7 +210,7 @@ def main(): required=True, help="Path to a file containing a list of paths to wheel (.whl) files, one per line." ) - + # Path to a file containing the integrity shasum parser.add_argument( '--integrity_file', @@ -219,7 +218,7 @@ def main(): required=False, help="Path to a file containing the final integrity SHA sum (e.g., SHA256)." ) - + # Output path for the final Gazelle manifest parser.add_argument( '--output', @@ -227,7 +226,7 @@ def main(): default=Path('gazelle_manifest.yaml'), help="Path to write the final YAML manifest file." ) - + args = parser.parse_args() # 1. Read integrity value @@ -240,7 +239,7 @@ def main(): else: # The null shasum integrity_value = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - + except Exception as e: print(f"Error reading integrity file {args.integrity_file}: {e}", file=sys.stderr) sys.exit(1) @@ -248,7 +247,18 @@ def main(): # 2. Read wheel paths try: whl_paths_raw = args.whl_paths_file.read_text().splitlines() - whl_paths = [Path(p.strip()) for p in whl_paths_raw if p.strip()] + whl_paths = [] + for p in whl_paths_raw: + p = p.strip() + if p: + p = Path(p) + if p.is_file(): + whl_paths.append(p) + elif p.is_dir(): + whl_paths.extend(p.glob("*.whl")) + else: + print(f"No wheels found for {p}", file=sys.stderr) + except Exception as e: print(f"Error reading wheel paths file {args.whl_paths_file}: {e}", file=sys.stderr) sys.exit(1) @@ -262,15 +272,15 @@ def main(): if not whl_path.exists(): print(f"Warning: Wheel file not found: {whl_path}. Skipping.", file=sys.stderr) continue - + # Get package name (requirement name) package_name = extract_package_name(whl_path) if not package_name: continue - + # Identify importable modules for this package modules = identify_modules(whl_path, package_name) - + # Merge results into the final map final_module_mapping.update(modules) diff --git a/uv/private/manifest/update.sh b/uv/private/gazelle_manifest/update.sh similarity index 100% rename from uv/private/manifest/update.sh rename to uv/private/gazelle_manifest/update.sh diff --git a/uv/private/uv_project/repository.bzl b/uv/private/uv_project/repository.bzl index 2cda9526..918fb24e 100644 --- a/uv/private/uv_project/repository.bzl +++ b/uv/private/uv_project/repository.bzl @@ -172,7 +172,7 @@ alias( all_requirements.setdefault("//private/venv:" + cfg, []).append("//:" + package) content.append(""" -py_library( +filegroup( name = "all_requirements", srcs = select({arms}), visibility = ["//visibility:public"], diff --git a/uv/private/whl_install/repository.bzl b/uv/private/whl_install/repository.bzl index 56000708..e7189517 100644 --- a/uv/private/whl_install/repository.bzl +++ b/uv/private/whl_install/repository.bzl @@ -162,10 +162,11 @@ select_chain( ) py_library( name = "whl_lib", - srcs = [], - data = [ + srcs = [ ":whl" ], + data = [ + ], visibility = ["//visibility:private"], ) """.format( From 29eb14a83e29fb79f3315217276d73f42966fca5 Mon Sep 17 00:00:00 2001 From: Reid D McKenzie Date: Thu, 19 Feb 2026 13:15:36 -0700 Subject: [PATCH 05/18] [NO TESTS] WIP --- e2e/BUILD.bazel | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 e2e/BUILD.bazel diff --git a/e2e/BUILD.bazel b/e2e/BUILD.bazel deleted file mode 100644 index 298076db..00000000 --- a/e2e/BUILD.bazel +++ /dev/null @@ -1,8 +0,0 @@ -load("@rules_python//python/pip_install:requirements.bzl", "compile_pip_requirements") - -compile_pip_requirements( - name = "requirements", - extra_args = ["--allow-unsafe"], - requirements_in = "requirements.in", - requirements_txt = "requirements.txt", -) From 6c4da481b9d99230bb9383c15524f2f8cdd5e02a Mon Sep 17 00:00:00 2001 From: Reid D McKenzie Date: Thu, 19 Feb 2026 13:16:01 -0700 Subject: [PATCH 06/18] [NO TESTS] WIP --- e2e/cases/uv-gazelle-778/BUILD.bazel | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 e2e/cases/uv-gazelle-778/BUILD.bazel diff --git a/e2e/cases/uv-gazelle-778/BUILD.bazel b/e2e/cases/uv-gazelle-778/BUILD.bazel new file mode 100644 index 00000000..5569d0a3 --- /dev/null +++ b/e2e/cases/uv-gazelle-778/BUILD.bazel @@ -0,0 +1,21 @@ +# buildifier: disable=bzl-visibility +load("@aspect_rules_py//uv/private/gazelle_manifest:defs.bzl", "gazelle_python_manifest") + +# gazelle:exclude internal_python_deps.bzl +# gazelle:exclude internal_deps.bzl +# gazelle:exclude py/tests/ +# gazelle:exclude examples/django +# gazelle:map_kind bzl_library bzl_library @bazel_lib//:bzl_library.bzl + +# Excercise generating a Gazelle manifest covering a ton of venvs +gazelle_python_manifest( + name = "gazelle_python_manifest", + hub = "pypi", + # Note that we _merge_ the package mappings from several configurations. + venvs = [ + "airflow", + "crossbuild", + "extras", + "say", + ], +) From e82d762d6996d5a7432ea6175dab56c07da7475d Mon Sep 17 00:00:00 2001 From: Reid D McKenzie Date: Thu, 19 Feb 2026 13:26:55 -0700 Subject: [PATCH 07/18] [NO TESTS] WIP --- e2e/cases/uv-gazelle-778/BUILD.bazel | 6 ------ 1 file changed, 6 deletions(-) diff --git a/e2e/cases/uv-gazelle-778/BUILD.bazel b/e2e/cases/uv-gazelle-778/BUILD.bazel index 5569d0a3..f1ee11f1 100644 --- a/e2e/cases/uv-gazelle-778/BUILD.bazel +++ b/e2e/cases/uv-gazelle-778/BUILD.bazel @@ -1,12 +1,6 @@ # buildifier: disable=bzl-visibility load("@aspect_rules_py//uv/private/gazelle_manifest:defs.bzl", "gazelle_python_manifest") -# gazelle:exclude internal_python_deps.bzl -# gazelle:exclude internal_deps.bzl -# gazelle:exclude py/tests/ -# gazelle:exclude examples/django -# gazelle:map_kind bzl_library bzl_library @bazel_lib//:bzl_library.bzl - # Excercise generating a Gazelle manifest covering a ton of venvs gazelle_python_manifest( name = "gazelle_python_manifest", From 17d33548053500f38199f7ceb86333d9151a6e8f Mon Sep 17 00:00:00 2001 From: "Reid D. McKenzie" Date: Thu, 19 Feb 2026 14:14:41 -0700 Subject: [PATCH 08/18] Rework hub to create a Gazelle wheel set --- e2e/cases/uv-gazelle-778/gazelle_python.yaml | 3496 ++++++++++++++++++ uv/private/extension/defs.bzl | 9 +- uv/private/gazelle_manifest/defs.bzl | 5 +- uv/private/gazelle_manifest/generate.py | 2 + uv/private/gazelle_manifest/update.sh | 2 +- uv/private/uv_hub/repository.bzl | 18 +- uv/private/uv_project/repository.bzl | 15 +- uv/private/whl_install/repository.bzl | 49 +- 8 files changed, 3559 insertions(+), 37 deletions(-) create mode 100644 e2e/cases/uv-gazelle-778/gazelle_python.yaml diff --git a/e2e/cases/uv-gazelle-778/gazelle_python.yaml b/e2e/cases/uv-gazelle-778/gazelle_python.yaml new file mode 100644 index 00000000..d28ece77 --- /dev/null +++ b/e2e/cases/uv-gazelle-778/gazelle_python.yaml @@ -0,0 +1,3496 @@ +manifest: + modules_mapping: + a2wsgi: a2wsgi + a2wsgi.asgi: a2wsgi + a2wsgi.asgi_typing: a2wsgi + a2wsgi.wsgi: a2wsgi + a2wsgi.wsgi_typing: a2wsgi + aiosmtplib: aiosmtplib + aiosmtplib.api: aiosmtplib + aiosmtplib.auth: aiosmtplib + aiosmtplib.email: aiosmtplib + aiosmtplib.errors: aiosmtplib + aiosmtplib.esmtp: aiosmtplib + aiosmtplib.protocol: aiosmtplib + aiosmtplib.response: aiosmtplib + aiosmtplib.smtp: aiosmtplib + aiosmtplib.status: aiosmtplib + aiosmtplib.typing: aiosmtplib + aiosqlite: aiosqlite + aiosqlite.context: aiosqlite + aiosqlite.core: aiosqlite + aiosqlite.cursor: aiosqlite + aiosqlite.tests: aiosqlite + aiosqlite.tests.helpers: aiosqlite + aiosqlite.tests.perf: aiosqlite + aiosqlite.tests.smoke: aiosqlite + airflow: apache_airflow_core + airflow.api: apache_airflow_core + airflow.api.client: apache_airflow_core + airflow.api.client.local_client: apache_airflow_core + airflow.api.common: apache_airflow_core + airflow.api.common.airflow_health: apache_airflow_core + airflow.api.common.delete_dag: apache_airflow_core + airflow.api.common.mark_tasks: apache_airflow_core + airflow.api.common.trigger_dag: apache_airflow_core + airflow.api_fastapi: apache_airflow_core + airflow.api_fastapi.app: apache_airflow_core + airflow.api_fastapi.auth: apache_airflow_core + airflow.api_fastapi.auth.managers: apache_airflow_core + airflow.api_fastapi.auth.managers.base_auth_manager: apache_airflow_core + airflow.api_fastapi.auth.managers.models: apache_airflow_core + airflow.api_fastapi.auth.managers.models.base_user: apache_airflow_core + airflow.api_fastapi.auth.managers.models.batch_apis: apache_airflow_core + airflow.api_fastapi.auth.managers.models.resource_details: apache_airflow_core + airflow.api_fastapi.auth.managers.simple: apache_airflow_core + airflow.api_fastapi.auth.managers.simple.datamodels: apache_airflow_core + airflow.api_fastapi.auth.managers.simple.datamodels.login: apache_airflow_core + airflow.api_fastapi.auth.managers.simple.middleware: apache_airflow_core + airflow.api_fastapi.auth.managers.simple.openapi: apache_airflow_core + airflow.api_fastapi.auth.managers.simple.routes: apache_airflow_core + airflow.api_fastapi.auth.managers.simple.routes.login: apache_airflow_core + airflow.api_fastapi.auth.managers.simple.services: apache_airflow_core + airflow.api_fastapi.auth.managers.simple.services.login: apache_airflow_core + airflow.api_fastapi.auth.managers.simple.simple_auth_manager: apache_airflow_core + airflow.api_fastapi.auth.managers.simple.user: apache_airflow_core + airflow.api_fastapi.auth.managers.simple.utils: apache_airflow_core + airflow.api_fastapi.auth.tokens: apache_airflow_core + airflow.api_fastapi.common: apache_airflow_core + airflow.api_fastapi.common.dagbag: apache_airflow_core + airflow.api_fastapi.common.db: apache_airflow_core + airflow.api_fastapi.common.db.common: apache_airflow_core + airflow.api_fastapi.common.db.dag_runs: apache_airflow_core + airflow.api_fastapi.common.db.dags: apache_airflow_core + airflow.api_fastapi.common.exceptions: apache_airflow_core + airflow.api_fastapi.common.headers: apache_airflow_core + airflow.api_fastapi.common.parameters: apache_airflow_core + airflow.api_fastapi.common.router: apache_airflow_core + airflow.api_fastapi.common.types: apache_airflow_core + airflow.api_fastapi.core_api: apache_airflow_core + airflow.api_fastapi.core_api.app: apache_airflow_core + airflow.api_fastapi.core_api.base: apache_airflow_core + airflow.api_fastapi.core_api.datamodels: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.assets: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.backfills: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.common: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.config: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.connections: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.dag_report: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.dag_run: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.dag_sources: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.dag_stats: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.dag_tags: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.dag_versions: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.dag_warning: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.dags: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.event_logs: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.extra_links: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.hitl: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.import_error: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.job: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.log: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.monitor: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.plugins: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.pools: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.providers: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.task_instances: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.tasks: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.trigger: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.ui: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.ui.auth: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.ui.calendar: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.ui.common: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.ui.config: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.ui.dag_runs: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.ui.dags: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.ui.dashboard: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.ui.grid: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.ui.structure: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.variables: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.version: apache_airflow_core + airflow.api_fastapi.core_api.datamodels.xcom: apache_airflow_core + airflow.api_fastapi.core_api.openapi: apache_airflow_core + airflow.api_fastapi.core_api.openapi.exceptions: apache_airflow_core + airflow.api_fastapi.core_api.routes: apache_airflow_core + airflow.api_fastapi.core_api.routes.public: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.assets: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.auth: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.backfills: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.config: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.connections: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.dag_parsing: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.dag_report: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.dag_run: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.dag_sources: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.dag_stats: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.dag_tags: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.dag_versions: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.dag_warning: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.dags: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.event_logs: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.extra_links: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.hitl: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.import_error: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.job: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.log: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.monitor: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.plugins: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.pools: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.providers: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.task_instances: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.tasks: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.variables: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.version: apache_airflow_core + airflow.api_fastapi.core_api.routes.public.xcom: apache_airflow_core + airflow.api_fastapi.core_api.routes.ui: apache_airflow_core + airflow.api_fastapi.core_api.routes.ui.assets: apache_airflow_core + airflow.api_fastapi.core_api.routes.ui.auth: apache_airflow_core + airflow.api_fastapi.core_api.routes.ui.backfills: apache_airflow_core + airflow.api_fastapi.core_api.routes.ui.calendar: apache_airflow_core + airflow.api_fastapi.core_api.routes.ui.config: apache_airflow_core + airflow.api_fastapi.core_api.routes.ui.connections: apache_airflow_core + airflow.api_fastapi.core_api.routes.ui.dags: apache_airflow_core + airflow.api_fastapi.core_api.routes.ui.dashboard: apache_airflow_core + airflow.api_fastapi.core_api.routes.ui.dependencies: apache_airflow_core + airflow.api_fastapi.core_api.routes.ui.grid: apache_airflow_core + airflow.api_fastapi.core_api.routes.ui.structure: apache_airflow_core + airflow.api_fastapi.core_api.security: apache_airflow_core + airflow.api_fastapi.core_api.services: apache_airflow_core + airflow.api_fastapi.core_api.services.public: apache_airflow_core + airflow.api_fastapi.core_api.services.public.common: apache_airflow_core + airflow.api_fastapi.core_api.services.public.config: apache_airflow_core + airflow.api_fastapi.core_api.services.public.connections: apache_airflow_core + airflow.api_fastapi.core_api.services.public.dag_run: apache_airflow_core + airflow.api_fastapi.core_api.services.public.pools: apache_airflow_core + airflow.api_fastapi.core_api.services.public.providers: apache_airflow_core + airflow.api_fastapi.core_api.services.public.task_instances: apache_airflow_core + airflow.api_fastapi.core_api.services.public.variables: apache_airflow_core + airflow.api_fastapi.core_api.services.ui: apache_airflow_core + airflow.api_fastapi.core_api.services.ui.calendar: apache_airflow_core + airflow.api_fastapi.core_api.services.ui.connections: apache_airflow_core + airflow.api_fastapi.core_api.services.ui.dependencies: apache_airflow_core + airflow.api_fastapi.core_api.services.ui.grid: apache_airflow_core + airflow.api_fastapi.core_api.services.ui.structure: apache_airflow_core + airflow.api_fastapi.core_api.services.ui.task_group: apache_airflow_core + airflow.api_fastapi.execution_api: apache_airflow_core + airflow.api_fastapi.execution_api.app: apache_airflow_core + airflow.api_fastapi.execution_api.datamodels: apache_airflow_core + airflow.api_fastapi.execution_api.datamodels.asset: apache_airflow_core + airflow.api_fastapi.execution_api.datamodels.asset_event: apache_airflow_core + airflow.api_fastapi.execution_api.datamodels.connection: apache_airflow_core + airflow.api_fastapi.execution_api.datamodels.dagrun: apache_airflow_core + airflow.api_fastapi.execution_api.datamodels.hitl: apache_airflow_core + airflow.api_fastapi.execution_api.datamodels.taskinstance: apache_airflow_core + airflow.api_fastapi.execution_api.datamodels.token: apache_airflow_core + airflow.api_fastapi.execution_api.datamodels.variable: apache_airflow_core + airflow.api_fastapi.execution_api.datamodels.xcom: apache_airflow_core + airflow.api_fastapi.execution_api.deps: apache_airflow_core + airflow.api_fastapi.execution_api.routes: apache_airflow_core + airflow.api_fastapi.execution_api.routes.asset_events: apache_airflow_core + airflow.api_fastapi.execution_api.routes.assets: apache_airflow_core + airflow.api_fastapi.execution_api.routes.connections: apache_airflow_core + airflow.api_fastapi.execution_api.routes.dag_runs: apache_airflow_core + airflow.api_fastapi.execution_api.routes.health: apache_airflow_core + airflow.api_fastapi.execution_api.routes.hitl: apache_airflow_core + airflow.api_fastapi.execution_api.routes.task_instances: apache_airflow_core + airflow.api_fastapi.execution_api.routes.task_reschedules: apache_airflow_core + airflow.api_fastapi.execution_api.routes.variables: apache_airflow_core + airflow.api_fastapi.execution_api.routes.xcoms: apache_airflow_core + airflow.api_fastapi.execution_api.versions: apache_airflow_core + airflow.api_fastapi.execution_api.versions.v2025_04_28: apache_airflow_core + airflow.api_fastapi.execution_api.versions.v2025_05_20: apache_airflow_core + airflow.api_fastapi.execution_api.versions.v2025_08_10: apache_airflow_core + airflow.api_fastapi.execution_api.versions.v2025_09_23: apache_airflow_core + airflow.api_fastapi.logging: apache_airflow_core + airflow.api_fastapi.logging.decorators: apache_airflow_core + airflow.api_fastapi.main: apache_airflow_core + airflow.assets: apache_airflow_core + airflow.assets.evaluation: apache_airflow_core + airflow.assets.manager: apache_airflow_core + airflow.callbacks: apache_airflow_core + airflow.callbacks.base_callback_sink: apache_airflow_core + airflow.callbacks.callback_requests: apache_airflow_core + airflow.callbacks.database_callback_sink: apache_airflow_core + airflow.cli: apache_airflow_core + airflow.cli.cli_config: apache_airflow_core + airflow.cli.cli_parser: apache_airflow_core + airflow.cli.commands: apache_airflow_core + airflow.cli.commands.api_server_command: apache_airflow_core + airflow.cli.commands.asset_command: apache_airflow_core + airflow.cli.commands.backfill_command: apache_airflow_core + airflow.cli.commands.cheat_sheet_command: apache_airflow_core + airflow.cli.commands.config_command: apache_airflow_core + airflow.cli.commands.connection_command: apache_airflow_core + airflow.cli.commands.daemon_utils: apache_airflow_core + airflow.cli.commands.dag_command: apache_airflow_core + airflow.cli.commands.dag_processor_command: apache_airflow_core + airflow.cli.commands.db_command: apache_airflow_core + airflow.cli.commands.db_manager_command: apache_airflow_core + airflow.cli.commands.info_command: apache_airflow_core + airflow.cli.commands.jobs_command: apache_airflow_core + airflow.cli.commands.kerberos_command: apache_airflow_core + airflow.cli.commands.legacy_commands: apache_airflow_core + airflow.cli.commands.plugins_command: apache_airflow_core + airflow.cli.commands.pool_command: apache_airflow_core + airflow.cli.commands.provider_command: apache_airflow_core + airflow.cli.commands.rotate_fernet_key_command: apache_airflow_core + airflow.cli.commands.scheduler_command: apache_airflow_core + airflow.cli.commands.standalone_command: apache_airflow_core + airflow.cli.commands.task_command: apache_airflow_core + airflow.cli.commands.triggerer_command: apache_airflow_core + airflow.cli.commands.variable_command: apache_airflow_core + airflow.cli.commands.version_command: apache_airflow_core + airflow.cli.simple_table: apache_airflow_core + airflow.cli.utils: apache_airflow_core + airflow.config_templates: apache_airflow_core + airflow.config_templates.airflow_local_settings: apache_airflow_core + airflow.config_templates.default_webserver_config: apache_airflow_core + airflow.configuration: apache_airflow_core + airflow.dag_processing: apache_airflow_core + airflow.dag_processing.bundles: apache_airflow_core + airflow.dag_processing.bundles.base: apache_airflow_core + airflow.dag_processing.bundles.local: apache_airflow_core + airflow.dag_processing.bundles.manager: apache_airflow_core + airflow.dag_processing.collection: apache_airflow_core + airflow.dag_processing.manager: apache_airflow_core + airflow.dag_processing.processor: apache_airflow_core + airflow.datasets: apache_airflow_core + airflow.datasets.metadata: apache_airflow_core + airflow.decorators: apache_airflow_core + airflow.example_dags: apache_airflow_core + airflow.example_dags.example_asset_alias: apache_airflow_core + airflow.example_dags.example_asset_alias_with_no_taskflow: apache_airflow_core + airflow.example_dags.example_asset_decorator: apache_airflow_core + airflow.example_dags.example_asset_with_watchers: apache_airflow_core + airflow.example_dags.example_assets: apache_airflow_core + airflow.example_dags.example_branch_labels: apache_airflow_core + airflow.example_dags.example_branch_python_dop_operator_3: apache_airflow_core + airflow.example_dags.example_complex: apache_airflow_core + airflow.example_dags.example_custom_weight: apache_airflow_core + airflow.example_dags.example_dag_decorator: apache_airflow_core + airflow.example_dags.example_display_name: apache_airflow_core + airflow.example_dags.example_dynamic_task_mapping: apache_airflow_core + airflow.example_dags.example_dynamic_task_mapping_with_no_taskflow_operators: apache_airflow_core + airflow.example_dags.example_inlet_event_extra: apache_airflow_core + airflow.example_dags.example_kubernetes_executor: apache_airflow_core + airflow.example_dags.example_latest_only_with_trigger: apache_airflow_core + airflow.example_dags.example_local_kubernetes_executor: apache_airflow_core + airflow.example_dags.example_nested_branch_dag: apache_airflow_core + airflow.example_dags.example_outlet_event_extra: apache_airflow_core + airflow.example_dags.example_params_trigger_ui: apache_airflow_core + airflow.example_dags.example_params_ui_tutorial: apache_airflow_core + airflow.example_dags.example_passing_params_via_test_command: apache_airflow_core + airflow.example_dags.example_setup_teardown: apache_airflow_core + airflow.example_dags.example_setup_teardown_taskflow: apache_airflow_core + airflow.example_dags.example_simplest_dag: apache_airflow_core + airflow.example_dags.example_skip_dag: apache_airflow_core + airflow.example_dags.example_task_group: apache_airflow_core + airflow.example_dags.example_task_group_decorator: apache_airflow_core + airflow.example_dags.example_time_delta_sensor_async: apache_airflow_core + airflow.example_dags.example_trigger_target_dag: apache_airflow_core + airflow.example_dags.example_workday_timetable: apache_airflow_core + airflow.example_dags.example_xcom: apache_airflow_core + airflow.example_dags.example_xcomargs: apache_airflow_core + airflow.example_dags.libs: apache_airflow_core + airflow.example_dags.libs.helper: apache_airflow_core + airflow.example_dags.plugins: apache_airflow_core + airflow.example_dags.plugins.decreasing_priority_weight_strategy: apache_airflow_core + airflow.example_dags.plugins.event_listener: apache_airflow_core + airflow.example_dags.plugins.listener_plugin: apache_airflow_core + airflow.example_dags.plugins.workday: apache_airflow_core + airflow.example_dags.standard: apache_airflow_core + airflow.example_dags.standard.example_bash_decorator: apache_airflow_core + airflow.example_dags.standard.example_bash_operator: apache_airflow_core + airflow.example_dags.standard.example_branch_datetime_operator: apache_airflow_core + airflow.example_dags.standard.example_branch_day_of_week_operator: apache_airflow_core + airflow.example_dags.standard.example_branch_operator: apache_airflow_core + airflow.example_dags.standard.example_branch_operator_decorator: apache_airflow_core + airflow.example_dags.standard.example_external_task_child_deferrable: apache_airflow_core + airflow.example_dags.standard.example_external_task_marker_dag: apache_airflow_core + airflow.example_dags.standard.example_external_task_parent_deferrable: apache_airflow_core + airflow.example_dags.standard.example_hitl_operator: apache_airflow_core + airflow.example_dags.standard.example_latest_only: apache_airflow_core + airflow.example_dags.standard.example_python_decorator: apache_airflow_core + airflow.example_dags.standard.example_python_operator: apache_airflow_core + airflow.example_dags.standard.example_sensor_decorator: apache_airflow_core + airflow.example_dags.standard.example_sensors: apache_airflow_core + airflow.example_dags.standard.example_short_circuit_decorator: apache_airflow_core + airflow.example_dags.standard.example_short_circuit_operator: apache_airflow_core + airflow.example_dags.standard.example_trigger_controller_dag: apache_airflow_core + airflow.example_dags.standard.sql: apache_airflow_core + airflow.example_dags.tutorial: apache_airflow_core + airflow.example_dags.tutorial_dag: apache_airflow_core + airflow.example_dags.tutorial_objectstorage: apache_airflow_core + airflow.example_dags.tutorial_taskflow_api: apache_airflow_core + airflow.example_dags.tutorial_taskflow_api_virtualenv: apache_airflow_core + airflow.example_dags.tutorial_taskflow_templates: apache_airflow_core + airflow.exceptions: apache_airflow_core + airflow.executors: apache_airflow_core + airflow.executors.base_executor: apache_airflow_core + airflow.executors.executor_constants: apache_airflow_core + airflow.executors.executor_loader: apache_airflow_core + airflow.executors.executor_utils: apache_airflow_core + airflow.executors.local_executor: apache_airflow_core + airflow.executors.workloads: apache_airflow_core + airflow.hooks: apache_airflow_core + airflow.hooks.base: apache_airflow_core + airflow.io: apache_airflow_core + airflow.jobs: apache_airflow_core + airflow.jobs.base_job_runner: apache_airflow_core + airflow.jobs.dag_processor_job_runner: apache_airflow_core + airflow.jobs.job: apache_airflow_core + airflow.jobs.scheduler_job_runner: apache_airflow_core + airflow.jobs.triggerer_job_runner: apache_airflow_core + airflow.lineage: apache_airflow_core + airflow.lineage.hook: apache_airflow_core + airflow.listeners: apache_airflow_core + airflow.listeners.listener: apache_airflow_core + airflow.listeners.spec: apache_airflow_core + airflow.listeners.spec.asset: apache_airflow_core + airflow.listeners.spec.dagrun: apache_airflow_core + airflow.listeners.spec.importerrors: apache_airflow_core + airflow.listeners.spec.lifecycle: apache_airflow_core + airflow.listeners.spec.taskinstance: apache_airflow_core + airflow.logging: apache_airflow_core + airflow.logging.remote: apache_airflow_core + airflow.logging_config: apache_airflow_core + airflow.macros: apache_airflow_core + airflow.metrics: apache_airflow_core + airflow.metrics.base_stats_logger: apache_airflow_core + airflow.metrics.datadog_logger: apache_airflow_core + airflow.metrics.otel_logger: apache_airflow_core + airflow.metrics.protocols: apache_airflow_core + airflow.metrics.statsd_logger: apache_airflow_core + airflow.metrics.validators: apache_airflow_core + airflow.migrations: apache_airflow_core + airflow.migrations.db_types: apache_airflow_core + airflow.migrations.env: apache_airflow_core + airflow.migrations.utils: apache_airflow_core + airflow.migrations.versions: apache_airflow_core + airflow.migrations.versions.0001_2_7_0_add_index_to_task_instance_table: apache_airflow_core + airflow.migrations.versions.0002_2_7_0_add_custom_operator_name_column: apache_airflow_core + airflow.migrations.versions.0003_2_7_0_add_include_deferred_column_to_pool: apache_airflow_core + airflow.migrations.versions.0004_2_8_0_add_clear_number_to_dag_run: apache_airflow_core + airflow.migrations.versions.0005_2_8_0_add_owner_display_name_to_audit_log_table: apache_airflow_core + airflow.migrations.versions.0006_2_8_0_make_connection_login_password_text: apache_airflow_core + airflow.migrations.versions.0007_2_8_0_add_processor_subdir_import_error: apache_airflow_core + airflow.migrations.versions.0008_2_8_1_refactor_dag_run_indexes: apache_airflow_core + airflow.migrations.versions.0009_2_9_0_add_rendered_map_index_to_taskinstance: apache_airflow_core + airflow.migrations.versions.0010_2_9_0_add_run_id_to_audit_log_table_and_change_event_name_length: apache_airflow_core + airflow.migrations.versions.0011_2_9_0_add_dataset_expression_in_dagmodel: apache_airflow_core + airflow.migrations.versions.0012_2_9_0_adding_adding_max_failure_runs_column_: apache_airflow_core + airflow.migrations.versions.0013_2_9_0_make_xcom_value_to_longblob_for_mysql: apache_airflow_core + airflow.migrations.versions.0014_2_9_0_add_display_name_for_dag_and_task_: apache_airflow_core + airflow.migrations.versions.0015_2_9_0_update_trigger_kwargs_type: apache_airflow_core + airflow.migrations.versions.0016_2_9_2_remove_idx_last_scheduling_decision_: apache_airflow_core + airflow.migrations.versions.0017_2_9_2_fix_inconsistency_between_ORM_and_migration_files: apache_airflow_core + airflow.migrations.versions.0018_2_10_0_add_indexes_on_dag_id_column_in_referencing_tables: apache_airflow_core + airflow.migrations.versions.0019_2_10_0_add_new_executor_field_to_db: apache_airflow_core + airflow.migrations.versions.0020_2_10_0_added_dagpriorityparsingrequest_table: apache_airflow_core + airflow.migrations.versions.0021_2_10_0_add_task_instance_history: apache_airflow_core + airflow.migrations.versions.0022_2_10_0_add_dataset_alias: apache_airflow_core + airflow.migrations.versions.0023_2_10_0_dataset_alias_dataset_event: apache_airflow_core + airflow.migrations.versions.0024_2_10_0_add_try_number_to_audit_log: apache_airflow_core + airflow.migrations.versions.0025_2_10_0_dataset_alias_dataset: apache_airflow_core + airflow.migrations.versions.0026_2_10_0_dag_schedule_dataset_alias_reference: apache_airflow_core + airflow.migrations.versions.0027_2_10_3_fix_dag_schedule_dataset_alias_reference_naming: apache_airflow_core + airflow.migrations.versions.0028_3_0_0_drop_ab_user_id_foreign_key: apache_airflow_core + airflow.migrations.versions.0029_3_0_0_remove_is_subdag: apache_airflow_core + airflow.migrations.versions.0030_3_0_0_rename_schedule_interval_to_timetable_: apache_airflow_core + airflow.migrations.versions.0031_3_0_0_add_triggered_by_field_to_dagrun: apache_airflow_core + airflow.migrations.versions.0032_3_0_0_rename_execution_date_to_logical_date_and_nullable: apache_airflow_core + airflow.migrations.versions.0033_3_0_0_add_tables_for_backfill: apache_airflow_core + airflow.migrations.versions.0034_3_0_0_remove_redundant_index: apache_airflow_core + airflow.migrations.versions.0035_3_0_0_update_user_id_type: apache_airflow_core + airflow.migrations.versions.0036_3_0_0_add_name_field_to_dataset_model: apache_airflow_core + airflow.migrations.versions.0037_3_0_0_add_backfill_to_dag_run_model: apache_airflow_core + airflow.migrations.versions.0038_3_0_0_add_asset_active: apache_airflow_core + airflow.migrations.versions.0039_3_0_0_tweak_assetaliasmodel_to_match_asset: apache_airflow_core + airflow.migrations.versions.0040_3_0_0_add_exception_reason_and_logical_date_: apache_airflow_core + airflow.migrations.versions.0041_3_0_0_rename_dataset_as_asset: apache_airflow_core + airflow.migrations.versions.0042_3_0_0_add_uuid_primary_key_to_task_instance_: apache_airflow_core + airflow.migrations.versions.0043_3_0_0_remove_scheduler_lock_column: apache_airflow_core + airflow.migrations.versions.0044_3_0_0__drop_task_fail_table: apache_airflow_core + airflow.migrations.versions.0045_3_0_0_add_last_heartbeat_at_directly_to_ti: apache_airflow_core + airflow.migrations.versions.0046_3_0_0_drop_dag_pickling: apache_airflow_core + airflow.migrations.versions.0047_3_0_0_add_dag_versioning: apache_airflow_core + airflow.migrations.versions.0048_3_0_0_add_trigger_asset_reference: apache_airflow_core + airflow.migrations.versions.0049_3_0_0_remove_pickled_data_from_xcom_table: apache_airflow_core + airflow.migrations.versions.0050_3_0_0_add_dagbundlemodel: apache_airflow_core + airflow.migrations.versions.0051_3_0_0_update_task_instance_trigger_timeout_to_utcdatetime: apache_airflow_core + airflow.migrations.versions.0052_3_0_0_add_deadline_alerts_table: apache_airflow_core + airflow.migrations.versions.0053_3_0_0_remove_processor_subdir: apache_airflow_core + airflow.migrations.versions.0054_3_0_0_add_asset_reference_models: apache_airflow_core + airflow.migrations.versions.0055_3_0_0_remove_pickled_data_from_dagrun_table: apache_airflow_core + airflow.migrations.versions.0056_3_0_0_add_relative_fileloc_column: apache_airflow_core + airflow.migrations.versions.0057_3_0_0_add_new_task_instance_field_scheduled_: apache_airflow_core + airflow.migrations.versions.0058_3_0_0_add_dagrun_run_after: apache_airflow_core + airflow.migrations.versions.0059_3_0_0_remove_external_trigger_field: apache_airflow_core + airflow.migrations.versions.0060_3_0_0_add_try_id_to_ti_and_tih: apache_airflow_core + airflow.migrations.versions.0061_3_0_0_use_ti_id_as_primary_key_to_TINote: apache_airflow_core + airflow.migrations.versions.0062_3_0_0_remove_dag_default_view: apache_airflow_core + airflow.migrations.versions.0063_3_0_0_use_ti_id_as_fk_to_taskreschedule: apache_airflow_core + airflow.migrations.versions.0064_3_0_0_support_bundles_in_: apache_airflow_core + airflow.migrations.versions.0065_3_0_0_add_new_otel_span_fields: apache_airflow_core + airflow.migrations.versions.0066_3_0_0_rename_dataset_triggered_to_asset_triggered: apache_airflow_core + airflow.migrations.versions.0067_3_0_0_rename_is_active_to_is_stale_column_in_: apache_airflow_core + airflow.migrations.versions.0068_3_0_0_ti_table_id_unique_per_try: apache_airflow_core + airflow.migrations.versions.0069_3_0_3_delete_import_errors: apache_airflow_core + airflow.migrations.versions.0070_3_1_0_add_deadline_to_dag: apache_airflow_core + airflow.migrations.versions.0071_3_1_0_rename_and_change_type_of_deadline_column: apache_airflow_core + airflow.migrations.versions.0072_3_1_0_change_ti_dag_version_fk_to_restrict: apache_airflow_core + airflow.migrations.versions.0073_3_1_0_add_task_inlet_asset_reference: apache_airflow_core + airflow.migrations.versions.0074_3_1_0_add_triggering_user_to_dag_run: apache_airflow_core + airflow.migrations.versions.0075_3_1_0_add_dag_favorite_table: apache_airflow_core + airflow.migrations.versions.0076_3_1_0_add_human_in_the_loop_response: apache_airflow_core + airflow.migrations.versions.0077_3_1_0_add_trigger_id_to_deadline: apache_airflow_core + airflow.migrations.versions.0078_3_1_0_add_callback_state_to_deadline: apache_airflow_core + airflow.migrations.versions.0079_3_1_0_add_url_and_template_params_to_dagbundle_model: apache_airflow_core + airflow.migrations.versions.0080_3_1_0_modify_deadline_callback_schema: apache_airflow_core + airflow.migrations.versions.0081_3_1_0_remove_dag_id_from_deadline: apache_airflow_core + airflow.migrations.versions.0082_3_1_0_make_bundle_name_not_nullable: apache_airflow_core + airflow.migrations.versions.0083_3_1_0_add_teams: apache_airflow_core + airflow.migrations.versions.0084_3_1_0_add_last_parse_duration_to_dag_model: apache_airflow_core + airflow.migrations.versions.0085_3_1_0_downgrade_serialized_dag_version_to_v2: apache_airflow_core + airflow.models: apache_airflow_core + airflow.models.asset: apache_airflow_core + airflow.models.backfill: apache_airflow_core + airflow.models.base: apache_airflow_core + airflow.models.connection: apache_airflow_core + airflow.models.crypto: apache_airflow_core + airflow.models.dag: apache_airflow_core + airflow.models.dag_favorite: apache_airflow_core + airflow.models.dag_version: apache_airflow_core + airflow.models.dagbag: apache_airflow_core + airflow.models.dagbundle: apache_airflow_core + airflow.models.dagcode: apache_airflow_core + airflow.models.dagrun: apache_airflow_core + airflow.models.dagwarning: apache_airflow_core + airflow.models.db_callback_request: apache_airflow_core + airflow.models.deadline: apache_airflow_core + airflow.models.errors: apache_airflow_core + airflow.models.expandinput: apache_airflow_core + airflow.models.hitl: apache_airflow_core + airflow.models.log: apache_airflow_core + airflow.models.mappedoperator: apache_airflow_core + airflow.models.pool: apache_airflow_core + airflow.models.referencemixin: apache_airflow_core + airflow.models.renderedtifields: apache_airflow_core + airflow.models.serialized_dag: apache_airflow_core + airflow.models.skipmixin: apache_airflow_core + airflow.models.taskinstance: apache_airflow_core + airflow.models.taskinstancehistory: apache_airflow_core + airflow.models.taskinstancekey: apache_airflow_core + airflow.models.tasklog: apache_airflow_core + airflow.models.taskmap: apache_airflow_core + airflow.models.taskmixin: apache_airflow_core + airflow.models.taskreschedule: apache_airflow_core + airflow.models.team: apache_airflow_core + airflow.models.trigger: apache_airflow_core + airflow.models.variable: apache_airflow_core + airflow.models.xcom: apache_airflow_core + airflow.models.xcom_arg: apache_airflow_core + airflow.notifications: apache_airflow_core + airflow.operators: apache_airflow_core + airflow.plugins_manager: apache_airflow_core + airflow.policies: apache_airflow_core + airflow.providers.common.compat: apache_airflow_providers_common_compat + airflow.providers.common.compat.assets: apache_airflow_providers_common_compat + airflow.providers.common.compat.check: apache_airflow_providers_common_compat + airflow.providers.common.compat.get_provider_info: apache_airflow_providers_common_compat + airflow.providers.common.compat.lineage: apache_airflow_providers_common_compat + airflow.providers.common.compat.lineage.entities: apache_airflow_providers_common_compat + airflow.providers.common.compat.lineage.hook: apache_airflow_providers_common_compat + airflow.providers.common.compat.notifier: apache_airflow_providers_common_compat + airflow.providers.common.compat.openlineage: apache_airflow_providers_common_compat + airflow.providers.common.compat.openlineage.check: apache_airflow_providers_common_compat + airflow.providers.common.compat.openlineage.facet: apache_airflow_providers_common_compat + airflow.providers.common.compat.openlineage.utils: apache_airflow_providers_common_compat + airflow.providers.common.compat.openlineage.utils.spark: apache_airflow_providers_common_compat + airflow.providers.common.compat.openlineage.utils.sql: apache_airflow_providers_common_compat + airflow.providers.common.compat.openlineage.utils.utils: apache_airflow_providers_common_compat + airflow.providers.common.compat.security: apache_airflow_providers_common_compat + airflow.providers.common.compat.security.permissions: apache_airflow_providers_common_compat + airflow.providers.common.compat.standard: apache_airflow_providers_common_compat + airflow.providers.common.compat.standard.operators: apache_airflow_providers_common_compat + airflow.providers.common.compat.standard.triggers: apache_airflow_providers_common_compat + airflow.providers.common.compat.standard.utils: apache_airflow_providers_common_compat + airflow.providers.common.compat.version_compat: apache_airflow_providers_common_compat + airflow.providers.common.io: apache_airflow_providers_common_io + airflow.providers.common.io.assets: apache_airflow_providers_common_io + airflow.providers.common.io.assets.assets: apache_airflow_providers_common_io + airflow.providers.common.io.assets.file: apache_airflow_providers_common_io + airflow.providers.common.io.get_provider_info: apache_airflow_providers_common_io + airflow.providers.common.io.operators: apache_airflow_providers_common_io + airflow.providers.common.io.operators.file_transfer: apache_airflow_providers_common_io + airflow.providers.common.io.version_compat: apache_airflow_providers_common_io + airflow.providers.common.io.xcom: apache_airflow_providers_common_io + airflow.providers.common.io.xcom.backend: apache_airflow_providers_common_io + airflow.providers.common.sql: apache_airflow_providers_common_sql + airflow.providers.common.sql.dialects: apache_airflow_providers_common_sql + airflow.providers.common.sql.dialects.dialect: apache_airflow_providers_common_sql + airflow.providers.common.sql.get_provider_info: apache_airflow_providers_common_sql + airflow.providers.common.sql.hooks: apache_airflow_providers_common_sql + airflow.providers.common.sql.hooks.handlers: apache_airflow_providers_common_sql + airflow.providers.common.sql.hooks.sql: apache_airflow_providers_common_sql + airflow.providers.common.sql.operators: apache_airflow_providers_common_sql + airflow.providers.common.sql.operators.generic_transfer: apache_airflow_providers_common_sql + airflow.providers.common.sql.operators.sql: apache_airflow_providers_common_sql + airflow.providers.common.sql.sensors: apache_airflow_providers_common_sql + airflow.providers.common.sql.sensors.sql: apache_airflow_providers_common_sql + airflow.providers.common.sql.triggers: apache_airflow_providers_common_sql + airflow.providers.common.sql.triggers.sql: apache_airflow_providers_common_sql + airflow.providers.common.sql.version_compat: apache_airflow_providers_common_sql + airflow.providers.smtp: apache_airflow_providers_smtp + airflow.providers.smtp.get_provider_info: apache_airflow_providers_smtp + airflow.providers.smtp.hooks: apache_airflow_providers_smtp + airflow.providers.smtp.hooks.smtp: apache_airflow_providers_smtp + airflow.providers.smtp.notifications: apache_airflow_providers_smtp + airflow.providers.smtp.notifications.smtp: apache_airflow_providers_smtp + airflow.providers.smtp.notifications.templates: apache_airflow_providers_smtp + airflow.providers.smtp.operators: apache_airflow_providers_smtp + airflow.providers.smtp.operators.smtp: apache_airflow_providers_smtp + airflow.providers.smtp.version_compat: apache_airflow_providers_smtp + airflow.providers.sqlite: apache_airflow_providers_sqlite + airflow.providers.sqlite.get_provider_info: apache_airflow_providers_sqlite + airflow.providers.sqlite.hooks: apache_airflow_providers_sqlite + airflow.providers.sqlite.hooks.sqlite: apache_airflow_providers_sqlite + airflow.providers.standard: apache_airflow_providers_standard + airflow.providers.standard.decorators: apache_airflow_providers_standard + airflow.providers.standard.decorators.bash: apache_airflow_providers_standard + airflow.providers.standard.decorators.branch_external_python: apache_airflow_providers_standard + airflow.providers.standard.decorators.branch_python: apache_airflow_providers_standard + airflow.providers.standard.decorators.branch_virtualenv: apache_airflow_providers_standard + airflow.providers.standard.decorators.external_python: apache_airflow_providers_standard + airflow.providers.standard.decorators.python: apache_airflow_providers_standard + airflow.providers.standard.decorators.python_virtualenv: apache_airflow_providers_standard + airflow.providers.standard.decorators.sensor: apache_airflow_providers_standard + airflow.providers.standard.decorators.short_circuit: apache_airflow_providers_standard + airflow.providers.standard.decorators.stub: apache_airflow_providers_standard + airflow.providers.standard.example_dags: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_bash_decorator: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_bash_operator: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_branch_datetime_operator: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_branch_day_of_week_operator: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_branch_operator: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_branch_operator_decorator: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_external_task_child_deferrable: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_external_task_marker_dag: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_external_task_parent_deferrable: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_hitl_operator: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_latest_only: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_python_decorator: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_python_operator: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_sensor_decorator: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_sensors: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_short_circuit_decorator: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_short_circuit_operator: apache_airflow_providers_standard + airflow.providers.standard.example_dags.example_trigger_controller_dag: apache_airflow_providers_standard + airflow.providers.standard.example_dags.sql: apache_airflow_providers_standard + airflow.providers.standard.exceptions: apache_airflow_providers_standard + airflow.providers.standard.get_provider_info: apache_airflow_providers_standard + airflow.providers.standard.hooks: apache_airflow_providers_standard + airflow.providers.standard.hooks.filesystem: apache_airflow_providers_standard + airflow.providers.standard.hooks.package_index: apache_airflow_providers_standard + airflow.providers.standard.hooks.subprocess: apache_airflow_providers_standard + airflow.providers.standard.models: apache_airflow_providers_standard + airflow.providers.standard.operators: apache_airflow_providers_standard + airflow.providers.standard.operators.bash: apache_airflow_providers_standard + airflow.providers.standard.operators.branch: apache_airflow_providers_standard + airflow.providers.standard.operators.datetime: apache_airflow_providers_standard + airflow.providers.standard.operators.empty: apache_airflow_providers_standard + airflow.providers.standard.operators.hitl: apache_airflow_providers_standard + airflow.providers.standard.operators.latest_only: apache_airflow_providers_standard + airflow.providers.standard.operators.python: apache_airflow_providers_standard + airflow.providers.standard.operators.smooth: apache_airflow_providers_standard + airflow.providers.standard.operators.trigger_dagrun: apache_airflow_providers_standard + airflow.providers.standard.operators.weekday: apache_airflow_providers_standard + airflow.providers.standard.sensors: apache_airflow_providers_standard + airflow.providers.standard.sensors.bash: apache_airflow_providers_standard + airflow.providers.standard.sensors.date_time: apache_airflow_providers_standard + airflow.providers.standard.sensors.external_task: apache_airflow_providers_standard + airflow.providers.standard.sensors.filesystem: apache_airflow_providers_standard + airflow.providers.standard.sensors.python: apache_airflow_providers_standard + airflow.providers.standard.sensors.time: apache_airflow_providers_standard + airflow.providers.standard.sensors.time_delta: apache_airflow_providers_standard + airflow.providers.standard.sensors.weekday: apache_airflow_providers_standard + airflow.providers.standard.triggers: apache_airflow_providers_standard + airflow.providers.standard.triggers.external_task: apache_airflow_providers_standard + airflow.providers.standard.triggers.file: apache_airflow_providers_standard + airflow.providers.standard.triggers.hitl: apache_airflow_providers_standard + airflow.providers.standard.triggers.temporal: apache_airflow_providers_standard + airflow.providers.standard.utils: apache_airflow_providers_standard + airflow.providers.standard.utils.python_virtualenv: apache_airflow_providers_standard + airflow.providers.standard.utils.sensor_helper: apache_airflow_providers_standard + airflow.providers.standard.utils.skipmixin: apache_airflow_providers_standard + airflow.providers.standard.utils.weekday: apache_airflow_providers_standard + airflow.providers.standard.version_compat: apache_airflow_providers_standard + airflow.providers_manager: apache_airflow_core + airflow.sdk: apache_airflow_task_sdk + airflow.sdk.api: apache_airflow_task_sdk + airflow.sdk.api.client: apache_airflow_task_sdk + airflow.sdk.api.datamodels: apache_airflow_task_sdk + airflow.sdk.api.datamodels.activities: apache_airflow_task_sdk + airflow.sdk.bases: apache_airflow_task_sdk + airflow.sdk.bases.decorator: apache_airflow_task_sdk + airflow.sdk.bases.hook: apache_airflow_task_sdk + airflow.sdk.bases.notifier: apache_airflow_task_sdk + airflow.sdk.bases.operator: apache_airflow_task_sdk + airflow.sdk.bases.operatorlink: apache_airflow_task_sdk + airflow.sdk.bases.sensor: apache_airflow_task_sdk + airflow.sdk.bases.xcom: apache_airflow_task_sdk + airflow.sdk.definitions: apache_airflow_task_sdk + airflow.sdk.definitions.asset: apache_airflow_task_sdk + airflow.sdk.definitions.asset.decorators: apache_airflow_task_sdk + airflow.sdk.definitions.asset.metadata: apache_airflow_task_sdk + airflow.sdk.definitions.connection: apache_airflow_task_sdk + airflow.sdk.definitions.context: apache_airflow_task_sdk + airflow.sdk.definitions.dag: apache_airflow_task_sdk + airflow.sdk.definitions.deadline: apache_airflow_task_sdk + airflow.sdk.definitions.decorators: apache_airflow_task_sdk + airflow.sdk.definitions.decorators.condition: apache_airflow_task_sdk + airflow.sdk.definitions.decorators.setup_teardown: apache_airflow_task_sdk + airflow.sdk.definitions.decorators.task_group: apache_airflow_task_sdk + airflow.sdk.definitions.edges: apache_airflow_task_sdk + airflow.sdk.definitions.mappedoperator: apache_airflow_task_sdk + airflow.sdk.definitions.operator_resources: apache_airflow_task_sdk + airflow.sdk.definitions.param: apache_airflow_task_sdk + airflow.sdk.definitions.taskgroup: apache_airflow_task_sdk + airflow.sdk.definitions.template: apache_airflow_task_sdk + airflow.sdk.definitions.variable: apache_airflow_task_sdk + airflow.sdk.definitions.xcom_arg: apache_airflow_task_sdk + airflow.sdk.exceptions: apache_airflow_task_sdk + airflow.sdk.execution_time: apache_airflow_task_sdk + airflow.sdk.execution_time.cache: apache_airflow_task_sdk + airflow.sdk.execution_time.callback_runner: apache_airflow_task_sdk + airflow.sdk.execution_time.comms: apache_airflow_task_sdk + airflow.sdk.execution_time.context: apache_airflow_task_sdk + airflow.sdk.execution_time.execute_workload: apache_airflow_task_sdk + airflow.sdk.execution_time.hitl: apache_airflow_task_sdk + airflow.sdk.execution_time.lazy_sequence: apache_airflow_task_sdk + airflow.sdk.execution_time.macros: apache_airflow_task_sdk + airflow.sdk.execution_time.secrets_masker: apache_airflow_task_sdk + airflow.sdk.execution_time.supervisor: apache_airflow_task_sdk + airflow.sdk.execution_time.task_runner: apache_airflow_task_sdk + airflow.sdk.execution_time.timeout: apache_airflow_task_sdk + airflow.sdk.execution_time.xcom: apache_airflow_task_sdk + airflow.sdk.io: apache_airflow_task_sdk + airflow.sdk.io.fs: apache_airflow_task_sdk + airflow.sdk.io.path: apache_airflow_task_sdk + airflow.sdk.io.stat: apache_airflow_task_sdk + airflow.sdk.io.store: apache_airflow_task_sdk + airflow.sdk.io.typedef: apache_airflow_task_sdk + airflow.sdk.log: apache_airflow_task_sdk + airflow.sdk.module_loading: apache_airflow_task_sdk + airflow.sdk.timezone: apache_airflow_task_sdk + airflow.sdk.types: apache_airflow_task_sdk + airflow.secrets: apache_airflow_core + airflow.secrets.base_secrets: apache_airflow_core + airflow.secrets.environment_variables: apache_airflow_core + airflow.secrets.local_filesystem: apache_airflow_core + airflow.secrets.metastore: apache_airflow_core + airflow.security: apache_airflow_core + airflow.security.kerberos: apache_airflow_core + airflow.security.permissions: apache_airflow_core + airflow.security.utils: apache_airflow_core + airflow.sensors: apache_airflow_core + airflow.sentry: apache_airflow_core + airflow.serialization: apache_airflow_core + airflow.serialization.dag_dependency: apache_airflow_core + airflow.serialization.definitions: apache_airflow_core + airflow.serialization.definitions.taskgroup: apache_airflow_core + airflow.serialization.enums: apache_airflow_core + airflow.serialization.helpers: apache_airflow_core + airflow.serialization.json_schema: apache_airflow_core + airflow.serialization.serde: apache_airflow_core + airflow.serialization.serialized_objects: apache_airflow_core + airflow.serialization.serializers: apache_airflow_core + airflow.serialization.serializers.bignum: apache_airflow_core + airflow.serialization.serializers.builtin: apache_airflow_core + airflow.serialization.serializers.datetime: apache_airflow_core + airflow.serialization.serializers.deltalake: apache_airflow_core + airflow.serialization.serializers.iceberg: apache_airflow_core + airflow.serialization.serializers.kubernetes: apache_airflow_core + airflow.serialization.serializers.numpy: apache_airflow_core + airflow.serialization.serializers.pandas: apache_airflow_core + airflow.serialization.serializers.pydantic: apache_airflow_core + airflow.serialization.serializers.timezone: apache_airflow_core + airflow.serialization.typing: apache_airflow_core + airflow.settings: apache_airflow_core + airflow.stats: apache_airflow_core + airflow.task: apache_airflow_core + airflow.task.priority_strategy: apache_airflow_core + airflow.task.trigger_rule: apache_airflow_core + airflow.task.weight_rule: apache_airflow_core + airflow.ti_deps: apache_airflow_core + airflow.ti_deps.dep_context: apache_airflow_core + airflow.ti_deps.dependencies_deps: apache_airflow_core + airflow.ti_deps.dependencies_states: apache_airflow_core + airflow.ti_deps.deps: apache_airflow_core + airflow.ti_deps.deps.base_ti_dep: apache_airflow_core + airflow.ti_deps.deps.dag_ti_slots_available_dep: apache_airflow_core + airflow.ti_deps.deps.dag_unpaused_dep: apache_airflow_core + airflow.ti_deps.deps.dagrun_exists_dep: apache_airflow_core + airflow.ti_deps.deps.exec_date_after_start_date_dep: apache_airflow_core + airflow.ti_deps.deps.mapped_task_expanded: apache_airflow_core + airflow.ti_deps.deps.mapped_task_upstream_dep: apache_airflow_core + airflow.ti_deps.deps.not_in_retry_period_dep: apache_airflow_core + airflow.ti_deps.deps.not_previously_skipped_dep: apache_airflow_core + airflow.ti_deps.deps.pool_slots_available_dep: apache_airflow_core + airflow.ti_deps.deps.prev_dagrun_dep: apache_airflow_core + airflow.ti_deps.deps.ready_to_reschedule: apache_airflow_core + airflow.ti_deps.deps.runnable_exec_date_dep: apache_airflow_core + airflow.ti_deps.deps.task_concurrency_dep: apache_airflow_core + airflow.ti_deps.deps.task_not_running_dep: apache_airflow_core + airflow.ti_deps.deps.trigger_rule_dep: apache_airflow_core + airflow.ti_deps.deps.valid_state_dep: apache_airflow_core + airflow.timetables: apache_airflow_core + airflow.timetables.assets: apache_airflow_core + airflow.timetables.base: apache_airflow_core + airflow.timetables.datasets: apache_airflow_core + airflow.timetables.events: apache_airflow_core + airflow.timetables.interval: apache_airflow_core + airflow.timetables.simple: apache_airflow_core + airflow.timetables.trigger: apache_airflow_core + airflow.traces: apache_airflow_core + airflow.traces.otel_tracer: apache_airflow_core + airflow.traces.tracer: apache_airflow_core + airflow.traces.utils: apache_airflow_core + airflow.triggers: apache_airflow_core + airflow.triggers.base: apache_airflow_core + airflow.triggers.deadline: apache_airflow_core + airflow.triggers.testing: apache_airflow_core + airflow.typing_compat: apache_airflow_core + airflow.utils: apache_airflow_core + airflow.utils.cli: apache_airflow_core + airflow.utils.cli_action_loggers: apache_airflow_core + airflow.utils.code_utils: apache_airflow_core + airflow.utils.context: apache_airflow_core + airflow.utils.dag_cycle_tester: apache_airflow_core + airflow.utils.dag_edges: apache_airflow_core + airflow.utils.dag_parsing_context: apache_airflow_core + airflow.utils.dates: apache_airflow_core + airflow.utils.db: apache_airflow_core + airflow.utils.db_cleanup: apache_airflow_core + airflow.utils.db_manager: apache_airflow_core + airflow.utils.deprecation_tools: apache_airflow_core + airflow.utils.docs: apache_airflow_core + airflow.utils.dot_renderer: apache_airflow_core + airflow.utils.edgemodifier: apache_airflow_core + airflow.utils.email: apache_airflow_core + airflow.utils.entry_points: apache_airflow_core + airflow.utils.event_scheduler: apache_airflow_core + airflow.utils.file: apache_airflow_core + airflow.utils.hashlib_wrapper: apache_airflow_core + airflow.utils.helpers: apache_airflow_core + airflow.utils.json: apache_airflow_core + airflow.utils.log: apache_airflow_core + airflow.utils.log.action_logger: apache_airflow_core + airflow.utils.log.colored_log: apache_airflow_core + airflow.utils.log.file_processor_handler: apache_airflow_core + airflow.utils.log.file_task_handler: apache_airflow_core + airflow.utils.log.json_formatter: apache_airflow_core + airflow.utils.log.log_reader: apache_airflow_core + airflow.utils.log.log_stream_accumulator: apache_airflow_core + airflow.utils.log.logging_mixin: apache_airflow_core + airflow.utils.log.non_caching_file_handler: apache_airflow_core + airflow.utils.log.task_handler_with_custom_formatter: apache_airflow_core + airflow.utils.log.timezone_aware: apache_airflow_core + airflow.utils.module_loading: apache_airflow_core + airflow.utils.net: apache_airflow_core + airflow.utils.operator_helpers: apache_airflow_core + airflow.utils.orm_event_handlers: apache_airflow_core + airflow.utils.platform: apache_airflow_core + airflow.utils.process_utils: apache_airflow_core + airflow.utils.providers_configuration_loader: apache_airflow_core + airflow.utils.retries: apache_airflow_core + airflow.utils.scheduler_health: apache_airflow_core + airflow.utils.serve_logs: apache_airflow_core + airflow.utils.serve_logs.core: apache_airflow_core + airflow.utils.serve_logs.log_server: apache_airflow_core + airflow.utils.session: apache_airflow_core + airflow.utils.singleton: apache_airflow_core + airflow.utils.span_status: apache_airflow_core + airflow.utils.sqlalchemy: apache_airflow_core + airflow.utils.state: apache_airflow_core + airflow.utils.strings: apache_airflow_core + airflow.utils.task_instance_session: apache_airflow_core + airflow.utils.thread_safe_dict: apache_airflow_core + airflow.utils.types: apache_airflow_core + airflow.utils.yaml: apache_airflow_core + airflow.version: apache_airflow_core + alembic: alembic + alembic.autogenerate: alembic + alembic.autogenerate.api: alembic + alembic.autogenerate.compare: alembic + alembic.autogenerate.render: alembic + alembic.autogenerate.rewriter: alembic + alembic.command: alembic + alembic.config: alembic + alembic.context: alembic + alembic.ddl: alembic + alembic.ddl.base: alembic + alembic.ddl.impl: alembic + alembic.ddl.mssql: alembic + alembic.ddl.mysql: alembic + alembic.ddl.oracle: alembic + alembic.ddl.postgresql: alembic + alembic.ddl.sqlite: alembic + alembic.environment: alembic + alembic.migration: alembic + alembic.op: alembic + alembic.operations: alembic + alembic.operations.base: alembic + alembic.operations.batch: alembic + alembic.operations.ops: alembic + alembic.operations.schemaobj: alembic + alembic.operations.toimpl: alembic + alembic.runtime: alembic + alembic.runtime.environment: alembic + alembic.runtime.migration: alembic + alembic.script: alembic + alembic.script.base: alembic + alembic.script.revision: alembic + alembic.script.write_hooks: alembic + alembic.templates.async.env: alembic + alembic.templates.generic.env: alembic + alembic.templates.multidb.env: alembic + alembic.templates.pyproject.env: alembic + alembic.templates.pyproject_async.env: alembic + alembic.testing: alembic + alembic.testing.assertions: alembic + alembic.testing.env: alembic + alembic.testing.fixtures: alembic + alembic.testing.plugin: alembic + alembic.testing.plugin.bootstrap: alembic + alembic.testing.requirements: alembic + alembic.testing.schemacompare: alembic + alembic.testing.suite: alembic + alembic.testing.suite.test_autogen_comments: alembic + alembic.testing.suite.test_autogen_computed: alembic + alembic.testing.suite.test_autogen_diffs: alembic + alembic.testing.suite.test_autogen_fks: alembic + alembic.testing.suite.test_autogen_identity: alembic + alembic.testing.suite.test_environment: alembic + alembic.testing.suite.test_op: alembic + alembic.testing.util: alembic + alembic.testing.warnings: alembic + alembic.util: alembic + alembic.util.compat: alembic + alembic.util.editor: alembic + alembic.util.exc: alembic + alembic.util.langhelpers: alembic + alembic.util.messaging: alembic + alembic.util.pyfiles: alembic + alembic.util.sqla_compat: alembic + annotated_types: annotated_types + annotated_types.test_cases: annotated_types + anyio: anyio + anyio.abc: anyio + anyio.from_thread: anyio + anyio.lowlevel: anyio + anyio.pytest_plugin: anyio + anyio.streams: anyio + anyio.streams.buffered: anyio + anyio.streams.file: anyio + anyio.streams.memory: anyio + anyio.streams.stapled: anyio + anyio.streams.text: anyio + anyio.streams.tls: anyio + anyio.to_interpreter: anyio + anyio.to_process: anyio + anyio.to_thread: anyio + argcomplete: argcomplete + argcomplete.completers: argcomplete + argcomplete.exceptions: argcomplete + argcomplete.finders: argcomplete + argcomplete.io: argcomplete + argcomplete.lexers: argcomplete + argcomplete.packages: argcomplete + argcomplete.scripts: argcomplete + argcomplete.scripts.activate_global_python_argcomplete: argcomplete + argcomplete.scripts.python_argcomplete_check_easy_install_script: argcomplete + argcomplete.scripts.register_python_argcomplete: argcomplete + argcomplete.shell_integration: argcomplete + asgiref: asgiref + asgiref.compatibility: asgiref + asgiref.current_thread_executor: asgiref + asgiref.local: asgiref + asgiref.server: asgiref + asgiref.sync: asgiref + asgiref.testing: asgiref + asgiref.timeout: asgiref + asgiref.typing: asgiref + asgiref.wsgi: asgiref + attr: attrs + attr.converters: attrs + attr.exceptions: attrs + attr.filters: attrs + attr.setters: attrs + attr.validators: attrs + attrs: attrs + attrs.converters: attrs + attrs.exceptions: attrs + attrs.filters: attrs + attrs.setters: attrs + attrs.validators: attrs + brotli: brotli + brotlicffi: brotlicffi + build: build + build.env: build + build.util: build + cadwyn: cadwyn + cadwyn.applications: cadwyn + cadwyn.changelogs: cadwyn + cadwyn.dependencies: cadwyn + cadwyn.exceptions: cadwyn + cadwyn.middleware: cadwyn + cadwyn.route_generation: cadwyn + cadwyn.routing: cadwyn + cadwyn.schema_generation: cadwyn + cadwyn.static: cadwyn + cadwyn.structure: cadwyn + cadwyn.structure.common: cadwyn + cadwyn.structure.data: cadwyn + cadwyn.structure.endpoints: cadwyn + cadwyn.structure.enums: cadwyn + cadwyn.structure.schemas: cadwyn + cadwyn.structure.versions: cadwyn + certifi: certifi + certifi.core: certifi + cffi: cffi + cffi.api: cffi + cffi.backend_ctypes: cffi + cffi.cffi_opcode: cffi + cffi.commontypes: cffi + cffi.cparser: cffi + cffi.error: cffi + cffi.ffiplatform: cffi + cffi.lock: cffi + cffi.model: cffi + cffi.pkgconfig: cffi + cffi.recompiler: cffi + cffi.setuptools_ext: cffi + cffi.vengine_cpy: cffi + cffi.vengine_gen: cffi + cffi.verifier: cffi + charset_normalizer: charset_normalizer + charset_normalizer.api: charset_normalizer + charset_normalizer.cd: charset_normalizer + charset_normalizer.cli: charset_normalizer + charset_normalizer.constant: charset_normalizer + charset_normalizer.legacy: charset_normalizer + charset_normalizer.md: charset_normalizer + charset_normalizer.models: charset_normalizer + charset_normalizer.utils: charset_normalizer + charset_normalizer.version: charset_normalizer + click: click + click.core: click + click.decorators: click + click.exceptions: click + click.formatting: click + click.globals: click + click.parser: click + click.shell_completion: click + click.termui: click + click.testing: click + click.types: click + click.utils: click + colorama: colorama + colorama.ansi: colorama + colorama.ansitowin32: colorama + colorama.initialise: colorama + colorama.tests: colorama + colorama.tests.ansi_test: colorama + colorama.tests.ansitowin32_test: colorama + colorama.tests.initialise_test: colorama + colorama.tests.isatty_test: colorama + colorama.tests.utils: colorama + colorama.tests.winterm_test: colorama + colorama.win32: colorama + colorama.winterm: colorama + colorlog: colorlog + colorlog.escape_codes: colorlog + colorlog.formatter: colorlog + colorlog.wrappers: colorlog + cron_descriptor: cron_descriptor + cron_descriptor.CasingTypeEnum: cron_descriptor + cron_descriptor.DescriptionTypeEnum: cron_descriptor + cron_descriptor.Exception: cron_descriptor + cron_descriptor.ExpressionDescriptor: cron_descriptor + cron_descriptor.ExpressionParser: cron_descriptor + cron_descriptor.ExpressionValidator: cron_descriptor + cron_descriptor.GetText: cron_descriptor + cron_descriptor.Options: cron_descriptor + cron_descriptor.StringBuilder: cron_descriptor + croniter: croniter + croniter.croniter: croniter + cryptography: cryptography + cryptography.exceptions: cryptography + cryptography.fernet: cryptography + cryptography.hazmat: cryptography + cryptography.hazmat.asn1: cryptography + cryptography.hazmat.asn1.asn1: cryptography + cryptography.hazmat.backends: cryptography + cryptography.hazmat.backends.openssl: cryptography + cryptography.hazmat.backends.openssl.backend: cryptography + cryptography.hazmat.bindings: cryptography + cryptography.hazmat.bindings.openssl: cryptography + cryptography.hazmat.bindings.openssl.binding: cryptography + cryptography.hazmat.decrepit: cryptography + cryptography.hazmat.decrepit.ciphers: cryptography + cryptography.hazmat.decrepit.ciphers.algorithms: cryptography + cryptography.hazmat.primitives: cryptography + cryptography.hazmat.primitives.asymmetric: cryptography + cryptography.hazmat.primitives.asymmetric.dh: cryptography + cryptography.hazmat.primitives.asymmetric.dsa: cryptography + cryptography.hazmat.primitives.asymmetric.ec: cryptography + cryptography.hazmat.primitives.asymmetric.ed25519: cryptography + cryptography.hazmat.primitives.asymmetric.ed448: cryptography + cryptography.hazmat.primitives.asymmetric.padding: cryptography + cryptography.hazmat.primitives.asymmetric.rsa: cryptography + cryptography.hazmat.primitives.asymmetric.types: cryptography + cryptography.hazmat.primitives.asymmetric.utils: cryptography + cryptography.hazmat.primitives.asymmetric.x25519: cryptography + cryptography.hazmat.primitives.asymmetric.x448: cryptography + cryptography.hazmat.primitives.ciphers: cryptography + cryptography.hazmat.primitives.ciphers.aead: cryptography + cryptography.hazmat.primitives.ciphers.algorithms: cryptography + cryptography.hazmat.primitives.ciphers.base: cryptography + cryptography.hazmat.primitives.ciphers.modes: cryptography + cryptography.hazmat.primitives.cmac: cryptography + cryptography.hazmat.primitives.constant_time: cryptography + cryptography.hazmat.primitives.hashes: cryptography + cryptography.hazmat.primitives.hmac: cryptography + cryptography.hazmat.primitives.kdf: cryptography + cryptography.hazmat.primitives.kdf.argon2: cryptography + cryptography.hazmat.primitives.kdf.concatkdf: cryptography + cryptography.hazmat.primitives.kdf.hkdf: cryptography + cryptography.hazmat.primitives.kdf.kbkdf: cryptography + cryptography.hazmat.primitives.kdf.pbkdf2: cryptography + cryptography.hazmat.primitives.kdf.scrypt: cryptography + cryptography.hazmat.primitives.kdf.x963kdf: cryptography + cryptography.hazmat.primitives.keywrap: cryptography + cryptography.hazmat.primitives.padding: cryptography + cryptography.hazmat.primitives.poly1305: cryptography + cryptography.hazmat.primitives.serialization: cryptography + cryptography.hazmat.primitives.serialization.base: cryptography + cryptography.hazmat.primitives.serialization.pkcs12: cryptography + cryptography.hazmat.primitives.serialization.pkcs7: cryptography + cryptography.hazmat.primitives.serialization.ssh: cryptography + cryptography.hazmat.primitives.twofactor: cryptography + cryptography.hazmat.primitives.twofactor.hotp: cryptography + cryptography.hazmat.primitives.twofactor.totp: cryptography + cryptography.utils: cryptography + cryptography.x509: cryptography + cryptography.x509.base: cryptography + cryptography.x509.certificate_transparency: cryptography + cryptography.x509.extensions: cryptography + cryptography.x509.general_name: cryptography + cryptography.x509.name: cryptography + cryptography.x509.ocsp: cryptography + cryptography.x509.oid: cryptography + cryptography.x509.verification: cryptography + daemon: python_daemon + daemon.daemon: python_daemon + daemon.pidfile: python_daemon + dateutil: python_dateutil + dateutil.easter: python_dateutil + dateutil.parser: python_dateutil + dateutil.parser.isoparser: python_dateutil + dateutil.relativedelta: python_dateutil + dateutil.rrule: python_dateutil + dateutil.tz: python_dateutil + dateutil.tz.tz: python_dateutil + dateutil.tz.win: python_dateutil + dateutil.tzwin: python_dateutil + dateutil.utils: python_dateutil + dateutil.zoneinfo: python_dateutil + dateutil.zoneinfo.rebuild: python_dateutil + deprecated: deprecated + deprecated.classic: deprecated + deprecated.sphinx: deprecated + dill: dill + dill.detect: dill + dill.logger: dill + dill.objtypes: dill + dill.pointers: dill + dill.session: dill + dill.settings: dill + dill.source: dill + dill.temp: dill + dill.tests: dill + dill.tests.test_abc: dill + dill.tests.test_check: dill + dill.tests.test_classdef: dill + dill.tests.test_dataclasses: dill + dill.tests.test_detect: dill + dill.tests.test_dictviews: dill + dill.tests.test_diff: dill + dill.tests.test_extendpickle: dill + dill.tests.test_fglobals: dill + dill.tests.test_file: dill + dill.tests.test_functions: dill + dill.tests.test_functors: dill + dill.tests.test_logger: dill + dill.tests.test_mixins: dill + dill.tests.test_module: dill + dill.tests.test_moduledict: dill + dill.tests.test_nested: dill + dill.tests.test_objects: dill + dill.tests.test_properties: dill + dill.tests.test_pycapsule: dill + dill.tests.test_recursive: dill + dill.tests.test_registered: dill + dill.tests.test_restricted: dill + dill.tests.test_selected: dill + dill.tests.test_session: dill + dill.tests.test_source: dill + dill.tests.test_sources: dill + dill.tests.test_temp: dill + dill.tests.test_threads: dill + dill.tests.test_weakref: dill + dns: dnspython + dns.asyncbackend: dnspython + dns.asyncquery: dnspython + dns.asyncresolver: dnspython + dns.btree: dnspython + dns.btreezone: dnspython + dns.dnssec: dnspython + dns.dnssecalgs: dnspython + dns.dnssecalgs.base: dnspython + dns.dnssecalgs.cryptography: dnspython + dns.dnssecalgs.dsa: dnspython + dns.dnssecalgs.ecdsa: dnspython + dns.dnssecalgs.eddsa: dnspython + dns.dnssecalgs.rsa: dnspython + dns.dnssectypes: dnspython + dns.e164: dnspython + dns.edns: dnspython + dns.entropy: dnspython + dns.enum: dnspython + dns.exception: dnspython + dns.flags: dnspython + dns.grange: dnspython + dns.immutable: dnspython + dns.inet: dnspython + dns.ipv4: dnspython + dns.ipv6: dnspython + dns.message: dnspython + dns.name: dnspython + dns.namedict: dnspython + dns.nameserver: dnspython + dns.node: dnspython + dns.opcode: dnspython + dns.query: dnspython + dns.quic: dnspython + dns.rcode: dnspython + dns.rdata: dnspython + dns.rdataclass: dnspython + dns.rdataset: dnspython + dns.rdatatype: dnspython + dns.rdtypes: dnspython + dns.rdtypes.ANY: dnspython + dns.rdtypes.ANY.AFSDB: dnspython + dns.rdtypes.ANY.AMTRELAY: dnspython + dns.rdtypes.ANY.AVC: dnspython + dns.rdtypes.ANY.CAA: dnspython + dns.rdtypes.ANY.CDNSKEY: dnspython + dns.rdtypes.ANY.CDS: dnspython + dns.rdtypes.ANY.CERT: dnspython + dns.rdtypes.ANY.CNAME: dnspython + dns.rdtypes.ANY.CSYNC: dnspython + dns.rdtypes.ANY.DLV: dnspython + dns.rdtypes.ANY.DNAME: dnspython + dns.rdtypes.ANY.DNSKEY: dnspython + dns.rdtypes.ANY.DS: dnspython + dns.rdtypes.ANY.DSYNC: dnspython + dns.rdtypes.ANY.EUI48: dnspython + dns.rdtypes.ANY.EUI64: dnspython + dns.rdtypes.ANY.GPOS: dnspython + dns.rdtypes.ANY.HINFO: dnspython + dns.rdtypes.ANY.HIP: dnspython + dns.rdtypes.ANY.ISDN: dnspython + dns.rdtypes.ANY.L32: dnspython + dns.rdtypes.ANY.L64: dnspython + dns.rdtypes.ANY.LOC: dnspython + dns.rdtypes.ANY.LP: dnspython + dns.rdtypes.ANY.MX: dnspython + dns.rdtypes.ANY.NID: dnspython + dns.rdtypes.ANY.NINFO: dnspython + dns.rdtypes.ANY.NS: dnspython + dns.rdtypes.ANY.NSEC: dnspython + dns.rdtypes.ANY.NSEC3: dnspython + dns.rdtypes.ANY.NSEC3PARAM: dnspython + dns.rdtypes.ANY.OPENPGPKEY: dnspython + dns.rdtypes.ANY.OPT: dnspython + dns.rdtypes.ANY.PTR: dnspython + dns.rdtypes.ANY.RESINFO: dnspython + dns.rdtypes.ANY.RP: dnspython + dns.rdtypes.ANY.RRSIG: dnspython + dns.rdtypes.ANY.RT: dnspython + dns.rdtypes.ANY.SMIMEA: dnspython + dns.rdtypes.ANY.SOA: dnspython + dns.rdtypes.ANY.SPF: dnspython + dns.rdtypes.ANY.SSHFP: dnspython + dns.rdtypes.ANY.TKEY: dnspython + dns.rdtypes.ANY.TLSA: dnspython + dns.rdtypes.ANY.TSIG: dnspython + dns.rdtypes.ANY.TXT: dnspython + dns.rdtypes.ANY.URI: dnspython + dns.rdtypes.ANY.WALLET: dnspython + dns.rdtypes.ANY.X25: dnspython + dns.rdtypes.ANY.ZONEMD: dnspython + dns.rdtypes.CH: dnspython + dns.rdtypes.CH.A: dnspython + dns.rdtypes.IN: dnspython + dns.rdtypes.IN.A: dnspython + dns.rdtypes.IN.AAAA: dnspython + dns.rdtypes.IN.APL: dnspython + dns.rdtypes.IN.DHCID: dnspython + dns.rdtypes.IN.HTTPS: dnspython + dns.rdtypes.IN.IPSECKEY: dnspython + dns.rdtypes.IN.KX: dnspython + dns.rdtypes.IN.NAPTR: dnspython + dns.rdtypes.IN.NSAP: dnspython + dns.rdtypes.IN.NSAP_PTR: dnspython + dns.rdtypes.IN.PX: dnspython + dns.rdtypes.IN.SRV: dnspython + dns.rdtypes.IN.SVCB: dnspython + dns.rdtypes.IN.WKS: dnspython + dns.rdtypes.dnskeybase: dnspython + dns.rdtypes.dsbase: dnspython + dns.rdtypes.euibase: dnspython + dns.rdtypes.mxbase: dnspython + dns.rdtypes.nsbase: dnspython + dns.rdtypes.svcbbase: dnspython + dns.rdtypes.tlsabase: dnspython + dns.rdtypes.txtbase: dnspython + dns.rdtypes.util: dnspython + dns.renderer: dnspython + dns.resolver: dnspython + dns.reversename: dnspython + dns.rrset: dnspython + dns.serial: dnspython + dns.set: dnspython + dns.tokenizer: dnspython + dns.transaction: dnspython + dns.tsig: dnspython + dns.tsigkeyring: dnspython + dns.ttl: dnspython + dns.update: dnspython + dns.version: dnspython + dns.versioned: dnspython + dns.win32util: dnspython + dns.wire: dnspython + dns.xfr: dnspython + dns.zone: dnspython + dns.zonefile: dnspython + dns.zonetypes: dnspython + dotenv: python_dotenv + dotenv.cli: python_dotenv + dotenv.ipython: python_dotenv + dotenv.main: python_dotenv + dotenv.parser: python_dotenv + dotenv.variables: python_dotenv + dotenv.version: python_dotenv + email_validator: email_validator + email_validator.deliverability: email_validator + email_validator.exceptions: email_validator + email_validator.rfc_constants: email_validator + email_validator.syntax: email_validator + email_validator.types: email_validator + email_validator.validate_email: email_validator + email_validator.version: email_validator + fastapi: fastapi + fastapi.applications: fastapi + fastapi.background: fastapi + fastapi.cli: fastapi + fastapi.concurrency: fastapi + fastapi.datastructures: fastapi + fastapi.dependencies: fastapi + fastapi.dependencies.models: fastapi + fastapi.dependencies.utils: fastapi + fastapi.encoders: fastapi + fastapi.exception_handlers: fastapi + fastapi.exceptions: fastapi + fastapi.logger: fastapi + fastapi.middleware: fastapi + fastapi.middleware.asyncexitstack: fastapi + fastapi.middleware.cors: fastapi + fastapi.middleware.gzip: fastapi + fastapi.middleware.httpsredirect: fastapi + fastapi.middleware.trustedhost: fastapi + fastapi.middleware.wsgi: fastapi + fastapi.openapi: fastapi + fastapi.openapi.constants: fastapi + fastapi.openapi.docs: fastapi + fastapi.openapi.models: fastapi + fastapi.openapi.utils: fastapi + fastapi.param_functions: fastapi + fastapi.params: fastapi + fastapi.requests: fastapi + fastapi.responses: fastapi + fastapi.routing: fastapi + fastapi.security: fastapi + fastapi.security.api_key: fastapi + fastapi.security.base: fastapi + fastapi.security.http: fastapi + fastapi.security.oauth2: fastapi + fastapi.security.open_id_connect_url: fastapi + fastapi.security.utils: fastapi + fastapi.staticfiles: fastapi + fastapi.templating: fastapi + fastapi.testclient: fastapi + fastapi.types: fastapi + fastapi.utils: fastapi + fastapi.websockets: fastapi + fastapi_cli: fastapi_cli + fastapi_cli.cli: fastapi_cli + fastapi_cli.discover: fastapi_cli + fastapi_cli.exceptions: fastapi_cli + fastapi_cli.logging: fastapi_cli + fastapi_cli.utils: fastapi_cli + fastapi_cli.utils.cli: fastapi_cli + fsspec: fsspec + fsspec.archive: fsspec + fsspec.asyn: fsspec + fsspec.caching: fsspec + fsspec.callbacks: fsspec + fsspec.compression: fsspec + fsspec.config: fsspec + fsspec.conftest: fsspec + fsspec.core: fsspec + fsspec.dircache: fsspec + fsspec.exceptions: fsspec + fsspec.fuse: fsspec + fsspec.generic: fsspec + fsspec.gui: fsspec + fsspec.implementations: fsspec + fsspec.implementations.arrow: fsspec + fsspec.implementations.asyn_wrapper: fsspec + fsspec.implementations.cache_mapper: fsspec + fsspec.implementations.cache_metadata: fsspec + fsspec.implementations.cached: fsspec + fsspec.implementations.dask: fsspec + fsspec.implementations.data: fsspec + fsspec.implementations.dbfs: fsspec + fsspec.implementations.dirfs: fsspec + fsspec.implementations.ftp: fsspec + fsspec.implementations.gist: fsspec + fsspec.implementations.git: fsspec + fsspec.implementations.github: fsspec + fsspec.implementations.http: fsspec + fsspec.implementations.http_sync: fsspec + fsspec.implementations.jupyter: fsspec + fsspec.implementations.libarchive: fsspec + fsspec.implementations.local: fsspec + fsspec.implementations.memory: fsspec + fsspec.implementations.reference: fsspec + fsspec.implementations.sftp: fsspec + fsspec.implementations.smb: fsspec + fsspec.implementations.tar: fsspec + fsspec.implementations.webhdfs: fsspec + fsspec.implementations.zip: fsspec + fsspec.json: fsspec + fsspec.mapping: fsspec + fsspec.parquet: fsspec + fsspec.registry: fsspec + fsspec.spec: fsspec + fsspec.tests.abstract: fsspec + fsspec.tests.abstract.common: fsspec + fsspec.tests.abstract.copy: fsspec + fsspec.tests.abstract.get: fsspec + fsspec.tests.abstract.mv: fsspec + fsspec.tests.abstract.open: fsspec + fsspec.tests.abstract.pipe: fsspec + fsspec.tests.abstract.put: fsspec + fsspec.transaction: fsspec + fsspec.utils: fsspec + google.api.annotations_pb2: googleapis_common_protos + google.api.auth_pb2: googleapis_common_protos + google.api.backend_pb2: googleapis_common_protos + google.api.billing_pb2: googleapis_common_protos + google.api.client_pb2: googleapis_common_protos + google.api.config_change_pb2: googleapis_common_protos + google.api.consumer_pb2: googleapis_common_protos + google.api.context_pb2: googleapis_common_protos + google.api.control_pb2: googleapis_common_protos + google.api.distribution_pb2: googleapis_common_protos + google.api.documentation_pb2: googleapis_common_protos + google.api.endpoint_pb2: googleapis_common_protos + google.api.error_reason_pb2: googleapis_common_protos + google.api.field_behavior_pb2: googleapis_common_protos + google.api.field_info_pb2: googleapis_common_protos + google.api.http_pb2: googleapis_common_protos + google.api.httpbody_pb2: googleapis_common_protos + google.api.label_pb2: googleapis_common_protos + google.api.launch_stage_pb2: googleapis_common_protos + google.api.log_pb2: googleapis_common_protos + google.api.logging_pb2: googleapis_common_protos + google.api.metric_pb2: googleapis_common_protos + google.api.monitored_resource_pb2: googleapis_common_protos + google.api.monitoring_pb2: googleapis_common_protos + google.api.policy_pb2: googleapis_common_protos + google.api.quota_pb2: googleapis_common_protos + google.api.resource_pb2: googleapis_common_protos + google.api.routing_pb2: googleapis_common_protos + google.api.service_pb2: googleapis_common_protos + google.api.source_info_pb2: googleapis_common_protos + google.api.system_parameter_pb2: googleapis_common_protos + google.api.usage_pb2: googleapis_common_protos + google.api.visibility_pb2: googleapis_common_protos + google.cloud.extended_operations_pb2: googleapis_common_protos + google.cloud.location.locations_pb2: googleapis_common_protos + google.gapic.metadata.gapic_metadata_pb2: googleapis_common_protos + google.logging.type.http_request_pb2: googleapis_common_protos + google.logging.type.log_severity_pb2: googleapis_common_protos + google.longrunning.operations_grpc: googleapis_common_protos + google.longrunning.operations_grpc_pb2: googleapis_common_protos + google.longrunning.operations_pb2: googleapis_common_protos + google.longrunning.operations_pb2_grpc: googleapis_common_protos + google.longrunning.operations_proto: googleapis_common_protos + google.longrunning.operations_proto_pb2: googleapis_common_protos + google.protobuf: protobuf + google.protobuf.any: protobuf + google.protobuf.any_pb2: protobuf + google.protobuf.api_pb2: protobuf + google.protobuf.compiler: protobuf + google.protobuf.compiler.plugin_pb2: protobuf + google.protobuf.descriptor: protobuf + google.protobuf.descriptor_database: protobuf + google.protobuf.descriptor_pb2: protobuf + google.protobuf.descriptor_pool: protobuf + google.protobuf.duration: protobuf + google.protobuf.duration_pb2: protobuf + google.protobuf.empty_pb2: protobuf + google.protobuf.field_mask_pb2: protobuf + google.protobuf.internal: protobuf + google.protobuf.internal.api_implementation: protobuf + google.protobuf.internal.builder: protobuf + google.protobuf.internal.containers: protobuf + google.protobuf.internal.decoder: protobuf + google.protobuf.internal.encoder: protobuf + google.protobuf.internal.enum_type_wrapper: protobuf + google.protobuf.internal.extension_dict: protobuf + google.protobuf.internal.field_mask: protobuf + google.protobuf.internal.message_listener: protobuf + google.protobuf.internal.python_edition_defaults: protobuf + google.protobuf.internal.python_message: protobuf + google.protobuf.internal.testing_refleaks: protobuf + google.protobuf.internal.type_checkers: protobuf + google.protobuf.internal.well_known_types: protobuf + google.protobuf.internal.wire_format: protobuf + google.protobuf.json_format: protobuf + google.protobuf.message: protobuf + google.protobuf.message_factory: protobuf + google.protobuf.proto: protobuf + google.protobuf.proto_builder: protobuf + google.protobuf.proto_json: protobuf + google.protobuf.proto_text: protobuf + google.protobuf.pyext: protobuf + google.protobuf.pyext.cpp_message: protobuf + google.protobuf.reflection: protobuf + google.protobuf.runtime_version: protobuf + google.protobuf.service_reflection: protobuf + google.protobuf.source_context_pb2: protobuf + google.protobuf.struct_pb2: protobuf + google.protobuf.symbol_database: protobuf + google.protobuf.testdata: protobuf + google.protobuf.text_encoding: protobuf + google.protobuf.text_format: protobuf + google.protobuf.timestamp: protobuf + google.protobuf.timestamp_pb2: protobuf + google.protobuf.type_pb2: protobuf + google.protobuf.unknown_fields: protobuf + google.protobuf.util: protobuf + google.protobuf.wrappers_pb2: protobuf + google.rpc.code_pb2: googleapis_common_protos + google.rpc.context.attribute_context_pb2: googleapis_common_protos + google.rpc.context.audit_context_pb2: googleapis_common_protos + google.rpc.error_details_pb2: googleapis_common_protos + google.rpc.http_pb2: googleapis_common_protos + google.rpc.status_pb2: googleapis_common_protos + google.type.calendar_period_pb2: googleapis_common_protos + google.type.color_pb2: googleapis_common_protos + google.type.date_pb2: googleapis_common_protos + google.type.datetime_pb2: googleapis_common_protos + google.type.dayofweek_pb2: googleapis_common_protos + google.type.decimal_pb2: googleapis_common_protos + google.type.expr_pb2: googleapis_common_protos + google.type.fraction_pb2: googleapis_common_protos + google.type.interval_pb2: googleapis_common_protos + google.type.latlng_pb2: googleapis_common_protos + google.type.localized_text_pb2: googleapis_common_protos + google.type.money_pb2: googleapis_common_protos + google.type.month_pb2: googleapis_common_protos + google.type.phone_number_pb2: googleapis_common_protos + google.type.postal_address_pb2: googleapis_common_protos + google.type.quaternion_pb2: googleapis_common_protos + google.type.timeofday_pb2: googleapis_common_protos + greenback: greenback + greenlet: greenlet + greenlet.platform: greenlet + greenlet.tests: greenlet + greenlet.tests.fail_clearing_run_switches: greenlet + greenlet.tests.fail_cpp_exception: greenlet + greenlet.tests.fail_initialstub_already_started: greenlet + greenlet.tests.fail_slp_switch: greenlet + greenlet.tests.fail_switch_three_greenlets: greenlet + greenlet.tests.fail_switch_three_greenlets2: greenlet + greenlet.tests.fail_switch_two_greenlets: greenlet + greenlet.tests.leakcheck: greenlet + greenlet.tests.test_contextvars: greenlet + greenlet.tests.test_cpp: greenlet + greenlet.tests.test_extension_interface: greenlet + greenlet.tests.test_gc: greenlet + greenlet.tests.test_generator: greenlet + greenlet.tests.test_generator_nested: greenlet + greenlet.tests.test_greenlet: greenlet + greenlet.tests.test_greenlet_trash: greenlet + greenlet.tests.test_leaks: greenlet + greenlet.tests.test_stack_saved: greenlet + greenlet.tests.test_throw: greenlet + greenlet.tests.test_tracing: greenlet + greenlet.tests.test_version: greenlet + greenlet.tests.test_weakref: greenlet + grpc: grpcio + grpc.aio: grpcio + grpc.beta: grpcio + grpc.beta.implementations: grpcio + grpc.beta.interfaces: grpcio + grpc.beta.utilities: grpcio + grpc.experimental: grpcio + grpc.experimental.aio: grpcio + grpc.experimental.gevent: grpcio + grpc.experimental.session_cache: grpcio + grpc.framework: grpcio + grpc.framework.common: grpcio + grpc.framework.common.cardinality: grpcio + grpc.framework.common.style: grpcio + grpc.framework.foundation: grpcio + grpc.framework.foundation.abandonment: grpcio + grpc.framework.foundation.callable_util: grpcio + grpc.framework.foundation.future: grpcio + grpc.framework.foundation.logging_pool: grpcio + grpc.framework.foundation.stream: grpcio + grpc.framework.foundation.stream_util: grpcio + grpc.framework.interfaces: grpcio + grpc.framework.interfaces.base: grpcio + grpc.framework.interfaces.base.base: grpcio + grpc.framework.interfaces.base.utilities: grpcio + grpc.framework.interfaces.face: grpcio + grpc.framework.interfaces.face.face: grpcio + grpc.framework.interfaces.face.utilities: grpcio + h11: h11 + httpcore: httpcore + httptools: httptools + httptools.parser: httptools + httptools.parser.errors: httptools + httpx: httpx + idna: idna + idna.codec: idna + idna.compat: idna + idna.core: idna + idna.idnadata: idna + idna.intranges: idna + idna.package_data: idna + idna.uts46data: idna + importlib_metadata: importlib_metadata + importlib_metadata.compat: importlib_metadata + importlib_metadata.compat.py311: importlib_metadata + importlib_metadata.compat.py39: importlib_metadata + importlib_metadata.diagnose: importlib_metadata + itsdangerous: itsdangerous + itsdangerous.encoding: itsdangerous + itsdangerous.exc: itsdangerous + itsdangerous.serializer: itsdangerous + itsdangerous.signer: itsdangerous + itsdangerous.timed: itsdangerous + itsdangerous.url_safe: itsdangerous + jinja2: jinja2 + jinja2.async_utils: jinja2 + jinja2.bccache: jinja2 + jinja2.compiler: jinja2 + jinja2.constants: jinja2 + jinja2.debug: jinja2 + jinja2.defaults: jinja2 + jinja2.environment: jinja2 + jinja2.exceptions: jinja2 + jinja2.ext: jinja2 + jinja2.filters: jinja2 + jinja2.idtracking: jinja2 + jinja2.lexer: jinja2 + jinja2.loaders: jinja2 + jinja2.meta: jinja2 + jinja2.nativetypes: jinja2 + jinja2.nodes: jinja2 + jinja2.optimizer: jinja2 + jinja2.parser: jinja2 + jinja2.runtime: jinja2 + jinja2.sandbox: jinja2 + jinja2.tests: jinja2 + jinja2.utils: jinja2 + jinja2.visitor: jinja2 + jsonschema: jsonschema + jsonschema.benchmarks: jsonschema + jsonschema.benchmarks.const_vs_enum: jsonschema + jsonschema.benchmarks.contains: jsonschema + jsonschema.benchmarks.issue232: jsonschema + jsonschema.benchmarks.json_schema_test_suite: jsonschema + jsonschema.benchmarks.nested_schemas: jsonschema + jsonschema.benchmarks.subcomponents: jsonschema + jsonschema.benchmarks.unused_registry: jsonschema + jsonschema.benchmarks.useless_applicator_schemas: jsonschema + jsonschema.benchmarks.useless_keywords: jsonschema + jsonschema.benchmarks.validator_creation: jsonschema + jsonschema.cli: jsonschema + jsonschema.exceptions: jsonschema + jsonschema.protocols: jsonschema + jsonschema.tests: jsonschema + jsonschema.tests.fuzz_validate: jsonschema + jsonschema.tests.test_cli: jsonschema + jsonschema.tests.test_deprecations: jsonschema + jsonschema.tests.test_exceptions: jsonschema + jsonschema.tests.test_format: jsonschema + jsonschema.tests.test_jsonschema_test_suite: jsonschema + jsonschema.tests.test_types: jsonschema + jsonschema.tests.test_utils: jsonschema + jsonschema.tests.test_validators: jsonschema + jsonschema.tests.typing: jsonschema + jsonschema.tests.typing.test_all_concrete_validators_match_protocol: jsonschema + jsonschema.validators: jsonschema + jsonschema_specifications: jsonschema_specifications + jsonschema_specifications.tests: jsonschema_specifications + jsonschema_specifications.tests.test_jsonschema_specifications: jsonschema_specifications + jwt: pyjwt + jwt.algorithms: pyjwt + jwt.api_jwk: pyjwt + jwt.api_jws: pyjwt + jwt.api_jwt: pyjwt + jwt.exceptions: pyjwt + jwt.help: pyjwt + jwt.jwk_set_cache: pyjwt + jwt.jwks_client: pyjwt + jwt.types: pyjwt + jwt.utils: pyjwt + jwt.warnings: pyjwt + lazy_object_proxy: lazy_object_proxy + lazy_object_proxy.compat: lazy_object_proxy + lazy_object_proxy.simple: lazy_object_proxy + lazy_object_proxy.slots: lazy_object_proxy + lazy_object_proxy.utils: lazy_object_proxy + libcst: libcst + libcst.codegen: libcst + libcst.codegen.gather: libcst + libcst.codegen.gen_matcher_classes: libcst + libcst.codegen.gen_type_mapping: libcst + libcst.codegen.gen_visitor_functions: libcst + libcst.codegen.generate: libcst + libcst.codegen.tests: libcst + libcst.codegen.tests.test_codegen_clean: libcst + libcst.codegen.transforms: libcst + libcst.codemod: libcst + libcst.codemod.commands: libcst + libcst.codemod.commands.add_pyre_directive: libcst + libcst.codemod.commands.add_trailing_commas: libcst + libcst.codemod.commands.convert_format_to_fstring: libcst + libcst.codemod.commands.convert_namedtuple_to_dataclass: libcst + libcst.codemod.commands.convert_percent_format_to_fstring: libcst + libcst.codemod.commands.convert_type_comments: libcst + libcst.codemod.commands.convert_union_to_or: libcst + libcst.codemod.commands.ensure_import_present: libcst + libcst.codemod.commands.fix_pyre_directives: libcst + libcst.codemod.commands.fix_variadic_callable: libcst + libcst.codemod.commands.noop: libcst + libcst.codemod.commands.remove_pyre_directive: libcst + libcst.codemod.commands.remove_unused_imports: libcst + libcst.codemod.commands.rename: libcst + libcst.codemod.commands.rename_typing_generic_aliases: libcst + libcst.codemod.commands.strip_strings_from_types: libcst + libcst.codemod.commands.tests: libcst + libcst.codemod.commands.tests.test_add_pyre_directive: libcst + libcst.codemod.commands.tests.test_add_trailing_commas: libcst + libcst.codemod.commands.tests.test_convert_format_to_fstring: libcst + libcst.codemod.commands.tests.test_convert_namedtuple_to_dataclass: libcst + libcst.codemod.commands.tests.test_convert_percent_format_to_fstring: libcst + libcst.codemod.commands.tests.test_convert_type_comments: libcst + libcst.codemod.commands.tests.test_convert_union_to_or: libcst + libcst.codemod.commands.tests.test_ensure_import_present: libcst + libcst.codemod.commands.tests.test_fix_pyre_directives: libcst + libcst.codemod.commands.tests.test_fix_variadic_callable: libcst + libcst.codemod.commands.tests.test_noop: libcst + libcst.codemod.commands.tests.test_remove_pyre_directive: libcst + libcst.codemod.commands.tests.test_remove_unused_imports: libcst + libcst.codemod.commands.tests.test_rename: libcst + libcst.codemod.commands.tests.test_rename_typing_generic_aliases: libcst + libcst.codemod.commands.tests.test_strip_strings_from_types: libcst + libcst.codemod.commands.tests.test_unnecessary_format_string: libcst + libcst.codemod.commands.unnecessary_format_string: libcst + libcst.codemod.tests: libcst + libcst.codemod.tests.test_codemod: libcst + libcst.codemod.tests.test_codemod_cli: libcst + libcst.codemod.tests.test_metadata: libcst + libcst.codemod.tests.test_runner: libcst + libcst.codemod.visitors: libcst + libcst.codemod.visitors.tests: libcst + libcst.codemod.visitors.tests.test_add_imports: libcst + libcst.codemod.visitors.tests.test_apply_type_annotations: libcst + libcst.codemod.visitors.tests.test_gather_comments: libcst + libcst.codemod.visitors.tests.test_gather_exports: libcst + libcst.codemod.visitors.tests.test_gather_global_names: libcst + libcst.codemod.visitors.tests.test_gather_imports: libcst + libcst.codemod.visitors.tests.test_gather_string_annotation_names: libcst + libcst.codemod.visitors.tests.test_gather_unused_imports: libcst + libcst.codemod.visitors.tests.test_remove_imports: libcst + libcst.display: libcst + libcst.display.graphviz: libcst + libcst.display.tests: libcst + libcst.display.tests.test_dump_graphviz: libcst + libcst.display.tests.test_dump_text: libcst + libcst.display.text: libcst + libcst.helpers: libcst + libcst.helpers.common: libcst + libcst.helpers.expression: libcst + libcst.helpers.matchers: libcst + libcst.helpers.module: libcst + libcst.helpers.node_fields: libcst + libcst.helpers.paths: libcst + libcst.helpers.tests: libcst + libcst.helpers.tests.test_expression: libcst + libcst.helpers.tests.test_matchers: libcst + libcst.helpers.tests.test_module: libcst + libcst.helpers.tests.test_node_fields: libcst + libcst.helpers.tests.test_paths: libcst + libcst.helpers.tests.test_template: libcst + libcst.matchers: libcst + libcst.matchers.tests: libcst + libcst.matchers.tests.test_decorators: libcst + libcst.matchers.tests.test_extract: libcst + libcst.matchers.tests.test_findall: libcst + libcst.matchers.tests.test_matchers: libcst + libcst.matchers.tests.test_matchers_with_metadata: libcst + libcst.matchers.tests.test_replace: libcst + libcst.matchers.tests.test_visitors: libcst + libcst.metadata: libcst + libcst.metadata.accessor_provider: libcst + libcst.metadata.base_provider: libcst + libcst.metadata.expression_context_provider: libcst + libcst.metadata.file_path_provider: libcst + libcst.metadata.full_repo_manager: libcst + libcst.metadata.name_provider: libcst + libcst.metadata.parent_node_provider: libcst + libcst.metadata.position_provider: libcst + libcst.metadata.reentrant_codegen: libcst + libcst.metadata.scope_provider: libcst + libcst.metadata.span_provider: libcst + libcst.metadata.tests: libcst + libcst.metadata.tests.test_accessor_provider: libcst + libcst.metadata.tests.test_base_provider: libcst + libcst.metadata.tests.test_expression_context_provider: libcst + libcst.metadata.tests.test_file_path_provider: libcst + libcst.metadata.tests.test_full_repo_manager: libcst + libcst.metadata.tests.test_metadata_provider: libcst + libcst.metadata.tests.test_metadata_wrapper: libcst + libcst.metadata.tests.test_name_provider: libcst + libcst.metadata.tests.test_parent_node_provider: libcst + libcst.metadata.tests.test_position_provider: libcst + libcst.metadata.tests.test_reentrant_codegen: libcst + libcst.metadata.tests.test_scope_provider: libcst + libcst.metadata.tests.test_span_provider: libcst + libcst.metadata.tests.test_type_inference_provider: libcst + libcst.metadata.type_inference_provider: libcst + libcst.metadata.wrapper: libcst + libcst.testing: libcst + libcst.testing.utils: libcst + libcst.tests: libcst + libcst.tests.pyre.simple_class: libcst + libcst.tests.test_add_slots: libcst + libcst.tests.test_batched_visitor: libcst + libcst.tests.test_deep_clone: libcst + libcst.tests.test_deep_replace: libcst + libcst.tests.test_e2e: libcst + libcst.tests.test_exceptions: libcst + libcst.tests.test_fuzz: libcst + libcst.tests.test_import: libcst + libcst.tests.test_pyre_integration: libcst + libcst.tests.test_roundtrip: libcst + libcst.tests.test_tabs: libcst + libcst.tests.test_type_enforce: libcst + libcst.tests.test_visitor: libcst + libcst.tool: libcst + linkify_it: linkify_it_py + linkify_it.main: linkify_it_py + linkify_it.tlds: linkify_it_py + linkify_it.ucre: linkify_it_py + lockfile: lockfile + lockfile.linklockfile: lockfile + lockfile.mkdirlockfile: lockfile + lockfile.pidlockfile: lockfile + lockfile.sqlitelockfile: lockfile + lockfile.symlinklockfile: lockfile + mako: mako + mako.ast: mako + mako.cache: mako + mako.cmd: mako + mako.codegen: mako + mako.compat: mako + mako.exceptions: mako + mako.ext: mako + mako.ext.autohandler: mako + mako.ext.babelplugin: mako + mako.ext.beaker_cache: mako + mako.ext.extract: mako + mako.ext.linguaplugin: mako + mako.ext.preprocessors: mako + mako.ext.pygmentplugin: mako + mako.ext.turbogears: mako + mako.filters: mako + mako.lexer: mako + mako.lookup: mako + mako.parsetree: mako + mako.pygen: mako + mako.pyparser: mako + mako.runtime: mako + mako.template: mako + mako.testing: mako + mako.testing.assertions: mako + mako.testing.config: mako + mako.testing.exclusions: mako + mako.testing.fixtures: mako + mako.testing.helpers: mako + mako.util: mako + markdown_it: markdown_it_py + markdown_it.cli: markdown_it_py + markdown_it.cli.parse: markdown_it_py + markdown_it.common: markdown_it_py + markdown_it.common.entities: markdown_it_py + markdown_it.common.html_blocks: markdown_it_py + markdown_it.common.html_re: markdown_it_py + markdown_it.common.normalize_url: markdown_it_py + markdown_it.common.utils: markdown_it_py + markdown_it.helpers: markdown_it_py + markdown_it.helpers.parse_link_destination: markdown_it_py + markdown_it.helpers.parse_link_label: markdown_it_py + markdown_it.helpers.parse_link_title: markdown_it_py + markdown_it.main: markdown_it_py + markdown_it.parser_block: markdown_it_py + markdown_it.parser_core: markdown_it_py + markdown_it.parser_inline: markdown_it_py + markdown_it.presets: markdown_it_py + markdown_it.presets.commonmark: markdown_it_py + markdown_it.presets.default: markdown_it_py + markdown_it.presets.zero: markdown_it_py + markdown_it.renderer: markdown_it_py + markdown_it.ruler: markdown_it_py + markdown_it.rules_block: markdown_it_py + markdown_it.rules_block.blockquote: markdown_it_py + markdown_it.rules_block.code: markdown_it_py + markdown_it.rules_block.fence: markdown_it_py + markdown_it.rules_block.heading: markdown_it_py + markdown_it.rules_block.hr: markdown_it_py + markdown_it.rules_block.html_block: markdown_it_py + markdown_it.rules_block.lheading: markdown_it_py + markdown_it.rules_block.list: markdown_it_py + markdown_it.rules_block.paragraph: markdown_it_py + markdown_it.rules_block.reference: markdown_it_py + markdown_it.rules_block.state_block: markdown_it_py + markdown_it.rules_block.table: markdown_it_py + markdown_it.rules_core: markdown_it_py + markdown_it.rules_core.block: markdown_it_py + markdown_it.rules_core.inline: markdown_it_py + markdown_it.rules_core.linkify: markdown_it_py + markdown_it.rules_core.normalize: markdown_it_py + markdown_it.rules_core.replacements: markdown_it_py + markdown_it.rules_core.smartquotes: markdown_it_py + markdown_it.rules_core.state_core: markdown_it_py + markdown_it.rules_core.text_join: markdown_it_py + markdown_it.rules_inline: markdown_it_py + markdown_it.rules_inline.autolink: markdown_it_py + markdown_it.rules_inline.backticks: markdown_it_py + markdown_it.rules_inline.balance_pairs: markdown_it_py + markdown_it.rules_inline.emphasis: markdown_it_py + markdown_it.rules_inline.entity: markdown_it_py + markdown_it.rules_inline.escape: markdown_it_py + markdown_it.rules_inline.fragments_join: markdown_it_py + markdown_it.rules_inline.html_inline: markdown_it_py + markdown_it.rules_inline.image: markdown_it_py + markdown_it.rules_inline.link: markdown_it_py + markdown_it.rules_inline.linkify: markdown_it_py + markdown_it.rules_inline.newline: markdown_it_py + markdown_it.rules_inline.state_inline: markdown_it_py + markdown_it.rules_inline.strikethrough: markdown_it_py + markdown_it.rules_inline.text: markdown_it_py + markdown_it.token: markdown_it_py + markdown_it.tree: markdown_it_py + markdown_it.utils: markdown_it_py + markupsafe: markupsafe + mdurl: mdurl + methodtools: methodtools + more_itertools: more_itertools + more_itertools.more: more_itertools + more_itertools.recipes: more_itertools + msgspec: msgspec + msgspec.inspect: msgspec + msgspec.json: msgspec + msgspec.msgpack: msgspec + msgspec.structs: msgspec + msgspec.toml: msgspec + msgspec.yaml: msgspec + multipart: python_multipart + multipart.decoders: python_multipart + multipart.exceptions: python_multipart + multipart.multipart: python_multipart + natsort: natsort + natsort.compat: natsort + natsort.compat.fake_fastnumbers: natsort + natsort.compat.fastnumbers: natsort + natsort.compat.locale: natsort + natsort.natsort: natsort + natsort.ns_enum: natsort + natsort.unicode_numbers: natsort + natsort.unicode_numeric_hex: natsort + natsort.utils: natsort + opentelemetry.attributes: opentelemetry_api + opentelemetry.baggage: opentelemetry_api + opentelemetry.baggage.propagation: opentelemetry_api + opentelemetry.context: opentelemetry_api + opentelemetry.context.context: opentelemetry_api + opentelemetry.context.contextvars_context: opentelemetry_api + opentelemetry.environment_variables: opentelemetry_api + opentelemetry.exporter.otlp.proto.common: opentelemetry_exporter_otlp_proto_common + opentelemetry.exporter.otlp.proto.common.metrics_encoder: opentelemetry_exporter_otlp_proto_common + opentelemetry.exporter.otlp.proto.common.trace_encoder: opentelemetry_exporter_otlp_proto_common + opentelemetry.exporter.otlp.proto.common.version: opentelemetry_exporter_otlp_proto_common + opentelemetry.exporter.otlp.proto.grpc: opentelemetry_exporter_otlp_proto_grpc + opentelemetry.exporter.otlp.proto.grpc.exporter: opentelemetry_exporter_otlp_proto_grpc + opentelemetry.exporter.otlp.proto.grpc.metric_exporter: opentelemetry_exporter_otlp_proto_grpc + opentelemetry.exporter.otlp.proto.grpc.trace_exporter: opentelemetry_exporter_otlp_proto_grpc + opentelemetry.exporter.otlp.proto.grpc.version: opentelemetry_exporter_otlp_proto_grpc + opentelemetry.exporter.otlp.proto.http: opentelemetry_exporter_otlp_proto_http + opentelemetry.exporter.otlp.proto.http.metric_exporter: opentelemetry_exporter_otlp_proto_http + opentelemetry.exporter.otlp.proto.http.trace_exporter: opentelemetry_exporter_otlp_proto_http + opentelemetry.exporter.otlp.proto.http.trace_exporter.encoder: opentelemetry_exporter_otlp_proto_http + opentelemetry.exporter.otlp.proto.http.version: opentelemetry_exporter_otlp_proto_http + opentelemetry.exporter.otlp.version: opentelemetry_exporter_otlp + opentelemetry.metrics: opentelemetry_api + opentelemetry.propagate: opentelemetry_api + opentelemetry.propagators.composite: opentelemetry_api + opentelemetry.propagators.textmap: opentelemetry_api + opentelemetry.proto: opentelemetry_proto + opentelemetry.proto.collector: opentelemetry_proto + opentelemetry.proto.collector.logs.v1.logs_service_pb2: opentelemetry_proto + opentelemetry.proto.collector.logs.v1.logs_service_pb2_grpc: opentelemetry_proto + opentelemetry.proto.collector.metrics: opentelemetry_proto + opentelemetry.proto.collector.metrics.v1: opentelemetry_proto + opentelemetry.proto.collector.metrics.v1.metrics_service_pb2: opentelemetry_proto + opentelemetry.proto.collector.metrics.v1.metrics_service_pb2_grpc: opentelemetry_proto + opentelemetry.proto.collector.profiles.v1development.profiles_service_pb2: opentelemetry_proto + opentelemetry.proto.collector.profiles.v1development.profiles_service_pb2_grpc: opentelemetry_proto + opentelemetry.proto.collector.trace: opentelemetry_proto + opentelemetry.proto.collector.trace.v1: opentelemetry_proto + opentelemetry.proto.collector.trace.v1.trace_service_pb2: opentelemetry_proto + opentelemetry.proto.collector.trace.v1.trace_service_pb2_grpc: opentelemetry_proto + opentelemetry.proto.common: opentelemetry_proto + opentelemetry.proto.common.v1: opentelemetry_proto + opentelemetry.proto.common.v1.common_pb2: opentelemetry_proto + opentelemetry.proto.logs.v1.logs_pb2: opentelemetry_proto + opentelemetry.proto.metrics: opentelemetry_proto + opentelemetry.proto.metrics.v1: opentelemetry_proto + opentelemetry.proto.metrics.v1.metrics_pb2: opentelemetry_proto + opentelemetry.proto.profiles.v1development.profiles_pb2: opentelemetry_proto + opentelemetry.proto.resource: opentelemetry_proto + opentelemetry.proto.resource.v1: opentelemetry_proto + opentelemetry.proto.resource.v1.resource_pb2: opentelemetry_proto + opentelemetry.proto.trace: opentelemetry_proto + opentelemetry.proto.trace.v1: opentelemetry_proto + opentelemetry.proto.trace.v1.trace_pb2: opentelemetry_proto + opentelemetry.proto.version: opentelemetry_proto + opentelemetry.sdk.environment_variables: opentelemetry_sdk + opentelemetry.sdk.error_handler: opentelemetry_sdk + opentelemetry.sdk.metrics: opentelemetry_sdk + opentelemetry.sdk.metrics.export: opentelemetry_sdk + opentelemetry.sdk.metrics.view: opentelemetry_sdk + opentelemetry.sdk.resources: opentelemetry_sdk + opentelemetry.sdk.trace: opentelemetry_sdk + opentelemetry.sdk.trace.export: opentelemetry_sdk + opentelemetry.sdk.trace.export.in_memory_span_exporter: opentelemetry_sdk + opentelemetry.sdk.trace.id_generator: opentelemetry_sdk + opentelemetry.sdk.trace.sampling: opentelemetry_sdk + opentelemetry.sdk.util: opentelemetry_sdk + opentelemetry.sdk.util.instrumentation: opentelemetry_sdk + opentelemetry.sdk.version: opentelemetry_sdk + opentelemetry.semconv: opentelemetry_semantic_conventions + opentelemetry.semconv.attributes: opentelemetry_semantic_conventions + opentelemetry.semconv.attributes.client_attributes: opentelemetry_semantic_conventions + opentelemetry.semconv.attributes.code_attributes: opentelemetry_semantic_conventions + opentelemetry.semconv.attributes.db_attributes: opentelemetry_semantic_conventions + opentelemetry.semconv.attributes.error_attributes: opentelemetry_semantic_conventions + opentelemetry.semconv.attributes.exception_attributes: opentelemetry_semantic_conventions + opentelemetry.semconv.attributes.http_attributes: opentelemetry_semantic_conventions + opentelemetry.semconv.attributes.network_attributes: opentelemetry_semantic_conventions + opentelemetry.semconv.attributes.otel_attributes: opentelemetry_semantic_conventions + opentelemetry.semconv.attributes.server_attributes: opentelemetry_semantic_conventions + opentelemetry.semconv.attributes.service_attributes: opentelemetry_semantic_conventions + opentelemetry.semconv.attributes.telemetry_attributes: opentelemetry_semantic_conventions + opentelemetry.semconv.attributes.url_attributes: opentelemetry_semantic_conventions + opentelemetry.semconv.attributes.user_agent_attributes: opentelemetry_semantic_conventions + opentelemetry.semconv.metrics: opentelemetry_semantic_conventions + opentelemetry.semconv.metrics.db_metrics: opentelemetry_semantic_conventions + opentelemetry.semconv.metrics.http_metrics: opentelemetry_semantic_conventions + opentelemetry.semconv.resource: opentelemetry_semantic_conventions + opentelemetry.semconv.schemas: opentelemetry_semantic_conventions + opentelemetry.semconv.trace: opentelemetry_semantic_conventions + opentelemetry.semconv.version: opentelemetry_semantic_conventions + opentelemetry.trace: opentelemetry_api + opentelemetry.trace.propagation: opentelemetry_api + opentelemetry.trace.propagation.tracecontext: opentelemetry_api + opentelemetry.trace.span: opentelemetry_api + opentelemetry.trace.status: opentelemetry_api + opentelemetry.util.re: opentelemetry_api + opentelemetry.util.types: opentelemetry_api + opentelemetry.version: opentelemetry_api + outcome: outcome + packaging: packaging + packaging.licenses: packaging + packaging.markers: packaging + packaging.metadata: packaging + packaging.pylock: packaging + packaging.requirements: packaging + packaging.specifiers: packaging + packaging.tags: packaging + packaging.utils: packaging + packaging.version: packaging + pathspec: pathspec + pathspec.gitignore: pathspec + pathspec.pathspec: pathspec + pathspec.pattern: pathspec + pathspec.patterns: pathspec + pathspec.patterns.gitwildmatch: pathspec + pathspec.util: pathspec + pendulum: pendulum + pendulum.constants: pendulum + pendulum.date: pendulum + pendulum.datetime: pendulum + pendulum.day: pendulum + pendulum.duration: pendulum + pendulum.exceptions: pendulum + pendulum.formatting: pendulum + pendulum.formatting.difference_formatter: pendulum + pendulum.formatting.formatter: pendulum + pendulum.helpers: pendulum + pendulum.interval: pendulum + pendulum.locales: pendulum + pendulum.locales.bg: pendulum + pendulum.locales.bg.custom: pendulum + pendulum.locales.bg.locale: pendulum + pendulum.locales.cs: pendulum + pendulum.locales.cs.custom: pendulum + pendulum.locales.cs.locale: pendulum + pendulum.locales.da: pendulum + pendulum.locales.da.custom: pendulum + pendulum.locales.da.locale: pendulum + pendulum.locales.de: pendulum + pendulum.locales.de.custom: pendulum + pendulum.locales.de.locale: pendulum + pendulum.locales.en: pendulum + pendulum.locales.en.custom: pendulum + pendulum.locales.en.locale: pendulum + pendulum.locales.en_gb: pendulum + pendulum.locales.en_gb.custom: pendulum + pendulum.locales.en_gb.locale: pendulum + pendulum.locales.en_us: pendulum + pendulum.locales.en_us.custom: pendulum + pendulum.locales.en_us.locale: pendulum + pendulum.locales.es: pendulum + pendulum.locales.es.custom: pendulum + pendulum.locales.es.locale: pendulum + pendulum.locales.fa: pendulum + pendulum.locales.fa.custom: pendulum + pendulum.locales.fa.locale: pendulum + pendulum.locales.fo: pendulum + pendulum.locales.fo.custom: pendulum + pendulum.locales.fo.locale: pendulum + pendulum.locales.fr: pendulum + pendulum.locales.fr.custom: pendulum + pendulum.locales.fr.locale: pendulum + pendulum.locales.he: pendulum + pendulum.locales.he.custom: pendulum + pendulum.locales.he.locale: pendulum + pendulum.locales.id: pendulum + pendulum.locales.id.custom: pendulum + pendulum.locales.id.locale: pendulum + pendulum.locales.it: pendulum + pendulum.locales.it.custom: pendulum + pendulum.locales.it.locale: pendulum + pendulum.locales.ja: pendulum + pendulum.locales.ja.custom: pendulum + pendulum.locales.ja.locale: pendulum + pendulum.locales.ko: pendulum + pendulum.locales.ko.custom: pendulum + pendulum.locales.ko.locale: pendulum + pendulum.locales.locale: pendulum + pendulum.locales.lt: pendulum + pendulum.locales.lt.custom: pendulum + pendulum.locales.lt.locale: pendulum + pendulum.locales.nb: pendulum + pendulum.locales.nb.custom: pendulum + pendulum.locales.nb.locale: pendulum + pendulum.locales.nl: pendulum + pendulum.locales.nl.custom: pendulum + pendulum.locales.nl.locale: pendulum + pendulum.locales.nn: pendulum + pendulum.locales.nn.custom: pendulum + pendulum.locales.nn.locale: pendulum + pendulum.locales.pl: pendulum + pendulum.locales.pl.custom: pendulum + pendulum.locales.pl.locale: pendulum + pendulum.locales.pt_br: pendulum + pendulum.locales.pt_br.custom: pendulum + pendulum.locales.pt_br.locale: pendulum + pendulum.locales.ru: pendulum + pendulum.locales.ru.custom: pendulum + pendulum.locales.ru.locale: pendulum + pendulum.locales.sk: pendulum + pendulum.locales.sk.custom: pendulum + pendulum.locales.sk.locale: pendulum + pendulum.locales.sv: pendulum + pendulum.locales.sv.custom: pendulum + pendulum.locales.sv.locale: pendulum + pendulum.locales.tr: pendulum + pendulum.locales.tr.custom: pendulum + pendulum.locales.tr.locale: pendulum + pendulum.locales.ua: pendulum + pendulum.locales.ua.custom: pendulum + pendulum.locales.ua.locale: pendulum + pendulum.locales.zh: pendulum + pendulum.locales.zh.custom: pendulum + pendulum.locales.zh.locale: pendulum + pendulum.mixins: pendulum + pendulum.mixins.default: pendulum + pendulum.parser: pendulum + pendulum.parsing: pendulum + pendulum.parsing.exceptions: pendulum + pendulum.parsing.iso8601: pendulum + pendulum.testing: pendulum + pendulum.testing.traveller: pendulum + pendulum.time: pendulum + pendulum.tz: pendulum + pendulum.tz.data: pendulum + pendulum.tz.data.windows: pendulum + pendulum.tz.exceptions: pendulum + pendulum.tz.local_timezone: pendulum + pendulum.tz.timezone: pendulum + pendulum.utils: pendulum + pkg_resources: setuptools + pkg_resources.tests: setuptools + pkg_resources.tests.data.my_test_package_source.setup: setuptools + pkg_resources.tests.test_find_distributions: setuptools + pkg_resources.tests.test_integration_zope_interface: setuptools + pkg_resources.tests.test_markers: setuptools + pkg_resources.tests.test_pkg_resources: setuptools + pkg_resources.tests.test_resources: setuptools + pkg_resources.tests.test_working_set: setuptools + pluggy: pluggy + psutil: psutil + psutil.tests: psutil + psutil.tests.test_aix: psutil + psutil.tests.test_bsd: psutil + psutil.tests.test_connections: psutil + psutil.tests.test_contracts: psutil + psutil.tests.test_linux: psutil + psutil.tests.test_memleaks: psutil + psutil.tests.test_misc: psutil + psutil.tests.test_osx: psutil + psutil.tests.test_posix: psutil + psutil.tests.test_process: psutil + psutil.tests.test_process_all: psutil + psutil.tests.test_scripts: psutil + psutil.tests.test_sudo: psutil + psutil.tests.test_sunos: psutil + psutil.tests.test_system: psutil + psutil.tests.test_testutils: psutil + psutil.tests.test_unicode: psutil + psutil.tests.test_windows: psutil + psycopg2: psycopg2_binary + psycopg2.errorcodes: psycopg2_binary + psycopg2.errors: psycopg2_binary + psycopg2.extensions: psycopg2_binary + psycopg2.extras: psycopg2_binary + psycopg2.pool: psycopg2_binary + psycopg2.sql: psycopg2_binary + psycopg2.tz: psycopg2_binary + pycparser: pycparser + pycparser.ast_transforms: pycparser + pycparser.c_ast: pycparser + pycparser.c_generator: pycparser + pycparser.c_lexer: pycparser + pycparser.c_parser: pycparser + pycparser.lextab: pycparser + pycparser.ply: pycparser + pycparser.ply.cpp: pycparser + pycparser.ply.ctokens: pycparser + pycparser.ply.lex: pycparser + pycparser.ply.yacc: pycparser + pycparser.ply.ygen: pycparser + pycparser.plyparser: pycparser + pycparser.yacctab: pycparser + pydantic: pydantic + pydantic.alias_generators: pydantic + pydantic.aliases: pydantic + pydantic.annotated_handlers: pydantic + pydantic.class_validators: pydantic + pydantic.color: pydantic + pydantic.config: pydantic + pydantic.dataclasses: pydantic + pydantic.datetime_parse: pydantic + pydantic.decorator: pydantic + pydantic.deprecated: pydantic + pydantic.deprecated.class_validators: pydantic + pydantic.deprecated.config: pydantic + pydantic.deprecated.copy_internals: pydantic + pydantic.deprecated.decorator: pydantic + pydantic.deprecated.json: pydantic + pydantic.deprecated.parse: pydantic + pydantic.deprecated.tools: pydantic + pydantic.env_settings: pydantic + pydantic.error_wrappers: pydantic + pydantic.errors: pydantic + pydantic.experimental: pydantic + pydantic.experimental.arguments_schema: pydantic + pydantic.experimental.pipeline: pydantic + pydantic.fields: pydantic + pydantic.functional_serializers: pydantic + pydantic.functional_validators: pydantic + pydantic.generics: pydantic + pydantic.json: pydantic + pydantic.json_schema: pydantic + pydantic.main: pydantic + pydantic.mypy: pydantic + pydantic.networks: pydantic + pydantic.parse: pydantic + pydantic.plugin: pydantic + pydantic.root_model: pydantic + pydantic.schema: pydantic + pydantic.tools: pydantic + pydantic.type_adapter: pydantic + pydantic.types: pydantic + pydantic.typing: pydantic + pydantic.utils: pydantic + pydantic.v1: pydantic + pydantic.v1.annotated_types: pydantic + pydantic.v1.class_validators: pydantic + pydantic.v1.color: pydantic + pydantic.v1.config: pydantic + pydantic.v1.dataclasses: pydantic + pydantic.v1.datetime_parse: pydantic + pydantic.v1.decorator: pydantic + pydantic.v1.env_settings: pydantic + pydantic.v1.error_wrappers: pydantic + pydantic.v1.errors: pydantic + pydantic.v1.fields: pydantic + pydantic.v1.generics: pydantic + pydantic.v1.json: pydantic + pydantic.v1.main: pydantic + pydantic.v1.mypy: pydantic + pydantic.v1.networks: pydantic + pydantic.v1.parse: pydantic + pydantic.v1.schema: pydantic + pydantic.v1.tools: pydantic + pydantic.v1.types: pydantic + pydantic.v1.typing: pydantic + pydantic.v1.utils: pydantic + pydantic.v1.validators: pydantic + pydantic.v1.version: pydantic + pydantic.validate_call_decorator: pydantic + pydantic.validators: pydantic + pydantic.version: pydantic + pydantic.warnings: pydantic + pydantic_core: pydantic_core + pydantic_core.core_schema: pydantic_core + pygments: pygments + pygments.cmdline: pygments + pygments.console: pygments + pygments.filter: pygments + pygments.filters: pygments + pygments.formatter: pygments + pygments.formatters: pygments + pygments.formatters.bbcode: pygments + pygments.formatters.groff: pygments + pygments.formatters.html: pygments + pygments.formatters.img: pygments + pygments.formatters.irc: pygments + pygments.formatters.latex: pygments + pygments.formatters.other: pygments + pygments.formatters.pangomarkup: pygments + pygments.formatters.rtf: pygments + pygments.formatters.svg: pygments + pygments.formatters.terminal: pygments + pygments.formatters.terminal256: pygments + pygments.lexer: pygments + pygments.lexers: pygments + pygments.lexers.actionscript: pygments + pygments.lexers.ada: pygments + pygments.lexers.agile: pygments + pygments.lexers.algebra: pygments + pygments.lexers.ambient: pygments + pygments.lexers.amdgpu: pygments + pygments.lexers.ampl: pygments + pygments.lexers.apdlexer: pygments + pygments.lexers.apl: pygments + pygments.lexers.archetype: pygments + pygments.lexers.arrow: pygments + pygments.lexers.arturo: pygments + pygments.lexers.asc: pygments + pygments.lexers.asm: pygments + pygments.lexers.asn1: pygments + pygments.lexers.automation: pygments + pygments.lexers.bare: pygments + pygments.lexers.basic: pygments + pygments.lexers.bdd: pygments + pygments.lexers.berry: pygments + pygments.lexers.bibtex: pygments + pygments.lexers.blueprint: pygments + pygments.lexers.boa: pygments + pygments.lexers.bqn: pygments + pygments.lexers.business: pygments + pygments.lexers.c_cpp: pygments + pygments.lexers.c_like: pygments + pygments.lexers.capnproto: pygments + pygments.lexers.carbon: pygments + pygments.lexers.cddl: pygments + pygments.lexers.chapel: pygments + pygments.lexers.clean: pygments + pygments.lexers.codeql: pygments + pygments.lexers.comal: pygments + pygments.lexers.compiled: pygments + pygments.lexers.configs: pygments + pygments.lexers.console: pygments + pygments.lexers.cplint: pygments + pygments.lexers.crystal: pygments + pygments.lexers.csound: pygments + pygments.lexers.css: pygments + pygments.lexers.d: pygments + pygments.lexers.dalvik: pygments + pygments.lexers.data: pygments + pygments.lexers.dax: pygments + pygments.lexers.devicetree: pygments + pygments.lexers.diff: pygments + pygments.lexers.dns: pygments + pygments.lexers.dotnet: pygments + pygments.lexers.dsls: pygments + pygments.lexers.dylan: pygments + pygments.lexers.ecl: pygments + pygments.lexers.eiffel: pygments + pygments.lexers.elm: pygments + pygments.lexers.elpi: pygments + pygments.lexers.email: pygments + pygments.lexers.erlang: pygments + pygments.lexers.esoteric: pygments + pygments.lexers.ezhil: pygments + pygments.lexers.factor: pygments + pygments.lexers.fantom: pygments + pygments.lexers.felix: pygments + pygments.lexers.fift: pygments + pygments.lexers.floscript: pygments + pygments.lexers.forth: pygments + pygments.lexers.fortran: pygments + pygments.lexers.foxpro: pygments + pygments.lexers.freefem: pygments + pygments.lexers.func: pygments + pygments.lexers.functional: pygments + pygments.lexers.futhark: pygments + pygments.lexers.gcodelexer: pygments + pygments.lexers.gdscript: pygments + pygments.lexers.gleam: pygments + pygments.lexers.go: pygments + pygments.lexers.grammar_notation: pygments + pygments.lexers.graph: pygments + pygments.lexers.graphics: pygments + pygments.lexers.graphql: pygments + pygments.lexers.graphviz: pygments + pygments.lexers.gsql: pygments + pygments.lexers.hare: pygments + pygments.lexers.haskell: pygments + pygments.lexers.haxe: pygments + pygments.lexers.hdl: pygments + pygments.lexers.hexdump: pygments + pygments.lexers.html: pygments + pygments.lexers.idl: pygments + pygments.lexers.igor: pygments + pygments.lexers.inferno: pygments + pygments.lexers.installers: pygments + pygments.lexers.int_fiction: pygments + pygments.lexers.iolang: pygments + pygments.lexers.j: pygments + pygments.lexers.javascript: pygments + pygments.lexers.jmespath: pygments + pygments.lexers.jslt: pygments + pygments.lexers.json5: pygments + pygments.lexers.jsonnet: pygments + pygments.lexers.jsx: pygments + pygments.lexers.julia: pygments + pygments.lexers.jvm: pygments + pygments.lexers.kuin: pygments + pygments.lexers.kusto: pygments + pygments.lexers.ldap: pygments + pygments.lexers.lean: pygments + pygments.lexers.lilypond: pygments + pygments.lexers.lisp: pygments + pygments.lexers.macaulay2: pygments + pygments.lexers.make: pygments + pygments.lexers.maple: pygments + pygments.lexers.markup: pygments + pygments.lexers.math: pygments + pygments.lexers.matlab: pygments + pygments.lexers.maxima: pygments + pygments.lexers.meson: pygments + pygments.lexers.mime: pygments + pygments.lexers.minecraft: pygments + pygments.lexers.mips: pygments + pygments.lexers.ml: pygments + pygments.lexers.modeling: pygments + pygments.lexers.modula2: pygments + pygments.lexers.mojo: pygments + pygments.lexers.monte: pygments + pygments.lexers.mosel: pygments + pygments.lexers.ncl: pygments + pygments.lexers.nimrod: pygments + pygments.lexers.nit: pygments + pygments.lexers.nix: pygments + pygments.lexers.numbair: pygments + pygments.lexers.oberon: pygments + pygments.lexers.objective: pygments + pygments.lexers.ooc: pygments + pygments.lexers.openscad: pygments + pygments.lexers.other: pygments + pygments.lexers.parasail: pygments + pygments.lexers.parsers: pygments + pygments.lexers.pascal: pygments + pygments.lexers.pawn: pygments + pygments.lexers.pddl: pygments + pygments.lexers.perl: pygments + pygments.lexers.phix: pygments + pygments.lexers.php: pygments + pygments.lexers.pointless: pygments + pygments.lexers.pony: pygments + pygments.lexers.praat: pygments + pygments.lexers.procfile: pygments + pygments.lexers.prolog: pygments + pygments.lexers.promql: pygments + pygments.lexers.prql: pygments + pygments.lexers.ptx: pygments + pygments.lexers.python: pygments + pygments.lexers.q: pygments + pygments.lexers.qlik: pygments + pygments.lexers.qvt: pygments + pygments.lexers.r: pygments + pygments.lexers.rdf: pygments + pygments.lexers.rebol: pygments + pygments.lexers.rego: pygments + pygments.lexers.resource: pygments + pygments.lexers.ride: pygments + pygments.lexers.rita: pygments + pygments.lexers.rnc: pygments + pygments.lexers.roboconf: pygments + pygments.lexers.robotframework: pygments + pygments.lexers.ruby: pygments + pygments.lexers.rust: pygments + pygments.lexers.sas: pygments + pygments.lexers.savi: pygments + pygments.lexers.scdoc: pygments + pygments.lexers.scripting: pygments + pygments.lexers.sgf: pygments + pygments.lexers.shell: pygments + pygments.lexers.sieve: pygments + pygments.lexers.slash: pygments + pygments.lexers.smalltalk: pygments + pygments.lexers.smithy: pygments + pygments.lexers.smv: pygments + pygments.lexers.snobol: pygments + pygments.lexers.solidity: pygments + pygments.lexers.soong: pygments + pygments.lexers.sophia: pygments + pygments.lexers.special: pygments + pygments.lexers.spice: pygments + pygments.lexers.sql: pygments + pygments.lexers.srcinfo: pygments + pygments.lexers.stata: pygments + pygments.lexers.supercollider: pygments + pygments.lexers.tablegen: pygments + pygments.lexers.tact: pygments + pygments.lexers.tal: pygments + pygments.lexers.tcl: pygments + pygments.lexers.teal: pygments + pygments.lexers.templates: pygments + pygments.lexers.teraterm: pygments + pygments.lexers.testing: pygments + pygments.lexers.text: pygments + pygments.lexers.textedit: pygments + pygments.lexers.textfmts: pygments + pygments.lexers.theorem: pygments + pygments.lexers.thingsdb: pygments + pygments.lexers.tlb: pygments + pygments.lexers.tls: pygments + pygments.lexers.tnt: pygments + pygments.lexers.trafficscript: pygments + pygments.lexers.typoscript: pygments + pygments.lexers.typst: pygments + pygments.lexers.ul4: pygments + pygments.lexers.unicon: pygments + pygments.lexers.urbi: pygments + pygments.lexers.usd: pygments + pygments.lexers.varnish: pygments + pygments.lexers.verification: pygments + pygments.lexers.verifpal: pygments + pygments.lexers.vip: pygments + pygments.lexers.vyper: pygments + pygments.lexers.web: pygments + pygments.lexers.webassembly: pygments + pygments.lexers.webidl: pygments + pygments.lexers.webmisc: pygments + pygments.lexers.wgsl: pygments + pygments.lexers.whiley: pygments + pygments.lexers.wowtoc: pygments + pygments.lexers.wren: pygments + pygments.lexers.x10: pygments + pygments.lexers.xorg: pygments + pygments.lexers.yang: pygments + pygments.lexers.yara: pygments + pygments.lexers.zig: pygments + pygments.modeline: pygments + pygments.plugin: pygments + pygments.regexopt: pygments + pygments.scanner: pygments + pygments.sphinxext: pygments + pygments.style: pygments + pygments.styles: pygments + pygments.styles.abap: pygments + pygments.styles.algol: pygments + pygments.styles.algol_nu: pygments + pygments.styles.arduino: pygments + pygments.styles.autumn: pygments + pygments.styles.borland: pygments + pygments.styles.bw: pygments + pygments.styles.coffee: pygments + pygments.styles.colorful: pygments + pygments.styles.default: pygments + pygments.styles.dracula: pygments + pygments.styles.emacs: pygments + pygments.styles.friendly: pygments + pygments.styles.friendly_grayscale: pygments + pygments.styles.fruity: pygments + pygments.styles.gh_dark: pygments + pygments.styles.gruvbox: pygments + pygments.styles.igor: pygments + pygments.styles.inkpot: pygments + pygments.styles.lightbulb: pygments + pygments.styles.lilypond: pygments + pygments.styles.lovelace: pygments + pygments.styles.manni: pygments + pygments.styles.material: pygments + pygments.styles.monokai: pygments + pygments.styles.murphy: pygments + pygments.styles.native: pygments + pygments.styles.nord: pygments + pygments.styles.onedark: pygments + pygments.styles.paraiso_dark: pygments + pygments.styles.paraiso_light: pygments + pygments.styles.pastie: pygments + pygments.styles.perldoc: pygments + pygments.styles.rainbow_dash: pygments + pygments.styles.rrt: pygments + pygments.styles.sas: pygments + pygments.styles.solarized: pygments + pygments.styles.staroffice: pygments + pygments.styles.stata_dark: pygments + pygments.styles.stata_light: pygments + pygments.styles.tango: pygments + pygments.styles.trac: pygments + pygments.styles.vim: pygments + pygments.styles.vs: pygments + pygments.styles.xcode: pygments + pygments.styles.zenburn: pygments + pygments.token: pygments + pygments.unistring: pygments + pygments.util: pygments + pygtrie: pygtrie + pyproject_hooks: pyproject_hooks + python_multipart: python_multipart + python_multipart.decoders: python_multipart + python_multipart.exceptions: python_multipart + python_multipart.multipart: python_multipart + pytz: pytz + pytz.exceptions: pytz + pytz.lazy: pytz + pytz.reference: pytz + pytz.tzfile: pytz + pytz.tzinfo: pytz + referencing: referencing + referencing.exceptions: referencing + referencing.jsonschema: referencing + referencing.retrieval: referencing + referencing.tests: referencing + referencing.tests.test_core: referencing + referencing.tests.test_exceptions: referencing + referencing.tests.test_jsonschema: referencing + referencing.tests.test_referencing_suite: referencing + referencing.tests.test_retrieval: referencing + referencing.typing: referencing + requests: requests + requests.adapters: requests + requests.api: requests + requests.auth: requests + requests.certs: requests + requests.compat: requests + requests.cookies: requests + requests.exceptions: requests + requests.help: requests + requests.hooks: requests + requests.models: requests + requests.packages: requests + requests.sessions: requests + requests.status_codes: requests + requests.structures: requests + requests.utils: requests + retryhttp: retryhttp + rich: rich + rich.abc: rich + rich.align: rich + rich.ansi: rich + rich.bar: rich + rich.box: rich + rich.cells: rich + rich.color: rich + rich.color_triplet: rich + rich.columns: rich + rich.console: rich + rich.constrain: rich + rich.containers: rich + rich.control: rich + rich.default_styles: rich + rich.diagnose: rich + rich.emoji: rich + rich.errors: rich + rich.file_proxy: rich + rich.filesize: rich + rich.highlighter: rich + rich.json: rich + rich.jupyter: rich + rich.layout: rich + rich.live: rich + rich.live_render: rich + rich.logging: rich + rich.markdown: rich + rich.markup: rich + rich.measure: rich + rich.padding: rich + rich.pager: rich + rich.palette: rich + rich.panel: rich + rich.pretty: rich + rich.progress: rich + rich.progress_bar: rich + rich.prompt: rich + rich.protocol: rich + rich.region: rich + rich.repr: rich + rich.rule: rich + rich.scope: rich + rich.screen: rich + rich.segment: rich + rich.spinner: rich + rich.status: rich + rich.style: rich + rich.styled: rich + rich.syntax: rich + rich.table: rich + rich.terminal_theme: rich + rich.text: rich + rich.theme: rich + rich.themes: rich + rich.traceback: rich + rich.tree: rich + rich_argparse: rich_argparse + rich_argparse.contrib: rich_argparse + rich_argparse.django: rich_argparse + rich_argparse.optparse: rich_argparse + rich_toolkit: rich_toolkit + rich_toolkit.button: rich_toolkit + rich_toolkit.container: rich_toolkit + rich_toolkit.element: rich_toolkit + rich_toolkit.form: rich_toolkit + rich_toolkit.input: rich_toolkit + rich_toolkit.menu: rich_toolkit + rich_toolkit.progress: rich_toolkit + rich_toolkit.spacer: rich_toolkit + rich_toolkit.styles: rich_toolkit + rich_toolkit.styles.base: rich_toolkit + rich_toolkit.styles.border: rich_toolkit + rich_toolkit.styles.fancy: rich_toolkit + rich_toolkit.styles.minimal: rich_toolkit + rich_toolkit.styles.tagged: rich_toolkit + rich_toolkit.toolkit: rich_toolkit + rich_toolkit.utils: rich_toolkit + rich_toolkit.utils.colors: rich_toolkit + rich_toolkit.utils.map_range: rich_toolkit + rpds: rpds_py + setproctitle: setproctitle + setuptools: setuptools + setuptools.archive_util: setuptools + setuptools.build_meta: setuptools + setuptools.command: setuptools + setuptools.command.alias: setuptools + setuptools.command.bdist_egg: setuptools + setuptools.command.bdist_rpm: setuptools + setuptools.command.bdist_wheel: setuptools + setuptools.command.build: setuptools + setuptools.command.build_clib: setuptools + setuptools.command.build_ext: setuptools + setuptools.command.build_py: setuptools + setuptools.command.develop: setuptools + setuptools.command.dist_info: setuptools + setuptools.command.easy_install: setuptools + setuptools.command.editable_wheel: setuptools + setuptools.command.egg_info: setuptools + setuptools.command.install: setuptools + setuptools.command.install_egg_info: setuptools + setuptools.command.install_lib: setuptools + setuptools.command.install_scripts: setuptools + setuptools.command.rotate: setuptools + setuptools.command.saveopts: setuptools + setuptools.command.sdist: setuptools + setuptools.command.setopt: setuptools + setuptools.command.test: setuptools + setuptools.compat: setuptools + setuptools.compat.py310: setuptools + setuptools.compat.py311: setuptools + setuptools.compat.py312: setuptools + setuptools.compat.py39: setuptools + setuptools.config: setuptools + setuptools.config.expand: setuptools + setuptools.config.pyprojecttoml: setuptools + setuptools.config.setupcfg: setuptools + setuptools.depends: setuptools + setuptools.discovery: setuptools + setuptools.dist: setuptools + setuptools.errors: setuptools + setuptools.extension: setuptools + setuptools.glob: setuptools + setuptools.installer: setuptools + setuptools.launch: setuptools + setuptools.logging: setuptools + setuptools.modified: setuptools + setuptools.monkey: setuptools + setuptools.msvc: setuptools + setuptools.namespaces: setuptools + setuptools.tests: setuptools + setuptools.tests.compat: setuptools + setuptools.tests.compat.py39: setuptools + setuptools.tests.config: setuptools + setuptools.tests.config.downloads: setuptools + setuptools.tests.config.downloads.preload: setuptools + setuptools.tests.config.test_apply_pyprojecttoml: setuptools + setuptools.tests.config.test_expand: setuptools + setuptools.tests.config.test_pyprojecttoml: setuptools + setuptools.tests.config.test_pyprojecttoml_dynamic_deps: setuptools + setuptools.tests.config.test_setupcfg: setuptools + setuptools.tests.contexts: setuptools + setuptools.tests.environment: setuptools + setuptools.tests.fixtures: setuptools + setuptools.tests.integration: setuptools + setuptools.tests.integration.helpers: setuptools + setuptools.tests.integration.test_pbr: setuptools + setuptools.tests.integration.test_pip_install_sdist: setuptools + setuptools.tests.mod_with_constant: setuptools + setuptools.tests.namespaces: setuptools + setuptools.tests.script_with_bom: setuptools + setuptools.tests.test_archive_util: setuptools + setuptools.tests.test_bdist_deprecations: setuptools + setuptools.tests.test_bdist_egg: setuptools + setuptools.tests.test_bdist_wheel: setuptools + setuptools.tests.test_build: setuptools + setuptools.tests.test_build_clib: setuptools + setuptools.tests.test_build_ext: setuptools + setuptools.tests.test_build_meta: setuptools + setuptools.tests.test_build_py: setuptools + setuptools.tests.test_config_discovery: setuptools + setuptools.tests.test_core_metadata: setuptools + setuptools.tests.test_depends: setuptools + setuptools.tests.test_develop: setuptools + setuptools.tests.test_dist: setuptools + setuptools.tests.test_dist_info: setuptools + setuptools.tests.test_distutils_adoption: setuptools + setuptools.tests.test_editable_install: setuptools + setuptools.tests.test_egg_info: setuptools + setuptools.tests.test_extern: setuptools + setuptools.tests.test_find_packages: setuptools + setuptools.tests.test_find_py_modules: setuptools + setuptools.tests.test_glob: setuptools + setuptools.tests.test_install_scripts: setuptools + setuptools.tests.test_logging: setuptools + setuptools.tests.test_manifest: setuptools + setuptools.tests.test_namespaces: setuptools + setuptools.tests.test_scripts: setuptools + setuptools.tests.test_sdist: setuptools + setuptools.tests.test_setopt: setuptools + setuptools.tests.test_setuptools: setuptools + setuptools.tests.test_shutil_wrapper: setuptools + setuptools.tests.test_unicode_utils: setuptools + setuptools.tests.test_virtualenv: setuptools + setuptools.tests.test_warnings: setuptools + setuptools.tests.test_wheel: setuptools + setuptools.tests.test_windows_wrappers: setuptools + setuptools.tests.text: setuptools + setuptools.tests.textwrap: setuptools + setuptools.unicode_utils: setuptools + setuptools.version: setuptools + setuptools.warnings: setuptools + setuptools.wheel: setuptools + setuptools.windows_support: setuptools + shellingham: shellingham + shellingham.nt: shellingham + shellingham.posix: shellingham + shellingham.posix.proc: shellingham + shellingham.posix.ps: shellingham + six: six + slugify: python_slugify + slugify.slugify: python_slugify + slugify.special: python_slugify + sniffio: sniffio + sqlalchemy: sqlalchemy + sqlalchemy.connectors: sqlalchemy + sqlalchemy.connectors.aioodbc: sqlalchemy + sqlalchemy.connectors.asyncio: sqlalchemy + sqlalchemy.connectors.pyodbc: sqlalchemy + sqlalchemy.cyextension: sqlalchemy + sqlalchemy.dialects: sqlalchemy + sqlalchemy.dialects.mssql: sqlalchemy + sqlalchemy.dialects.mssql.aioodbc: sqlalchemy + sqlalchemy.dialects.mssql.base: sqlalchemy + sqlalchemy.dialects.mssql.information_schema: sqlalchemy + sqlalchemy.dialects.mssql.json: sqlalchemy + sqlalchemy.dialects.mssql.provision: sqlalchemy + sqlalchemy.dialects.mssql.pymssql: sqlalchemy + sqlalchemy.dialects.mssql.pyodbc: sqlalchemy + sqlalchemy.dialects.mysql: sqlalchemy + sqlalchemy.dialects.mysql.aiomysql: sqlalchemy + sqlalchemy.dialects.mysql.asyncmy: sqlalchemy + sqlalchemy.dialects.mysql.base: sqlalchemy + sqlalchemy.dialects.mysql.cymysql: sqlalchemy + sqlalchemy.dialects.mysql.dml: sqlalchemy + sqlalchemy.dialects.mysql.enumerated: sqlalchemy + sqlalchemy.dialects.mysql.expression: sqlalchemy + sqlalchemy.dialects.mysql.json: sqlalchemy + sqlalchemy.dialects.mysql.mariadb: sqlalchemy + sqlalchemy.dialects.mysql.mariadbconnector: sqlalchemy + sqlalchemy.dialects.mysql.mysqlconnector: sqlalchemy + sqlalchemy.dialects.mysql.mysqldb: sqlalchemy + sqlalchemy.dialects.mysql.provision: sqlalchemy + sqlalchemy.dialects.mysql.pymysql: sqlalchemy + sqlalchemy.dialects.mysql.pyodbc: sqlalchemy + sqlalchemy.dialects.mysql.reflection: sqlalchemy + sqlalchemy.dialects.mysql.reserved_words: sqlalchemy + sqlalchemy.dialects.mysql.types: sqlalchemy + sqlalchemy.dialects.oracle: sqlalchemy + sqlalchemy.dialects.oracle.base: sqlalchemy + sqlalchemy.dialects.oracle.cx_oracle: sqlalchemy + sqlalchemy.dialects.oracle.dictionary: sqlalchemy + sqlalchemy.dialects.oracle.oracledb: sqlalchemy + sqlalchemy.dialects.oracle.provision: sqlalchemy + sqlalchemy.dialects.oracle.types: sqlalchemy + sqlalchemy.dialects.oracle.vector: sqlalchemy + sqlalchemy.dialects.postgresql: sqlalchemy + sqlalchemy.dialects.postgresql.array: sqlalchemy + sqlalchemy.dialects.postgresql.asyncpg: sqlalchemy + sqlalchemy.dialects.postgresql.base: sqlalchemy + sqlalchemy.dialects.postgresql.dml: sqlalchemy + sqlalchemy.dialects.postgresql.ext: sqlalchemy + sqlalchemy.dialects.postgresql.hstore: sqlalchemy + sqlalchemy.dialects.postgresql.json: sqlalchemy + sqlalchemy.dialects.postgresql.named_types: sqlalchemy + sqlalchemy.dialects.postgresql.operators: sqlalchemy + sqlalchemy.dialects.postgresql.pg8000: sqlalchemy + sqlalchemy.dialects.postgresql.pg_catalog: sqlalchemy + sqlalchemy.dialects.postgresql.provision: sqlalchemy + sqlalchemy.dialects.postgresql.psycopg: sqlalchemy + sqlalchemy.dialects.postgresql.psycopg2: sqlalchemy + sqlalchemy.dialects.postgresql.psycopg2cffi: sqlalchemy + sqlalchemy.dialects.postgresql.ranges: sqlalchemy + sqlalchemy.dialects.postgresql.types: sqlalchemy + sqlalchemy.dialects.sqlite: sqlalchemy + sqlalchemy.dialects.sqlite.aiosqlite: sqlalchemy + sqlalchemy.dialects.sqlite.base: sqlalchemy + sqlalchemy.dialects.sqlite.dml: sqlalchemy + sqlalchemy.dialects.sqlite.json: sqlalchemy + sqlalchemy.dialects.sqlite.provision: sqlalchemy + sqlalchemy.dialects.sqlite.pysqlcipher: sqlalchemy + sqlalchemy.dialects.sqlite.pysqlite: sqlalchemy + sqlalchemy.engine: sqlalchemy + sqlalchemy.engine.base: sqlalchemy + sqlalchemy.engine.characteristics: sqlalchemy + sqlalchemy.engine.create: sqlalchemy + sqlalchemy.engine.cursor: sqlalchemy + sqlalchemy.engine.default: sqlalchemy + sqlalchemy.engine.events: sqlalchemy + sqlalchemy.engine.interfaces: sqlalchemy + sqlalchemy.engine.mock: sqlalchemy + sqlalchemy.engine.processors: sqlalchemy + sqlalchemy.engine.reflection: sqlalchemy + sqlalchemy.engine.result: sqlalchemy + sqlalchemy.engine.row: sqlalchemy + sqlalchemy.engine.strategies: sqlalchemy + sqlalchemy.engine.url: sqlalchemy + sqlalchemy.engine.util: sqlalchemy + sqlalchemy.event: sqlalchemy + sqlalchemy.event.api: sqlalchemy + sqlalchemy.event.attr: sqlalchemy + sqlalchemy.event.base: sqlalchemy + sqlalchemy.event.legacy: sqlalchemy + sqlalchemy.event.registry: sqlalchemy + sqlalchemy.events: sqlalchemy + sqlalchemy.exc: sqlalchemy + sqlalchemy.ext: sqlalchemy + sqlalchemy.ext.associationproxy: sqlalchemy + sqlalchemy.ext.asyncio: sqlalchemy + sqlalchemy.ext.asyncio.base: sqlalchemy + sqlalchemy.ext.asyncio.engine: sqlalchemy + sqlalchemy.ext.asyncio.exc: sqlalchemy + sqlalchemy.ext.asyncio.result: sqlalchemy + sqlalchemy.ext.asyncio.scoping: sqlalchemy + sqlalchemy.ext.asyncio.session: sqlalchemy + sqlalchemy.ext.automap: sqlalchemy + sqlalchemy.ext.baked: sqlalchemy + sqlalchemy.ext.compiler: sqlalchemy + sqlalchemy.ext.declarative: sqlalchemy + sqlalchemy.ext.declarative.extensions: sqlalchemy + sqlalchemy.ext.horizontal_shard: sqlalchemy + sqlalchemy.ext.hybrid: sqlalchemy + sqlalchemy.ext.indexable: sqlalchemy + sqlalchemy.ext.instrumentation: sqlalchemy + sqlalchemy.ext.mutable: sqlalchemy + sqlalchemy.ext.mypy: sqlalchemy + sqlalchemy.ext.mypy.apply: sqlalchemy + sqlalchemy.ext.mypy.decl_class: sqlalchemy + sqlalchemy.ext.mypy.infer: sqlalchemy + sqlalchemy.ext.mypy.names: sqlalchemy + sqlalchemy.ext.mypy.plugin: sqlalchemy + sqlalchemy.ext.mypy.util: sqlalchemy + sqlalchemy.ext.orderinglist: sqlalchemy + sqlalchemy.ext.serializer: sqlalchemy + sqlalchemy.future: sqlalchemy + sqlalchemy.future.engine: sqlalchemy + sqlalchemy.inspection: sqlalchemy + sqlalchemy.log: sqlalchemy + sqlalchemy.orm: sqlalchemy + sqlalchemy.orm.attributes: sqlalchemy + sqlalchemy.orm.base: sqlalchemy + sqlalchemy.orm.bulk_persistence: sqlalchemy + sqlalchemy.orm.clsregistry: sqlalchemy + sqlalchemy.orm.collections: sqlalchemy + sqlalchemy.orm.context: sqlalchemy + sqlalchemy.orm.decl_api: sqlalchemy + sqlalchemy.orm.decl_base: sqlalchemy + sqlalchemy.orm.dependency: sqlalchemy + sqlalchemy.orm.descriptor_props: sqlalchemy + sqlalchemy.orm.dynamic: sqlalchemy + sqlalchemy.orm.evaluator: sqlalchemy + sqlalchemy.orm.events: sqlalchemy + sqlalchemy.orm.exc: sqlalchemy + sqlalchemy.orm.identity: sqlalchemy + sqlalchemy.orm.instrumentation: sqlalchemy + sqlalchemy.orm.interfaces: sqlalchemy + sqlalchemy.orm.loading: sqlalchemy + sqlalchemy.orm.mapped_collection: sqlalchemy + sqlalchemy.orm.mapper: sqlalchemy + sqlalchemy.orm.path_registry: sqlalchemy + sqlalchemy.orm.persistence: sqlalchemy + sqlalchemy.orm.properties: sqlalchemy + sqlalchemy.orm.query: sqlalchemy + sqlalchemy.orm.relationships: sqlalchemy + sqlalchemy.orm.scoping: sqlalchemy + sqlalchemy.orm.session: sqlalchemy + sqlalchemy.orm.state: sqlalchemy + sqlalchemy.orm.state_changes: sqlalchemy + sqlalchemy.orm.strategies: sqlalchemy + sqlalchemy.orm.strategy_options: sqlalchemy + sqlalchemy.orm.sync: sqlalchemy + sqlalchemy.orm.unitofwork: sqlalchemy + sqlalchemy.orm.util: sqlalchemy + sqlalchemy.orm.writeonly: sqlalchemy + sqlalchemy.pool: sqlalchemy + sqlalchemy.pool.base: sqlalchemy + sqlalchemy.pool.events: sqlalchemy + sqlalchemy.pool.impl: sqlalchemy + sqlalchemy.schema: sqlalchemy + sqlalchemy.sql: sqlalchemy + sqlalchemy.sql.annotation: sqlalchemy + sqlalchemy.sql.base: sqlalchemy + sqlalchemy.sql.cache_key: sqlalchemy + sqlalchemy.sql.coercions: sqlalchemy + sqlalchemy.sql.compiler: sqlalchemy + sqlalchemy.sql.crud: sqlalchemy + sqlalchemy.sql.ddl: sqlalchemy + sqlalchemy.sql.default_comparator: sqlalchemy + sqlalchemy.sql.dml: sqlalchemy + sqlalchemy.sql.elements: sqlalchemy + sqlalchemy.sql.events: sqlalchemy + sqlalchemy.sql.expression: sqlalchemy + sqlalchemy.sql.functions: sqlalchemy + sqlalchemy.sql.lambdas: sqlalchemy + sqlalchemy.sql.naming: sqlalchemy + sqlalchemy.sql.operators: sqlalchemy + sqlalchemy.sql.roles: sqlalchemy + sqlalchemy.sql.schema: sqlalchemy + sqlalchemy.sql.selectable: sqlalchemy + sqlalchemy.sql.sqltypes: sqlalchemy + sqlalchemy.sql.traversals: sqlalchemy + sqlalchemy.sql.type_api: sqlalchemy + sqlalchemy.sql.util: sqlalchemy + sqlalchemy.sql.visitors: sqlalchemy + sqlalchemy.testing: sqlalchemy + sqlalchemy.testing.assertions: sqlalchemy + sqlalchemy.testing.assertsql: sqlalchemy + sqlalchemy.testing.asyncio: sqlalchemy + sqlalchemy.testing.config: sqlalchemy + sqlalchemy.testing.engines: sqlalchemy + sqlalchemy.testing.entities: sqlalchemy + sqlalchemy.testing.exclusions: sqlalchemy + sqlalchemy.testing.fixtures: sqlalchemy + sqlalchemy.testing.fixtures.base: sqlalchemy + sqlalchemy.testing.fixtures.mypy: sqlalchemy + sqlalchemy.testing.fixtures.orm: sqlalchemy + sqlalchemy.testing.fixtures.sql: sqlalchemy + sqlalchemy.testing.pickleable: sqlalchemy + sqlalchemy.testing.plugin: sqlalchemy + sqlalchemy.testing.plugin.bootstrap: sqlalchemy + sqlalchemy.testing.plugin.plugin_base: sqlalchemy + sqlalchemy.testing.plugin.pytestplugin: sqlalchemy + sqlalchemy.testing.profiling: sqlalchemy + sqlalchemy.testing.provision: sqlalchemy + sqlalchemy.testing.requirements: sqlalchemy + sqlalchemy.testing.schema: sqlalchemy + sqlalchemy.testing.suite: sqlalchemy + sqlalchemy.testing.suite.test_cte: sqlalchemy + sqlalchemy.testing.suite.test_ddl: sqlalchemy + sqlalchemy.testing.suite.test_deprecations: sqlalchemy + sqlalchemy.testing.suite.test_dialect: sqlalchemy + sqlalchemy.testing.suite.test_insert: sqlalchemy + sqlalchemy.testing.suite.test_reflection: sqlalchemy + sqlalchemy.testing.suite.test_results: sqlalchemy + sqlalchemy.testing.suite.test_rowcount: sqlalchemy + sqlalchemy.testing.suite.test_select: sqlalchemy + sqlalchemy.testing.suite.test_sequence: sqlalchemy + sqlalchemy.testing.suite.test_types: sqlalchemy + sqlalchemy.testing.suite.test_unicode_ddl: sqlalchemy + sqlalchemy.testing.suite.test_update_delete: sqlalchemy + sqlalchemy.testing.util: sqlalchemy + sqlalchemy.testing.warnings: sqlalchemy + sqlalchemy.types: sqlalchemy + sqlalchemy.util: sqlalchemy + sqlalchemy.util.compat: sqlalchemy + sqlalchemy.util.concurrency: sqlalchemy + sqlalchemy.util.deprecations: sqlalchemy + sqlalchemy.util.langhelpers: sqlalchemy + sqlalchemy.util.preloaded: sqlalchemy + sqlalchemy.util.queue: sqlalchemy + sqlalchemy.util.tool_support: sqlalchemy + sqlalchemy.util.topological: sqlalchemy + sqlalchemy.util.typing: sqlalchemy + sqlalchemy_jsonfield: sqlalchemy_jsonfield + sqlalchemy_jsonfield.jsonfield: sqlalchemy_jsonfield + sqlalchemy_utils: sqlalchemy_utils + sqlalchemy_utils.aggregates: sqlalchemy_utils + sqlalchemy_utils.asserts: sqlalchemy_utils + sqlalchemy_utils.compat: sqlalchemy_utils + sqlalchemy_utils.exceptions: sqlalchemy_utils + sqlalchemy_utils.expressions: sqlalchemy_utils + sqlalchemy_utils.functions: sqlalchemy_utils + sqlalchemy_utils.functions.database: sqlalchemy_utils + sqlalchemy_utils.functions.foreign_keys: sqlalchemy_utils + sqlalchemy_utils.functions.mock: sqlalchemy_utils + sqlalchemy_utils.functions.orm: sqlalchemy_utils + sqlalchemy_utils.functions.render: sqlalchemy_utils + sqlalchemy_utils.functions.sort_query: sqlalchemy_utils + sqlalchemy_utils.generic: sqlalchemy_utils + sqlalchemy_utils.i18n: sqlalchemy_utils + sqlalchemy_utils.listeners: sqlalchemy_utils + sqlalchemy_utils.models: sqlalchemy_utils + sqlalchemy_utils.observer: sqlalchemy_utils + sqlalchemy_utils.operators: sqlalchemy_utils + sqlalchemy_utils.path: sqlalchemy_utils + sqlalchemy_utils.primitives: sqlalchemy_utils + sqlalchemy_utils.primitives.country: sqlalchemy_utils + sqlalchemy_utils.primitives.currency: sqlalchemy_utils + sqlalchemy_utils.primitives.ltree: sqlalchemy_utils + sqlalchemy_utils.primitives.weekday: sqlalchemy_utils + sqlalchemy_utils.primitives.weekdays: sqlalchemy_utils + sqlalchemy_utils.proxy_dict: sqlalchemy_utils + sqlalchemy_utils.query_chain: sqlalchemy_utils + sqlalchemy_utils.relationships: sqlalchemy_utils + sqlalchemy_utils.relationships.chained_join: sqlalchemy_utils + sqlalchemy_utils.types: sqlalchemy_utils + sqlalchemy_utils.types.arrow: sqlalchemy_utils + sqlalchemy_utils.types.bit: sqlalchemy_utils + sqlalchemy_utils.types.choice: sqlalchemy_utils + sqlalchemy_utils.types.color: sqlalchemy_utils + sqlalchemy_utils.types.country: sqlalchemy_utils + sqlalchemy_utils.types.currency: sqlalchemy_utils + sqlalchemy_utils.types.email: sqlalchemy_utils + sqlalchemy_utils.types.encrypted: sqlalchemy_utils + sqlalchemy_utils.types.encrypted.encrypted_type: sqlalchemy_utils + sqlalchemy_utils.types.encrypted.padding: sqlalchemy_utils + sqlalchemy_utils.types.enriched_datetime: sqlalchemy_utils + sqlalchemy_utils.types.enriched_datetime.arrow_datetime: sqlalchemy_utils + sqlalchemy_utils.types.enriched_datetime.enriched_date_type: sqlalchemy_utils + sqlalchemy_utils.types.enriched_datetime.enriched_datetime_type: sqlalchemy_utils + sqlalchemy_utils.types.enriched_datetime.pendulum_date: sqlalchemy_utils + sqlalchemy_utils.types.enriched_datetime.pendulum_datetime: sqlalchemy_utils + sqlalchemy_utils.types.ip_address: sqlalchemy_utils + sqlalchemy_utils.types.json: sqlalchemy_utils + sqlalchemy_utils.types.locale: sqlalchemy_utils + sqlalchemy_utils.types.ltree: sqlalchemy_utils + sqlalchemy_utils.types.password: sqlalchemy_utils + sqlalchemy_utils.types.pg_composite: sqlalchemy_utils + sqlalchemy_utils.types.phone_number: sqlalchemy_utils + sqlalchemy_utils.types.range: sqlalchemy_utils + sqlalchemy_utils.types.scalar_coercible: sqlalchemy_utils + sqlalchemy_utils.types.scalar_list: sqlalchemy_utils + sqlalchemy_utils.types.timezone: sqlalchemy_utils + sqlalchemy_utils.types.ts_vector: sqlalchemy_utils + sqlalchemy_utils.types.url: sqlalchemy_utils + sqlalchemy_utils.types.uuid: sqlalchemy_utils + sqlalchemy_utils.types.weekdays: sqlalchemy_utils + sqlalchemy_utils.utils: sqlalchemy_utils + sqlalchemy_utils.view: sqlalchemy_utils + sqlparse: sqlparse + sqlparse.cli: sqlparse + sqlparse.engine: sqlparse + sqlparse.engine.filter_stack: sqlparse + sqlparse.engine.grouping: sqlparse + sqlparse.engine.statement_splitter: sqlparse + sqlparse.exceptions: sqlparse + sqlparse.filters: sqlparse + sqlparse.filters.aligned_indent: sqlparse + sqlparse.filters.others: sqlparse + sqlparse.filters.output: sqlparse + sqlparse.filters.reindent: sqlparse + sqlparse.filters.right_margin: sqlparse + sqlparse.filters.tokens: sqlparse + sqlparse.formatter: sqlparse + sqlparse.keywords: sqlparse + sqlparse.lexer: sqlparse + sqlparse.sql: sqlparse + sqlparse.tokens: sqlparse + sqlparse.utils: sqlparse + starlette: starlette + starlette.applications: starlette + starlette.authentication: starlette + starlette.background: starlette + starlette.concurrency: starlette + starlette.config: starlette + starlette.convertors: starlette + starlette.datastructures: starlette + starlette.endpoints: starlette + starlette.exceptions: starlette + starlette.formparsers: starlette + starlette.middleware: starlette + starlette.middleware.authentication: starlette + starlette.middleware.base: starlette + starlette.middleware.cors: starlette + starlette.middleware.errors: starlette + starlette.middleware.exceptions: starlette + starlette.middleware.gzip: starlette + starlette.middleware.httpsredirect: starlette + starlette.middleware.sessions: starlette + starlette.middleware.trustedhost: starlette + starlette.middleware.wsgi: starlette + starlette.requests: starlette + starlette.responses: starlette + starlette.routing: starlette + starlette.schemas: starlette + starlette.staticfiles: starlette + starlette.status: starlette + starlette.templating: starlette + starlette.testclient: starlette + starlette.types: starlette + starlette.websockets: starlette + structlog: structlog + structlog.contextvars: structlog + structlog.dev: structlog + structlog.exceptions: structlog + structlog.processors: structlog + structlog.stdlib: structlog + structlog.testing: structlog + structlog.threadlocal: structlog + structlog.tracebacks: structlog + structlog.twisted: structlog + structlog.types: structlog + structlog.typing: structlog + svcs: svcs + svcs.aiohttp: svcs + svcs.exceptions: svcs + svcs.fastapi: svcs + svcs.flask: svcs + svcs.pyramid: svcs + svcs.starlette: svcs + tabulate: tabulate + tabulate.version: tabulate + tenacity: tenacity + tenacity.after: tenacity + tenacity.asyncio: tenacity + tenacity.asyncio.retry: tenacity + tenacity.before: tenacity + tenacity.before_sleep: tenacity + tenacity.nap: tenacity + tenacity.retry: tenacity + tenacity.stop: tenacity + tenacity.tornadoweb: tenacity + tenacity.wait: tenacity + termcolor: termcolor + termcolor.termcolor: termcolor + text_unidecode: text_unidecode + tools.compilepos: cron_descriptor + tools.resx2po: cron_descriptor + typer: typer + typer.cli: typer + typer.colors: typer + typer.completion: typer + typer.core: typer + typer.main: typer + typer.models: typer + typer.params: typer + typer.rich_utils: typer + typer.testing: typer + typer.utils: typer + typing_extensions: typing_extensions + typing_inspection: typing_inspection + typing_inspection.introspection: typing_inspection + typing_inspection.typing_objects: typing_inspection + tzdata: tzdata + tzdata.zoneinfo: tzdata + tzdata.zoneinfo.Africa: tzdata + tzdata.zoneinfo.America: tzdata + tzdata.zoneinfo.America.Argentina: tzdata + tzdata.zoneinfo.America.Indiana: tzdata + tzdata.zoneinfo.America.Kentucky: tzdata + tzdata.zoneinfo.America.North_Dakota: tzdata + tzdata.zoneinfo.Antarctica: tzdata + tzdata.zoneinfo.Arctic: tzdata + tzdata.zoneinfo.Asia: tzdata + tzdata.zoneinfo.Atlantic: tzdata + tzdata.zoneinfo.Australia: tzdata + tzdata.zoneinfo.Brazil: tzdata + tzdata.zoneinfo.Canada: tzdata + tzdata.zoneinfo.Chile: tzdata + tzdata.zoneinfo.Etc: tzdata + tzdata.zoneinfo.Europe: tzdata + tzdata.zoneinfo.Indian: tzdata + tzdata.zoneinfo.Mexico: tzdata + tzdata.zoneinfo.Pacific: tzdata + tzdata.zoneinfo.US: tzdata + uc_micro: uc_micro_py + uc_micro.categories: uc_micro_py + uc_micro.categories.Cc: uc_micro_py + uc_micro.categories.Cc.regex: uc_micro_py + uc_micro.categories.Cf: uc_micro_py + uc_micro.categories.Cf.regex: uc_micro_py + uc_micro.categories.P: uc_micro_py + uc_micro.categories.P.regex: uc_micro_py + uc_micro.categories.Z: uc_micro_py + uc_micro.categories.Z.regex: uc_micro_py + uc_micro.properties: uc_micro_py + uc_micro.properties.Any: uc_micro_py + uc_micro.properties.Any.regex: uc_micro_py + upath: universal_pathlib + upath.core: universal_pathlib + upath.errors: universal_pathlib + upath.implementations: universal_pathlib + upath.implementations.cloud: universal_pathlib + upath.implementations.data: universal_pathlib + upath.implementations.github: universal_pathlib + upath.implementations.hdfs: universal_pathlib + upath.implementations.http: universal_pathlib + upath.implementations.local: universal_pathlib + upath.implementations.memory: universal_pathlib + upath.implementations.sftp: universal_pathlib + upath.implementations.smb: universal_pathlib + upath.implementations.webdav: universal_pathlib + upath.registry: universal_pathlib + urllib3: urllib3 + urllib3.connection: urllib3 + urllib3.connectionpool: urllib3 + urllib3.contrib: urllib3 + urllib3.contrib.emscripten: urllib3 + urllib3.contrib.emscripten.connection: urllib3 + urllib3.contrib.emscripten.fetch: urllib3 + urllib3.contrib.emscripten.request: urllib3 + urllib3.contrib.emscripten.response: urllib3 + urllib3.contrib.pyopenssl: urllib3 + urllib3.contrib.socks: urllib3 + urllib3.exceptions: urllib3 + urllib3.fields: urllib3 + urllib3.filepost: urllib3 + urllib3.http2: urllib3 + urllib3.http2.connection: urllib3 + urllib3.http2.probe: urllib3 + urllib3.poolmanager: urllib3 + urllib3.response: urllib3 + urllib3.util: urllib3 + urllib3.util.connection: urllib3 + urllib3.util.proxy: urllib3 + urllib3.util.request: urllib3 + urllib3.util.response: urllib3 + urllib3.util.retry: urllib3 + urllib3.util.ssl_: urllib3 + urllib3.util.ssl_match_hostname: urllib3 + urllib3.util.ssltransport: urllib3 + urllib3.util.timeout: urllib3 + urllib3.util.url: urllib3 + urllib3.util.util: urllib3 + urllib3.util.wait: urllib3 + uuid6: uuid6 + uvicorn: uvicorn + uvicorn.config: uvicorn + uvicorn.importer: uvicorn + uvicorn.lifespan: uvicorn + uvicorn.lifespan.off: uvicorn + uvicorn.lifespan.on: uvicorn + uvicorn.logging: uvicorn + uvicorn.loops: uvicorn + uvicorn.loops.asyncio: uvicorn + uvicorn.loops.auto: uvicorn + uvicorn.loops.uvloop: uvicorn + uvicorn.main: uvicorn + uvicorn.middleware: uvicorn + uvicorn.middleware.asgi2: uvicorn + uvicorn.middleware.message_logger: uvicorn + uvicorn.middleware.proxy_headers: uvicorn + uvicorn.middleware.wsgi: uvicorn + uvicorn.protocols: uvicorn + uvicorn.protocols.http: uvicorn + uvicorn.protocols.http.auto: uvicorn + uvicorn.protocols.http.flow_control: uvicorn + uvicorn.protocols.http.h11_impl: uvicorn + uvicorn.protocols.http.httptools_impl: uvicorn + uvicorn.protocols.utils: uvicorn + uvicorn.protocols.websockets: uvicorn + uvicorn.protocols.websockets.auto: uvicorn + uvicorn.protocols.websockets.websockets_impl: uvicorn + uvicorn.protocols.websockets.websockets_sansio_impl: uvicorn + uvicorn.protocols.websockets.wsproto_impl: uvicorn + uvicorn.server: uvicorn + uvicorn.supervisors: uvicorn + uvicorn.supervisors.basereload: uvicorn + uvicorn.supervisors.multiprocess: uvicorn + uvicorn.supervisors.statreload: uvicorn + uvicorn.supervisors.watchfilesreload: uvicorn + uvicorn.workers: uvicorn + uvloop: uvloop + uvloop.includes: uvloop + watchfiles: watchfiles + watchfiles.cli: watchfiles + watchfiles.filters: watchfiles + watchfiles.main: watchfiles + watchfiles.run: watchfiles + watchfiles.version: watchfiles + websockets: websockets + websockets.asyncio: websockets + websockets.asyncio.async_timeout: websockets + websockets.asyncio.client: websockets + websockets.asyncio.compatibility: websockets + websockets.asyncio.connection: websockets + websockets.asyncio.messages: websockets + websockets.asyncio.router: websockets + websockets.asyncio.server: websockets + websockets.auth: websockets + websockets.cli: websockets + websockets.client: websockets + websockets.connection: websockets + websockets.datastructures: websockets + websockets.exceptions: websockets + websockets.extensions: websockets + websockets.extensions.base: websockets + websockets.extensions.permessage_deflate: websockets + websockets.frames: websockets + websockets.headers: websockets + websockets.http: websockets + websockets.http11: websockets + websockets.imports: websockets + websockets.legacy: websockets + websockets.legacy.auth: websockets + websockets.legacy.client: websockets + websockets.legacy.exceptions: websockets + websockets.legacy.framing: websockets + websockets.legacy.handshake: websockets + websockets.legacy.http: websockets + websockets.legacy.protocol: websockets + websockets.legacy.server: websockets + websockets.protocol: websockets + websockets.server: websockets + websockets.streams: websockets + websockets.sync: websockets + websockets.sync.client: websockets + websockets.sync.connection: websockets + websockets.sync.messages: websockets + websockets.sync.router: websockets + websockets.sync.server: websockets + websockets.sync.utils: websockets + websockets.typing: websockets + websockets.uri: websockets + websockets.utils: websockets + websockets.version: websockets + wirerope: wirerope + wirerope.callable: wirerope + wirerope.rope: wirerope + wirerope.wire: wirerope + wrapt: wrapt + wrapt.arguments: wrapt + wrapt.decorators: wrapt + wrapt.importer: wrapt + wrapt.patches: wrapt + wrapt.weakrefs: wrapt + wrapt.wrappers: wrapt + yaml: pyyaml + yaml.composer: pyyaml + yaml.constructor: pyyaml + yaml.cyaml: pyyaml + yaml.dumper: pyyaml + yaml.emitter: pyyaml + yaml.error: pyyaml + yaml.events: pyyaml + yaml.loader: pyyaml + yaml.nodes: pyyaml + yaml.parser: pyyaml + yaml.reader: pyyaml + yaml.representer: pyyaml + yaml.resolver: pyyaml + yaml.scanner: pyyaml + yaml.serializer: pyyaml + yaml.tokens: pyyaml + yaml_ft: pyyaml_ft + yaml_ft.composer: pyyaml_ft + yaml_ft.constructor: pyyaml_ft + yaml_ft.cyaml: pyyaml_ft + yaml_ft.dumper: pyyaml_ft + yaml_ft.emitter: pyyaml_ft + yaml_ft.error: pyyaml_ft + yaml_ft.events: pyyaml_ft + yaml_ft.loader: pyyaml_ft + yaml_ft.nodes: pyyaml_ft + yaml_ft.parser: pyyaml_ft + yaml_ft.reader: pyyaml_ft + yaml_ft.registry: pyyaml_ft + yaml_ft.representer: pyyaml_ft + yaml_ft.resolver: pyyaml_ft + yaml_ft.scanner: pyyaml_ft + yaml_ft.serializer: pyyaml_ft + yaml_ft.tokens: pyyaml_ft + zipp: zipp + zipp.compat: zipp + zipp.compat.overlay: zipp + zipp.compat.py310: zipp + zipp.compat.py313: zipp + zipp.glob: zipp + pip_repository: pypi +integrity: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" diff --git a/uv/private/extension/defs.bzl b/uv/private/extension/defs.bzl index 50c109e6..b99e3a99 100644 --- a/uv/private/extension/defs.bzl +++ b/uv/private/extension/defs.bzl @@ -245,11 +245,10 @@ def _parse_projects(module_ctx, hub_specs): # Case of an overriden package continue - if "editable" in package["source"]: - # Don't generate a sdist build or anything else for the self-package - if package["name"] == normalize_name(project_name): - continue - elif install_key in install_table: + if install_key in install_table: + continue + elif "editable" in package["source"] or "virtual" in package["source"]: + if package["name"] == project_name: continue else: fail("Virtual package {} in lockfile {} doesn't have a mandatory `uv.override_package()` annotation!".format(package["name"], project.lock)) diff --git a/uv/private/gazelle_manifest/defs.bzl b/uv/private/gazelle_manifest/defs.bzl index 31be1006..5ae2f30d 100644 --- a/uv/private/gazelle_manifest/defs.bzl +++ b/uv/private/gazelle_manifest/defs.bzl @@ -7,7 +7,6 @@ def _modules_mapping_impl(ctx): whl_file_deps = [] for target in ctx.attr.wheels: - print(pprint(target[DefaultInfo])) files_depset = target[DefaultInfo].files whl_file_deps.append(files_depset) @@ -89,7 +88,7 @@ def gazelle_python_manifest(name, hub, venvs = [], lockfile = None): name = platform_name + "_whls", target_platform = platform_name, srcs = [ - "@{}//:all_whl_requirements".format(hub), + "@{}//:gazelle_index_whls".format(hub), ], ) whls.append(platform_name + "_whls") @@ -108,5 +107,5 @@ def gazelle_python_manifest(name, hub, venvs = [], lockfile = None): name = name + ".update", srcs = [update], data = [name], - args = ["$(location :%s)" % name, dest], + args = ["$(location %s)" % name, dest], ) diff --git a/uv/private/gazelle_manifest/generate.py b/uv/private/gazelle_manifest/generate.py index c2d3a6b4..4ee06087 100644 --- a/uv/private/gazelle_manifest/generate.py +++ b/uv/private/gazelle_manifest/generate.py @@ -137,6 +137,8 @@ def identify_modules(whl_path: Path, package_name: str) -> dict[str, str]: requirement_name = package_name.lower().replace('-', '_') try: + print(f"Indexing {whl_path.name}...", file=sys.stderr) + with ZipFile(whl_path, 'r') as zf: for member in zf.namelist(): # Skip files inside dist-info, test, or example directories diff --git a/uv/private/gazelle_manifest/update.sh b/uv/private/gazelle_manifest/update.sh index 973ddc96..3ed47bba 100755 --- a/uv/private/gazelle_manifest/update.sh +++ b/uv/private/gazelle_manifest/update.sh @@ -1,4 +1,4 @@ #!/usr/bin/env sh # Use cat rather than cp to avoid retaining r/o permissions -cat "$1" > "$BUILD_WORKING_DIRECTORY/$2" +cat "$1" > "$BUILD_WORKSPACE_DIRECTORY/$2" diff --git a/uv/private/uv_hub/repository.bzl b/uv/private/uv_hub/repository.bzl index cb6eabd3..78129985 100644 --- a/uv/private/uv_hub/repository.bzl +++ b/uv/private/uv_hub/repository.bzl @@ -61,25 +61,19 @@ load("@aspect_rules_py//uv/private:defs.bzl", "py_whl_library", "whl_requirement """, ] - select_clauses = { - "//venv:" + cfg: ["@{}//:all_requirements".format(project_id)] + index_select_clauses = { + "//venv:" + cfg: ["@{}//:gazelle_index_whls".format(project_id)] for cfg, project_id in repository_ctx.attr.configurations.items() } - + content.append(""" filegroup( - name = "all_requirements", - srcs = select({select_clauses}, + name = "gazelle_index_whls", + srcs = select({index_select_clauses}, ), visibility = ["//visibility:public"], ) - -whl_requirements( - name = "all_whl_requirements", - srcs = [":all_requirements"], - visibility = ["//visibility:public"], -) -""".format(select_clauses = indent(pprint(select_clauses), " ").lstrip())) +""".format(index_select_clauses = indent(pprint(index_select_clauses), " ").lstrip())) repository_ctx.file("BUILD.bazel", "\n".join(content)) diff --git a/uv/private/uv_project/repository.bzl b/uv/private/uv_project/repository.bzl index 918fb24e..9440f9dc 100644 --- a/uv/private/uv_project/repository.bzl +++ b/uv/private/uv_project/repository.bzl @@ -38,6 +38,12 @@ def _project_impl(repository_ctx): scc_deps = json.decode(repository_ctx.attr.scc_deps) scc_graph = json.decode(repository_ctx.attr.scc_graph) + # Collect all the underlying whl installs + installs = {} + for scc_installs in scc_graph.values(): + for install in scc_installs: + installs[install] = 1 + # As we go for simplicity we collect markers marker_table = {} @@ -177,7 +183,14 @@ filegroup( srcs = select({arms}), visibility = ["//visibility:public"], ) -""".format(arms = indent(pprint(all_requirements), " " * 4).lstrip())) +filegroup( + name = "gazelle_index_whls", + srcs = {gazelle_whls}, + visibility = ["//visibility:public"], +) +""".format(arms = indent(pprint(all_requirements), " " * 4).lstrip(), + gazelle_whls = indent(pprint([it.replace("//:install", "//:gazelle_index_whl") for it in installs]), " " * 4).lstrip())) + repository_ctx.file("BUILD.bazel", "\n".join(content)) ################################0################################################ diff --git a/uv/private/whl_install/repository.bzl b/uv/private/whl_install/repository.bzl index e7189517..5266795f 100644 --- a/uv/private/whl_install/repository.bzl +++ b/uv/private/whl_install/repository.bzl @@ -8,9 +8,13 @@ produce a filegroup/TreeArtifact. """ load("//uv/private:parse_whl_name.bzl", "parse_whl_name") +load("//uv/private/pprint:defs.bzl", "pprint") load("//uv/private/constraints/platform:defs.bzl", "supported_platform") load("//uv/private/constraints/python:defs.bzl", "supported_python") +def indent(text, space = " "): + return "\n".join(["{}{}".format(space, l) for l in text.splitlines()]) + def _format_arms(d): content = [" \"{}\": \"{}\"".format(k, v) for k, v in d.items()] content = ",\n".join(content) @@ -153,24 +157,39 @@ def _whl_install_impl(repository_ctx): "//conditions:default": str(repository_ctx.attr.sbuild), } + if prebuilds: + gazelle_index_whl = prebuilds.values()[0] # Effectively random choice :shrug: + elif repository_ctx.attr.sbuild: + gazelle_index_whl = repository_ctx.attr.sbuild + else: + fail("Cannot identify a wheel or sbuild of {} to analyze for Gazelle indexing".format(repository_ctx.name)) + content.append( """ select_chain( name = "whl", - arms = {}, + arms = {arms}, visibility = ["//visibility:private"], ) + +filegroup( + name = "gazelle_index_whl", + srcs = {index_whl}, + visibility = ["//visibility:public"], +) + py_library( - name = "whl_lib", - srcs = [ + name = "whl_lib", + srcs = [ ":whl" - ], - data = [ - ], - visibility = ["//visibility:private"], + ], + data = [ + ], + visibility = ["//visibility:private"], ) """.format( - _format_arms(select_arms), + arms = _format_arms(select_arms), + index_whl = indent(pprint([str(gazelle_index_whl)]), " " * 4).lstrip(), ), ) @@ -178,17 +197,17 @@ py_library( content.append( """ whl_install( - name = "actual_install", - src = ":whl", - visibility = ["//visibility:private"], + name = "actual_install", + src = ":whl", + visibility = ["//visibility:private"], ) alias( - name = "install", - actual = select({ + name = "install", + actual = select({ "@aspect_rules_py//uv/private/constraints:libs_are_libs": ":actual_install", "@aspect_rules_py//uv/private/constraints:libs_are_whls": ":whl_lib", - }), - visibility = ["//visibility:public"], + }), + visibility = ["//visibility:public"], ) """, ) From bb7f1414a1ef96f483023cc7c6932fa22b4f14a5 Mon Sep 17 00:00:00 2001 From: "aspect-marvin[bot]" Date: Thu, 19 Feb 2026 21:15:46 +0000 Subject: [PATCH 09/18] Pre-commit changes --- e2e/cases/uv-gazelle-778/BUILD.bazel | 2 +- uv/private/extension/defs.bzl | 2 +- uv/private/gazelle_manifest/defs.bzl | 1 - uv/private/uv_hub/repository.bzl | 4 ++-- uv/private/uv_project/repository.bzl | 8 +++++--- uv/private/whl_install/repository.bzl | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/e2e/cases/uv-gazelle-778/BUILD.bazel b/e2e/cases/uv-gazelle-778/BUILD.bazel index f1ee11f1..2925d5f2 100644 --- a/e2e/cases/uv-gazelle-778/BUILD.bazel +++ b/e2e/cases/uv-gazelle-778/BUILD.bazel @@ -1,7 +1,7 @@ # buildifier: disable=bzl-visibility load("@aspect_rules_py//uv/private/gazelle_manifest:defs.bzl", "gazelle_python_manifest") -# Excercise generating a Gazelle manifest covering a ton of venvs +# Exercise generating a Gazelle manifest covering a ton of venvs gazelle_python_manifest( name = "gazelle_python_manifest", hub = "pypi", diff --git a/uv/private/extension/defs.bzl b/uv/private/extension/defs.bzl index b99e3a99..80dc2201 100644 --- a/uv/private/extension/defs.bzl +++ b/uv/private/extension/defs.bzl @@ -242,7 +242,7 @@ def _parse_projects(module_ctx, hub_specs): for package in lock_data.get("package", []): install_key = (project_id, package["name"], package["version"], "__base__") if install_key in install_table: - # Case of an overriden package + # Case of an overridden package continue if install_key in install_table: diff --git a/uv/private/gazelle_manifest/defs.bzl b/uv/private/gazelle_manifest/defs.bzl index 5ae2f30d..dd52248d 100644 --- a/uv/private/gazelle_manifest/defs.bzl +++ b/uv/private/gazelle_manifest/defs.bzl @@ -1,6 +1,5 @@ load("@bazel_lib//lib:transitions.bzl", "platform_transition_filegroup") load("@rules_shell//shell:sh_binary.bzl", "sh_binary") -load("//uv/private/pprint:defs.bzl", "pprint") def _modules_mapping_impl(ctx): out = ctx.actions.declare_file(ctx.label.name + ".yaml") diff --git a/uv/private/uv_hub/repository.bzl b/uv/private/uv_hub/repository.bzl index 78129985..6a4a73c8 100644 --- a/uv/private/uv_hub/repository.bzl +++ b/uv/private/uv_hub/repository.bzl @@ -65,7 +65,7 @@ load("@aspect_rules_py//uv/private:defs.bzl", "py_whl_library", "whl_requirement "//venv:" + cfg: ["@{}//:gazelle_index_whls".format(project_id)] for cfg, project_id in repository_ctx.attr.configurations.items() } - + content.append(""" filegroup( name = "gazelle_index_whls", @@ -210,7 +210,7 @@ uv_hub = repository_rule( attrs = { "configurations": attr.string_dict( doc = """ - Mapping of configuration name to a project _containing_ that configuraiton. + Mapping of configuration name to a project _containing_ that configuration. """, ), "packages": attr.string( diff --git a/uv/private/uv_project/repository.bzl b/uv/private/uv_project/repository.bzl index 9440f9dc..423c0004 100644 --- a/uv/private/uv_project/repository.bzl +++ b/uv/private/uv_project/repository.bzl @@ -43,7 +43,7 @@ def _project_impl(repository_ctx): for scc_installs in scc_graph.values(): for install in scc_installs: installs[install] = 1 - + # As we go for simplicity we collect markers marker_table = {} @@ -188,8 +188,10 @@ filegroup( srcs = {gazelle_whls}, visibility = ["//visibility:public"], ) -""".format(arms = indent(pprint(all_requirements), " " * 4).lstrip(), - gazelle_whls = indent(pprint([it.replace("//:install", "//:gazelle_index_whl") for it in installs]), " " * 4).lstrip())) +""".format( + arms = indent(pprint(all_requirements), " " * 4).lstrip(), + gazelle_whls = indent(pprint([it.replace("//:install", "//:gazelle_index_whl") for it in installs]), " " * 4).lstrip(), + )) repository_ctx.file("BUILD.bazel", "\n".join(content)) diff --git a/uv/private/whl_install/repository.bzl b/uv/private/whl_install/repository.bzl index 5266795f..38b4514e 100644 --- a/uv/private/whl_install/repository.bzl +++ b/uv/private/whl_install/repository.bzl @@ -8,9 +8,9 @@ produce a filegroup/TreeArtifact. """ load("//uv/private:parse_whl_name.bzl", "parse_whl_name") -load("//uv/private/pprint:defs.bzl", "pprint") load("//uv/private/constraints/platform:defs.bzl", "supported_platform") load("//uv/private/constraints/python:defs.bzl", "supported_python") +load("//uv/private/pprint:defs.bzl", "pprint") def indent(text, space = " "): return "\n".join(["{}{}".format(space, l) for l in text.splitlines()]) From 2e8053b9795ae76c3e1c4404d37b6b8fb160b517 Mon Sep 17 00:00:00 2001 From: Reid D McKenzie Date: Thu, 19 Feb 2026 15:10:29 -0700 Subject: [PATCH 10/18] Rip out the integrity machinery --- uv/private/gazelle_manifest/defs.bzl | 2 -- uv/private/gazelle_manifest/generate.py | 32 +++---------------------- 2 files changed, 3 insertions(+), 31 deletions(-) diff --git a/uv/private/gazelle_manifest/defs.bzl b/uv/private/gazelle_manifest/defs.bzl index dd52248d..ab311790 100644 --- a/uv/private/gazelle_manifest/defs.bzl +++ b/uv/private/gazelle_manifest/defs.bzl @@ -32,7 +32,6 @@ def _modules_mapping_impl(ctx): arguments = [ "--whl_paths_file", args_file.path, - # "--integrity_file", attr.file.integrity.path, "--output", out.path, ], @@ -56,7 +55,6 @@ _modules_mapping = rule( implementation = _modules_mapping_impl, attrs = { "wheels": attr.label_list(providers = [[DefaultInfo]]), - # "integrity": attr.label(allow_single_file = True), "_generator": attr.label( default = Label(":generator"), executable = True, diff --git a/uv/private/gazelle_manifest/generate.py b/uv/private/gazelle_manifest/generate.py index 4ee06087..58ee83c9 100644 --- a/uv/private/gazelle_manifest/generate.py +++ b/uv/private/gazelle_manifest/generate.py @@ -161,16 +161,14 @@ def identify_modules(whl_path: Path, package_name: str) -> dict[str, str]: return module_mapping def write_manifest(module_mapping: dict[str, str], - integrity_value: str, output_path: Path, pip_repository_name: str = "pypi") -> None: """ - Formats the module mapping and integrity into a YAML-like string and + Formats the module mapping into a YAML-like string and writes it to the specified output path. No pyyaml is used. Args: module_mapping: The collected module-to-requirement map. - integrity_value: The SHA256 integrity hash. output_path: Path to write the manifest file. pip_repository_name: The name to use for pip_repository in the output. """ @@ -185,7 +183,6 @@ def write_manifest(module_mapping: dict[str, str], modules_mapping: {sorted_mapping} pip_repository: {pip_repository_name} -integrity: "{integrity_value}" """ try: @@ -213,14 +210,6 @@ def main(): help="Path to a file containing a list of paths to wheel (.whl) files, one per line." ) - # Path to a file containing the integrity shasum - parser.add_argument( - '--integrity_file', - type=Path, - required=False, - help="Path to a file containing the final integrity SHA sum (e.g., SHA256)." - ) - # Output path for the final Gazelle manifest parser.add_argument( '--output', @@ -231,22 +220,7 @@ def main(): args = parser.parse_args() - # 1. Read integrity value - try: - if args.integrity_file: - integrity_value = args.integrity_file.read_text().strip() - if not integrity_value: - print("Error: Integrity file is empty.", file=sys.stderr) - sys.exit(1) - else: - # The null shasum - integrity_value = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - - except Exception as e: - print(f"Error reading integrity file {args.integrity_file}: {e}", file=sys.stderr) - sys.exit(1) - - # 2. Read wheel paths + # Read wheel paths try: whl_paths_raw = args.whl_paths_file.read_text().splitlines() whl_paths = [] @@ -287,7 +261,7 @@ def main(): final_module_mapping.update(modules) # 4. Write the final manifest - write_manifest(final_module_mapping, integrity_value, args.output) + write_manifest(final_module_mapping, args.output) if __name__ == '__main__': main() From 49a58c90717ac5e3260b41cc81bd2973d2f73ddd Mon Sep 17 00:00:00 2001 From: "Reid D. McKenzie" Date: Thu, 19 Feb 2026 15:11:07 -0700 Subject: [PATCH 11/18] Rip the integrity value out --- e2e/cases/uv-gazelle-778/gazelle_python.yaml | 1 - gazelle_python.yaml | 1 - 2 files changed, 2 deletions(-) diff --git a/e2e/cases/uv-gazelle-778/gazelle_python.yaml b/e2e/cases/uv-gazelle-778/gazelle_python.yaml index d28ece77..66557d8d 100644 --- a/e2e/cases/uv-gazelle-778/gazelle_python.yaml +++ b/e2e/cases/uv-gazelle-778/gazelle_python.yaml @@ -3493,4 +3493,3 @@ manifest: zipp.compat.py313: zipp zipp.glob: zipp pip_repository: pypi -integrity: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" diff --git a/gazelle_python.yaml b/gazelle_python.yaml index 929a27af..64b28fc9 100644 --- a/gazelle_python.yaml +++ b/gazelle_python.yaml @@ -4138,4 +4138,3 @@ manifest: zipp.compat.py313: zipp zipp.glob: zipp pip_repository: pypi -integrity: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" From 50ee77657568deca7cffc2b2af417fc63f186864 Mon Sep 17 00:00:00 2001 From: Reid D McKenzie Date: Thu, 19 Feb 2026 15:19:22 -0700 Subject: [PATCH 12/18] Tolerate lockfile HTTP assets without digests Fixes #793, #790 --- uv/private/extension/defs.bzl | 6 +++++- uv/private/extension/lockfile.bzl | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/uv/private/extension/defs.bzl b/uv/private/extension/defs.bzl index 80dc2201..af34d052 100644 --- a/uv/private/extension/defs.bzl +++ b/uv/private/extension/defs.bzl @@ -420,10 +420,14 @@ def _uv_impl(module_ctx): fail("Unsupported archive! {}".format(repr(sdist_cfg))) for bdist_name, bdist_cfg in cfg.bdist_cfgs.items(): + sha256 = None + if "hash" in bdist_cfg: + sha256 = bdist_cfg["hash"][len("sha256:"):] + http_file( name = bdist_name, url = bdist_cfg["url"], - sha256 = bdist_cfg["hash"][len("sha256:"):], + sha256 = sha256, downloaded_file_path = bdist_cfg["url"].split("/")[-1].split("?")[0].split("#")[0], ) diff --git a/uv/private/extension/lockfile.bzl b/uv/private/extension/lockfile.bzl index 338031f5..53a85f17 100644 --- a/uv/private/extension/lockfile.bzl +++ b/uv/private/extension/lockfile.bzl @@ -195,7 +195,14 @@ def collect_bdists(lock_data): bdist_table = {} for package in lock_data.get("package", []): for bdist in package.get("wheels", []): - bdist_repo_name = "whl__{}__{}".format(package["name"], bdist["hash"].split(":")[1][:16]) + + identifier = None + if "hash" in bdist: + identifier = bdist["hash"].split(":")[1][:16] + else: + identifier = sha1(bdist["url"])[:16] + + bdist_repo_name = "whl__{}__{}".format(package["name"], identifier) bdist_specs[bdist_repo_name] = bdist bdist_table[bdist["hash"]] = "@{}//file".format(bdist_repo_name) @@ -223,7 +230,14 @@ def collect_sdists( k = "sdist_build__{}__{}__{}".format(lock_id, package["name"], package["version"].replace(".", "_")) if "sdist" in package: sdist = package["sdist"] - sdist_repo_name = "sdist__{}__{}".format(package["name"], sdist["hash"].split(":")[1][:16]) + + identifier = None + if "hash" in sdist: + identifier = sdist["hash"].split(":")[1][:16] + else: + identifier = sha1(sdist["url"])[:16] + + sdist_repo_name = "sdist__{}__{}".format(package["name"], identifier) sdist_specs[sdist_repo_name] = {"file": sdist} sdist_table[k] = "@{}//file".format(sdist_repo_name) From bed623750cc5556e1d52eb4f840b7e81d47253e3 Mon Sep 17 00:00:00 2001 From: "aspect-marvin[bot]" Date: Thu, 19 Feb 2026 22:20:30 +0000 Subject: [PATCH 13/18] Pre-commit changes --- uv/private/extension/lockfile.bzl | 1 - 1 file changed, 1 deletion(-) diff --git a/uv/private/extension/lockfile.bzl b/uv/private/extension/lockfile.bzl index 53a85f17..de541a68 100644 --- a/uv/private/extension/lockfile.bzl +++ b/uv/private/extension/lockfile.bzl @@ -195,7 +195,6 @@ def collect_bdists(lock_data): bdist_table = {} for package in lock_data.get("package", []): for bdist in package.get("wheels", []): - identifier = None if "hash" in bdist: identifier = bdist["hash"].split(":")[1][:16] From 2575f7a24f3a79a165202cb0874b9a957c04e5a3 Mon Sep 17 00:00:00 2001 From: Reid D McKenzie Date: Thu, 19 Feb 2026 15:26:21 -0700 Subject: [PATCH 14/18] Remove pip.parse usage --- e2e/MODULE.bazel | 29 ---------------------------- e2e/cases/cross-repo-610/BUILD.bazel | 3 ++- e2e/requirements.in | 1 - e2e/requirements.txt | 9 --------- 4 files changed, 2 insertions(+), 40 deletions(-) delete mode 100644 e2e/requirements.in delete mode 100644 e2e/requirements.txt diff --git a/e2e/MODULE.bazel b/e2e/MODULE.bazel index 39973469..38f505ab 100644 --- a/e2e/MODULE.bazel +++ b/e2e/MODULE.bazel @@ -62,35 +62,6 @@ python.toolchain( python_version = "3.13", ) -# TODO: Swap in our pip -pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") -pip.parse( - hub_name = "pip", - python_version = "3.9", - requirements_lock = "//:requirements.txt", -) -pip.parse( - hub_name = "pip", - python_version = "3.10", - requirements_lock = "//:requirements.txt", -) -pip.parse( - hub_name = "pip", - python_version = "3.11", - requirements_lock = "//:requirements.txt", -) -pip.parse( - hub_name = "pip", - python_version = "3.12", - requirements_lock = "//:requirements.txt", -) -pip.parse( - hub_name = "pip", - python_version = "3.13", - requirements_lock = "//:requirements.txt", -) -use_repo(pip, "pip") - # For cases/cross-repo-610 local_repository = use_repo_rule("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository") diff --git a/e2e/cases/cross-repo-610/BUILD.bazel b/e2e/cases/cross-repo-610/BUILD.bazel index a387f7f9..609ccf15 100644 --- a/e2e/cases/cross-repo-610/BUILD.bazel +++ b/e2e/cases/cross-repo-610/BUILD.bazel @@ -10,7 +10,8 @@ py_venv_test( ], main = "test.py", deps = [ - "@pip//cowsay", + "@pypi//cowsay", "@subrepo_a//:foo", ], + venv = "say", ) diff --git a/e2e/requirements.in b/e2e/requirements.in deleted file mode 100644 index c6b9ffd0..00000000 --- a/e2e/requirements.in +++ /dev/null @@ -1 +0,0 @@ -cowsay diff --git a/e2e/requirements.txt b/e2e/requirements.txt deleted file mode 100644 index b318878f..00000000 --- a/e2e/requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# bazel run //:requirements.update -# -cowsay==6.1 \ - --hash=sha256:274b1e6fc1b966d53976333eb90ac94cb07a450a700b455af9fbdf882244b30a - # via -r requirements.in From f890841f24a8f4a5e4d8c7b7fc2394e45c1f5d41 Mon Sep 17 00:00:00 2001 From: "aspect-marvin[bot]" Date: Thu, 19 Feb 2026 22:27:37 +0000 Subject: [PATCH 15/18] Pre-commit changes --- e2e/cases/cross-repo-610/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/cases/cross-repo-610/BUILD.bazel b/e2e/cases/cross-repo-610/BUILD.bazel index 609ccf15..6a9e4b6b 100644 --- a/e2e/cases/cross-repo-610/BUILD.bazel +++ b/e2e/cases/cross-repo-610/BUILD.bazel @@ -9,9 +9,9 @@ py_venv_test( ".", ], main = "test.py", + venv = "say", deps = [ "@pypi//cowsay", "@subrepo_a//:foo", ], - venv = "say", ) From efa837055db6520685e626a410cfbf8ba38ca106 Mon Sep 17 00:00:00 2001 From: Reid D McKenzie Date: Thu, 19 Feb 2026 15:30:26 -0700 Subject: [PATCH 16/18] Re-comment/block --- e2e/MODULE.bazel | 57 ++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/e2e/MODULE.bazel b/e2e/MODULE.bazel index 38f505ab..df73b5c7 100644 --- a/e2e/MODULE.bazel +++ b/e2e/MODULE.bazel @@ -12,35 +12,11 @@ bazel_dep(name = "toolchains_llvm_bootstrapped", version = "0.3.1") bazel_dep(name = "rules_oci", version = "2.2.6") bazel_dep(name = "rules_rust", version = "0.68.1") -oci = use_extension("@rules_oci//oci:extensions.bzl", "oci") -oci.pull( - name = "ubuntu", - digest = "sha256:c35e29c9450151419d9448b0fd75374fec4fff364a27f176fb458d472dfc9e54", - image = "public.ecr.aws/docker/library/ubuntu", - platforms = [ - "linux/arm64/v8", - "linux/amd64", - ], - tag = "latest", -) -use_repo(oci, "ubuntu", "ubuntu_linux_amd64", "ubuntu_linux_arm64_v8") - -bazel_dep(name = "container_structure_test", version = "1.19.1") -git_override( - module_name = "container_structure_test", - commit = "63ee63e15fae64f00b1c1ace1eb5cc99251b9e02", - remote = "https://github.com/GoogleContainerTools/container-structure-test.git", -) - local_path_override( module_name = "aspect_rules_py", path = "..", ) -# FIXME: Can we clean this up now that sdist builds don't use tar -bazel_lib_toolchains = use_extension("@tar.bzl//tar:extensions.bzl", "toolchains", dev_dependency = True) -use_repo(bazel_lib_toolchains, "bsd_tar_toolchains") - python = use_extension("@rules_python//python/extensions:python.bzl", "python") python.toolchain( configure_coverage_tool = True, @@ -62,7 +38,35 @@ python.toolchain( python_version = "3.13", ) + +# For the OCI tests +# {{{ +oci = use_extension("@rules_oci//oci:extensions.bzl", "oci") +oci.pull( + name = "ubuntu", + digest = "sha256:c35e29c9450151419d9448b0fd75374fec4fff364a27f176fb458d472dfc9e54", + image = "public.ecr.aws/docker/library/ubuntu", + platforms = [ + "linux/arm64/v8", + "linux/amd64", + ], + tag = "latest", +) +use_repo(oci, "ubuntu", "ubuntu_linux_amd64", "ubuntu_linux_arm64_v8") + +bazel_dep(name = "container_structure_test", version = "1.19.1") +git_override( + module_name = "container_structure_test", + commit = "63ee63e15fae64f00b1c1ace1eb5cc99251b9e02", + remote = "https://github.com/GoogleContainerTools/container-structure-test.git", +) + +bazel_lib_toolchains = use_extension("@tar.bzl//tar:extensions.bzl", "toolchains", dev_dependency = True) +use_repo(bazel_lib_toolchains, "bsd_tar_toolchains") +# }}} + # For cases/cross-repo-610 +# {{{ local_repository = use_repo_rule("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository") local_repository( @@ -74,12 +78,16 @@ local_repository( name = "subrepo_b", path = "./cases/cross-repo-610/subrepo_b", ) +# }}} # For cases/repository-rule-deps-299 +# {{{ importer = use_extension("//cases/repository-rule-deps-299/rules:import.bzl", "importer") use_repo(importer, "myrepo") +# }}} # For cases/uv-deps-650 +# {{{ uv = use_extension("@aspect_rules_py//uv/unstable:extension.bzl", "uv") uv.declare_hub(hub_name = "pypi") uv.project( @@ -108,4 +116,5 @@ uv.project( lock = "//cases/uv-deps-650/extras:uv.lock", pyproject = "//cases/uv-deps-650/extras:pyproject.toml", ) +# }}} use_repo(uv, "pypi") From aa32fc5fa6d881956b611819353f1793e444ef45 Mon Sep 17 00:00:00 2001 From: "Reid D. McKenzie" Date: Thu, 19 Feb 2026 17:18:19 -0700 Subject: [PATCH 17/18] Add test covering UV workspace patterns --- e2e/MODULE.bazel | 20 +++ e2e/cases/uv-workspace-789/BUILD.bazel | 14 ++ e2e/cases/uv-workspace-789/README.md | 6 + e2e/cases/uv-workspace-789/__test__.py | 10 ++ .../uv-workspace-789/packages/foo/BUILD.bazel | 11 ++ .../packages/foo/pyproject.toml | 6 + .../packages/foo/src/foo/__init__.py | 6 + .../uv-workspace-789/packages/pi/BUILD.bazel | 11 ++ .../packages/pi/pyproject.toml | 6 + .../uv-workspace-789/packages/pi/src/pi.py | 8 + e2e/cases/uv-workspace-789/pyproject.toml | 12 ++ e2e/cases/uv-workspace-789/uv.lock | 152 ++++++++++++++++++ uv/private/extension/defs.bzl | 7 +- uv/private/extension/projectfile.bzl | 8 +- 14 files changed, 269 insertions(+), 8 deletions(-) create mode 100644 e2e/cases/uv-workspace-789/BUILD.bazel create mode 100644 e2e/cases/uv-workspace-789/README.md create mode 100644 e2e/cases/uv-workspace-789/__test__.py create mode 100644 e2e/cases/uv-workspace-789/packages/foo/BUILD.bazel create mode 100644 e2e/cases/uv-workspace-789/packages/foo/pyproject.toml create mode 100644 e2e/cases/uv-workspace-789/packages/foo/src/foo/__init__.py create mode 100644 e2e/cases/uv-workspace-789/packages/pi/BUILD.bazel create mode 100644 e2e/cases/uv-workspace-789/packages/pi/pyproject.toml create mode 100644 e2e/cases/uv-workspace-789/packages/pi/src/pi.py create mode 100644 e2e/cases/uv-workspace-789/pyproject.toml create mode 100644 e2e/cases/uv-workspace-789/uv.lock diff --git a/e2e/MODULE.bazel b/e2e/MODULE.bazel index df73b5c7..bd52343d 100644 --- a/e2e/MODULE.bazel +++ b/e2e/MODULE.bazel @@ -117,4 +117,24 @@ uv.project( pyproject = "//cases/uv-deps-650/extras:pyproject.toml", ) # }}} + +# For cases/uv-workspace-789 +# {{{ +uv.project( + hub_name = "pypi", + lock = "//cases/uv-workspace-789:uv.lock", + pyproject = "//cases/uv-workspace-789:pyproject.toml", +) +uv.override_package( + name = "foo", + lock = "//cases/uv-workspace-789:uv.lock", + target = "//cases/uv-workspace-789/packages/foo", +) +uv.override_package( + name = "pi", + lock = "//cases/uv-workspace-789:uv.lock", + target = "//cases/uv-workspace-789/packages/pi", +) +# }}} + use_repo(uv, "pypi") diff --git a/e2e/cases/uv-workspace-789/BUILD.bazel b/e2e/cases/uv-workspace-789/BUILD.bazel new file mode 100644 index 00000000..5d8bc8fc --- /dev/null +++ b/e2e/cases/uv-workspace-789/BUILD.bazel @@ -0,0 +1,14 @@ +load("@aspect_rules_py//py/unstable:defs.bzl", "py_venv_test") + +py_venv_test( + name = "test", + srcs = [ + "__test__.py", + ], + deps = [ + "@pypi//foo", # Firstparty package + "@pypi//pi", # Firstparty package + ], + main = "__test__.py", + venv = "workspace", +) diff --git a/e2e/cases/uv-workspace-789/README.md b/e2e/cases/uv-workspace-789/README.md new file mode 100644 index 00000000..72d671eb --- /dev/null +++ b/e2e/cases/uv-workspace-789/README.md @@ -0,0 +1,6 @@ +# Editable internal dependencies; #789 + +UV workspaces allow for packages within the workspace to depend on each other. +The UV extension needs to force the user to provide an override target mapping +for each such target, and dependencies BETWEEN these projects' Bazel targets +need to work. Dependencies taken via the UV hub need to work as well. diff --git a/e2e/cases/uv-workspace-789/__test__.py b/e2e/cases/uv-workspace-789/__test__.py new file mode 100644 index 00000000..2143b062 --- /dev/null +++ b/e2e/cases/uv-workspace-789/__test__.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python3 + +import pi +assert "uv-workspace-789" in pi.__file__ + +import foo +assert "uv-workspace-789" in foo.__file__ + +import requests +assert ".runfiles" in requests.__file__ diff --git a/e2e/cases/uv-workspace-789/packages/foo/BUILD.bazel b/e2e/cases/uv-workspace-789/packages/foo/BUILD.bazel new file mode 100644 index 00000000..958711b8 --- /dev/null +++ b/e2e/cases/uv-workspace-789/packages/foo/BUILD.bazel @@ -0,0 +1,11 @@ +load("@aspect_rules_py//py:defs.bzl", "py_library") + +py_library( + name = "foo", + srcs = glob(["src/**/*.py"]), + deps = [ + "//cases/uv-workspace-789/packages/pi", + ], + imports = ["src"], + visibility = ["//visibility:public"], +) diff --git a/e2e/cases/uv-workspace-789/packages/foo/pyproject.toml b/e2e/cases/uv-workspace-789/packages/foo/pyproject.toml new file mode 100644 index 00000000..ea8b2ae9 --- /dev/null +++ b/e2e/cases/uv-workspace-789/packages/foo/pyproject.toml @@ -0,0 +1,6 @@ +[project] +name = "foo" +version = "0.0.0" +dependencies = [ + "pi", +] diff --git a/e2e/cases/uv-workspace-789/packages/foo/src/foo/__init__.py b/e2e/cases/uv-workspace-789/packages/foo/src/foo/__init__.py new file mode 100644 index 00000000..5ed8ff45 --- /dev/null +++ b/e2e/cases/uv-workspace-789/packages/foo/src/foo/__init__.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 + +from pi import pi + +def sixteen(): + return pi()[:16] diff --git a/e2e/cases/uv-workspace-789/packages/pi/BUILD.bazel b/e2e/cases/uv-workspace-789/packages/pi/BUILD.bazel new file mode 100644 index 00000000..245b35f6 --- /dev/null +++ b/e2e/cases/uv-workspace-789/packages/pi/BUILD.bazel @@ -0,0 +1,11 @@ +load("@aspect_rules_py//py:defs.bzl", "py_library") + +py_library( + name = "pi", + srcs = glob(["src/**/*.py"]), + imports = ["src"], + deps = [ + "@pypi//requests", + ], + visibility = ["//visibility:public"], +) diff --git a/e2e/cases/uv-workspace-789/packages/pi/pyproject.toml b/e2e/cases/uv-workspace-789/packages/pi/pyproject.toml new file mode 100644 index 00000000..e3a4d77b --- /dev/null +++ b/e2e/cases/uv-workspace-789/packages/pi/pyproject.toml @@ -0,0 +1,6 @@ +[project] +name = "pi" +version = "0.0.0" +dependencies = [ + "requests", +] diff --git a/e2e/cases/uv-workspace-789/packages/pi/src/pi.py b/e2e/cases/uv-workspace-789/packages/pi/src/pi.py new file mode 100644 index 00000000..a226a028 --- /dev/null +++ b/e2e/cases/uv-workspace-789/packages/pi/src/pi.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import requests + +def pi(): + body = requests.get("https://raw.githubusercontent.com/eneko/Pi/3d647f65f5ec7a6ed9a5c2f9e61f17ce94aad0e6/one-million.txt").body + start = body.index("3.\n") + return body[start:].replace("\n", "") diff --git a/e2e/cases/uv-workspace-789/pyproject.toml b/e2e/cases/uv-workspace-789/pyproject.toml new file mode 100644 index 00000000..f24bf8c2 --- /dev/null +++ b/e2e/cases/uv-workspace-789/pyproject.toml @@ -0,0 +1,12 @@ +[project] +name = "workspace" +version = "0.0.0" +dependencies = [] + +[tool.uv.sources] +workspace = { workspace = true } +foo = { workspace = true } +pi = { workspace = true } + +[tool.uv.workspace] +members = ["packages/*"] diff --git a/e2e/cases/uv-workspace-789/uv.lock b/e2e/cases/uv-workspace-789/uv.lock new file mode 100644 index 00000000..829fcfd9 --- /dev/null +++ b/e2e/cases/uv-workspace-789/uv.lock @@ -0,0 +1,152 @@ +version = 1 +revision = 3 +requires-python = ">=3.11" + +[manifest] +members = [ + "foo", + "pi", + "workspace", +] + +[[package]] +name = "certifi" +version = "2026.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120", size = 154268, upload-time = "2026-01-04T02:42:41.825Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c", size = 152900, upload-time = "2026-01-04T02:42:40.15Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", size = 206988, upload-time = "2025-10-14T04:40:33.79Z" }, + { url = "https://files.pythonhosted.org/packages/94/59/2e87300fe67ab820b5428580a53cad894272dbb97f38a7a814a2a1ac1011/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", size = 147324, upload-time = "2025-10-14T04:40:34.961Z" }, + { url = "https://files.pythonhosted.org/packages/07/fb/0cf61dc84b2b088391830f6274cb57c82e4da8bbc2efeac8c025edb88772/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", size = 142742, upload-time = "2025-10-14T04:40:36.105Z" }, + { url = "https://files.pythonhosted.org/packages/62/8b/171935adf2312cd745d290ed93cf16cf0dfe320863ab7cbeeae1dcd6535f/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc", size = 160863, upload-time = "2025-10-14T04:40:37.188Z" }, + { url = "https://files.pythonhosted.org/packages/09/73/ad875b192bda14f2173bfc1bc9a55e009808484a4b256748d931b6948442/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897", size = 157837, upload-time = "2025-10-14T04:40:38.435Z" }, + { url = "https://files.pythonhosted.org/packages/6d/fc/de9cce525b2c5b94b47c70a4b4fb19f871b24995c728e957ee68ab1671ea/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381", size = 151550, upload-time = "2025-10-14T04:40:40.053Z" }, + { url = "https://files.pythonhosted.org/packages/55/c2/43edd615fdfba8c6f2dfbd459b25a6b3b551f24ea21981e23fb768503ce1/charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815", size = 149162, upload-time = "2025-10-14T04:40:41.163Z" }, + { url = "https://files.pythonhosted.org/packages/03/86/bde4ad8b4d0e9429a4e82c1e8f5c659993a9a863ad62c7df05cf7b678d75/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0", size = 150019, upload-time = "2025-10-14T04:40:42.276Z" }, + { url = "https://files.pythonhosted.org/packages/1f/86/a151eb2af293a7e7bac3a739b81072585ce36ccfb4493039f49f1d3cae8c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161", size = 143310, upload-time = "2025-10-14T04:40:43.439Z" }, + { url = "https://files.pythonhosted.org/packages/b5/fe/43dae6144a7e07b87478fdfc4dbe9efd5defb0e7ec29f5f58a55aeef7bf7/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4", size = 162022, upload-time = "2025-10-14T04:40:44.547Z" }, + { url = "https://files.pythonhosted.org/packages/80/e6/7aab83774f5d2bca81f42ac58d04caf44f0cc2b65fc6db2b3b2e8a05f3b3/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89", size = 149383, upload-time = "2025-10-14T04:40:46.018Z" }, + { url = "https://files.pythonhosted.org/packages/4f/e8/b289173b4edae05c0dde07f69f8db476a0b511eac556dfe0d6bda3c43384/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569", size = 159098, upload-time = "2025-10-14T04:40:47.081Z" }, + { url = "https://files.pythonhosted.org/packages/d8/df/fe699727754cae3f8478493c7f45f777b17c3ef0600e28abfec8619eb49c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224", size = 152991, upload-time = "2025-10-14T04:40:48.246Z" }, + { url = "https://files.pythonhosted.org/packages/1a/86/584869fe4ddb6ffa3bd9f491b87a01568797fb9bd8933f557dba9771beaf/charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", size = 99456, upload-time = "2025-10-14T04:40:49.376Z" }, + { url = "https://files.pythonhosted.org/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", size = 106978, upload-time = "2025-10-14T04:40:50.844Z" }, + { url = "https://files.pythonhosted.org/packages/7a/9d/0710916e6c82948b3be62d9d398cb4fcf4e97b56d6a6aeccd66c4b2f2bd5/charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", size = 99969, upload-time = "2025-10-14T04:40:52.272Z" }, + { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, + { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, + { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, + { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, + { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, + { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, + { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, + { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, + { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, + { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, + { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, + { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, + { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, + { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, + { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, + { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, + { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, + { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, + { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, + { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, + { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, + { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, + { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, + { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, +] + +[[package]] +name = "foo" +version = "0.0.0" +source = { editable = "packages/foo" } +dependencies = [ + { name = "pi" }, +] + +[package.metadata] +requires-dist = [{ name = "pi", editable = "packages/pi" }] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "pi" +version = "0.0.0" +source = { editable = "packages/pi" } +dependencies = [ + { name = "requests" }, +] + +[package.metadata] +requires-dist = [{ name = "requests" }] + +[[package]] +name = "requests" +version = "2.32.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, +] + +[[package]] +name = "workspace" +version = "0.0.0" +source = { virtual = "." } diff --git a/uv/private/extension/defs.bzl b/uv/private/extension/defs.bzl index af34d052..81baf91f 100644 --- a/uv/private/extension/defs.bzl +++ b/uv/private/extension/defs.bzl @@ -206,7 +206,7 @@ def _parse_projects(module_ctx, hub_specs): whl_configurations.update(collect_configurations(lock_data)) - configuration_names, activated_extras = collect_activated_extras(project.lock, project_data, default_versions, marker_graph) + configuration_names, activated_extras = collect_activated_extras(project.lock, project_data, lock_data, default_versions, marker_graph) version_activations = collate_versions_by_name(activated_extras) # Mapping from SCC ID to marked SCC members @@ -244,10 +244,9 @@ def _parse_projects(module_ctx, hub_specs): if install_key in install_table: # Case of an overridden package continue - - if install_key in install_table: - continue elif "editable" in package["source"] or "virtual" in package["source"]: + # Case of the workspace self-package + # FIXME: Workspace packages can have srcs? It's a bit weird if package["name"] == project_name: continue else: diff --git a/uv/private/extension/projectfile.bzl b/uv/private/extension/projectfile.bzl index d3035a6f..0895187d 100644 --- a/uv/private/extension/projectfile.bzl +++ b/uv/private/extension/projectfile.bzl @@ -98,7 +98,7 @@ def extract_requirement_marker_pairs(projectfile, req_string, version_map): return results -def collect_activated_extras(projectfile, project_data, default_versions, graph): +def collect_activated_extras(projectfile, project_data, lock_data, default_versions, graph): """Collects the set of transitively activated extras for each configuration. This function determines the full set of extras that are activated for each @@ -121,11 +121,11 @@ def collect_activated_extras(projectfile, project_data, default_versions, graph) `{dep: {cfg: {extra_dep: {marker: 1}}}}`. """ - # If no dependency-groups are specified, create a default group + # If no dependency-groups are specified, use the lock members manifest, or just the self-list dep_groups = project_data.get("dependency-groups", { - project_data["project"]["name"]: [ + project_data["project"]["name"]: lock_data.get("manifest", {}).get("members", [ project_data["project"]["name"], - ], + ]), }) # Normalize dep groups to our dependency triples (graph keys) From e4f76b89cff837a6583b0833c24440e328c32ca1 Mon Sep 17 00:00:00 2001 From: "aspect-marvin[bot]" Date: Fri, 20 Feb 2026 00:19:37 +0000 Subject: [PATCH 18/18] Pre-commit changes --- e2e/MODULE.bazel | 1 - e2e/cases/uv-workspace-789/BUILD.bazel | 6 +++--- e2e/cases/uv-workspace-789/packages/foo/BUILD.bazel | 4 ++-- e2e/cases/uv-workspace-789/packages/pi/BUILD.bazel | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/e2e/MODULE.bazel b/e2e/MODULE.bazel index bd52343d..56e50fdb 100644 --- a/e2e/MODULE.bazel +++ b/e2e/MODULE.bazel @@ -38,7 +38,6 @@ python.toolchain( python_version = "3.13", ) - # For the OCI tests # {{{ oci = use_extension("@rules_oci//oci:extensions.bzl", "oci") diff --git a/e2e/cases/uv-workspace-789/BUILD.bazel b/e2e/cases/uv-workspace-789/BUILD.bazel index 5d8bc8fc..353c2132 100644 --- a/e2e/cases/uv-workspace-789/BUILD.bazel +++ b/e2e/cases/uv-workspace-789/BUILD.bazel @@ -5,10 +5,10 @@ py_venv_test( srcs = [ "__test__.py", ], + main = "__test__.py", + venv = "workspace", deps = [ "@pypi//foo", # Firstparty package - "@pypi//pi", # Firstparty package + "@pypi//pi", # Firstparty package ], - main = "__test__.py", - venv = "workspace", ) diff --git a/e2e/cases/uv-workspace-789/packages/foo/BUILD.bazel b/e2e/cases/uv-workspace-789/packages/foo/BUILD.bazel index 958711b8..b5988933 100644 --- a/e2e/cases/uv-workspace-789/packages/foo/BUILD.bazel +++ b/e2e/cases/uv-workspace-789/packages/foo/BUILD.bazel @@ -3,9 +3,9 @@ load("@aspect_rules_py//py:defs.bzl", "py_library") py_library( name = "foo", srcs = glob(["src/**/*.py"]), + imports = ["src"], + visibility = ["//visibility:public"], deps = [ "//cases/uv-workspace-789/packages/pi", ], - imports = ["src"], - visibility = ["//visibility:public"], ) diff --git a/e2e/cases/uv-workspace-789/packages/pi/BUILD.bazel b/e2e/cases/uv-workspace-789/packages/pi/BUILD.bazel index 245b35f6..486bbd49 100644 --- a/e2e/cases/uv-workspace-789/packages/pi/BUILD.bazel +++ b/e2e/cases/uv-workspace-789/packages/pi/BUILD.bazel @@ -4,8 +4,8 @@ py_library( name = "pi", srcs = glob(["src/**/*.py"]), imports = ["src"], + visibility = ["//visibility:public"], deps = [ "@pypi//requests", ], - visibility = ["//visibility:public"], )