-
Notifications
You must be signed in to change notification settings - Fork 70
Fxc 5438 trim generated docstrings for pydantic v 2 models #3240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Fxc 5438 trim generated docstrings for pydantic v 2 models #3240
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
|
This is amazing to address this thanks! |
5a85da9 to
14efed3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
|
This one got bigger than initially planned, but wanted to get rid of missing links/non-interpretable aliases and some overheads. |
21b7c7f to
68ad642
Compare
Diff CoverageDiff: origin/develop...HEAD, staged and unstaged changes
Summary
tidy3d/components/base.pyLines 281-289 281 _parent_namespace_depth=_parent_namespace_depth,
282 _types_namespace=_types_namespace,
283 )
284 if _DOCSTRING_RAW_ATTR not in cls.__dict__:
! 285 setattr(cls, _DOCSTRING_RAW_ATTR, cls.__doc__ or "")
286 cls.__doc__ = cls.generate_docstring()
287 return rebuilt
288
289 @model_validator(mode="wrap")Lines 1684-1692 1684 # keep any pre-existing class description
1685 original_docstrings = []
1686 raw_doc = cls.__dict__.get(_DOCSTRING_RAW_ATTR)
1687 if raw_doc is None:
! 1688 raw_doc = cls.__doc__ or ""
1689 if raw_doc:
1690 original_docstrings = raw_doc.split("\n\n")
1691 doc += original_docstrings.pop(0)
1692 original_docstrings = "\n\n".join(original_docstrings)Lines 1707-1716 1707 # default / default_factory
1708 if field.default_factory is not None:
1709 try:
1710 default_val = field.default_factory()
! 1711 except Exception:
! 1712 default_val = f"{field.default_factory.__name__}()"
1713 else:
1714 default_val = field.get_default(call_default_factory=False)
1715
1716 if isinstance(default_val, BaseModel):Lines 1717-1725 1717 default_val = _format_model_default(
1718 default_val, show_default_args=show_default_args
1719 )
1720 elif "=" in str(default_val) if default_val is not None else False:
! 1721 default_val = _clean_default_repr(
1722 str(f"{default_val.__class__.__name__}({default_val})")
1723 )
1724
1725 default_str = "" if field.is_required() else f" = {default_val}"tidy3d/components/docstrings.pyLines 31-39 31 origin = get_origin(ann)
32 if origin is not None and getattr(origin, "__name__", None) == "Annotated":
33 args = get_args(ann)
34 if not args:
! 35 return ann, []
36 return args[0], list(args[1:])
37 return ann, []
38 Lines 48-58 48
49 def _format_type_name(ann: Any) -> str:
50 """Return a concise, human-readable name for a type-like object."""
51 if ann is type(None):
! 52 return "None"
53 if ann is object:
! 54 return "Any"
55 try:
56 from tidy3d.components.base import Tidy3dBaseModel
57
58 if isinstance(ann, type) and issubclass(ann, Tidy3dBaseModel):Lines 56-72 56 from tidy3d.components.base import Tidy3dBaseModel
57
58 if isinstance(ann, type) and issubclass(ann, Tidy3dBaseModel):
59 return f":class:`~{ann.__module__}.{ann.__name__}`"
! 60 except Exception:
! 61 pass
62 forward_arg = getattr(ann, "__forward_arg__", None)
63 if forward_arg:
64 if forward_arg.startswith("tidy3d."):
! 65 return f":class:`~{forward_arg}`"
66 return forward_arg
67 if isinstance(ann, str) and ann.startswith("tidy3d."):
! 68 return f":class:`~{ann}`"
69 if hasattr(ann, "__name__"):
70 return ann.__name__
71 return _strip_typing_prefixes(str(ann))Lines 103-111 103 def base_repr(m: BaseModel) -> str:
104 return BaseModel.__repr__(m)
105
106 if show_default_args:
! 107 return _clean_default_repr(" ".join(base_repr(model).split()))
108
109 model_cls = model.__class__
110 try:
111 default_model = model_cls()Lines 127-136 127 for key in ordered_fields:
128 if key in diff_keys:
129 try:
130 value = getattr(model, key)
! 131 except Exception:
! 132 value = current_dump.get(key)
133 parts.append(
134 f"{key}={_format_default_value(value, show_default_args=show_default_args)}"
135 )Lines 135-143 135 )
136
137 for key in diff_keys:
138 if key not in ordered_fields:
! 139 parts.append(
140 f"{key}={_format_default_value(current_dump[key], show_default_args=show_default_args)}"
141 )
142
143 return _clean_default_repr(f"{model_cls.__name__}({', '.join(parts)})")Lines 169-178 169 "i": "int",
170 "u": "int",
171 "b": "bool",
172 }.get(kind, np_dtype.name)
! 173 except Exception:
! 174 dtype_str = str(dtype)
175
176 parts: list[str] = []
177 if dtype_str is not None:
178 parts.append(f"dtype={dtype_str}")Lines 191-200 191 if isinstance(val, type):
192 return True
193 try:
194 return get_origin(val) is not None or bool(get_args(val))
! 195 except Exception:
! 196 return False
197
198
199 def _extract_traced_alias_base(metadata: list[Any]) -> Any | None:
200 """Extract a base annotation from validator closures used by traced aliases."""Lines 202-210 202 func = getattr(meta, "func", None)
203 if func is None or getattr(func, "__name__", "") != "_validate_box_or_container":
204 continue
205 if not func.__closure__:
! 206 continue
207 for cell in func.__closure__:
208 val = cell.cell_contents
209 if isinstance(val, TypeAdapter):
210 continueLines 290-296 290
291 def _fmt_ann_literal(ann: Any, field_metadata: list[Any] | None = None) -> str:
292 """Render a concise annotation string for docstrings."""
293 if ann is None:
! 294 return "Any"
295 return _format_annotation(ann, field_metadata=field_metadata) |
This PR overhauls docstring generation for Pydantic v2 and cleans up Sphinx docs to reduce noise and ambiguity.
Changes
Docstring generation refactor + cleanup
docstrings.py) and wiredTidy3dBaseModelto use them.Annotatedmetadata and verbosetyping_extensions.*prefixes.PositiveFloat,NonNegativeInt, etc.).ArrayLike[...]withdtype/ndim/shapemetadata.attrs={}andtype=...from reprs.attrsby default and toggle default-arg verbosity.Docstring regression tests
test_docstrings.pyto assert:Annotated/discriminated_union,Docs fixes and cleanup
attrsfrom autodoc and autosummary (no moreattrssubpages).to_gdspyremoval; clarifiedgdstkonly).Scene,Geometry,ModeSolverData) by using~tidy3d.*aliases.See as reference example images (before -> after)
Tests
pytest -k docstrings(new docstring regression coverage viatest_docstrings.py)Notes
Note
Medium Risk
Touches
Tidy3dBaseModeldocstring generation and__repr__used across most models, so regressions would be broad (though largely documentation/UI-facing). Sphinx build behavior also changes (autosummary overwrite, skip hooks, xref rewriting), which could affect doc build output and link resolution.Overview
Refactors model docstring rendering by moving formatting logic into new
components/docstrings.pyand wiringTidy3dBaseModelto cache raw class docs, regenerate docstrings on subclass init/rebuild, hideattrsby default, collapse default model reprs, and render cleaner type annotations (stripAnnotatednoise, preserve constrained types, support ArrayLike metadata, handle autograd traced aliases).Overhauls Sphinx API generation to reduce noise and broken links: autosummary stubs are now overwritten, templates filter out internal members (
attrs, Pydantic internals, private/dunder), anddocs/conf.pyadds hooks to skip private members, strip default Pydanticmodel_*doc blocks, and rewrite/validate:class:cross-references against known doc targets (with added intersphinx mappings).Updates many API docs to fix/modernize autosummary targets and references (new abstract/base entries, moved/renamed symbols,
tidy3d.rf.*namespace, removedgdspymention), adds Gaussian overlap monitor docs, exportsFreqDataArray/FreqModeDataArrayintidy3d.__init__, adds docstring regression tests, and removes/adjusts some autograd cache-related test scaffolding.Written by Cursor Bugbot for commit 14efed3. This will update automatically on new commits. Configure here.