Skip to content

ENG-9533 feat: render concise, readable types in docgen class documentation#6634

Open
FarhanAliRaza wants to merge 5 commits into
reflex-dev:mainfrom
FarhanAliRaza:fix-api-refs
Open

ENG-9533 feat: render concise, readable types in docgen class documentation#6634
FarhanAliRaza wants to merge 5 commits into
reflex-dev:mainfrom
FarhanAliRaza:fix-api-refs

Conversation

@FarhanAliRaza

@FarhanAliRaza FarhanAliRaza commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Rework reflex-docgen's type/signature rendering so generated class docs read cleanly instead of leaking implementation noise.

  • Add a public format_type() that strips module qualifiers, preserves type-alias names, and renders unions (Optional[...]), literals, and callables recursively.
  • Define the ASGI aliases (Scope, Message, Receive, Send, ASGIApp) via TypeAliasType so their short names survive introspection and docs show e.g. ASGIApp rather than a fully expanded MutableMapping/Awaitable blob.
  • Render method signatures without self/cls, with forward-ref strings kept verbatim (each annotation independently, so one TYPE_CHECKING-only name doesn't poison the rest) and optionality normalized to match format_type.
  • Clean field/parameter defaults: show function names or empty-collection literals instead of volatile <function ... at 0x...> reprs, and exclude function-valued field defaults from the methods table.
  • Polish App attribute docstrings with doc links and a fuller api_transformer description.

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)

New Feature Submission:

  • Does your submission pass the tests?
  • Have you linted your code locally prior to submission?

Changes To Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally?

Before

image

After
image

Rework reflex-docgen's type/signature rendering so generated class docs
read cleanly instead of leaking implementation noise.

- Add a public format_type() that strips module qualifiers, preserves
  type-alias names, and renders unions (Optional[...]), literals, and
  callables recursively.
- Define the ASGI aliases (Scope, Message, Receive, Send, ASGIApp) via
  TypeAliasType so their short names survive introspection and docs show
  e.g. ASGIApp rather than a fully expanded MutableMapping/Awaitable blob.
