Extra dataclass_transform
features
typing.dataclass_transform
is a bit strange.
It is a compromise to fulfill the urgent need to support dataclass-like objects
(mostly in pydantic
and attrs
) to some extent without adding a generic and flexible
mechanism for defining your own dataclass_transform
.
If your use case deviates from what dataclass_transform
explicitly supports,
it can be difficult or impossible to work around that.
Luckily, dataclass_transform
accepts arbitrary keyword arguments at runtime
to allow type checkers to add their own little hacks on top of the standard ones.
basedpyright
currently supports these options:
-
skip_replace
: setting this toTrue
disables the synthesis of the__replace__
method.Pyright (and basedpyright) assumes that classes produced by a dataclass transform define a
__replace__
method, as long as the class is not marked withinit=False
and does not define a custom__init__
method. However,typing.dataclass_transform
doesn't require that the__replace__
method is defined.In addition,
__replace__
messes with the variance inference of frozen dataclasses (see this discourse thread for details). Here's a recipe you can use to work around this:from typing import dataclass_transform @dataclass_transform(skip_replace=True, frozen_default=True) def frozen[T: type](t: T) -> T: return dataclass(frozen=True, slots=True)(t) # check that this enables covariance: @frozen class Box[T]: value: T box1: Box[str] = Box("test") box2: Box[str | int] = box1
All of these options require the enableBasedFeatures
configuration option to be set to true
.