From 364830d58d31f6fe4ac3e60121edf52ad013e941 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 5 Apr 2022 18:16:58 -0700 Subject: [PATCH 1/3] dataclass_transform: accept **kwargs, rename field_descriptors --- typing_extensions/src/typing_extensions.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/typing_extensions/src/typing_extensions.py b/typing_extensions/src/typing_extensions.py index 5698a76cc..c7686bfe7 100644 --- a/typing_extensions/src/typing_extensions.py +++ b/typing_extensions/src/typing_extensions.py @@ -1795,10 +1795,11 @@ def dataclass_transform( eq_default: bool = True, order_default: bool = False, kw_only_default: bool = False, - field_descriptors: typing.Tuple[ + field_specifiers: typing.Tuple[ typing.Union[typing.Type[typing.Any], typing.Callable[..., typing.Any]], ... ] = (), + **kwargs: typing.Any, ) -> typing.Callable[[T], T]: """Decorator that marks a function, class, or metaclass as providing dataclass-like behavior. @@ -1850,7 +1851,7 @@ class CustomerModel(ModelBase): 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_descriptors`` specifies a static list of supported classes + - ``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 @@ -1864,7 +1865,8 @@ def decorator(cls_or_fn): "eq_default": eq_default, "order_default": order_default, "kw_only_default": kw_only_default, - "field_descriptors": field_descriptors, + "field_specifiers": field_specifiers, + "kwargs": kwargs, } return cls_or_fn return decorator From e226fedbb6f1c1aa2cb519568ef984d05bfc70ad Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 5 Apr 2022 18:25:58 -0700 Subject: [PATCH 2/3] tests and changelog --- typing_extensions/CHANGELOG | 3 +++ .../src/test_typing_extensions.py | 18 +++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/typing_extensions/CHANGELOG b/typing_extensions/CHANGELOG index a9a598045..746a8aad1 100644 --- a/typing_extensions/CHANGELOG +++ b/typing_extensions/CHANGELOG @@ -1,5 +1,8 @@ # Unreleased +- Update `typing_extensions.dataclass_transform` to rename the + `field_descriptors` parameter to `field_specifiers` and accept + arbitrary keyword arguments. - Add `typing.assert_type`. Backport from bpo-46480. - Drop support for Python 3.6. Original patch by Adam Turner (@AA-Turner). diff --git a/typing_extensions/src/test_typing_extensions.py b/typing_extensions/src/test_typing_extensions.py index b8fe5e352..5bd2878dd 100644 --- a/typing_extensions/src/test_typing_extensions.py +++ b/typing_extensions/src/test_typing_extensions.py @@ -2646,7 +2646,8 @@ class CustomerModel: "eq_default": True, "order_default": False, "kw_only_default": True, - "field_descriptors": (), + "field_specifiers": (), + "kwargs": {}, } ) self.assertIs( @@ -2658,7 +2659,12 @@ def test_base_class(self): class ModelBase: def __init_subclass__(cls, *, frozen: bool = False): ... - Decorated = dataclass_transform(eq_default=True, order_default=True)(ModelBase) + Decorated = dataclass_transform( + eq_default=True, + order_default=True, + # Arbitrary unrecognized kwargs are accepted at runtime. + make_everything_awesome=True, + )(ModelBase) class CustomerModel(Decorated, frozen=True): id: int @@ -2670,7 +2676,8 @@ class CustomerModel(Decorated, frozen=True): "eq_default": True, "order_default": True, "kw_only_default": False, - "field_descriptors": (), + "field_specifiers": (), + "kwargs": {"make_everything_awesome": True}, } ) self.assertIsSubclass(CustomerModel, Decorated) @@ -2685,7 +2692,7 @@ def __new__( return super().__new__(cls, name, bases, namespace) Decorated = dataclass_transform( - order_default=True, field_descriptors=(Field,) + order_default=True, field_specifiers=(Field,) )(ModelMeta) class ModelBase(metaclass=Decorated): ... @@ -2700,7 +2707,8 @@ class CustomerModel(ModelBase, init=False): "eq_default": True, "order_default": True, "kw_only_default": False, - "field_descriptors": (Field,), + "field_specifiers": (Field,), + "kwargs": {}, } ) self.assertIsInstance(CustomerModel, Decorated) From 8c9ad30c93778dcc9fbbae4ac51f70b93dd2067e Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 5 Apr 2022 18:27:02 -0700 Subject: [PATCH 3/3] grammar --- typing_extensions/src/typing_extensions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typing_extensions/src/typing_extensions.py b/typing_extensions/src/typing_extensions.py index c7686bfe7..91ce0c429 100644 --- a/typing_extensions/src/typing_extensions.py +++ b/typing_extensions/src/typing_extensions.py @@ -1852,7 +1852,7 @@ class CustomerModel(ModelBase): - ``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()``. + 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.