- Render method signatures without self/cls, with forward-ref strings kept
  verbatim (each annotation independently, so one TYPE_CHECKING-only name
  doesn't poison the rest) and optionality normalized to match format_type.
- Clean field/parameter defaults: show function names or empty-collection
  literals instead of volatile <function ... at 0x...> reprs, and exclude
  function-valued field defaults from the methods table.
- Polish App attribute docstrings with doc links and a fuller
  api_transformer description.
@FarhanAliRaza FarhanAliRaza requested a review from a team as a code owner June 9, 2026 09:04
@FarhanAliRaza FarhanAliRaza added the skip-changelog For doc/internal changes label Jun 9, 2026
@codspeed-hq

codspeed-hq Bot commented Jun 9, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing FarhanAliRaza:fix-api-refs (0b3a28c) with main (932f20f)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@greptile-apps

greptile-apps Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR reworks reflex-docgen's type and signature rendering so generated API reference pages show concise, readable output instead of fully-expanded implementation details (e.g. ASGIApp instead of Callable[[MutableMapping[str, Any], ...], Awaitable[None]]).

  • Adds a public format_type() that strips module qualifiers, preserves TypeAliasType short names, and recursively renders unions, literals, and callables; updates _format_default() to return stable names/empty-collection literals instead of volatile <function … at 0x…> reprs; adds _format_signature() that drops self/cls and handles forward-ref string annotations independently per parameter.
  • Converts the five ASGI type aliases (Scope, Message, Receive, Send, ASGIApp) from plain assignments to TypeAliasType instances so their short names survive get_type_hints() introspection; fixes a small broken-link typo in App's docstring and enriches several attribute descriptions with doc links; removes the deprecated rx.Model from both API reference lists.

Confidence Score: 5/5

Safe to merge — all call sites for the ASGI aliases use them purely as annotations, and the docgen changes are isolated to the documentation pipeline with comprehensive test coverage.

The ASGI TypeAliasType change touches types that are only used as annotations (never for isinstance or get_args calls at runtime), so the behavioral change is contained to get_type_hints() introspection, which is exactly the intended improvement. The new format_type / _format_signature logic is well-covered by parameterized tests including edge cases (ParamSpec, forward-ref strings, quote-safe module stripping, lambda defaults). The only minor concern is commented-out list items in two docs files.

No files require special attention beyond the two docs files (_plugin.py and apiref.py) where rx.Model was left as a comment rather than removed.

Important Files Changed

Filename Overview
packages/reflex-docgen/src/reflex_docgen/_class.py Core rewrite: adds format_type(), _format_default(), _format_signature(), _format_annotation(), and extracts docstring parsing into sections. Logic is well-structured and thoroughly tested; no functional issues found.
packages/reflex-base/src/reflex_base/utils/types.py ASGI aliases (Scope, Message, Receive, Send, ASGIApp) converted from plain assignments to TypeAliasType so their short names survive get_type_hints() introspection. All call sites use these as annotations only (not for isinstance or get_args), so the change is safe at runtime.
reflex/app.py Docstring improvements only: fixes a broken link (extra }) in style, adds doc links to several attributes, and expands the api_transformer description. No logic changes.
tests/units/docgen/test_class_and_component.py Comprehensive new tests for format_type, _format_annotation, _format_signature, callable/factory defaults, field vs method disambiguation, and description stripping. Covers ParamSpec, forward-ref strings, quote-safe module-path stripping, and App-level integration checks.
docs/app/agent_files/_plugin.py Removes rx.Model from the API reference list (deprecated/removed), but leaves it as a comment with an explanation rather than deleting the line.
docs/app/reflex_docs/pages/docs/apiref.py Same rx.Model removal as _plugin.py — same commented-out style issue applies.
packages/reflex-docgen/src/reflex_docgen/init.py Re-exports the new public format_type() function and adds it to all.
tests/units/reflex_base/utils/test_types.py New test file verifying the ASGI aliases are TypeAliasType instances with the correct name values.

Reviews (3): Last reviewed commit: "Merge branch 'main' into fix-api-refs" | Re-trigger Greptile

Comment thread packages/reflex-docgen/src/reflex_docgen/_class.py
Comment on lines +488 to +490
if param.default is not empty:
default = _format_default(param.default, is_factory=False)
text += f" = {default if default is not None else '...'}"

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.

P2 Opaque defaults rendered as = ...

When _format_default returns None for a lambda or unnamed callable default, the signature renders = ... (the Ellipsis literal). This is a reasonable "hidden default" convention used by stub files, but in generated documentation it can be confused with Python's ... stub-body syntax. Consider an explicit placeholder like = <default> or omitting the default entirely so readers understand there is a default without implying the Ellipsis object is the value.

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!

Fold _literal_value, _EMPTY_FACTORY_DISPLAY, _strip_module_qualifiers, and
_optional_from_string into their lone call sites. The string-only forward-ref
handling now lives directly in _format_annotation, so the qualifier-stripping
and Optional[...] rewrite read top-to-bottom in one place instead of hopping
through tiny indirections. No behavior change; tests updated to exercise
_format_annotation directly.
@masenf

masenf commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

the App, Event, EventHandler, EventSpec, page still has all of the attributes listed as body text in addition to appearing in the table

image

The Model page should be removed from auto-gen reference pages, since it is now deprecated.

The class description was the raw cleandoc'd docstring, so a Google-style
Attributes section rendered both as body text and in the fields table,
duplicating every attribute on the API reference page. Parse the docstring
into griffe sections once and derive the prose description (sans Attributes)
and the attribute mapping from the same result.

Also drop the deprecated rx.Model from the generated API reference.
@FarhanAliRaza FarhanAliRaza requested a review from Alek99 as a code owner June 17, 2026 15:19
@FarhanAliRaza

FarhanAliRaza commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

Fixed.
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changelog For doc/internal changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants