diff --git a/typing_extensions/CHANGELOG b/typing_extensions/CHANGELOG index 970bbd4a6..550a14631 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_extensions.get_overloads` and `typing_extensions.clear_overloads`, and add registry support to `typing_extensions.overload`. Backport from python/cpython#89263. diff --git a/typing_extensions/src/test_typing_extensions.py b/typing_extensions/src/test_typing_extensions.py index ab03244d3..8e11eb671 100644 --- a/typing_extensions/src/test_typing_extensions.py +++ b/typing_extensions/src/test_typing_extensions.py @@ -2718,7 +2718,8 @@ class CustomerModel: "eq_default": True, "order_default": False, "kw_only_default": True, - "field_descriptors": (), + "field_specifiers": (), + "kwargs": {}, } ) self.assertIs( @@ -2730,7 +2731,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 @@ -2742,7 +2748,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) @@ -2757,7 +2764,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): ... @@ -2772,7 +2779,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) diff --git a/typing_extensions/src/typing_extensions.py b/typing_extensions/src/typing_extensions.py index 491109991..1e3e12829 100644 --- a/typing_extensions/src/typing_extensions.py +++ b/typing_extensions/src/typing_extensions.py @@ -1866,10 +1866,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. @@ -1921,8 +1922,8 @@ 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 - or functions, that describe fields, similar to ``dataclasses.field()``. + - ``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. @@ -1935,7 +1936,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