Skip to content

Commit 752860e

Browse files
authored
DOC: hide sympified attributes from expression classes (#424)
* DX: allow appending to empty docstring * ENH: improve `get_sympy_fields()` return type hint * ENH: insert non-sympy fields into signature * FIX: show `doit()` rendering of `FormFactor`
1 parent fc189cd commit 752860e

File tree

3 files changed

+53
-24
lines changed

3 files changed

+53
-24
lines changed

docs/_extend_docstrings.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -300,13 +300,7 @@ def extend_FormFactor() -> None:
300300

301301
s, m_a, m_b, L, d = sp.symbols("s m_a m_b L d")
302302
form_factor = FormFactor(s, m_a, m_b, angular_momentum=L, meson_radius=d)
303-
_append_to_docstring(
304-
FormFactor,
305-
f"""
306-
.. math:: {sp.latex(form_factor)}
307-
:label: FormFactor
308-
""",
309-
)
303+
_append_latex_doit_definition(form_factor)
310304

311305

312306
def extend_Kallen() -> None:
@@ -726,8 +720,10 @@ def _create_latex_doit_definition(expr: sp.Expr, deep: bool = False) -> str:
726720

727721

728722
def _append_to_docstring(class_type: Callable | type, appended_text: str) -> None:
729-
assert class_type.__doc__ is not None
730-
class_type.__doc__ += appended_text
723+
if class_type.__doc__ is None:
724+
class_type.__doc__ = appended_text
725+
else:
726+
class_type.__doc__ += appended_text
731727

732728

733729
def __generate_transitions_cached(

docs/conf.py

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
from __future__ import annotations
22

3+
import importlib
4+
import inspect
35
import os
46
import sys
7+
from dataclasses import is_dataclass
58

69
from sphinx_api_relink.helpers import (
710
get_branch_name,
@@ -12,9 +15,51 @@
1215
set_intersphinx_version_remapping,
1316
)
1417

18+
from ampform.sympy._decorator import get_sympy_fields # noqa: PLC2701
19+
1520
sys.path.insert(0, os.path.abspath("."))
1621
from _extend_docstrings import extend_docstrings # noqa: PLC2701
1722

23+
24+
def _get_excluded_members() -> list[str]:
25+
default_exclusions = {
26+
"as_explicit",
27+
"default_assumptions",
28+
"doit",
29+
"evaluate",
30+
"is_commutative",
31+
"is_extended_real",
32+
"items",
33+
"keys",
34+
"precedence",
35+
"values",
36+
}
37+
for cls in [
38+
*_get_dataclasses_recursive("ampform"),
39+
]:
40+
fields = get_sympy_fields(cls)
41+
arg_names = {f.name for f in fields}
42+
default_exclusions.update(arg_names)
43+
return sorted(default_exclusions)
44+
45+
46+
def _get_dataclasses_recursive(module_name: str) -> list[type]:
47+
module = importlib.import_module(module_name)
48+
dataclass_list = _get_dataclasses(module)
49+
for _, submodule in inspect.getmembers(module, inspect.ismodule):
50+
if submodule.__name__.startswith(module_name):
51+
dataclass_list.extend(_get_dataclasses_recursive(submodule.__name__))
52+
return dataclass_list
53+
54+
55+
def _get_dataclasses(module):
56+
dataclass_list = []
57+
for _, obj in inspect.getmembers(module):
58+
if inspect.isclass(obj) and is_dataclass(obj):
59+
dataclass_list.append(obj)
60+
return dataclass_list
61+
62+
1863
extend_docstrings()
1964
set_intersphinx_version_remapping({
2065
"ipython": {
@@ -85,18 +130,7 @@
85130
}
86131
author = "Common Partial Wave Analysis"
87132
autodoc_default_options = {
88-
"exclude-members": ", ".join([
89-
"as_explicit",
90-
"default_assumptions",
91-
"doit",
92-
"evaluate",
93-
"is_commutative",
94-
"is_extended_real",
95-
"items",
96-
"keys",
97-
"precedence",
98-
"values",
99-
]),
133+
"exclude-members": ", ".join(_get_excluded_members()),
100134
"members": True,
101135
"undoc-members": True,
102136
"show-inheritance": True,

src/ampform/sympy/_decorator.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,11 @@ def _implement_new_method(cls: type[ExprClass]) -> type[ExprClass]:
251251
frozen=False,
252252
)(cls)
253253
cls = _update_field_metadata(cls)
254-
sympy_fields = _get_sympy_fields(cls)
255254
non_sympy_fields = tuple(f for f in _get_fields(cls) if not _is_sympify(f)) # type: ignore[arg-type]
256255
cls.__slots__ = tuple(f.name for f in non_sympy_fields) # type: ignore[arg-type]
257256

258257
@functools.wraps(cls.__new__)
259-
@_insert_args_in_signature([f.name for f in sympy_fields], idx=1)
258+
@_insert_args_in_signature([f.name for f in _get_fields(cls)], idx=1) # type:ignore[arg-type]
260259
def new_method(cls, *args, evaluate: bool = False, **kwargs) -> type[ExprClass]:
261260
fields_with_values, hints = _extract_field_values(cls, *args, **kwargs)
262261
fields_with_sympified_values = {
@@ -548,7 +547,7 @@ def _xreplace_method(self, rule) -> tuple[sp.Expr, bool]:
548547
return self, False
549548

550549

551-
def _get_sympy_fields(cls) -> tuple:
550+
def get_sympy_fields(cls) -> tuple[Field, ...]:
552551
return tuple(f for f in _get_fields(cls) if _is_sympify(f))
553552

554553

0 commit comments

Comments
 (0)