Promptice

Sphinx Python Domain: :var: Fields Incorrectly Cross-Reference Variable Names

sphinx-doc__sphinx-8638 · cardboard

Sphinx Python Domain: :var: Fields Incorrectly Cross-Reference Variable Names

You are working in the sphinx-doc/sphinx repository at commit 4b452338f914d4f6b54704222d70ae8a746e3db5.

Problem

In Sphinx's Python domain, docstring field lists accept :var:, :ivar:, and :cvar: field types to document instance, class, and plain variables on a class or module. These fields accept an optional type annotation and a variable name, for example:

.. py:class:: MyClass

   :var int attr: Some integer attribute.

The bug: the variable name (attr in the example above) is currently wrapped in a pending_xref node — the same mechanism Sphinx uses to resolve cross-references to other objects in the documentation. This causes Sphinx to attempt a cross-reference lookup for the bare variable name attr, which can match unrelated attributes in other classes or modules. The variable name should be rendered as addnodes.literal_strong (plain bold monospace text), not as a hyperlink to wherever Sphinx can find something named attr.

The type annotation (int in the example) must continue to produce a pending_xref with reftype='class' so that type names resolve normally.

Requirements / Interface

1. File to modify: sphinx/domains/python.py

2. Target object: The PyTypedField instance named 'variable' (field names 'var', 'ivar', 'cvar') defined inside PyObject.doc_field_types. At the base commit this entry looks roughly like:

```python
PyTypedField('variable', label=_('Variables'),

names=('var', 'ivar', 'cvar'),

typerolename='class', rolename='obj',

can_collapse=True),

```

3. Required change: The rolename='obj' argument causes the field argument (variable name) to become a pending_xref. Remove or replace that argument so the variable name is emitted as addnodes.literal_strong instead. The typerolename='class' must be preserved so type annotations still cross-reference as class objects.

4. Test that must pass (added by the hidden test patch): tests/test_domain_py.py::test_info_field_list_var

The hidden test parses the RST:

```rst
.. py:class:: Class

:var int attr: blah blah
```

and asserts that the field list entry for attr is structured as:

```
(

[addnodes.literal_strong, 'attr'],

' (',

[pending_xref, addnodes.literal_emphasis, 'int'],

')',

' -- ',

'blah blah'

)

```

Crucially, attr must not be inside a pending_xref node.

5. All 34 pre-existing tests in tests/test_domain_py.py listed in the pass-to-pass set must continue to pass.

Examples

Before the fix (current behaviour)

Parsing :var int attr: blah blah inside a .. py:class:: directive produces a node tree that wraps the variable name in a cross-reference:

pending_xref(attr)   literal_emphasis(int)   text('blah blah')

Because pending_xref(attr) is resolved against the entire documentation tree, it can silently link attr to an unrelated class attribute that happens to share the name.

After the fix

literal_strong(attr)   pending_xref → literal_emphasis(int)   text('blah blah')

No cross-reference is produced for the variable name itself.

Constraints

  • Only modify sphinx/domains/python.py (and tests/test_domain_py.py if you want to add the test locally, but the hidden grader will apply its own test patch regardless).
  • Do not alter the typerolename='class' argument — type annotations must still resolve.
  • Do not change the field names 'var', 'ivar', 'cvar' or the can_collapse=True setting.
  • The rolename parameter in TypedField / PyTypedField controls whether the field argument gets a cross-reference. Setting it to an empty string or omitting it entirely is the idiomatic Sphinx fix.
  • The fix is a single-line or very small change. Large refactors of docfields.py or PyTypedField internals are out of scope and may break other tests.

Scoring

Your submission is accepted if:

1. The hidden test tests/test_domain_py.py::test_info_field_list_var passes.
2. All 34 pass-to-pass tests in tests/test_domain_py.py continue to pass.

Leaderboards additionally rank accepted runs by estimated token usage, cost, and wall-clock time.

Container

not started

Visible tests

35

Hidden tests

0

Last run

Not run

35 total0 passed0 failed
1

Test 1

fail to pass

info field list var

2

Test 2

pass to pass

function signatures

3

Test 3

pass to pass

domain py xrefs

4

Test 4

pass to pass

domain py objects

5

Test 5

pass to pass

resolve xref for properties

6

Test 6

pass to pass

domain py find obj

7

Test 7

pass to pass

get full qualified name

8

Test 8

pass to pass

parse annotation

9

Test 9

pass to pass

pyfunction signature

10

Test 10

pass to pass

pyfunction signature full

11

Test 11

pass to pass

pyfunction signature full py38

12

Test 12

pass to pass

pyfunction with number literals

13

Test 13

pass to pass

optional pyfunction signature

14

Test 14

pass to pass

pyexception signature

15

Test 15

pass to pass

exceptions module is ignored

16

Test 16

pass to pass

pydata signature

17

Test 17

pass to pass

pydata signature old

18

Test 18

pass to pass

pyobject prefix

19

Test 19

pass to pass

pydata

20

Test 20

pass to pass

pyfunction

21

Test 21

pass to pass

pyclass options

22

Test 22

pass to pass

pymethod options

23

Test 23

pass to pass

pyclassmethod

24

Test 24

pass to pass

pystaticmethod

25

Test 25

pass to pass

pyattribute

26

Test 26

pass to pass

pydecorator signature

27

Test 27

pass to pass

pydecoratormethod signature

28

Test 28

pass to pass

canonical

29

Test 29

pass to pass

info field list

30

Test 30

pass to pass

module index

31

Test 31

pass to pass

module index submodule

32

Test 32

pass to pass

module index not collapsed

33

Test 33

pass to pass

modindex common prefix

34

Test 34

pass to pass

noindexentry

35

Test 35

pass to pass

warn missing reference

README.md

sphinx-doc/sphinx

Loading repository...code-server
Loading...
Workspace Terminal