Finding edge cases for PEPs 484, 563, and 649 (type annotations)

Edge case with PEP 563: using annotations not defined in the module scope

(Please note, this is taken more-or-less verbatim from the related pydantic issue).

Example:

from __future__ import annotations
from pydantic import BaseModel

def main():
    from pydantic import PositiveInt

    class TestModel(BaseModel):
        foo: PositiveInt

    print(TestModel(foo=1))

main()

This is not a fundamental problem with types being left as strings, but rather with how PEP 563 was implemented:

Annotations can only use names present in the module scope as postponed evaluation using local names is not reliable (with the sole exception of class-level names resolved by typing.get_type_hints() )

Of course, I’ve used from pydantic import PositiveInt above, but it could be any import or a custom type defined within the function, including another pydantic model. It could even be simple type alias like Method = Literal['GET', 'POST'].

Personally I think this is very confusing as it’s very different from the way python scope works otherwise.

(Sorry if this has been mentioned above, I thought it best to add my example for completeness.)

1 Like