Skip to content

build(pyrefly): enable Pyrefly static type checking across Python targets - #4020

Open
rickeylev wants to merge 65 commits into
bazel-contrib:mainfrom
rickeylev:enable_pyrefly_python_targets
Open

build(pyrefly): enable Pyrefly static type checking across Python targets#4020
rickeylev wants to merge 65 commits into
bazel-contrib:mainfrom
rickeylev:enable_pyrefly_python_targets

Conversation

@rickeylev

Copy link
Copy Markdown
Collaborator

Enables Pyrefly static type checking across Python source and test
targets in rules_python and sphinxdocs.

Previously, static type analysis was not uniformly applied across
all Python targets, leaving potential type inconsistencies and
unbound variable edge cases uncaught during builds and CI runs.

This change configures the global Pyrefly aspect to evaluate Python
targets by default in Bzlmod mode, adds type annotations and
narrowing assertions on runfiles resolution, and annotates dynamic
imports (such as generated protobuf stubs and compiled C extensions)
with explicit type ignore comments. Targets utilizing dynamically
generated bootstrap wrappers retain opt-out tags with documented
rationales.

Integrates rules_pyrefly in MODULE.bazel, defines the Pyrefly aspect in tools/pyrefly.bzl with --config=pyrefly in .bazelrc, and addresses a type override suppression in python/runfiles/runfiles.py.
Relocates pyrefly.bzl into tools/private and updates the aspect target reference in .bazelrc.
Relocates pyrefly.bzl under tools/private/pyrefly and updates .bazelrc label reference.
Synchronizes BUILD.bazel with Gazelle generated rules.
Updates the aspect reference in .bazelrc to use the tools/private/pyrefly package path.
…ate BUILD files

Cleans up unused pyrefly bzl_library definitions now that pyrefly.bzl lives in tools/private/pyrefly.
Removes the unnecessary bzl_library target and BUILD.bazel from tools/private/pyrefly, updating .bazelrc to reference //tools/private:pyrefly/pyrefly.bzl%pyrefly_aspect.
…ype checking

Implements pyrefly_check in tools/private:pyrefly/pyrefly.bzl taking targets as a label list, and instantiates runfiles_check in tests/runfiles/BUILD.bazel targeting //python/runfiles:runfiles.
…d use default_visibility in tools/private/pyrefly/BUILD.bazel
Defines pyrefly_check_test with test = True so running bazel test //tests/runfiles/... automatically discovers and executes runfiles_check as a test target.
Restores pyrefly_check as a build rule in tools/private/pyrefly/pyrefly.bzl and tests it using standard build_test in tests/runfiles/BUILD.bazel.
Encapsulates pyrefly_check rule and build_test into a reusable pyrefly_check_test macro in tools/private/pyrefly/pyrefly.bzl.
Relocates the pyrefly test helper package from tools/private/pyrefly to tests/support/pyrefly and updates load references.
Replaces the custom pyrefly_check wrapper rule with rules_pyrefly's
native opt_in_tags feature. Applies pyrefly_aspect globally via
.bazelrc while tagging //python/runfiles:runfiles for opt-in static
type checking.
Prevents WORKSPACE-mode (non-Bzlmod) builds from failing due to
unresolved @rules_pyrefly repository references while preserving
opt-in tag-based static type checking under Bzlmod.
Top-level if statements are forbidden in Bazel BUILD files. Moving
the BZLMOD_ENABLED check inside the pyrefly_check_test macro
definition in pyrefly.bzl ensures clean BUILD file evaluation while
preserving Bzlmod-only target generation.
Adds rules_pyrefly repository definition to rules_python_internal_deps
in internal_dev_deps.bzl so package loading succeeds during WORKSPACE
mode builds. Removes non-existent bzl_library dependency target.
Clarifies in pyrefly.bzl that Pyrefly type checking does not support
WORKSPACE mode and exits early when Bzlmod is not enabled.
Registers rules_pyrefly_stub in internal_dev_deps.bzl for WORKSPACE
mode so load() statements resolve, and adds global aspect flag to
.bazelrc to apply Pyrefly static type checking across tagged targets.
Removes the macro target invocation now that Pyrefly type checking is applied globally via aspect on tagged targets.
Removes the unused macro and rule definitions, leaving only pyrefly_aspect in tests/support/pyrefly/pyrefly.bzl.
Adds an always-on workspace rule prohibiting the use of auth tokens in command line arguments.
Enable Pyrefly type checking by default using opt-out enforcement.
Configure rules_pyrefly aspect and toolchain setup in sphinxdocs module.
Set --config=pyrefly by default in root and sphinxdocs .bazelrc files.
Enable Pyrefly type checking across tests and sphinxdocs libraries to ensure
type safety, resolving typing diagnostics and adding necessary type ignores
for generated proto stubs.

- Remove no-pyrefly tags across sphinxdocs, test targets, and fixtures.
- Add TypedDict definitions and modernize type annotations in sphinx_build and bzl.py.
- Introduce _get_bzl_domain() helper in bzl.py and preserve @OverRide decorators.
- Simplify variable assignment in dependency_resolver.py.
- Add pyrefly enablement plan documenting findings and requirements.
…ule_directly

