Skip to content

Ship py.typed in the stub-generating component packages - #7710

Open
Parsiffall1 wants to merge 6 commits into
reflex-dev:mainfrom
Parsiffall1:fix/component-packages-py-typed
Open

Parsiffall1 wants to merge 6 commits into
reflex-dev:mainfrom
Parsiffall1:fix/component-packages-py-typed

Conversation

@Parsiffall1

@Parsiffall1 Parsiffall1 commented Nov 1, 2026 •

Copy link
Copy Markdown

All Submissions:

  • Have you followed the guidelines stated in CONTRIBUTING.md file?
  • Have you checked to ensure there aren't any other open Pull Requests for the desired changed?

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Description

Every workspace package that generates .pyi stubs at build time (the ones stub_packages() in tests/units/test_build_config.py picks up: the twelve reflex-components-* packages from the issue plus reflex-components-internal and reflex-site-shared) now ships an empty py.typed. Hatchling picks it up without config changes; the built reflex_components_radix wheel contains reflex_components_radix/py.typed next to themes/layout/box.pyi.

Once the packages are marked typed, pyright applies its library re-export rules to them, which flagged two in-repo imports:

  • reflex_components_radix.themes.components.icon_button imports Icon from the reflex_components_lucide root. That root, and the other package roots that import names from their submodules (gridjs, moment, plotly, react-player, sonner), now re-export them explicitly with from .x import Name as Name, the form reflex_components_markdown and MomentDelta already use. Without this, code like from reflex_components_sonner import toast would start failing pyright (reportPrivateImportUsage) and mypy --no-implicit-reexport once the markers land; a probe importing all of these names from the roots reports 9 such errors on the first commit and none now.
  • tests/units/utils/test_serializers.py imported Color through reflex_components_core.core.colors; it now imports it from reflex_base.constants.colors, where it is defined.

A new parametrized test, test_package_ships_py_typed, asserts that each stub-generating package has a py.typed and that its wheel config includes it, so a newly split package can't drop the marker silently again. News fragments are added per package.

Testing

  • The repro from the issue (mypy --strict, mypy 2.4.1) against the workspace install: before, import-untyped on reflex_components_radix.themes.layout.box, no-any-return, and rx.box / Box revealed as Any. After: Success: no issues found, with rx.box revealed as the generated Box.create signature.
  • uv run pytest tests/units/test_build_config.py: the new test fails for all 14 packages without the markers and passes with them (78 passed).
  • uv run pytest tests/units: 15290 passed. The 6 failures in tests/units/reflex_cli/... and test_event.py::test_arg_mismatch_warning_renders_brackets_verbatim fail the same way on main in my environment (terminal-width dependent output).
  • uv run pre-commit run --all-files passes, including pyright and ty.
  • reflex-release changelog-check passes.
  • pyright and mypy --strict on a probe that imports DataTable, Icon, Moment, MomentProvider, Plotly*, Audio, Video and toast from the package roots: no errors.

Closes #7708

@Parsiffall1
Parsiffall1 requested a review from a team as a code owner November 1, 2026 18:10

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 31 files

View guided diff | Re-trigger cubic

@greptile-apps

greptile-apps Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no new actionable issues were found.

Summary

Adds py.typed markers to all 14 stub-generating workspace packages.

  • Type checkers can now read stubs shipped with Reflex component packages.
  • Component package roots keep their names public to type checkers.

Reviews (6) · Last reviewed commit: "Merge branch 'main' into fix/component-p..." · Reviewed by Greptile

Comment thread tests/units/test_build_config.py Resolved
@greptile-apps

greptile-apps Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Comments Outside Diff

These findings could not be posted inline.

  • P1 Root imports fail Pyright checks packages/reflex-components-sonner/src/reflex_components_sonner/py.typed:1 ▶

    Adding py.typed enables Pyright's library export rules, but reflex_components_sonner still imports toast without explicitly exporting it. The same problem affects Moment and MomentProvider in reflex_components_moment. Users importing these names from the package roots now get errors saying they are not exported, even though their code still runs.

    Add same-name aliases or __all__, as this PR does for Icon.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

This branch has not been deployed

No deployments
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.

reflex-components-* packages ship .pyi stubs but no py.typed, so mypy types every component as Any

1 participant