Describe the Bug
A quoted forward reference in a class body resolves against a same-named class
member. The Python typing conformance test expects the quoted reference to
resolve outside the class scope, while the equivalent unquoted annotation
resolves to the class member and is rejected as an invalid type.
Minimal reproduction:
from typing import assert_type
class ClassD:
def int(self) -> None:
...
x: "int" = 0 # OK: quoted reference resolves to builtins.int
y: int = 0 # E: local method `int` isn't a legal type expression
assert_type(ClassD.x, int)
The quoted annotation produces an error for x:
Expected a type form, got instance of `(self: Self@ClassD) -> None`
It then treats ClassD.x as Unknown, producing a second failure:
assert_type(Unknown, int) failed
Expected behavior:
- Accept the quoted annotation
"int" and resolve it to builtins.int.
- Continue rejecting the unquoted annotation
int, which refers to the local
method and isn't a valid type expression.
- Preserve
ClassD.x as int without the cascading Unknown error.
The mismatch appears in
conformance.result.
The corresponding test is
annotations_forward_refs.py.
Related Work
- Issue #1900 discusses
same-named methods shadowing types, but its reproduction uses unquoted
annotations. Its discussion points to the expected error for the unquoted
case in this conformance test.
- PR #1983 added an
overload-specific lookup exception.
- Issue #357 and
PR #3617 address unquoted
forward references evaluated before Python 3.14.
- Issue #3387 and
PR #3391 address a different
from __future__ import annotations case.
This issue specifically covers lookup semantics for a quoted annotation when a
class member shadows the referenced name.
Sandbox Link
Not provided; the reproduction above is self-contained and comes directly from
the typing conformance suite.
Describe the Bug
A quoted forward reference in a class body resolves against a same-named class
member. The Python typing conformance test expects the quoted reference to
resolve outside the class scope, while the equivalent unquoted annotation
resolves to the class member and is rejected as an invalid type.
Minimal reproduction:
The quoted annotation produces an error for
x:It then treats
ClassD.xasUnknown, producing a second failure:Expected behavior:
"int"and resolve it tobuiltins.int.int, which refers to the localmethod and isn't a valid type expression.
ClassD.xasintwithout the cascadingUnknownerror.The mismatch appears in
conformance.result.The corresponding test is
annotations_forward_refs.py.Related Work
same-named methods shadowing types, but its reproduction uses unquoted
annotations. Its discussion points to the expected error for the unquoted
case in this conformance test.
overload-specific lookup exception.
PR #3617 address unquoted
forward references evaluated before Python 3.14.
PR #3391 address a different
from __future__ import annotationscase.This issue specifically covers lookup semantics for a quoted annotation when a
class member shadows the referenced name.
Sandbox Link
Not provided; the reproduction above is self-contained and comes directly from
the typing conformance suite.