forked from sphinx-doc/sphinx
-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Cross-references don't work in property's type annotations
User report
A documented type in property's type annotation does not get cross-referenced:
from typing import Optional
class Point:
"""
A class representing a point.
Attributes:
x: Position X.
y: Position Y.
"""
x: int
y: int
class Square:
"""A class representing a square figure."""
#: Square's start position (top-left corner).
start: Point
#: Square width.
width: int
#: Square height.
height: int
@property
def end(self) -> Point:
"""Square's end position (bottom-right corner)."""
return Point(self.start.x + self.width, self.start.y + self.height)
class Rectangle:
"""
A class representing a square figure.
Attributes:
start: Rectangle's start position (top-left corner).
width: Rectangle width.
height: Rectangle width.
"""
start: Point
width: int
height: int
@property
def end(self) -> Point:
"""Rectangle's end position (bottom-right corner)."""
return Point(self.start.x + self.width, self.start.y + self.height)How to reproduce
$ git clone https://github.com/jack1142/sphinx-issue-9585
$ cd sphinx-issue-9585
$ pip install sphinx
$ cd docs
$ make html
$ # open _build/html/index.html and see the issue
Expected behavior
Types in property annotations (e.g., def end(self) -> Point) should be cross-referenced like attributes/return types.
Observed failure
- Generated HTML shows the type name (e.g., "Point") as plain text in the property signature; it is not a link.
- No stack trace is emitted; this is a rendering/linking issue without build errors. Sphinx emits no warnings for the type in this scenario because the domain never creates a cross-reference for the property type.
Research specification (root cause and proposed fix)
Root cause
- Autodoc emits a ":type:" option for properties when
autodoc_typehints != 'none'(PropertyDocumenter usesstringify_typehint). - In the Python domain:
- PyAttribute.handle_signature() parses the
:type:string via_parse_annotation(typ, env)and creates pending_xref nodes, so attributes' types link correctly. - PyProperty.handle_signature() appends the
:type:value as plain text usingaddnodes.desc_annotation(typ, ': ' + typ)and does not call_parse_annotation.
- PyAttribute.handle_signature() parses the
- Because PyProperty bypasses
_parse_annotation, it never creates cross-reference nodes for the property type.
Proposed change
- File:
sphinx/domains/python.py - Function:
PyProperty.handle_signature() - When a
typeoption is present, parse it via_parse_annotation(typ, self.env)and insert the returned nodes into the signature, mirroring PyAttribute’s logic.- Pseudo-diff:
- Before:
signode += addnodes.desc_annotation(typ, ': ' + typ) - After:
annotations = _parse_annotation(typ, self.env); signode += addnodes.desc_annotation(typ, '', nodes.Text(': '), *annotations)
- Before:
- Pseudo-diff:
Notes and configs
- Respects
python_use_unqualified_type_names(modern) to show short labels while linking to fully qualified targets. - Works regardless of how
stringify_typehintrenders names; cross-reference creation happens in the domain layer. autodoc_typehints='none'remains unchanged (no type emitted; no linking).
Acceptance criteria
- Property type annotations are rendered as cross-references (links) like attributes.
- Behavior adheres to
python_use_unqualified_type_names. - No regressions for attributes, variables, or callable return types.
Test plan (to be implemented in PR)
- Domain-level tests ensuring PyProperty parses and links types (including
Noneand fully qualified names). - Autodoc integration tests showing
@property def end(self) -> Pointproduces a linked type in the signature. - A minimal docs example demonstrating pre/post-fix behavior.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels