33from __future__ import annotations
44
55import dataclasses
6- from typing import Annotated
76
87import reflex as rx
9- from typing_extensions import Doc
108
119
1210def test_class_doc_extraction ():
13- """generate_class_documentation extracts Doc from Annotated types and unwraps the type ."""
11+ """generate_class_documentation extracts descriptions from docstrings ."""
1412 from reflex_docgen import generate_class_documentation
1513
1614 @dataclasses .dataclass
1715 class FakeModule :
18- """A fake module for testing."""
16+ """A fake module for testing.
1917
20- name : Annotated [str , Doc ("The name of the thing." )]
21- count : Annotated [int , Doc ("How many things." )] = 0
18+ Attributes:
19+ name: The name of the thing.
20+ count: How many things.
21+ """
22+
23+ name : str
24+ count : int = 0
2225 plain : str = "hello"
2326
2427 doc = generate_class_documentation (FakeModule )
2528 by_name = {f .name : f for f in doc .fields }
2629
27- # Doc is extracted from Annotated metadata
30+ # Description is extracted from docstring
2831 assert by_name ["name" ].description == "The name of the thing."
2932 assert by_name ["count" ].description == "How many things."
3033 assert by_name ["plain" ].description is None
3134
32- # type is unwrapped (not Annotated)
3335 assert by_name ["name" ].type is str
3436 assert by_name ["count" ].type is int
3537 assert by_name ["plain" ].type is str
3638
3739
3840def test_class_no_annotated_in_format ():
39- """format_field should never produce a string containing 'Annotated'."""
41+ """format_field should not produce a string containing 'Annotated'."""
4042 from reflex_docgen import generate_class_documentation
4143
4244 from pcweb .pages .docs .source import format_field
4345
4446 @dataclasses .dataclass
4547 class FakeModule :
46- """A fake module for testing."""
48+ """A fake module for testing.
4749
48- name : Annotated [str , Doc ("The name." )] = "default"
49- items : Annotated [list [int ], Doc ("A list." )] = dataclasses .field (
50- default_factory = list
51- )
50+ Attributes:
51+ name: The name.
52+ items: A list.
53+ """
54+
55+ name : str = "default"
56+ items : list [int ] = dataclasses .field (default_factory = list )
5257
5358 doc = generate_class_documentation (FakeModule )
5459
@@ -68,14 +73,15 @@ def test_format_field_preserves_generic_subtypes():
6873
6974 @dataclasses .dataclass
7075 class FakeModule :
71- """A fake module for testing."""
76+ """A fake module for testing.
7277
73- items : Annotated [list [int ], Doc ("A list of ints." )] = dataclasses .field (
74- default_factory = list
75- )
76- mapping : Annotated [dict [str , int ], Doc ("A mapping." )] = dataclasses .field (
77- default_factory = dict
78- )
78+ Attributes:
79+ items: A list of ints.
80+ mapping: A mapping.
81+ """
82+
83+ items : list [int ] = dataclasses .field (default_factory = list )
84+ mapping : dict [str , int ] = dataclasses .field (default_factory = dict )
7985 plain : str = "hello"
8086
8187 doc = generate_class_documentation (FakeModule )
@@ -98,7 +104,7 @@ def test_class_string_annotations():
98104 from reflex_docgen import generate_class_documentation
99105
100106 # rx.App uses `from __future__ import annotations`, so its field types are strings.
101- # Verify we still extract docs and unwrap Annotated .
107+ # Verify types are still resolved correctly .
102108 doc = generate_class_documentation (rx .App )
103109
104110 for f in doc .fields :
0 commit comments