Skip to content

fix: Expand relative cross-references against the object the docstring was written on - #342

Merged
pawamoy merged 1 commit into
mkdocstrings:mainfrom
devtechedge:fix/inherited-relative-crossrefs
Sep 22, 2026
Merged

pawamoy merged 1 commit into
mkdocstrings:mainfrom
devtechedge:fix/inherited-relative-crossrefs

Conversation

@devtechedge

Copy link
Copy Markdown
Contributor

With inherited_members enabled, the docstring of a base class member is rendered in the docs of the inheriting class. In AutorefsHook.expand_identifier, leading-dot relative cross-references found in such docstrings walk up from current_object, which for an inherited member is a Griffe alias living under the inheriting class. A reference written on pkga.sub.Base.MAPPING therefore expands to pkgb.Thing in the docs of a package that subclasses Base, instead of pkga.Thing, silently linking to a wrong target or aborting strict builds when the consumer has relative_crossrefs disabled.

This change anchors the dot-walk on the docstring's parent, the object the docstring was actually written on, when that object is reachable, and falls back to the current object otherwise. This mirrors how get_context already uses docstring.parent for source location. The reproducer and root-cause analysis in #341 describe exactly this behavior, including the frequenz-sdk build failure against frequenz-quantities.

A regression test in tests/test_rendering.py builds two in-memory modules with cross-module inheritance and asserts a ....Thing reference in an inherited member's docstring expands to pkga.Thing; it fails on main and passes with this change. A control assertion also checks that non-inherited objects still expand identically.

Re-export aliases are anchored uniformly by this change: since docstring.parent of a re-export alias points at the private defining object, relative references there now expand against it. If different treatment is preferred for re-exports, happy to follow maintainer guidance. Whether the consumer's relative_crossrefs setting should gate expansion of a dependency's docstring at all is out of scope for this PR.

Fixes #341

…g was written on

With inherited members enabled, docstrings of base class members are
rendered in the docs of the inheriting class, where the current object
is a Griffe alias living under the inheriting class. Leading-dot
relative cross-references found in such docstrings were therefore
expanded against the consumer's tree instead of the dependency's tree,
resolving to wrong targets or failing strict builds.

Anchor the dot-walk on the docstring's parent (the defining object)
when it is reachable, falling back to the current object otherwise.
@pawamoy pawamoy self-assigned this Sep 17, 2026
@devtechedge

Copy link
Copy Markdown
Contributor Author

Hello - gentle follow-up on the inherited relative-crossref fix whenever the queue allows.

With inherited_members enabled, AutorefsHook.expand_identifier walked leading-dot relative cross-references from current_object, which for an inherited member is a Griffe alias under the inheriting class, so a reference written on pkga.sub.Base.MAPPING could expand to pkgb.Thing instead of pkga.Thing (Fixes #341).

This anchors the dot-walk on docstring.parent (the object the docstring was actually written on) when reachable, falling back to the current object otherwise, matching how get_context already uses docstring.parent for source location. The change lives in src/mkdocstrings_handlers/python/_internal/rendering.py.

A regression in tests/test_rendering.py builds two in-memory modules with cross-module inheritance and asserts a ....Thing reference in an inherited member's docstring expands to pkga.Thing; it fails on main and passes with this change, with a control that non-inherited objects still expand identically.

Quality checks are green across platforms; several lowest-direct / Windows / 3.15 legs fail on this PR the same way they already fail on main at the base commit, so they are not introduced here.

Happy to special-case re-export aliases differently, or gate expansion on the consumer's relative_crossrefs setting, if that is the preferred shape.

No rush - still ready whenever it fits.

@pawamoy pawamoy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot, looking good!

@pawamoy
pawamoy merged commit a9a4ca3 into mkdocstrings:main Sep 22, 2026
20 of 33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: relative cross-references in inherited members are expanded against the inheriting class

2 participants