Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion numpydoc/docscrape.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,13 @@ def _error_location(self, msg, error=True):
filename = inspect.getsourcefile(self._obj)
except TypeError:
filename = None
msg += f" in the docstring of {self._obj.__name__}"
# Make UserWarning more descriptive via object introspection.
# Skip if introspection fails
name = getattr(self._obj, '__name__', None)
if name is None:
name = getattr(getattr(self._obj, '__class__', None), '__name__', None)
if name is not None:
msg += f" in the docstring of {name}"
msg += f" in {filename}." if filename else ""
if error:
raise ValueError(msg)
Expand Down
26 changes: 26 additions & 0 deletions numpydoc/tests/test_docscrape.py
Original file line number Diff line number Diff line change
Expand Up @@ -1522,6 +1522,32 @@ def __init__(self, a, b):
line_by_line_compare(str(doc), xref_doc_txt_expected)


def test__error_location_no_name_attr():
"""
Ensure that NumpyDocString._error_location doesn't fail when self._obj
does not have a __name__ attr.

See gh-362
"""
from collections.abc import Callable

# Create a Callable that doesn't have a __name__ attribute
class Foo():
def __call__(self):
pass


foo = Foo() # foo is a Callable, but no a function instance
assert isinstance(foo, Callable)

# Create an NumpyDocString instance to call the _error_location method
nds = get_doc_object(foo)

msg = "Potentially wrong underline length"
with pytest.raises(ValueError, match=msg):
nds._error_location(msg=msg)


if __name__ == "__main__":
import pytest
pytest.main()