Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
1 task done
devmonkey22 opened this issue Sep 25, 2023 · 1 comment · Fixed by #7680
Closed
1 task done
Assignees
Labels
bug V2 Bug related to Pydantic V2

Comments

@devmonkey22
Copy link
Contributor

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']
@devmonkey22 devmonkey22 added bug V2 Bug related to Pydantic V2 unconfirmed Bug not yet confirmed as valid/applicable labels Sep 25, 2023
@samuelcolvin samuelcolvin removed the unconfirmed Bug not yet confirmed as valid/applicable label Sep 26, 2023
@samuelcolvin
Copy link
Member

Thanks for reporting. It seems typing.get_type_hints(BaseModel.model_copy) is fixed by moving Model and IncEx outside the if TYPE_CHECKING.

PR welcome to fix this and any other non deprecated method. I'm really so interested in fixing BaseModel.dict etc.

PR should:

  • move only the required things outside if TYPE_CHECKING
  • include a comment explaining why they're not inside
  • add tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug V2 Bug related to Pydantic V2
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants