mirror of https://github.com/python/cpython
gh-118974: Add `decorator` argument to `make_dataclass` (gh-122723)
This is to allow the `dataclasses.make_dataclass` infrastructure to be used with another decorator that's compliant with `typing.dataclass_transform`. The new `decorator` argument to `dataclasses.make_dataclass` is `dataclasses.dataclass`, which used to be hard coded.
This commit is contained in:
parent
91e64be731
commit
3e3a4d2315
|
@ -399,7 +399,7 @@ Module contents
|
|||
:func:`!astuple` raises :exc:`TypeError` if *obj* is not a dataclass
|
||||
instance.
|
||||
|
||||
.. function:: make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False, module=None)
|
||||
.. function:: make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False, module=None, decorator=dataclass)
|
||||
|
||||
Creates a new dataclass with name *cls_name*, fields as defined
|
||||
in *fields*, base classes as given in *bases*, and initialized
|
||||
|
@ -415,6 +415,11 @@ Module contents
|
|||
of the dataclass is set to that value.
|
||||
By default, it is set to the module name of the caller.
|
||||
|
||||
The *decorator* parameter is a callable that will be used to create the dataclass.
|
||||
It should take the class object as a first argument and the same keyword arguments
|
||||
as :func:`@dataclass <dataclass>`. By default, the :func:`@dataclass <dataclass>`
|
||||
function is used.
|
||||
|
||||
This function is not strictly required, because any Python
|
||||
mechanism for creating a new class with :attr:`!__annotations__` can
|
||||
then apply the :func:`@dataclass <dataclass>` function to convert that class to
|
||||
|
@ -438,6 +443,9 @@ Module contents
|
|||
def add_one(self):
|
||||
return self.x + 1
|
||||
|
||||
.. versionadded:: 3.14
|
||||
Added the *decorator* parameter.
|
||||
|
||||
.. function:: replace(obj, /, **changes)
|
||||
|
||||
Creates a new object of the same type as *obj*, replacing
|
||||
|
|
|
@ -1550,7 +1550,7 @@ def _astuple_inner(obj, tuple_factory):
|
|||
def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
|
||||
repr=True, eq=True, order=False, unsafe_hash=False,
|
||||
frozen=False, match_args=True, kw_only=False, slots=False,
|
||||
weakref_slot=False, module=None):
|
||||
weakref_slot=False, module=None, decorator=dataclass):
|
||||
"""Return a new dynamically created dataclass.
|
||||
|
||||
The dataclass name will be 'cls_name'. 'fields' is an iterable
|
||||
|
@ -1630,8 +1630,8 @@ def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
|
|||
if module is not None:
|
||||
cls.__module__ = module
|
||||
|
||||
# Apply the normal decorator.
|
||||
return dataclass(cls, init=init, repr=repr, eq=eq, order=order,
|
||||
# Apply the normal provided decorator.
|
||||
return decorator(cls, init=init, repr=repr, eq=eq, order=order,
|
||||
unsafe_hash=unsafe_hash, frozen=frozen,
|
||||
match_args=match_args, kw_only=kw_only, slots=slots,
|
||||
weakref_slot=weakref_slot)
|
||||
|
|
|
@ -4317,6 +4317,23 @@ class TestMakeDataclass(unittest.TestCase):
|
|||
C = make_dataclass(classname, ['a', 'b'])
|
||||
self.assertEqual(C.__name__, classname)
|
||||
|
||||
def test_dataclass_decorator_default(self):
|
||||
C = make_dataclass('C', [('x', int)], decorator=dataclass)
|
||||
c = C(10)
|
||||
self.assertEqual(c.x, 10)
|
||||
|
||||
def test_dataclass_custom_decorator(self):
|
||||
def custom_dataclass(cls, *args, **kwargs):
|
||||
dc = dataclass(cls, *args, **kwargs)
|
||||
dc.__custom__ = True
|
||||
return dc
|
||||
|
||||
C = make_dataclass('C', [('x', int)], decorator=custom_dataclass)
|
||||
c = C(10)
|
||||
self.assertEqual(c.x, 10)
|
||||
self.assertEqual(c.__custom__, True)
|
||||
|
||||
|
||||
class TestReplace(unittest.TestCase):
|
||||
def test(self):
|
||||
@dataclass(frozen=True)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Add ``decorator`` parameter to :func:`dataclasses.make_dataclass`
|
||||
to customize the functional creation of dataclasses.
|
Loading…
Reference in New Issue