Both Pydantic and Dataclass can typehint the object creation based on the attributes and their typings, like these examples:
from pydantic import BaseModel, PrivateAttr, Field
from dataclasses import dataclass
# Pydantic way
class Person(BaseModel):
name : str
address : str
_valid : bool = PrivateAttr(default=False)
#dataclass way
@dataclass
class PersonDataclass():
name : str
address : str
_valid : bool = False
bob = Person(name="Bob", address="New York")
bobDataclass = PersonDataclass("Bob", "New York")
With this code, I can get typehint on object creation (see screenshots below):
pydantic typehint on object creation
dataclass typehint on object creation
Not only that, but the object's attributes also get documented.
I studied the code of pydantic to try to achieve the same result, but I couldn't. The code that I tried was this:
class MyBaseModelMeta(type):
def __new__(cls, name, bases, dct):
def new_init(self : cls, /, name : str, address : str):
self.name = name
self.address = address
self._valid = False
dct["__init__"] = new_init
dct["__annotations__"] = {"__init__": {"name": str, "address": str, "_valid": bool}}
return super().__new__(cls, name, bases, dct)
class MyBaseModel(metaclass=MyBaseModelMeta):
def __repr__(self) -> str:
return f"MyBaseModel: {self.__dict__}"
class MyPerson(MyBaseModel):
pass
myBob = MyPerson("Bob", "New York")
My class works (the dynamic init insertion works) but the class and object get no typehint.
my class works but it doesn't get typehinted
What am I doing wrong? How can I achieve the typehints?
@Daniil Fajnberg is mostly correct,
but depending on your type checker you can can use the dataclass_transform
(Python 3.11)
or __dataclass_transform__
early adopters program decorator.
Pylance and Pyright (usually used in VS-Code) at least work with these.
You can only mimic the behaviour of dataclasses that way though, I don't think you're able to define that your Metaclass adds extra fields. :/
Edit: At least pydantic uses this decorator for their BaseModel: https://pydantic-docs.helpmanual.io/visual_studio_code/#technical-details
If you dig through the code of pydantic you'll find that their ModelMetaclass is decorated with __dataclass_transform__