[9 regression] WARNING: py:obj reference target not found: typing.Literal['rerun'
type:bug
### Describe the bug
With `autodoc_typehints = "signature"` under `nitpicky`/`-n`, Sphinx 9.1.0 emits `reference target not found` warnings whose "target" is a **fragment of a rendered signature split at a comma** — i.e. the cross-reference machinery is tokenizing a composite annotation (or a default *value*) on commas and looking up each fragment as a Python object. Two shapes:
**(a) `Literal[...]` type aliases** used as field types split at their commas:
```text
WARNING: py:obj reference target not found: typing.Literal['rerun' [ref.obj]
WARNING: py:obj reference target not found: typing.Literal['lcm' [ref.obj]
WARNING: py:class reference target not found: bool | Literal['all' [ref.class]
WARNING: py:class reference target not found: dict[str [ref.class]
WARNING: py:class reference target not found: Mapping[str [ref.class]
```
**(b) Large string *default values*** on (pydantic) model fields are rendered and split, so the string's own prose is looked up as a class name:
```text
WARNING: py:class reference target not found:
SAFETY\nPrioritize human safety above all else. Respect personal boundaries... [ref.class]
WARNING: py:class reference target not found:
"Heading to the front door—let me know if I should go elsewhere."\n\n## Deliveries... [ref.class]
```
A default *value* should never be a cross-reference target, and a `Literal[...]` should be rendered as a single unit. Both are clean on Sphinx 8.2.3; both appear on 9.1.0.
### The key diagnostic: the warnings are context-sensitive
The set of these warnings depends on **which other objects are documented in the same build**, not just on the offending class. This is deterministic run-to-run but changes as unrelated `autoclass` directives are added/removed:
| Documented set | `Literal[...]` warnings |
|---|---|
| `GlobalConfig` alone (full project conf) | **5** |
| `GlobalConfig` + any one unrelated class | **0** |
| Documented set | string-default warnings |
|---|---|
| `McpClientConfig` alone | **0** |
| `McpClientConfig` + a class with a `config:` field of that type | **2** |
Because adding or removing an unrelated documented object flips these warnings on or off, the cause appears to be **shared state during reference resolution** (the new `sphinx.ext.autodoc._dynamic` machinery / the write-phase xref resolver) rather than per-object signature rendering. This context-sensitivity is also why we could not reduce it to a small standalone project — it only manifests with the full set of documented objects.
### Expected behavior
- `Literal["a", "b"]` (directly or via a `TypeAlias`) renders as one unit and is not split at its commas into per-value cross-references.
- A field/parameter **default value** is never emitted as a cross-reference target.
- The presence of `reference target not found` warnings for an object does not depend on which *other* objects are documented in the same build.
(All hold on Sphinx 8.2.3.)
### How to Reproduce
Can't seem to reproduce in isolation. If the issue isn't obvious, I'll prepare a branch on our repo that reproduces it.
### Environment Information
```text
Platform: darwin
Python: 3.12
Sphinx: 9.1.0 (issue not present in 8.x)
Docutils: 0.21.2
Jinja2: 3.1.6
Pygments: 2.19.2
```
### Sphinx extensions
```python
```
### Additional context
Only occurs with `autodoc_typehints = "signature"`; switching to `"none"` removes shape (a) entirely and reduces shape (b) (the string-default warnings persist). All warnings report location `<unknown>:1:`, consistent with being emitted from the reference-resolution phase rather than a source line.
2 条评论