CarliJoy / intersection_examples

Python Typing Intersection examples
MIT License
33 stars 2 forks source link

Sample use case: Returning from a dataclass-transform #27

Open NeilGirdhar opened 1 year ago

NeilGirdhar commented 1 year ago

This is a typical use of the PEP 681 dataclass_transform:

class DataclassInstance(Protocol):  # See usefule_types.experimental.DataclassLike
    __dataclass_fields__: ClassVar[dict[str, dataclasses.Field[Any]]]

@overload
@dataclass_transform(frozen_default=True, field_specifiers=(field,))
def dataclass(*, init: bool = True, repr_: bool = True, eq: bool = True,
              order: bool = False) -> Callable[[type[Any]], type[DataclassInstance]]:
    ...

@overload
@dataclass_transform(frozen_default=True, field_specifiers=(field,))
def dataclass(cls: type[Any], /, *, init: bool = True, repr_: bool = True, eq: bool = True,
              order: bool = False) -> type[DataclassInstance]:
    ...

What we would like to have, in fact, would be the following return types:

@overload
@dataclass_transform(frozen_default=True, field_specifiers=(field,))
def dataclass[T](*, init: bool = True, repr_: bool = True, eq: bool = True,
              order: bool = False) -> Callable[[type[T]], type[T] & type[DataclassInstance]]:
    ...

@overload
@dataclass_transform(frozen_default=True, field_specifiers=(field,))
def dataclass[T](cls: type[T], /, *, init: bool = True, repr_: bool = True, eq: bool = True,
              order: bool = False) -> type[T] & type[DataclassInstance]:
    ...

This would allow the type check to know that the returned dataclass is both a DataclassInstance (supports dataclasses.fields, dataclasses.replace, etc.) as well as remaining T.