Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ common --incompatible_disallow_empty_glob=False
# Define value used by tests
common --define=SOME_VAR=SOME_VALUE

# Set the default virtualenv to 'default'
common --@pypi//dep_group=aspect_rules_py
# dep_group=default is the flag's default; no explicit setting needed
# because pyproject.toml has no [dependency-groups] table and the uv
# extension synthesizes a single "default" group.

common --incompatible_enable_cc_toolchain_resolution
common --@llvm//config:experimental_stub_libgcc_s
Expand Down
2 changes: 1 addition & 1 deletion BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ gazelle_python_manifest(
name = "gazelle_python_manifest",
hub = "pypi",
venvs = [
"aspect_rules_py",
"",
],
)

Expand Down
521 changes: 454 additions & 67 deletions docs/uv.md

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions e2e/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,41 @@ uv.project(
use_repo(uv, "pypi-pytorch")
# }}}

# For cases/uv-shared-hub-848
# {{{
# Distinct hub deliberately registering two projects with overlapping
# group names ("shared") and project-unique groups ("a_only", "b_only").
# Exercises the namespacing paths added in v2.0.
uv.declare_hub(hub_name = "pypi_shared_848")
uv.project(
hub_name = "pypi_shared_848",
lock = "//cases/uv-shared-hub-848/proj_a:uv.lock",
pyproject = "//cases/uv-shared-hub-848/proj_a:pyproject.toml",
)
uv.project(
hub_name = "pypi_shared_848",
lock = "//cases/uv-shared-hub-848/proj_b:uv.lock",
pyproject = "//cases/uv-shared-hub-848/proj_b:pyproject.toml",
)
use_repo(uv, "pypi_shared_848")
# }}}

# For cases/uv-synthesis-default-848
# {{{
# Single-project hub whose pyproject.toml has no [dependency-groups] table.
# Exercises the synthesis fallback (empty-keyed group + `<name>` alias)
# and the zero-config path where the dep_group flag's
# build_setting_default of `""` makes everything resolve without any
# .bazelrc entry.
uv.declare_hub(hub_name = "pypi_synth_848")
uv.project(
hub_name = "pypi_synth_848",
lock = "//cases/uv-synthesis-default-848:uv.lock",
pyproject = "//cases/uv-synthesis-default-848:pyproject.toml",
)
use_repo(uv, "pypi_synth_848")
# }}}

use_repo(uv, "pypi")

register_toolchains("@uv//:all")
6 changes: 3 additions & 3 deletions e2e/cases/firebase-admin-import/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ load("@bazel_skylib//rules:build_test.bzl", "build_test")
py_test(
name = "test",
srcs = ["test.py"],
dep_group = "firebase-admin-import",
dep_group = "firebase_admin_import",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did defaults change in some way? Why did all these change?

main = "test.py",
deps = [
"@pypi//firebase_admin",
Expand All @@ -52,7 +52,7 @@ py_test(
py_test(
name = "test_tool",
srcs = ["test.py"],
dep_group = "firebase-admin-import",
dep_group = "firebase_admin_import",
expose_venv = True,
isolated = False,
main = "test.py",
Expand All @@ -72,7 +72,7 @@ py_test(
py_binary(
name = "firebase_importer",
srcs = ["test.py"],
dep_group = "firebase-admin-import",
dep_group = "firebase_admin_import",
main = "test.py",
deps = [
"@pypi//firebase_admin",
Expand Down
4 changes: 2 additions & 2 deletions e2e/cases/freethreaded-805/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ _LINUX_X86_64 = [
py_test(
name = "test_bin",
srcs = ["test.py"],
dep_group = "freethreaded-test",
dep_group = "freethreaded_test",
main = "test.py",
python_version = "3.13",
tags = ["manual"],
Expand All @@ -46,7 +46,7 @@ platform_transition_test(
py_test(
name = "venv_test_bin",
srcs = ["test.py"],
dep_group = "freethreaded-test",
dep_group = "freethreaded_test",
expose_venv = True,
isolated = False,
main = "test.py",
Expand Down
4 changes: 2 additions & 2 deletions e2e/cases/pth-namespace-547/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ load("@aspect_rules_py//py:defs.bzl", "py_test")
py_test(
name = "test",
srcs = ["__test__.py"],
dep_group = "pth-namespace-547",
dep_group = "pth_namespace_547",
expose_venv = True,
isolated = False,
main = "__test__.py",
Expand All @@ -20,7 +20,7 @@ py_test(
py_test(
name = "test_legacy",
srcs = ["__test__.py"],
dep_group = "pth-namespace-547",
dep_group = "pth_namespace_547",
main = "__test__.py",
deps = [
"@pypi//jaraco_classes",
Expand Down
10 changes: 5 additions & 5 deletions e2e/cases/pytest-main-867/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ load("@aspect_rules_py//py:defs.bzl", "py_pytest_main", "py_test")
py_test(
name = "test_example",
srcs = ["test_example.py"],
dep_group = "pytest-main-867",
dep_group = "pytest_main_867",
pytest_main = True,
deps = ["@pypi//pytest"],
)
Expand All @@ -15,7 +15,7 @@ py_test(
py_test(
name = "test_naming_regression",
srcs = ["test_example.py"],
dep_group = "pytest-main-867",
dep_group = "pytest_main_867",
pytest_main = True,
deps = ["@pypi//pytest"],
)
Expand All @@ -29,7 +29,7 @@ py_test(
"test_a.py",
"test_b.py",
],
dep_group = "pytest-main-867",
dep_group = "pytest_main_867",
pytest_main = True,
deps = ["@pypi//pytest"],
)
Expand All @@ -39,7 +39,7 @@ py_test(
py_test(
name = "test_collection_check",
srcs = ["test_collection_check.py"],
dep_group = "pytest-main-867",
dep_group = "pytest_main_867",
pytest_main = True,
deps = ["@pypi//pytest"],
)
Expand All @@ -58,7 +58,7 @@ py_test(
"test_a.py",
":test_direct_main",
],
dep_group = "pytest-main-867",
dep_group = "pytest_main_867",
main = ":__test__test_direct_main__.py",
deps = [
":test_direct_main",
Expand Down
4 changes: 2 additions & 2 deletions e2e/cases/pytest-mock-530/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ load("@aspect_rules_py//py:defs.bzl", "py_test")
py_test(
name = "test_mock_py_test",
srcs = ["test_mock.py"],
dep_group = "pytest-mock-530",
dep_group = "pytest_mock_530",
pytest_main = True,
deps = [
"@pypi//pytest",
Expand All @@ -18,7 +18,7 @@ py_test(
"__test__.py",
"test_mock.py",
],
dep_group = "pytest-mock-530",
dep_group = "pytest_mock_530",
expose_venv = True,
isolated = False,
main = "__test__.py",
Expand Down
2 changes: 1 addition & 1 deletion e2e/cases/pytest-subdir-imports/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ py_library(
py_test(
name = "test_subdir_import",
srcs = ["tests/test_subdir.py"],
dep_group = "pytest-subdir-imports",
dep_group = "pytest_subdir_imports",
pytest_main = True,
deps = [
":lib",
Expand Down
2 changes: 1 addition & 1 deletion e2e/cases/pytest-xdist-integration/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ py_test(
"-n",
"2",
],
dep_group = "pytest-xdist-integration",
dep_group = "pytest_xdist_integration",
pytest_main = True,
deps = [
"@pypi//pytest",
Expand Down
4 changes: 2 additions & 2 deletions e2e/cases/uv-abi3-compat-853/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ load("@aspect_rules_py//py:defs.bzl", "py_test")
py_test(
name = "test_import",
srcs = ["test_abi3.py"],
dep_group = "abi3-compat",
dep_group = "abi3_compat",
main = "test_abi3.py",
python_version = "3.12",
target_compatible_with = ["@platforms//os:linux"],
Expand All @@ -17,7 +17,7 @@ py_test(
py_test(
name = "test_import_venv_test",
srcs = ["test_abi3.py"],
dep_group = "abi3-compat",
dep_group = "abi3_compat",
expose_venv = True,
isolated = False,
main = "test_abi3.py",
Expand Down
Empty file modified e2e/cases/uv-console-script-binary/test.sh
100644 → 100755
Empty file.
8 changes: 5 additions & 3 deletions e2e/cases/uv-gazelle-778/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
load("@aspect_rules_py//uv:defs.bzl", "gazelle_python_manifest")

# Exercise generating a Gazelle manifest covering a ton of venvs
# Exercise generating a Gazelle manifest covering several dep_groups.
# `extras` is uv-deps-650/extras's explicit `[dependency-groups].extras`;
# the bare `<name>` entries are the synthesized per-project aliases for
# projects without explicit `[dependency-groups]` (airflow, say, crossbuild).
gazelle_python_manifest(
name = "gazelle_python_manifest",
hub = "pypi",
# Note that we _merge_ the package mappings from several configurations.
venvs = [
"extras",
"airflow",
"crossbuild",
"extras",
"say",
],
)
4 changes: 2 additions & 2 deletions e2e/cases/uv-plus-version/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ load("@aspect_rules_py//py:defs.bzl", "py_test")
py_test(
name = "test",
srcs = ["__test__.py"],
dep_group = "plus-version",
dep_group = "plus_version",
main = "__test__.py",
python_version = "3.12",
deps = [
Expand All @@ -14,7 +14,7 @@ py_test(
py_test(
name = "venv_test",
srcs = ["__test__.py"],
dep_group = "plus-version",
dep_group = "plus_version",
expose_venv = True,
isolated = False,
main = "__test__.py",
Expand Down
88 changes: 88 additions & 0 deletions e2e/cases/uv-shared-hub-848/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Shared-hub regression tests.
#
# Hub `pypi_shared_848` has two projects (proj-a-848, proj-b-848), each with a
# `shared` group containing `pytest` (pinned to the same version in both) and
# a project-unique `<x>_only` group also containing `pytest`. This shape
# exercises:
#
# - Multi-project hub coexistence (same hub, same-named "shared" group)
# - Version-equality dedup: when both projects provide `pytest` in `shared`
# at the same version, the unqualified `@hub//pytest` resolves to one
# canonical project's target rather than tripping Bazel's "multiple keys
# match" (which would only fire on a real version conflict).
# - Project-qualified labels (`@hub//.<project>:pytest`) routing
# deterministically per project regardless of overlap.
# - Unqualified labels under unique-owner groups (a_only, b_only).

load("@aspect_rules_py//py:defs.bzl", "py_test")

# Qualified labels, dep_group=shared. The qualified target under
# //.proj_a_848/.proj_b_848 selects only over its own project's groups, so it
# is unambiguous regardless of cross-project overlap.
py_test(
name = "test_qualified_a_shared",
srcs = ["test_pytest_import.py"],
dep_group = "shared",
main = "test_pytest_import.py",
deps = ["@pypi_shared_848//project/proj_a_848:pytest"],
)

py_test(
name = "test_qualified_b_shared",
srcs = ["test_pytest_import.py"],
dep_group = "shared",
main = "test_pytest_import.py",
deps = ["@pypi_shared_848//project/proj_b_848:pytest"],
)

# Version-equality dedup: both proj_a_848 and proj_b_848 pin pytest at the
# same version in their `shared` group. The hub's unqualified //pytest alias
# emits one arm per (group, versions) cluster — same-version clusters
# collapse to a single canonical arm, so dep_group=shared resolves cleanly
# instead of multi-matching.
py_test(
name = "test_unqualified_shared_dedupes",
srcs = ["test_pytest_import.py"],
dep_group = "shared",
main = "test_pytest_import.py",
deps = ["@pypi_shared_848//pytest"],
)

# Unqualified label, dep_group=a_only. Only proj_a_848 defines an `a_only`
# group, so its select arm is the only match.
py_test(
name = "test_unqualified_a_only",
srcs = ["test_pytest_import.py"],
dep_group = "a_only",
main = "test_pytest_import.py",
deps = ["@pypi_shared_848//pytest"],
)

py_test(
name = "test_unqualified_b_only",
srcs = ["test_pytest_import.py"],
dep_group = "b_only",
main = "test_pytest_import.py",
deps = ["@pypi_shared_848//pytest"],
)

# Per-project qualified flag form: `dep_group = "<stamp>/<group>"`
# narrows the activation to a single project's group regardless of
# cross-project overlap. The unqualified `@hub//pytest` resolves
# unambiguously because only that project's qualified config_setting
# matches.
py_test(
name = "test_qualified_flag_a_shared",
srcs = ["test_pytest_import.py"],
dep_group = "proj_a_848/shared",
main = "test_pytest_import.py",
deps = ["@pypi_shared_848//pytest"],
)

py_test(
name = "test_qualified_flag_b_shared",
srcs = ["test_pytest_import.py"],
dep_group = "proj_b_848/shared",
main = "test_pytest_import.py",
deps = ["@pypi_shared_848//pytest"],
)
6 changes: 6 additions & 0 deletions e2e/cases/uv-shared-hub-848/proj_a/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Marker package so the uv extension can resolve //cases/uv-shared-hub-848/proj_a:pyproject.toml.

exports_files([
"pyproject.toml",
"uv.lock",
])
16 changes: 16 additions & 0 deletions e2e/cases/uv-shared-hub-848/proj_a/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[project]
name = "proj-a-848"
version = "0.0.0"
requires-python = ">=3.11"
dependencies = [
"pytest",
]

# Two groups:
# - "shared": same name as proj-b-848's "shared". Both projects provide
# pytest in this group, exercising the cross-project ambiguity path.
# - "a_only": unique to proj-a-848. Setting dep_group=a_only routes
# @hub//pytest to proj_a's pytest unambiguously.
[dependency-groups]
shared = ["proj-a-848"]
a_only = ["proj-a-848"]
Loading