Skip to content

BaseModel method type annotations cause typing.get_type_hints to raise NameError #7623

@devmonkey22

Description

@devmonkey22

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

While using a project like autodoc_pydantic and Sphinx, it uses sphinx-autodoc-typehints and ultimately the stdlib typing.get_type_hints method to inspect pydantic models, their methods, etc. It seems that the type annotations that pydantic is advertising are incomplete/incorrect, causing NameError exceptions when calling get_type_hints, even natively from the Python REPL.

>>> import typing
>>> from pydantic import BaseModel
>>> typing.get_type_hints(BaseModel.model_copy)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.10/typing.py", line 1871, in get_type_hints
    value = _eval_type(value, globalns, localns)
  File "/usr/lib/python3.10/typing.py", line 327, in _eval_type
    return t._evaluate(globalns, localns, recursive_guard)
  File "/usr/lib/python3.10/typing.py", line 694, in _evaluate
    eval(self.__forward_code__, globalns, localns),
  File "<string>", line 1, in <module>
NameError: name 'Model' is not defined

>>> BaseModel.copy.__annotations__
{'self': 'Model', 'include': 'AbstractSetIntStr | MappingIntStrAny | None', 'exclude': 'AbstractSetIntStr | MappingIntStrAny | None', 'update': 'typing.Dict[str, Any] | None', 'deep': 'bool', 'return': 'Model'}

>>> typing.get_type_hints(BaseModel.dict)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.10/typing.py", line 1871, in get_type_hints
    value = _eval_type(value, globalns, localns)
  File "/usr/lib/python3.10/typing.py", line 327, in _eval_type
    return t._evaluate(globalns, localns, recursive_guard)
  File "/usr/lib/python3.10/typing.py", line 694, in _evaluate
    eval(self.__forward_code__, globalns, localns),
  File "<string>", line 1, in <module>
NameError: name 'IncEx' is not defined

Seems like the annotations need to be fully-qualified or some other similar solution? It may also be because of the conditional around typing.TYPE_CHECKING when defining type vars like Model, IncEx, Literal (from typing_extensions), etc.

For background, ideally need compatibility from Python 3.8-3.11+.

Example Code

import typing
from pydantic import BaseModel
typing.get_type_hints(BaseModel.model_copy)
typing.get_type_hints(BaseModel.model_dump)
typing.get_type_hints(BaseModel.dict)

Python, Pydantic & OS Version

pydantic version: 2.3.0
        pydantic-core version: 2.6.3
          pydantic-core build: profile=release pgo=true
                 install path: ....../env/lib/python3.10/site-packages/pydantic
               python version: 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0]
                     platform: Linux-6.2.0-33-generic-x86_64-with-glibc2.35
     optional deps. installed: ['email-validator', 'typing-extensions']

Metadata

Metadata

Assignees

Labels

bug V2Bug related to Pydantic V2

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions