feat(py): propagate type stubs and carry them into venvs - #1538
xangcastle wants to merge 3 commits into
Conversation
…to venvs Builds on the transitive_pyi_files plumbing from #1523 and makes the field mean the same thing on both sides of the ruleset boundary. - `.pyi` files listed in `srcs` are classified by extension into `PyInfo.transitive_pyi_files`, mirroring rules_python where stubs never count as runtime sources. `transitive_sources` no longer carries them, including through virtual-dependency resolutions. - Venvs that include sources and launchers put both depsets in runfiles, so stubs that only exist in a foreign provider (py_proto_library, a rules_python `pyi_srcs`) land beside the modules they annotate. - Under the migration flag the emitted rules_python PyInfo also populates `direct_pyi_files`. - Drops the redundant resolution wrapper and `has_py_info` guards; the interop accessor already returns an empty depset for foreign-less targets. Tests: analysis coverage in //py/tests/type-stubs for first-party, foreign, virtual-resolution, launcher, venv and compatibility-provider shapes, plus a runtime check that stubs sit in runfiles. e2e: a rules_python `pyi_srcs` library consumed by rules_py, protobuf's py_proto_library `_pb2.pyi` propagating and landing in runfiles, and rules_python's PyInfo builder merging a rules_py stub under the compatibility layer.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✨ Aspect Workflows Tasks📅 Fri Sep 11 04:47:26 UTC 2026 ✅ 44 successful tasks
⏱ Last updated Fri Sep 11 05:03:02 UTC 2026 · 📊 GitHub API quota 423/15,000 (3% used, resets in 54m) |
py_binary startup benchmark
sys.path quality
Bazel analysis benchmark
py_image_layer benchmark
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e3b746b3f4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if PyInfo in target: | ||
| return target[PyInfo].transitive_pyi_files |
There was a problem hiding this comment.
Default missing stub fields for legacy PyInfo producers
When a downstream custom rule constructs the publicly exported PyInfo using the previously documented four fields, its provider instance has no transitive_pyi_files value, yet this accessor now reads that field unconditionally whenever the target is used in deps or resolutions. Such existing targets therefore fail during analysis instead of contributing an empty stub set; use getattr(info, "transitive_pyi_files", depset()) so adding this field remains backward-compatible.
Useful? React with 👍 / 👎.
| runfiles = venv.runtime_runfiles.merge(ctx.runfiles(files = venv_only)) | ||
| if include_sources: | ||
| runfiles = runfiles.merge(ctx.runfiles(transitive_files = venv.transitive_sources)) | ||
| runfiles = runfiles.merge(ctx.runfiles(transitive_files = depset( |
There was a problem hiding this comment.
I don't think PYI should be in the runfiles at all...
| # A resolution target's default outputs stand in for its sources (a wheel | ||
| # install tree has no PyInfo of its own). Stubs among them belong to the | ||
| # pyi depset collected alongside, not to the runtime sources. | ||
| direct = _runtime_sources(target[DefaultInfo].files.to_list()) |
| fields = { | ||
| "transitive_sources": "depset[File] — postorder depset of first-party `.py` sources in the transitive closure.", | ||
| "transitive_sources": "depset[File] — postorder depset of first-party runtime sources in the transitive closure; `.pyi` stubs are excluded.", | ||
| "transitive_pyi_files": "depset[File] — postorder depset of `.pyi` type stubs in the transitive closure: stubs listed in `srcs` plus those carried by deps of either ruleset.", |
There was a problem hiding this comment.
I think we can drop the "stubs listed in srcs plus those carried by deps of either ruleset." - that is an implementation detail of rules, and I don't think we should mention "other rulesets" in these docs
Builds on #1523 (its commit is kept as the first commit here, authorship intact) and makes
transitive_pyi_filesmean the same thing on both sides of the ruleset boundary.Closes #558.
Changes
.pyifiles listed insrcsare classified by extension intoPyInfo.transitive_pyi_files, mirroring rules_python where stubs never count as runtime sources.transitive_sourcesno longer carries them, including through virtual-dependency resolutions. No newpyi_srcsattribute.py_proto_library_pb2.pyi, a rules_pythonpyi_srcs) now land beside the modules they annotate, so a type checker pointed at the venv resolves them. Neither rules_python nor protobuf put stubs in their own runfiles; the venv is where rules_py has to do it.--@aspect_rules_py//py:emit_rules_python_providersthe emitted rules_pythonPyInfoalso populatesdirect_pyi_files.has_py_infoguards; the interop accessor already returns an empty depset for targets carrying neither provider.Changes are visible to end-users: yes
PyInfo.transitive_sourcesno longer lists.pyifiles fromsrcs; they move toPyInfo.transitive_pyi_files. Runfiles of venvs and launchers gain stubs that come from rules_python deps.Test plan
//py/tests/type-stubs: analysis coverage for first-party, foreign, virtual-resolution, launcher, venv and compatibility-provider shapes, plus apy_testasserting the stubs sit in runfiles at execution time.e2e/rules-python-interop: a rules_python library withpyi_srcsconsumed by a rules_pypy_libraryandpy_test.e2e/rules-python-protobuf: protobuf'spy_proto_librarygeneratinggreeting_pb2.pyi, propagated through rules_py and present in runfiles.e2e/rules-python-provider-compat: rules_python'sPyInfobuilder merging a rules_py stub under the compatibility layer.//...plus the three e2e workspaces andtest.shpass locally.