8000 Merge pull request #208 from lpsinger/nondefault-fields · astropy/sphinx-automodapi@6ce8845 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6ce8845

Browse files
authored
Merge pull request #208 from lpsinger/nondefault-fields
Support for non-default dataclass fields (continuation of stale PR, #116)
2 parents ed5f54c + ec44299 commit 6ce8845

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

sphinx_automodapi/autodoc_enhancements.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""
2< 8000 /td>2
Miscellaneous enhancements to help autodoc along.
33
"""
4+
import dataclasses
5+
46
from sphinx.ext.autodoc import AttributeDocumenter
57

68
__all__ = []
@@ -58,7 +60,14 @@ def type_object_attrgetter(obj, attr, *defargs):
5860
return base.__dict__[attr]
5961
break
6062

61-
return getattr(obj, attr, *defargs)
63+
try:
64+
return getattr(obj, attr, *defargs)
65+
except AttributeError:
66+
# for dataclasses, get the attribute from the __dataclass_fields__
67+
if dataclasses.is_dataclass(obj) and attr in obj.__dataclass_fields__:
68+
return obj.__dataclass_fields__[attr].default
69+
else:
70+
raise
6271

6372

6473
def setup(app):

sphinx_automodapi/automodsumm.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class members that are inherited from a base class. This value can be
103103
import inspect
104104
import os
105105
import re
106+
import dataclasses
106107

107108
import sphinx
108109
from docutils.parsers.rst.directives import flag
@@ -595,11 +596,22 @@ def get_members_class(obj, typ, include_public=[],
595596
else:
596597
names = getattr(obj, '__dict__').keys()
597598

599+
# add dataclass_field names for dataclass classes
600+
if dataclasses.is_dataclass(obj):
601+
dataclass_fieldnames = getattr(obj, '__dataclass_fields__').keys()
602+
names = list(set(list(names) + list(dataclass_fieldnames)))
603+
598604
for name in names:
599605
try:
600606
documenter = get_documenter(app, safe_getattr(obj, name), obj)
601607
except AttributeError:
602-
continue
608+
# for dataclasses try to get the attribute from the __dataclass_fields__
609+
if dataclasses.is_dataclass(obj):
610+
try:
611+
attr = obj.__dataclass_fields__[name]
612+
documenter = get_documenter(app, attr, obj)
613+
except KeyError:
614+
continue
603615
if typ is None or documenter.objtype == typ:
604616
items.append(name)
605617
# elif typ == 'attribute' and documenter.objtype == 'property':

sphinx_automodapi/tests/test_autodoc_enhancements.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,20 @@ def test_type_attrgetter():
4141

4242
assert type_object_attrgetter(MyClass, 'susy', 'default') == 'default'
4343
assert type_object_attrgetter(MyClass, '__dict__') == MyClass.__dict__
44+
45+
46+
def test_type_attrgetter_for_dataclass():
47+
"""
48+
This tests the attribute getter for non-default dataclass fields
49+
"""
50+
import dataclasses
51+
52+
@dataclasses.dataclass
53+
class MyDataclass:
54+
foo: int
55+
bar: str = "bar value"
56+
57+
with pytest.raises(AttributeError):
58+
getattr(MyDataclass, 'foo')
59+
assert type_object_attrgetter(MyDataclass, 'foo') == dataclasses.MISSING
60+
assert getattr(MyDataclass, 'bar') == 'bar value'

0 commit comments

Comments
 (0)
0