diff --git a/README.rst b/README.rst index d1eddfd73..280588043 100644 --- a/README.rst +++ b/README.rst @@ -84,6 +84,11 @@ This is the last major release to support Python 3.7. Highest priority callables will be called first during post-processing. * Fix too noisy ``--verbose`` mode (suppres some ambiguous annotations warnings). +pydoctor 23.9.1 +^^^^^^^^^^^^^^^ + +* Fix regression in link not found warnings' line numbers. + pydoctor 23.9.0 ^^^^^^^^^^^^^^^ diff --git a/pydoctor/linker.py b/pydoctor/linker.py index a9019cadd..f403e64dc 100644 --- a/pydoctor/linker.py +++ b/pydoctor/linker.py @@ -252,8 +252,6 @@ def __init__(self, obj:'model.Documentable') -> None: self._scope = obj.parent or obj self._module_linker = self._module.docstring_linker self._scope_linker = self._scope.docstring_linker - - self.switch_context(obj).__enter__() @property def obj(self) -> 'model.Documentable': @@ -271,16 +269,18 @@ def warn_ambiguous_annotation(self, target:str) -> None: ) def link_to(self, target: str, label: "Flattenable") -> Tag: - if self._module.isNameDefined(target): - self.warn_ambiguous_annotation(target) - return self._module_linker.link_to(target, label) - elif self._scope.isNameDefined(target): - return self._scope_linker.link_to(target, label) - else: - return self._module_linker.link_to(target, label) + with self.switch_context(self._obj): + if self._module.isNameDefined(target): + self.warn_ambiguous_annotation(target) + return self._module_linker.link_to(target, label) + elif self._scope.isNameDefined(target): + return self._scope_linker.link_to(target, label) + else: + return self._module_linker.link_to(target, label) def link_xref(self, target: str, label: "Flattenable", lineno: int) -> Tag: - return self.obj.docstring_linker.link_xref(target, label, lineno) + with self.switch_context(self._obj): + return self.obj.docstring_linker.link_xref(target, label, lineno) @contextlib.contextmanager def switch_context(self, ob:Optional['model.Documentable']) -> Iterator[None]: diff --git a/pydoctor/test/test_epydoc2stan.py b/pydoctor/test/test_epydoc2stan.py index a8a495018..828edccfb 100644 --- a/pydoctor/test/test_epydoc2stan.py +++ b/pydoctor/test/test_epydoc2stan.py @@ -2120,3 +2120,46 @@ def func(): assert docstring2html(mod.contents['func'], docformat='plaintext') == expected captured = capsys.readouterr().out assert captured == '' + +def test_regression_not_found_linenumbers(capsys: CapSys) -> None: + """ + Test for issue https://github.com/twisted/pydoctor/issues/745 + """ + code = ''' + __docformat__ = 'restructuredtext' + class Settings: + """ + Object that manages the configuration for Twine. + + This object can only be instantiated with keyword arguments. + + For example, + + .. code-block:: python + + Settings(True, username='fakeusername') + + Will raise a :class:`TypeError`. Instead, you would want + + .. code-block:: python + + Settings(sign=True, username='fakeusername') + """ + + def check_repository_url(self) -> None: + """ + Verify we are not using legacy PyPI. + """ + ... + + def create_repository(self) -> repository.Repository: + """ + Create a new repository for uploading. + """ + ... + ''' + + mod = fromText(code, ) + docstring2html(mod.contents['Settings']) + captured = capsys.readouterr().out + assert captured == ':15: Cannot find link target for "TypeError"\n' \ No newline at end of file