How does `mypy` know the signature of the pydantic model?

Question:

How does mypy know the signature of the pydantic model in this manner?

from pydantic import BaseModel

class Model(BaseModel):
    a: int

Model(a='asd')  # error: Argument "a" to "Model" has incompatible type "str"; expected "int"

How can pydantic BaseModel‘s metaclass change the __init__ signature?

Asked By: Karen Petrosyan

||

Answers:

Pydantic uses PEP681 dataclass_transform on model metaclass to achieve behaviour similar to native dataclasses.dataclass decorator in order to generate an __init__ method for type checkers. Reading the source:

@typing_extensions.dataclass_transform(kw_only_default=True, field_specifiers=(Field,))
class ModelMetaclass(ABCMeta):
    ...  # [omitted by me]

class BaseModel(_repr.Representation, metaclass=ModelMetaclass):
    ... # [omitted by me]

In PEP:

If dataclass_transform is applied to a class, dataclass-like semantics will be assumed for any class that directly or indirectly derives from the decorated class or uses the decorated class as a metaclass.

PEP example (very similar to what pydantic does):

# The ``ModelMeta`` metaclass and ``ModelBase`` class are defined by
# a library. This could be in a type stub or inline.
@typing.dataclass_transform()
class ModelMeta(type): ...

class ModelBase(metaclass=ModelMeta): ...

# The ``ModelBase`` class can now be used to create new model
# subclasses, like this:
class CustomerModel(ModelBase):
    id: int
    name: str
Answered By: SUTerliakov
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.