pytype
pytype copied to clipboard
Erroneous typing when importing pydantic BaseModel
Description
When importing the BaseModel from pydantic, pytype assumes that it is a module, instead of a class.
To Reproduce
Run pytype on a file containing:
from pydantic import BaseModel
class NewModel(BaseModel):
pass
This code works fine at runtime.
Output
Computing dependencies
Analyzing 1 sources with 0 local dependencies
ninja: Entering directory `.pytype'
[1/1] check pydantic-type
FAILED: /Users/agtree/.pytype/pyi/pydantic-type.pyi
/Users/agtree/Software/anaconda3/envs/typechecking/bin/python -m pytype.single --imports_info /Users/agtree/.pytype/imports/pydantic-type.imports --module-name pydantic-type -V 3.9 -o /Users/agtree/.pytype/pyi/pydantic-type.pyi --analyze-annotated --nofail --quick /Users/agtree/pydantic-type.py
File "/Users/agtree/pydantic-type.py", line 4, in <module>: Invalid base class: <instance of module> [base-class-error]
For more details, see https://google.github.io/pytype/errors.html#base-class-error
ninja: build stopped: subcommand failed.
Leaving directory '.pytype'
Notes
import pydantic
class NewModel(pydantic.BaseModel):
pass
Does not throw an error.
Versions:
# Name Version Build Channel
attrs 21.2.0 pyhd3eb1b0_0
ca-certificates 2021.10.26 hecd8cb5_2
certifi 2021.10.8 py39hecd8cb5_2
dataclasses 0.8 pyh6d0b6a4_7
importlab 0.7 pyhd8ed1ab_0 conda-forge
libcst 0.3.19 py39hecd8cb5_0
libcxx 12.0.0 h2f01273_0
libffi 3.3 hb1e8313_2
mypy_extensions 0.4.3 py39hecd8cb5_1
ncurses 6.3 hca72f7f_2
networkx 2.6.3 pyhd3eb1b0_0
ninja 1.10.2.3 pypi_0 pypi
openssl 1.1.1m hca72f7f_0
pip 21.2.4 py39hecd8cb5_0
pydantic 1.8.2 py39hca72f7f_0
python 3.9.7 h88f2d9e_1
python_abi 3.9 2_cp39 conda-forge
pytype 2022.01.07 py39h9fcab8e_0 conda-forge
pyyaml 6.0 py39hca72f7f_1
readline 8.1.2 hca72f7f_1
setuptools 58.0.4 py39hecd8cb5_0
sqlite 3.37.0 h707629a_0
tabulate 0.8.9 py39hecd8cb5_0
tk 8.6.11 h7bc2e8c_0
toml 0.10.2 pyhd3eb1b0_0
typed-ast 1.5.1 py39h89e85a6_0 conda-forge
typing-extensions 3.10.0.2 hd3eb1b0_0
typing_extensions 3.10.0.2 pyh06a4308_0
typing_inspect 0.7.1 pyhd3eb1b0_0
tzdata 2021e hda174b7_0
wheel 0.37.1 pyhd3eb1b0_0
xz 5.2.5 h1de35cc_0
yaml 0.2.5 haf1e3a3_0
zlib 1.2.11 h4dc903c_4
Huh, that's a funny bug. I'm a little surprised we haven't run into this before. pytype doesn't have type information for pydantic, so it generates a default import mapping like so:
pydantic/BaseModel .pytype/imports/default.pyi
(That "default.pyi" file just contains def __getattr__(name) -> Any.) But the default mapping makes an assumption that "from x import y" always means that y is a module, which is obviously not true.
Probably for "from x import y" we should generate a pyi for x, not for y.
Anyone know of a workaround for this? It's a pretty big blocker here...
@declension under the "Notes" in my original post there's a different way to import that works fine. You can also just tell pytype to ignore the line: https://google.github.io/pytype/user_guide.html#silencing-errors
@declension under the "Notes" in my original post there's a different way to import that works fine. You can also just tell pytype to ignore the line: https://google.github.io/pytype/user_guide.html#silencing-errors
Thanks - though I really meant without changing lots of source code, but maybe that can do until a fix comes.
Just ran into this one when testing pytype, imo renders pytype pretty useless and will block adoption for me.
In addition to spuriously parsing from x import y as though y were a module, the underlying cause of this is https://github.com/google/pytype/issues/151 (no PEP 561 support in pytype). Pydantic is PEP 561 compliant.