The test asserts that importing a non-direct dependency raises
ModuleNotFoundError at runtime; keep the import with type ignore.
@rickeylev
rickeylev marked this pull request as draft August 8, 2026 23:51
auto-merge was automatically disabled August 8, 2026 23:51

Pull request was converted to draft

@rickeylev

Copy link
Copy Markdown
Collaborator Author

Apparently slopbot was lying about the tests it ran. I'll switch this back to non-draft once its sorted

Update type checking and runfiles usage according to review comments:
- Prefer in-file # type: ignore comments over target-level no-pyrefly tags
- Add Runfiles.CreateOrRaise() helper and use Path API in toolchain tests
- Factor out _compute_inert_node_types() in py_test_main_validator
- Restore @OverRide annotations in sphinx_bzl
- Clarify Python agent rules for type asserts and annotation consent
Add in-file # pyrefly: ignore[bad-override] annotations and # type: ignore
for intersphinx import in sphinx_bzl/bzl.py to allow sphinxdocs type
checking to pass without disabling target-level checking.
…ts_for_prs call

Allow MockGitHub to pass self to resolve_merge_commits_for_prs without
failing Pyrefly type checking on GitHub parameter type.
@rickeylev
rickeylev marked this pull request as ready for review August 9, 2026 03:35
@rickeylev

Copy link
Copy Markdown
Collaborator Author

Ready, PTAL

Comment thread .agents/rules/python.md Outdated
Comment thread .agents/rules/python.md
Comment thread examples/wheel/main.py Outdated
Comment thread python/private/pypi/whl_installer/arguments.py
Comment thread python/runfiles/runfiles.py Outdated
Comment thread sphinxdocs/sphinxdocs/src/sphinx_bzl/bzl.py
Comment thread sphinxdocs/sphinxdocs/src/sphinx_bzl/bzl.py Outdated
Comment thread sphinxdocs/sphinxdocs/private/proto_to_markdown.py Outdated
Comment thread tests/cc/py_extension/py_extension_pkg_test.py Outdated
Comment thread tests/pytest_test/BUILD.bazel Outdated
Use specific error-code ignores with pyrefly syntax, annotate type narrowing
assertions with '# type assert', replace @dev_pip with @pypi in release tool tests,
and remove obsolete test tags.
Add assertions to narrow Optional[Runfiles] and include mypy-specific type
ignores alongside pyrefly directives so both checkers pass.
Change return type from Self to Path to match Runfiles.root return type.
- Revert type ignores in debuggers.md docstring.
- Safely extract readline.__doc__ to avoid unsupported-operation on None.
- Use runfiles.CreateOrRaise() and Runfiles.root() in repl_template.py.
- Cast obj to Path in runfiles.py __new__ and _make_child to eliminate
  attribute ignores and type:ignore[misc].
Dynamically lookup _make_child on super() and cast to Path so both mypy
and pyrefly pass without explicit ignore comments.
Remove type ignores from documentation sample in debuggers.md and simplify
Path._make_child invocation in runfiles.py with proper type disable annotations.
Add comment explaining that _make_child is an internal CPython method in
Python < 3.12 omitted from typeshed stubs, requiring [misc] ignore for mypy
and [missing-attribute] ignore for pyrefly.
Sync with upstream/main to incorporate Runfiles.CreateOrRaise API.
Add explicit instruction to use error-specific ignores instead of blanket
or placeholder ignores.
Comment thread sphinxdocs/sphinxdocs/private/proto_to_markdown.py Outdated
Comment thread sphinxdocs/sphinxdocs/private/sphinx_build.py
Comment thread sphinxdocs/sphinxdocs/src/sphinx_bzl/bzl.py Outdated
Comment thread python/private/pypi/whl_installer/arguments.py Outdated
Comment thread sphinxdocs/sphinxdocs/src/sphinx_bzl/BUILD.bazel
Align parameter names (signode, contentnode) and types (location) in
sphinx_bzl with Sphinx base classes, eliminating bad-override suppressions.
…param

Restore bad-override ignores needed due to untyped Sphinx/docutils parent
classes, align _BzlTarget.handle_signature parameter naming to signode, and
remove transient plan file from git tracking.
Document why bad-override ignores are necessary for Path.open (simplified
overload signature) and sphinx_bzl methods (untyped parent classes in
Sphinx/docutils).
Restore comment explaining that sphinx_bzl provides the library on its own
and relies on the caller to provide runtime dependencies.
Replace typing collection aliases (Tuple, List, Set, Sequence, Iterable,
Iterator, AbstractSet) and typing.Union with collections.abc protocols and
builtin generic types across tools, tests, and sphinx_bzl.
Replace typing.Optional annotations with union with None (X | None)
and enable postponed evaluation of annotations where needed.
- In sphinx_build.py, index request arguments directly instead of .get().
- In repl_test.py, use runfiles.CreateOrRaise().
- In wheelmaker.py, clean up obsolete noqa on Sequence.
Add from __future__ import annotations to pathlib_test.py to enable
postponed evaluation of type annotations.
@rickeylev

Copy link
Copy Markdown
Collaborator Author

PTAL

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.

2 participants