I just stumbled across this weird thing with python 3.12.
I have a type I import under if TYPE_CHECKING:.
When trying to reference this type without quotes, I expect a NameError, because the variable BaseModel doesn't exist at runtime.
But for some reason python lets me use this name as "bound" in 3.12 generic syntax.
I didn't expect python to not error on an undefined BaseModel variable in why_does_this_work.
from typing import TYPE_CHECKING, TypeVar
if TYPE_CHECKING:
from pydantic import BaseModel
def works_as_expected[T: "BaseModel"](a: type[T]) -> T:
return a()
# ???
def why_does_this_work[T: BaseModel](a: type[T]) -> T:
return a()
# Breaks as expected:
# NameError: name 'BaseModel' is not defined
_T = TypeVar("_T", bound=BaseModel)
def whatever(a: type[_T]) -> _T:
return a()
Can someone explain this to me?
Is there a way to inspect this T in why_does_this_work at runtime, try to get it's "bound" type and, by doing so, trigger a NameError?
I know about PEP-649 and PEP-749 - deferred evaluation of annotations, but these PEPs are getting implemented in 3.14 and I found this behavior in 3.12.