Ship py.typed in the stub-generating component packages

PA
18h ago
+45-18

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