python / cpython

The Python programming language
https://www.python.org/
Other
60.91k stars 29.41k forks source link

Add `dataclass_factory` argument to `dataclasses.make_dataclass` for custom dataclass transformation support #118974

Open XuehaiPan opened 1 month ago

XuehaiPan commented 1 month ago

Feature or enhancement

Proposal:

typing.dataclass_transform (PEP 681 – Data Class Transforms) allows users define their own dataclass decorator that can be recognized by the type checker.

Here is a real-world example use case:

Also, dataclasses.asdict and dataclasses.astuple allow users pass an extra argument for the factory of the returned instance.

https://github.com/python/cpython/blob/0fb18b02c8ad56299d6a2910be0bab8ad601ef24/Lib/dataclasses.py#L1299-L1317

https://github.com/python/cpython/blob/0fb18b02c8ad56299d6a2910be0bab8ad601ef24/Lib/dataclasses.py#L1380-L1397

However, the make_dataclass function does not support third-party dataclass factory (e.g., flax.struct.dataclass):

https://github.com/python/cpython/blob/0fb18b02c8ad56299d6a2910be0bab8ad601ef24/Lib/dataclasses.py#L1441-L1528

It can only apply dataclasses.dataclass (see the return statement above).

This feature request issue will discuss the possibility of adding a new dataclass_factory argument to the dataclasses.make_dataclass to support third-party dataclasss transformation, similar to dict_factory for dataclasses.asdict.

# dataclasses.py

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,
                   dataclass_factory=dataclass):
    ...

    # Apply the normal decorator.
    return dataclass_factory(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)

Has this already been discussed elsewhere?

https://discuss.python.org/t/add-dataclass-factory-argument-to-dataclasses-make-dataclass-for-custom-dataclass-transformation-support/53188

Links to previous discussion of this feature:

No response

ericvsmith commented 1 month ago

That doesn't seem unreasonable to me. But as the issue template says, please discuss this on Discourse first: https://discuss.python.org/c/ideas/6

XuehaiPan commented 1 month ago

Thanks for the hint. I opened a new thread and let's discuss this there first.