[New-bugs-announce] [issue46539] typing: forward references don't understand special type forms

Gregory Beauregard report at bugs.python.org
Wed Jan 26 15:30:38 EST 2022

New submission from Gregory Beauregard <greg at greg.red>:

Consider the following code on 3.11 main:

from typing import Annotated, ClassVar, get_type_hints

class DC:
    a: ClassVar[int] = 3
    b: ClassVar["int"] = 3
    c: "ClassVar[int]" = 3
    d: Annotated[ClassVar[int], (2, 5)] = 3
    e: Annotated[ClassVar["int"], (2, 5)] = 3
    f: "Annotated[ClassVar[int], (2, 5)]" = 3

class DC_Special_ForwardRef:
    g: Annotated["ClassVar[int]", (] = 3

# OK
assert get_type_hints(DC, globals(), locals()) == {
    "a": ClassVar[int],
    "b": ClassVar[int],
    "c": ClassVar[int],
    "d": ClassVar[int],
    "e": ClassVar[int],
    "f": ClassVar[int],

# TypeError: typing.ClassVar[int] is not valid as type argument
get_type_hints(DC_Special_ForwardRef, globals(), locals())

Currently, the `Annotated["ClassVar[int]", (2, 5)]` annotation raises at runtime when `get_type_hints` is called, but all the other forward reference annotations are okay.

My understanding is this is because when typing._type_check runs on a type where special forms are allowed it's possible for the typing._type_convert it calls it itself run a typing._type_check on contained forward references. However, if that forward reference was itself a special form then it's possible to get an error because typing._type_check doesn't pass on that special forms are allowed.

I have drafted a patch to pass on this information. This will become important in the future as more special forms are allowed to wrap each other, such as allowing Final and ClassVar to nest each other in dataclasses, or when Required and NotRequired land. In the future we may also want to reconsider runtime restrictions on special forms in `typing.py` entirely and instead choose to leave this to type checkers.

Is my analysis/patch approach okay? Forward references can be tricky. Should we be discussing runtime restrictions in typing.py more generally in the future?

components: Library (Lib)
messages: 411790
nosy: GBeauregard, Jelle Zijlstra, gvanrossum, kj
priority: normal
severity: normal
status: open
title: typing: forward references don't understand special type forms
versions: Python 3.10, Python 3.11, Python 3.9

Python tracker <report at bugs.python.org>

More information about the New-bugs-announce mailing list