You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Docstring implicit inheritance can render cross-reference targets ambiguous. #6211
When a subclass is added, implicit docstring inheritance by its methods can create ambiguous cross-reference targets in the docstrings of the methods of the parent class.
class A:
"""The A."""
def dothis(self):
"""Call :obj:`.dothat`."""
def dothat(self):
"""Really do it."""
class Unrelated:
"""Nothing related."""
def dothat(self):
"""Has the same name as :obj:`A.dothat`, but otherwise unrelated."""
Build the docs with themodule.py in the PYTHONPATH (PYTHONPATH=. make html) -- things work fine; in particular the doc of A.dothis correctly links to A.dothat.
Now let's say someone adds (in the same module) a subclass of A that overrides dothis, but doesn't bother with a docstring:
class B(A):
def dothis(self): pass
Trying to build the docs now results in a warning:
/tmp/testdocs/themodule.py:docstring of themodule.B.dothis:1: WARNING: more than one target found for cross-reference 'dothat': themodule.A.dothat, themodule.Unrelated.dothat
i.e. B.dothis inherited A.dothis's docstring, but doesn't know what ":obj:`.dothat`" is supposed to refer to. I believe it should actually resolve it to mean B.dothat (which happens to be equal to A.dothat). (emphasis as this is the actual issue at hand) Indeed, if B also defines dothat:
class B(A):
def dothis(self): pass
def dothat(self): pass
then the docstring of B.dothisdoes link to B.dothat.
Expected behavior
In B.dothis's docstring, ":obj:`.dothat`" should link to A.dothat (if B.dothat does not exist).
Your project
n/a
Screenshots
n/a
Environment info
OS: linux
Python version: 3.7.2
Sphinx version: 1.8.5
Sphinx extensions: sphinx.ext.autodoc
Extra tools: n/a
Additional context
Add any other context about the problem here.
[e.g. URL or Ticket]
Reacted by vaaaaanquish, Stephen Rosen, Yunus Sevinchan, Jacob Stevens-Haas and Florian Best
I looked a bit into how to resolve this (and other similar issues, e.g. Derived classes in other modules losing the ability to refer to things defined in the module of the parent class). Unfortunately, it looks like by the time the references are getting resolved (in resolve_xref), the information that B derives from A (and thus that the docstrings should be resolved by preferring A) has been lost. Indeed, even when using :show-inheritance:, autodoc just formats the parent classes as
Bases: :class:`...`
It may help if :py:class: gained the ability to record base classes, e.g.
Activity
anntzer commentedon Nov 17, 2019
I looked a bit into how to resolve this (and other similar issues, e.g. Derived classes in other modules losing the ability to refer to things defined in the module of the parent class). Unfortunately, it looks like by the time the references are getting resolved (in
resolve_xref), the information thatBderives fromA(and thus that the docstrings should be resolved by preferringA) has been lost. Indeed, even when using :show-inheritance:, autodoc just formats the parent classes asIt may help if :py:class: gained the ability to record base classes, e.g.
(one can't use
.. py:class:: Derived(Base, ...)because parentheses specify the constructor signature).8 remaining items
spaceone commentedon Oct 13, 2025
CC me, as I am also affected by this bug.