From f20a6a54fb041507a334ad71706974960d1b473f Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Fri, 20 May 2022 07:32:29 -0700 Subject: gh-91860: documentation for typing.dataclass_transform (#92768) Co-authored-by: Alex Waygood --- Doc/library/typing.rst | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ Doc/whatsnew/3.11.rst | 10 ++++---- Lib/typing.py | 17 ++++++++----- 3 files changed, 84 insertions(+), 12 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 29bceda..7ddc84a 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -2429,6 +2429,75 @@ Functions and decorators .. versionadded:: 3.11 +.. decorator:: dataclass_transform + + :data:`~typing.dataclass_transform` may be used to + decorate a class, metaclass, or a function that is itself a decorator. + The presence of ``@dataclass_transform()`` tells a static type checker that the + decorated object performs runtime "magic" that + transforms a class, giving it :func:`dataclasses.dataclass`-like behaviors. + + Example usage with a decorator function:: + + T = TypeVar("T") + + @dataclass_transform() + def create_model(cls: type[T]) -> type[T]: + ... + return cls + + @create_model + class CustomerModel: + id: int + name: str + + On a base class:: + + @dataclass_transform() + class ModelBase: ... + + class CustomerModel(ModelBase): + id: int + name: str + + On a metaclass:: + + @dataclass_transform() + class ModelMeta(type): ... + + class ModelBase(metaclass=ModelMeta): ... + + class CustomerModel(ModelBase): + id: int + name: str + + The ``CustomerModel`` classes defined above will + be treated by type checkers similarly to classes created with + :func:`@dataclasses.dataclass `. + For example, type checkers will assume these classes have + ``__init__`` methods that accept ``id`` and ``name``. + + The arguments to this decorator can be used to customize this behavior: + + * ``eq_default`` indicates whether the ``eq`` parameter is assumed to be + ``True`` or ``False`` if it is omitted by the caller. + * ``order_default`` indicates whether the ``order`` parameter is + assumed to be True or False if it is omitted by the caller. + * ``kw_only_default`` indicates whether the ``kw_only`` parameter is + assumed to be True or False if it is omitted by the caller. + * ``field_specifiers`` specifies a static list of supported classes + or functions that describe fields, similar to ``dataclasses.field()``. + * Arbitrary other keyword arguments are accepted in order to allow for + possible future extensions. + + At runtime, this decorator records its arguments in the + ``__dataclass_transform__`` attribute on the decorated object. + It has no other runtime effect. + + See :pep:`681` for more details. + + .. versionadded:: 3.11 + .. decorator:: overload The ``@overload`` decorator allows describing functions and methods diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 1f88d25..ff94e45 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -306,17 +306,17 @@ Kumar Srinivasan and Graham Bleaney.) PEP 681: Data Class Transforms ------------------------------ -The new :data:`~typing.dataclass_transform` annotation may be used to -decorate a function that is itself a decorator, a class, or a metaclass. +:data:`~typing.dataclass_transform` may be used to +decorate a class, metaclass, or a function that is itself a decorator. The presence of ``@dataclass_transform()`` tells a static type checker that the -decorated function, class, or metaclass performs runtime "magic" that -transforms a class, endowing it with dataclass-like behaviors. +decorated object performs runtime "magic" that +transforms a class, giving it :func:`dataclasses.dataclass`-like behaviors. For example:: # The ``create_model`` decorator is defined by a library. @typing.dataclass_transform() - def create_model(cls: Type[_T]) -> Type[_T]: + def create_model(cls: Type[T]) -> Type[T]: cls.__init__ = ... cls.__eq__ = ... cls.__ne__ = ... diff --git a/Lib/typing.py b/Lib/typing.py index 306bb9f..40ab516 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -3368,10 +3368,10 @@ def dataclass_transform( Example usage with a decorator function: - _T = TypeVar("_T") + T = TypeVar("T") @dataclass_transform() - def create_model(cls: type[_T]) -> type[_T]: + def create_model(cls: type[T]) -> type[T]: ... return cls @@ -3400,20 +3400,23 @@ def dataclass_transform( id: int name: str - Each of the ``CustomerModel`` classes defined in this example will now - behave similarly to a dataclass created with the ``@dataclasses.dataclass`` - decorator. For example, the type checker will synthesize an ``__init__`` - method. + The ``CustomerModel`` classes defined above will + be treated by type checkers similarly to classes created with + ``@dataclasses.dataclass``. + For example, type checkers will assume these classes have + ``__init__`` methods that accept ``id`` and ``name``. The arguments to this decorator can be used to customize this behavior: - ``eq_default`` indicates whether the ``eq`` parameter is assumed to be - True or False if it is omitted by the caller. + ``True`` or ``False`` if it is omitted by the caller. - ``order_default`` indicates whether the ``order`` parameter is assumed to be True or False if it is omitted by the caller. - ``kw_only_default`` indicates whether the ``kw_only`` parameter is assumed to be True or False if it is omitted by the caller. - ``field_specifiers`` specifies a static list of supported classes or functions that describe fields, similar to ``dataclasses.field()``. + - Arbitrary other keyword arguments are accepted in order to allow for + possible future extensions. At runtime, this decorator records its arguments in the ``__dataclass_transform__`` attribute on the decorated object. -- cgit v0.12