Skip to content

Do not warn on references to in-scope PEP 695 type parameters - #14518

Open
apoorvdarshan wants to merge 1 commit into
sphinx-doc:masterfrom
apoorvdarshan:fix-14462-pep695-type-param-scope
Open

Do not warn on references to in-scope PEP 695 type parameters#14518
apoorvdarshan wants to merge 1 commit into
sphinx-doc:masterfrom
apoorvdarshan:fix-14462-pep695-type-param-scope

Conversation

@apoorvdarshan

Copy link
Copy Markdown

Fixes #14462

Problem

References to PEP 695 type parameters — in type parameter bounds, argument lists, return annotations, and the bodies of generic classes — are converted into py:class pending cross-references. Type parameters have no link target and, per PEP 695 scoping, shadow any documented object of the same name, so every such reference produces a spurious reference target not found warning under -n (the reporter counts ~1000 in an 8k LoC project). Reproduced on master with the issue's snippet (3 spurious warnings).

Fix

  • PyObject.handle_signature() records the type parameter names introduced by a signature in env.ref_context['py:type_params'] (saving the enclosing scope on the directive instance), so they are visible while parsing the type parameter list itself (bounds/constraints/defaults), the argument list, and the return annotation.
  • PyObject.after_content() restores the enclosing scope, so the names also cover the object's body — e.g. py:method:: eggs(arg: int) -> T inside py:class:: Spam[T] — and never leak past the directive (mirrors the existing py:class/py:module ref-context handling, including nesting).
  • type_to_xref() renders an in-scope, un-dotted name as plain Text instead of a pending_xref. Rendered output is unchanged — an unresolvable reference already fell back to plain text — but no warning is emitted, and a documented class shadowed by a type parameter is no longer (incorrectly) linked.

Out-of-scope references still warn: py:function:: outside(x: T) after a generic class continues to report T.

Two existing doctree-shape tests (test_class_def_pep_695, test_class_def_pep_696) pinned the old behavior of in-scope names inside bounds/constraints (e.g. S: Sequence[T]) being pending xrefs; they were updated to expect plain text for exactly those names (Sequence, tuple, int etc. remain xrefs).

This is complementary to #14504, which handles the autodoc/runtime-TypeVar side via missing-reference; this PR covers the directive-syntax layer, where scope is known at parse time.

Verification

  • New testroot test-domain-py-type-param-scope + test_pep_695_type_param_scope_nitpicky (asserts the only remaining warning is the genuinely out-of-scope T) and test_pep_695_type_params_render_as_text — both fail on master.
  • Full test suite (minus test_intl): ~2,900 passed, failure set byte-identical to master in my environment (6 pre-existing environment-dependent failures).
  • ruff check/ruff format clean on changed files; mypy clean on both changed modules.

AI policy disclosure

Per the AI policy: this contribution was prepared with the assistance of an AI tool (Claude Code), used for the investigation, the patch, and the tests. I reproduced the issue, reviewed and verified the change and all test results, and take responsibility for the contribution — I'll respond to review feedback personally.

References to PEP 695 type parameters in type parameter bounds,
argument lists, return annotations, and the bodies of generic objects
were turned into py:class cross references. Since type parameters have
no link target and shadow any documented object of the same name, this
produced spurious 'reference target not found' warnings in nitpicky
mode (one reporter counted about a thousand in an 8k LoC project).

Track the type parameter names introduced by a signature in
env.ref_context while the signature and the object's content are
parsed, and render in-scope names as plain text instead of pending
cross references. The rendered output is unchanged (an unresolvable
reference already fell back to plain text); out-of-scope references
still warn.

Fixes sphinx-doc#14462
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.

Type variables flagged as undefined with ref.class warning spuriously in nitpicky mode

1 participant