Skip to content

Commit

Permalink
fix 'Alias for field number X' problem with NamedTuples (#527)
Browse files Browse the repository at this point in the history
* fix 'Alias for field number X' problem with NamedTuples

* TST: Add test for duplicated attrs w/ namedtuples.

* TST: Add test of explicitly documented namedtuple params.

---------

Co-authored-by: Ross Barnowski <rossbar@berkeley.edu>
  • Loading branch information
fohrloop and rossbar committed Feb 20, 2024
1 parent 8e2d545 commit 46f532a
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
14 changes: 14 additions & 0 deletions numpydoc/docscrape.py
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,7 @@ def properties(self):
for name, func in inspect.getmembers(self._cls)
if (
not name.startswith("_")
and not self._should_skip_member(name, self._cls)
and (
func is None
or isinstance(func, (property, cached_property))
Expand All @@ -715,6 +716,19 @@ def properties(self):
)
]

@staticmethod
def _should_skip_member(name, klass):
if (
# Namedtuples should skip everything in their ._fields as the
# docstrings for each of the members is: "Alias for field number X"
issubclass(klass, tuple)
and hasattr(klass, "_asdict")
and hasattr(klass, "_fields")
and name in klass._fields
):
return True
return False

def _is_show_member(self, name):
if self.show_inherited_members:
return True # show all class members
Expand Down
57 changes: 57 additions & 0 deletions numpydoc/tests/test_docscrape.py
Original file line number Diff line number Diff line change
Expand Up @@ -1641,6 +1641,63 @@ def val(self):
assert class_docstring["Attributes"][0].name == "val"


def test_namedtuple_no_duplicate_attributes():
"""
Ensure that attributes of namedtuples are not duplicated in the docstring.
See gh-257
"""
from collections import namedtuple

foo = namedtuple("Foo", ("bar", "baz"))

# Create the SphinxClassDoc object via get_doc_object
sds = get_doc_object(foo)
assert sds["Attributes"] == []


def test_namedtuple_class_docstring():
"""Ensure that class docstring is preserved when inheriting from namedtuple.
See gh-257
"""
from collections import namedtuple

foo = namedtuple("Foo", ("bar", "baz"))

class MyFoo(foo):
"""MyFoo's class docstring"""

# Create the SphinxClassDoc object via get_doc_object
sds = get_doc_object(MyFoo)
assert sds["Summary"] == ["MyFoo's class docstring"]

# Example dataclass where constructor params are documented explicit.
# Parameter names/descriptions should be included in the docstring, but
# should not result in a duplicated `Attributes` section
class MyFooWithParams(foo):
"""
MyFoo's class docstring
Parameters
----------
bar : str
The bar attribute
baz : str
The baz attribute
"""

bar: str
baz: str

sds = get_doc_object(MyFooWithParams)
assert "MyFoo's class docstring" in sds["Summary"]
assert len(sds["Attributes"]) == 0
assert len(sds["Parameters"]) == 2
assert sds["Parameters"][0].desc[0] == "The bar attribute"
assert sds["Parameters"][1].desc[0] == "The baz attribute"


if __name__ == "__main__":
import pytest

Expand Down

0 comments on commit 46f532a

Please sign in to comment.