From d580df721186689f7ed8c893c957aaf218388c32 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Fri, 13 May 2022 01:15:24 -0700 Subject: [PATCH 1/8] gh-91860: documentation for typing.dataclass_transform --- Doc/library/typing.rst | 65 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 29bcedaddce9dd..4da650d8df36ee 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -2429,6 +2429,71 @@ Functions and decorators .. versionadded:: 3.11 +.. decorator:: dataclass_transform + + The :data:`~typing.dataclass_transform` annotation may be used to + decorate a function that is itself a decorator, a class, or a metaclass. + 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. + + 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 + + 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 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()``. + + 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 From 7dde8033dc7caa0bac615a3ee81febdeff9dd377 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Fri, 13 May 2022 01:25:36 -0700 Subject: [PATCH 2/8] fix rst --- Doc/library/typing.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 4da650d8df36ee..06420db317eff3 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -2437,7 +2437,7 @@ Functions and decorators decorated function, class, or metaclass performs runtime "magic" that transforms a class, endowing it with dataclass-like behaviors. - Example usage with a decorator function: + Example usage with a decorator function:: _T = TypeVar("_T") @@ -2451,7 +2451,7 @@ Functions and decorators id: int name: str - On a base class: + On a base class:: @dataclass_transform() class ModelBase: ... @@ -2460,7 +2460,7 @@ Functions and decorators id: int name: str - On a metaclass: + On a metaclass:: @dataclass_transform() class ModelMeta(type): ... From 57b60832d6a5beb5fe92fb628bb01a0c6708289b Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Fri, 13 May 2022 01:49:08 -0700 Subject: [PATCH 3/8] more rst --- Doc/library/typing.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 06420db317eff3..9b65c5ab1ad83a 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -2477,14 +2477,15 @@ Functions and decorators method. 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()``. + + * ``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()``. At runtime, this decorator records its arguments in the ``__dataclass_transform__`` attribute on the decorated object. From 908dffbbcfe7da3be60eae4525b7342ea8d02836 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Mon, 16 May 2022 17:51:08 -0700 Subject: [PATCH 4/8] review changes --- Doc/library/typing.rst | 25 ++++++++++++++----------- Doc/whatsnew/3.11.rst | 10 +++++----- Lib/typing.py | 17 ++++++++++------- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 9b65c5ab1ad83a..3c19b66a5e5cb8 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -2431,18 +2431,18 @@ Functions and decorators .. decorator:: dataclass_transform - The :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. 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 @@ -2471,21 +2471,24 @@ Functions and decorators 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 + :func:`@dataclasses.dataclass `. + For example, type checkers will assume these classes have an + ``__init__`` method analogous to that of a dataclass. 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. diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 6518eea4c7ba55..b5d6eb6e529216 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 306bb9fb6df784..1379984f4c0eb6 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 @@ class CustomerModel(ModelBase): 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 an + ``__init__`` method analogous to that of a dataclass. 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. From 30343137f53afa72fe8ccf943f6f2451ed3c204a Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Mon, 16 May 2022 17:53:20 -0700 Subject: [PATCH 5/8] lost the decorator in the markup --- Lib/typing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/typing.py b/Lib/typing.py index 1379984f4c0eb6..7142d6f8a656cb 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -3402,7 +3402,7 @@ class CustomerModel(ModelBase): The ``CustomerModel`` classes defined above will be treated by type checkers similarly to classes created with - ``dataclasses.dataclass``. + ``@dataclasses.dataclass``. For example, type checkers will assume these classes have an ``__init__`` method analogous to that of a dataclass. From fa723b2430ad376d24db4caf21f9b6a5899d164d Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Mon, 16 May 2022 17:54:32 -0700 Subject: [PATCH 6/8] be more concrete --- Doc/library/typing.rst | 2 +- Lib/typing.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 3c19b66a5e5cb8..5d1745343b55b6 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -2475,7 +2475,7 @@ Functions and decorators be treated by type checkers similarly to classes created with :func:`@dataclasses.dataclass `. For example, type checkers will assume these classes have an - ``__init__`` method analogous to that of a dataclass. + ``__init__`` method that accepts ``id`` and ``name``. The arguments to this decorator can be used to customize this behavior: diff --git a/Lib/typing.py b/Lib/typing.py index 7142d6f8a656cb..1d423b7f14b293 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -3404,7 +3404,7 @@ class CustomerModel(ModelBase): be treated by type checkers similarly to classes created with ``@dataclasses.dataclass``. For example, type checkers will assume these classes have an - ``__init__`` method analogous to that of a dataclass. + ``__init__`` method that accepts ``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 From 282c19406e36a30c107aeb25a96abf19eb14da49 Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Thu, 19 May 2022 18:47:14 -0700 Subject: [PATCH 7/8] Update Doc/library/typing.rst Co-authored-by: Alex Waygood --- Doc/library/typing.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 5d1745343b55b6..7ddc84ac5e4518 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -2474,8 +2474,8 @@ Functions and decorators 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 an - ``__init__`` method that accepts ``id`` and ``name``. + 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: From c30ff070b47e70b8eaaca453177052d1011801b5 Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Thu, 19 May 2022 18:47:20 -0700 Subject: [PATCH 8/8] Update Lib/typing.py Co-authored-by: Alex Waygood --- Lib/typing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/typing.py b/Lib/typing.py index 1d423b7f14b293..40ab516f7c8ff7 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -3403,8 +3403,8 @@ class CustomerModel(ModelBase): 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 an - ``__init__`` method that accepts ``id`` and ``name``. + 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