Skip to content

Commit f33a53e

Browse files
rossbarlarsoner
andauthored
Fix AttributeError in underline length check (#363)
* Add test for bad behavior. Fix test. * Add test for bad behavior. * Improve object name introspection Co-authored-by: Eric Larson <[email protected]> * Improve test specificity for name introspection Co-authored-by: Eric Larson <[email protected]> Co-authored-by: Eric Larson <[email protected]>
1 parent ffc3fa8 commit f33a53e

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

numpydoc/docscrape.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,13 @@ def _error_location(self, msg, error=True):
426426
filename = inspect.getsourcefile(self._obj)
427427
except TypeError:
428428
filename = None
429-
msg += f" in the docstring of {self._obj.__name__}"
429+
# Make UserWarning more descriptive via object introspection.
430+
# Skip if introspection fails
431+
name = getattr(self._obj, '__name__', None)
432+
if name is None:
433+
name = getattr(getattr(self._obj, '__class__', None), '__name__', None)
434+
if name is not None:
435+
msg += f" in the docstring of {name}"
430436
msg += f" in {filename}." if filename else ""
431437
if error:
432438
raise ValueError(msg)

numpydoc/tests/test_docscrape.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,32 @@ def __init__(self, a, b):
15221522
line_by_line_compare(str(doc), xref_doc_txt_expected)
15231523

15241524

1525+
def test__error_location_no_name_attr():
1526+
"""
1527+
Ensure that NumpyDocString._error_location doesn't fail when self._obj
1528+
does not have a __name__ attr.
1529+
1530+
See gh-362
1531+
"""
1532+
from collections.abc import Callable
1533+
1534+
# Create a Callable that doesn't have a __name__ attribute
1535+
class Foo():
1536+
def __call__(self):
1537+
pass
1538+
1539+
1540+
foo = Foo() # foo is a Callable, but no a function instance
1541+
assert isinstance(foo, Callable)
1542+
1543+
# Create an NumpyDocString instance to call the _error_location method
1544+
nds = get_doc_object(foo)
1545+
1546+
msg = "Potentially wrong underline length.*Foo.*"
1547+
with pytest.raises(ValueError, match=msg):
1548+
nds._error_location(msg=msg)
1549+
1550+
15251551
if __name__ == "__main__":
15261552
import pytest
15271553
pytest.main()

0 commit comments

Comments
 (0)