If I have a pydantic class like:
from typing import Annotated, get_origin
from pydantic import BaseModel
class IgnorableBaseModel(BaseModel):
_ignored: ClassVar[dict[str, Any]] = {}
def __getattr__(self, attr):
"""do something with _ignored, else fallback to default"""
def __init_subclass__(cls, **kwargs) -> None:
del_keys = []
for key, annotation in cls.__annotations__.items():
if key.startswith("_"): # exclude protected/private attributes
continue
if get_origin(annotation) is Annotated:
if get_args(annotation)[1] == "ignore me"
cls._ignored[key] = cls.__annotations__[key]
del_keys.append(key)
for key in del_keys:
del cls.__annotations__[key]
class MyClass(IgnorableBaseModel):
name: Annotated[str, "ignore me"] # ignore this
x: int
I am using this name for a variable that is defined during the __init__
and accessed via __getattr__
so I can't set a value for it. Is there a way to tell mypy to ignore this, or do I need to always override the init args like:
class MyClass(IgnorableBaseModel):
name: Annotated[str, "ignore me"]
x: int
def __init__(self, x: int):
self.x = x
It'd be great if there was an annotation I could add that would inform mypy that this variable was not needed during the init.
"ignore me" is used here to indicate that I don't want to see the error:
Missing named argument "name" for "MyClass"Mypycall-arg
To provide some background, I'm trying to make a python DSL and so it helps to be able to have some attributes type hinted, but not actually require values.
If you want name
to be defined by __init__
without having to pass its value as an argument, use the init
argument to Field
.
from typing import Annotated
from pydantic import BaseModel, Field
class MyClass(BaseModel):
name: Annotated[str, Field(init=False)]
x: int
This can also be written as
class MyClass(BaseModel):
name: str = Field(init=False)
x: int
Now the autogenerated __init__
method will only expect an argument for x
, and it will be up to use to ensure the name
attribute on an instance of MyClass
gets defined. (This could be by using a default value, or a default factory, or an explicitly defined __init__
method, or some other technique that Pydantic provides.)