Skip to content

fix: physically merge mixed namespace/regular top-level collisions#1199

Draft
acozzette wants to merge 2 commits into
mainfrom
issue-1118
Draft

fix: physically merge mixed namespace/regular top-level collisions#1199
acozzette wants to merge 2 commits into
mainfrom
issue-1118

Conversation

@acozzette

Copy link
Copy Markdown
Collaborator

When one wheel ships opentelemetry/__init__.py (marking opentelemetry as a regular package) while others treat it as a PEP 420 namespace, the previous "last winner wins" logic routed all traffic to the non-namespace wheel's directory, hiding the namespace wheels' subpackages.

Detect the mixed case (some is_ns = True, some is_ns = False) and route it to the existing physical-merge mechanism, producing the same layout a flat pip install would — one merged directory containing all wheels' contributions.

Fixes #1118.


Changes are visible to end-users: yes

  • Searched for relevant documentation and updated as needed: yes
  • Breaking change (forces users to change their own code or config): no
  • Suggested release notes appear below: yes

Physically merge directories when there is disagreement on whether a package is a namespace package.

Test plan

  • Covered by existing test cases
  • New test cases added

@aspect-workflows

aspect-workflows Bot commented Jun 25, 2026

Copy link
Copy Markdown

✨ Aspect Workflows Tasks

📅 Fri Jun 26 18:12:06 UTC 2026

✅ 14 successful tasks

  • ✅ buildifier · ⏱ 29.6s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ gazelle · ⏱ 22.9s · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ test-e2e-bazel-8 [test] · ⏱ 3m 3s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (181/181 passed)
  • ✅ test-e2e-bazel-9 [test] · ⏱ 3m 4s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (176/176 passed)
  • ✅ test-examples-debugger-bazel-8 [test] · ⏱ 30.4s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (1/1 passed · 1 cached)
  • ✅ test-examples-debugger-bazel-9 [test] · ⏱ 1m 16s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (1/1 passed)
  • ✅ test-examples-dev_deps-bazel-8 [test] · ⏱ 39s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (1/1 passed · 1 cached)
  • ✅ test-examples-dev_deps-bazel-9 [test] · ⏱ 54.2s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (1/1 passed)
  • ✅ test-examples-protobuf-bazel-8 [test] · ⏱ 1m 46s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (1/1 passed)
  • ✅ test-examples-protobuf-bazel-9 [test] · ⏱ 1m 54s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (1/1 passed)
  • ✅ test-examples-uv_pip_compile-bazel-8 [test] · ⏱ 35s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (1/1 passed)
  • ✅ test-examples-uv_pip_compile-bazel-9 [test] · ⏱ 51.5s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (1/1 passed)
  • ✅ test-root-bazel-8 [test] · ⏱ 2m 57s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (218/218 passed)
  • ✅ test-root-bazel-9 [test] · ⏱ 3m 54s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (217/217 passed)

⏱ Last updated Fri Jun 26 18:16:39 UTC 2026 · 📊 GitHub API quota 444/15,000 (3% used, resets in 14m)
🚀 Powered by Aspect CLI (v2026.26.18)  |  Aspect Build · X · LinkedIn · YouTube

@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown

py_binary startup benchmark

Version Mean (ms) Median (ms) ± stddev vs BCR vs main Build (s)
BCR 1.11.5 (baseline) 179.031 178.874 ±1.589 42.60
HEAD main 58.596 57.839 ±2.662 -67.3% 10.53
This PR 58.411 57.951 ±2.135 -67.4% -0.3% 7.37

Measured with hyperfine --warmup 5 --runs 50 on Linux
Gate: PR vs HEAD main (threshold: 10%). BCR is shown only as a historical baseline.
Build time: cold bazel build //:bench with isolated output base, no disk cache.

sys.path quality

Version sys.path entries distinct site-packages roots duplicate realpaths
BCR 1.11.5 (baseline) 6 1 0
HEAD main 7 2 0
This PR 7 2 0

sys.path quality measured by bench_syspath inside the assembled venv. Duplicate realpaths indicate symlink redundancy; many distinct site-packages roots suggest an inefficient venv layout.

✅ No regression detected (PR is -0.3% vs HEAD main)

acozzette and others added 2 commits June 26, 2026 11:11
When one wheel ships `opentelemetry/__init__.py` (marking `opentelemetry`
as a regular package) while others treat it as a PEP 420 namespace, the
previous "last winner wins" logic routed all traffic to the non-namespace
wheel's directory, hiding the namespace wheels' subpackages.

Detect the mixed case (some `is_ns = True`, some `is_ns = False`) and
route it to the existing physical-merge mechanism, producing the same
layout a flat `pip install` would — one merged directory containing all
wheels' contributions.

Fixes #1118.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… empty

The previous fix triggered a physical merge for ALL mixed namespace/regular
top-level collisions, regressing airflow: apache_airflow_core's non-empty
airflow/__init__.py (which uses extend_path) was merged into a copied venv
directory instead of staying as a symlink into the wheel's install tree.

The correct criterion is the __init__.py size. A 0-byte __init__.py (like
xds_protos's opentelemetry/__init__.py) is a legacy namespace stub with no
extend_path — it cannot merge namespace contributions at runtime, so a
physical merge is required. A non-empty __init__.py (like airflow's, 5549
bytes) handles namespace extension itself; the symlink + addsitedir approach
continues to work.

Detect this in repository.bzl by parsing the size field from RECORD lines
for depth-1 __init__.py entries. Propagate via a new empty_init_top_levels
field through whl_install attrs → PyWheelsInfo wheel struct. In venv.bzl,
only trigger the physical merge when the regular wheel's top-level appears
in empty_init_top_levels.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: v2.0.0-alpha.3 namespaced packages don't work with xds_protos package

1 participant