Dataclass Transform draft PEP
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
I've created a draft PEP for the "Dataclass Transforms" concept that Eric Traut presented at the December 1st Typing SIG meetup. Feedback is welcome! https://github.com/debonte/peps/blob/dataclass_transforms/pep-9999.rst Thanks, Erik
![](https://secure.gravatar.com/avatar/1df2cf3cbe352ba5020668a9d278df2f.jpg?s=120&d=mm&r=g)
I know this isn't a common use case but why does the transformer not work on regular classes? With the added support for __init_subclass__ and __set_name__ I see no reason why someone shouldn't be able to make a dataclass-like class without the need for a metaclass.
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Hi James, Thanks for your feedback and sorry for the delayed response. I wasn't familiar with __init_subclass__, but I experimented with it and you are correct that it can be used to create dataclass-like subclasses. Eric Traut pointed out to me that this introduces the possibility of a class being deriving from multiple dataclass_transform classes (or a class and a metaclass). We could disallow that. But given that we're not aware of any existing dataclass libraries that use __init_subclass__, it may not be worth the extra complexity. Does anyone have any opinions on whether this should be supported or not? -Erik -----Original Message----- From: James H-B <gobot1234yt@gmail.com> Sent: Monday, December 13, 2021 2:13 PM To: typing-sig@python.org Subject: [Typing-sig] Re: Dataclass Transform draft PEP [You don't often get email from gobot1234yt@gmail.com. Learn why this is important at http://aka.ms/LearnAboutSenderIdentification.] I know this isn't a common use case but why does the transformer not work on regular classes? With the added support for __init_subclass__ and __set_name__ I see no reason why someone shouldn't be able to make a dataclass-like class without the need for a metaclass. _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.pytho... Member address: erikd@microsoft.com
![](https://secure.gravatar.com/avatar/1df2cf3cbe352ba5020668a9d278df2f.jpg?s=120&d=mm&r=g)
Funnily enough this is something that's actually in the current spec: Example of using dataclass_transform to decorate a metaclass. ```py # Indicate that classes that use this metaclass default to synthesizing # comparison methods. @typing.dataclass_transform(eq_default=True, order_default=True) class ModelMeta(type): def __init_subclass__( cls, *, init: bool = True, frozen: bool = False, eq: bool = True, order: bool = True, ): ... class ModelBase(metaclass=ModelMeta): ... # Example of how this class would be used by code that imports # from this library: class CustomerModel(ModelBase, init=False, frozen=True, eq=False, order=False): id: int name: str ``` To make this actually work you'd need to do something like this (or define __new__ for the metaclass) ```py @typing.dataclass_transform(eq_default=True, order_default=True) class ModelBase(metaclass=ModelMeta): def __init_subclass__( cls, *, init: bool = True, frozen: bool = False, eq: bool = True, order: bool = True, ): ... class CustomerModel(ModelBase, init=False, frozen=True, eq=False, order=False): id: int name: str ```
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Oh, thanks for pointing out that issue. I've replaced __init_subclass__ on that example metaclass with __new__. -Erik -----Original Message----- From: James H-B <gobot1234yt@gmail.com> Sent: Wednesday, January 5, 2022 3:24 AM To: typing-sig@python.org Subject: [Typing-sig] Re: Dataclass Transform draft PEP Funnily enough this is something that's actually in the current spec: Example of using dataclass_transform to decorate a metaclass. ```py # Indicate that classes that use this metaclass default to synthesizing # comparison methods. @typing.dataclass_transform(eq_default=True, order_default=True) class ModelMeta(type): def __init_subclass__( cls, *, init: bool = True, frozen: bool = False, eq: bool = True, order: bool = True, ): ... class ModelBase(metaclass=ModelMeta): ... # Example of how this class would be used by code that imports # from this library: class CustomerModel(ModelBase, init=False, frozen=True, eq=False, order=False): id: int name: str ``` To make this actually work you'd need to do something like this (or define __new__ for the metaclass) ```py @typing.dataclass_transform(eq_default=True, order_default=True) class ModelBase(metaclass=ModelMeta): def __init_subclass__( cls, *, init: bool = True, frozen: bool = False, eq: bool = True, order: bool = True, ): ... class CustomerModel(ModelBase, init=False, frozen=True, eq=False, order=False): id: int name: str ``` _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.pytho... Member address: erik.debonte@microsoft.com
![](https://secure.gravatar.com/avatar/0f393da4b8265592816178e5ff6c1c62.jpg?s=120&d=mm&r=g)
I think James is right. This should work with ordinary classes and inheritance. Using a metaclass when one isn't needed is simply bad design. Metaclasses are hard to mix and should be avoided unless necessary. If you can get away with using __init_subclass__, you should. Here's an example of a dataclass maker that is an ordinary class: https://github.com/google/flax/blob/main/flax/struct.py#L184. And as you can see they are forced to create an unnecessary metaclass merely to please the type-checker. At least, they don't do it unless TYPE_CHECKING is on, but it would be better for them not to have to do it at all. Please don't force dataclass-makers to be metaclasses.
![](https://secure.gravatar.com/avatar/3247bfd67c8fa4c4a08b8d30e49eab39.jpg?s=120&d=mm&r=g)
Thanks for providing a link to that example. I hadn't seen this pattern previously. Based on this, I agree that `dataclass_transform` should also apply to ordinary classes as well as metaclasses. Erik, if you agree with that conclusion, please update the draft PEP. I'll then update the reference implementation in pyright.
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Ok. Thanks for the example Neil! The draft PEP has been updated. https://github.com/debonte/peps/blob/dataclass_transforms/pep-9999.rst -Erik -----Original Message----- From: Eric Traut <eric@traut.com> Sent: Friday, January 7, 2022 9:07 AM To: typing-sig@python.org Subject: [Typing-sig] Re: Dataclass Transform draft PEP [You don't often get email from eric@traut.com. Learn why this is important at http://aka.ms/LearnAboutSenderIdentification.] Thanks for providing a link to that example. I hadn't seen this pattern previously. Based on this, I agree that `dataclass_transform` should also apply to ordinary classes as well as metaclasses. Erik, if you agree with that conclusion, please update the draft PEP. I'll then update the reference implementation in pyright. _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.pytho... Member address: erik.debonte@microsoft.com
![](https://secure.gravatar.com/avatar/3247bfd67c8fa4c4a08b8d30e49eab39.jpg?s=120&d=mm&r=g)
The reference implementation in pyright has also been updated to support base classes as well as metaclasses. This support will be included in version 1.1.206 of pyright. -Eric
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Is anyone willing to sponsor this PEP? Thanks, Erik From: Erik De Bonte Sent: Monday, December 13, 2021 1:37 PM To: 'typing-sig@python.org' <typing-sig@python.org> Subject: Dataclass Transform draft PEP I've created a draft PEP for the "Dataclass Transforms" concept that Eric Traut presented at the December 1st Typing SIG meetup. Feedback is welcome! https://github.com/debonte/peps/blob/dataclass_transforms/pep-9999.rst Thanks, Erik
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
Thanks Erik! I have a few small pieces of feedback: - The runtime implementation is currently an identity function. I'd prefer if it sets some flag on the decorated object, similar to what I'm proposing in https://github.com/python/cpython/pull/30530 for @final. I'd suggest setting `cls.__dataclass_transform__ = {"eq_default": True, ...}` on the decorated object. - dataclasses now supports the KW_ONLY marker to make only some fields kw-only ( https://docs.python.org/3/library/dataclasses.html#dataclasses.KW_ONLY). Should this be added to the spec? El lun, 13 dic 2021 a las 13:38, Erik De Bonte via Typing-sig (< typing-sig@python.org>) escribió:
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Thanks Jelle. For the introspection issue, does this change properly describe what you suggested? Change runtime behavior to support introspection · debonte/peps@ccfa9c8 (github.com)<https://github.com/debonte/peps/commit/ccfa9c847675cd97268bc98e813f41e7c00f7...>. I'm not sure if my description of the attribute value ("a serialized dict...") is pythonic. Seems reasonable to call out the KW_ONLY sentinel value in the "Dataclass semantics" section, especially since it's newish. Is there a PEP or GitHub issue that defines its behavior? I wasn't able to find one. -Erik From: Jelle Zijlstra <jelle.zijlstra@gmail.com> Sent: Wednesday, January 12, 2022 10:52 AM To: Erik De Bonte <Erik.DeBonte@microsoft.com> Cc: typing-sig@python.org Subject: Re: [Typing-sig] Dataclass Transform draft PEP Thanks Erik! I have a few small pieces of feedback: - The runtime implementation is currently an identity function. I'd prefer if it sets some flag on the decorated object, similar to what I'm proposing in https://github.com/python/cpython/pull/30530<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fpython%2Fcpython%2Fpull%2F30530&data=04%7C01%7CErik.DeBonte%40microsoft.com%7Cb08d42dc30444ec5e25f08d9d5fc9d0a%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776104727887761%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=oku1vXFDjZr%2FyPDEEGdjAF1D1%2BEEA0Y5mhh5i39lSXo%3D&reserved=0> for @final. I'd suggest setting `cls.__dataclass_transform__ = {"eq_default": True, ...}` on the decorated object. - dataclasses now supports the KW_ONLY marker to make only some fields kw-only (https://docs.python.org/3/library/dataclasses.html#dataclasses.KW_ONLY<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Fdataclasses.html%23dataclasses.KW_ONLY&data=04%7C01%7CErik.DeBonte%40microsoft.com%7Cb08d42dc30444ec5e25f08d9d5fc9d0a%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776104727937756%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=7r%2B7SFFshM0oqZE6cmJaRZlfCEJwLdW%2BcI%2BJpMTDdnI%3D&reserved=0>). Should this be added to the spec? El lun, 13 dic 2021 a las 13:38, Erik De Bonte via Typing-sig (<typing-sig@python.org<mailto:typing-sig@python.org>>) escribió: I've created a draft PEP for the "Dataclass Transforms" concept that Eric Traut presented at the December 1st Typing SIG meetup. Feedback is welcome! https://github.com/debonte/peps/blob/dataclass_transforms/pep-9999.rst<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdebonte%2Fpeps%2Fblob%2Fdataclass_transforms%2Fpep-9999.rst&data=04%7C01%7CErik.DeBonte%40microsoft.com%7Cb08d42dc30444ec5e25f08d9d5fc9d0a%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776104727937756%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=pVPLGMtrbgw8v0ZYfnxituMRvvu00%2FtMgHIi%2BWZvLOo%3D&reserved=0> Thanks, Erik _______________________________________________ Typing-sig mailing list -- typing-sig@python.org<mailto:typing-sig@python.org> To unsubscribe send an email to typing-sig-leave@python.org<mailto:typing-sig-leave@python.org> https://mail.python.org/mailman3/lists/typing-sig.python.org/<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.python.org%2Fmailman3%2Flists%2Ftyping-sig.python.org%2F&data=04%7C01%7CErik.DeBonte%40microsoft.com%7Cb08d42dc30444ec5e25f08d9d5fc9d0a%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776104727937756%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=Ez3960Gl3AShBSS%2B1X6RkhmpawzT2PZt5hxK4JnxI2w%3D&reserved=0> Member address: jelle.zijlstra@gmail.com<mailto:jelle.zijlstra@gmail.com>
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
Thanks! El jue, 13 ene 2022 a las 10:22, Erik De Bonte (<Erik.DeBonte@microsoft.com>) escribió:
I'm not sure why it needs to be a serialized dict; it can just be a dict.
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
* it can just be a dict Oh thanks, I just misunderstood what you originally requested. Both of your suggestions are addressed in the latest version. -Erik From: Jelle Zijlstra <jelle.zijlstra@gmail.com> Sent: Thursday, January 13, 2022 10:25 AM To: Erik De Bonte <Erik.DeBonte@microsoft.com> Cc: typing-sig@python.org Subject: Re: [Typing-sig] Dataclass Transform draft PEP Thanks! El jue, 13 ene 2022 a las 10:22, Erik De Bonte (<Erik.DeBonte@microsoft.com<mailto:Erik.DeBonte@microsoft.com>>) escribió: Thanks Jelle. For the introspection issue, does this change properly describe what you suggested? Change runtime behavior to support introspection · debonte/peps@ccfa9c8 (github.com)<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdebonte%2Fpeps%2Fcommit%2Fccfa9c847675cd97268bc98e813f41e7c00f781a&data=04%7C01%7CErik.DeBonte%40microsoft.com%7C97c66242ac2f4c46b05808d9d6c215eb%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776951662412658%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=CxZBM0SInwqWZAw1alug2k8HaVXEnb5F5vk21sFa%2Fzw%3D&reserved=0>. I'm not sure if my description of the attribute value ("a serialized dict...") is pythonic. I'm not sure why it needs to be a serialized dict; it can just be a dict. Seems reasonable to call out the KW_ONLY sentinel value in the "Dataclass semantics" section, especially since it's newish. Is there a PEP or GitHub issue that defines its behavior? I wasn't able to find one. https://bugs.python.org/issue43532<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugs.python.org%2Fissue43532&data=04%7C01%7CErik.DeBonte%40microsoft.com%7C97c66242ac2f4c46b05808d9d6c215eb%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776951662412658%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=myuD9jeNUS2MWJoij76TXVCvioSL8USIqfbVI2Krt00%3D&reserved=0> -Erik From: Jelle Zijlstra <jelle.zijlstra@gmail.com<mailto:jelle.zijlstra@gmail.com>> Sent: Wednesday, January 12, 2022 10:52 AM To: Erik De Bonte <Erik.DeBonte@microsoft.com<mailto:Erik.DeBonte@microsoft.com>> Cc: typing-sig@python.org<mailto:typing-sig@python.org> Subject: Re: [Typing-sig] Dataclass Transform draft PEP Thanks Erik! I have a few small pieces of feedback: - The runtime implementation is currently an identity function. I'd prefer if it sets some flag on the decorated object, similar to what I'm proposing in https://github.com/python/cpython/pull/30530<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fpython%2Fcpython%2Fpull%2F30530&data=04%7C01%7CErik.DeBonte%40microsoft.com%7C97c66242ac2f4c46b05808d9d6c215eb%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776951662412658%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=YPTcMwJwfyC4Bn4zclQkjR0ul6P%2FSKM2ucZAp4D7CM4%3D&reserved=0> for @final. I'd suggest setting `cls.__dataclass_transform__ = {"eq_default": True, ...}` on the decorated object. - dataclasses now supports the KW_ONLY marker to make only some fields kw-only (https://docs.python.org/3/library/dataclasses.html#dataclasses.KW_ONLY<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Fdataclasses.html%23dataclasses.KW_ONLY&data=04%7C01%7CErik.DeBonte%40microsoft.com%7C97c66242ac2f4c46b05808d9d6c215eb%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776951662412658%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=KtnxQoyRcQI8yrPEAQfjLC6rO9%2FMi1MNwnSewfi46co%3D&reserved=0>). Should this be added to the spec? El lun, 13 dic 2021 a las 13:38, Erik De Bonte via Typing-sig (<typing-sig@python.org<mailto:typing-sig@python.org>>) escribió: I've created a draft PEP for the "Dataclass Transforms" concept that Eric Traut presented at the December 1st Typing SIG meetup. Feedback is welcome! https://github.com/debonte/peps/blob/dataclass_transforms/pep-9999.rst<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdebonte%2Fpeps%2Fblob%2Fdataclass_transforms%2Fpep-9999.rst&data=04%7C01%7CErik.DeBonte%40microsoft.com%7C97c66242ac2f4c46b05808d9d6c215eb%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776951662412658%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=T46WppIdEnbEd0y1%2FDGS%2FiA2s2rQy7b31hMYet2RxiI%3D&reserved=0> Thanks, Erik _______________________________________________ Typing-sig mailing list -- typing-sig@python.org<mailto:typing-sig@python.org> To unsubscribe send an email to typing-sig-leave@python.org<mailto:typing-sig-leave@python.org> https://mail.python.org/mailman3/lists/typing-sig.python.org/<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.python.org%2Fmailman3%2Flists%2Ftyping-sig.python.org%2F&data=04%7C01%7CErik.DeBonte%40microsoft.com%7C97c66242ac2f4c46b05808d9d6c215eb%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776951662412658%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=sw55JbZl624E%2FFFeV2h%2B07wZkrPrVoH1NeqfQoz4uck%3D&reserved=0> Member address: jelle.zijlstra@gmail.com<mailto:jelle.zijlstra@gmail.com>
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Reminder to provide feedback on the dataclass_transform PEP [1] if you have any. In particular, if you maintain a type checker and have any concerns, please let me know. Thanks, Erik [1] https://www.python.org/dev/peps/pep-0681/ From: Erik De Bonte Sent: Monday, December 13, 2021 1:37 PM To: 'typing-sig@python.org' <typing-sig@python.org> Subject: Dataclass Transform draft PEP I've created a draft PEP for the "Dataclass Transforms" concept that Eric Traut presented at the December 1st Typing SIG meetup. Feedback is welcome! https://github.com/debonte/peps/blob/dataclass_transforms/pep-9999.rst Thanks, Erik
![](https://secure.gravatar.com/avatar/c278b7144feb496c731ee0514355548c.jpg?s=120&d=mm&r=g)
Hi Erik, the dataclass_transform PEP looks great! I left some (mostly-stylistic) feedback in: https://github.com/python/peps/pull/2382 And here's additional feedback...
* ``hash`` is an alias for the ``unsafe_hash`` parameter.
Reasoning for providing this alias? Seems inconsistent. And perhaps unsafe to do if potentially disguising an unsafe feature as (by-default) safe.
(1) Could you provide an example of how this alternate form is actually used to mark a function, class, or metaclass? Perhaps the example could be extended with something like: ``` @__dataclass_transform__(kw_only_default=True, order_default=True) def create_model( *, frozen: bool = False, kw_only: bool = True, ) -> Callable[[Type[_T]], Type[_T]]: ... ``` (2) Is the above syntax accepted in a .pyi stub file by popular typecheckers that already exist? If I was a typechecker I *might* find it sketchy to see use of a stub decorator declared in the same file.
Rejected Ideas ==============
Django primary and foreign keys -------------------------------
users of Django would need to explicitly declare the ``id`` field.
As a Django user this is a bit inconvenient, but seems fine. (No changes suggested.)
This limitation may make it impractical to use the ``dataclass_transform`` mechanism with Django.
I wonder if this is too strong a statement... Everything I've read so far, minus the inconvenience of not autogenerating an "id" field, suggests that @dataclass_tranform *could* be used on Django's models.Model base class. Is there potential openness to adding support for declaring that a particular dataclass_transform does autogenerate certain "extra fields" with known names and types (like "id: int")? Either in this PEP or in a future PEP? Cheers, -- David Foster | Seattle, WA, USA Contributor to TypedDict, mypy, and Python's typing system On 3/4/22 3:42 PM, Erik De Bonte via Typing-sig wrote:
![](https://secure.gravatar.com/avatar/489cdabedd1112f98474038939668778.jpg?s=120&d=mm&r=g)
Does the PEP/implementation take into account the return type specified in the functions signature? For example, assuming we had Intersection as a type, would this work? class HasSomeAttr(typing.Protocol): attr: str @typing.dataclass_transform( kw_only_default=True, field_descriptors=(model_field, )) def create_model( *, init: bool = True, ) -> Callable[[Type[_T]], typing.Intersection[Type[_T], HasSomeAttr]]: ... On Sat, 5 Mar 2022 at 09:10, David Foster <davidfstr@gmail.com> wrote:
-- Patrick Arminio
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
That's an interesting idea, but no we do not consider the return type of decorators when looking for fields. -Erik From: Patrick Arminio <patrick.arminio@gmail.com> Sent: Sunday, March 6, 2022 5:23 PM To: David Foster <davidfstr@gmail.com> Cc: Erik De Bonte <Erik.DeBonte@microsoft.com>; typing-sig@python.org Subject: Re: [Typing-sig] Re: Dataclass Transform draft PEP Does the PEP/implementation take into account the return type specified in the functions signature? For example, assuming we had Intersection as a type, would this work? class HasSomeAttr(typing.Protocol): attr: str @typing.dataclass_transform( kw_only_default=True, field_descriptors=(model_field, )) def create_model( *, init: bool = True, ) -> Callable[[Type[_T]], typing.Intersection[Type[_T], HasSomeAttr]]: ... -- Patrick Arminio
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
* ``hash`` is an alias for the ``unsafe_hash`` parameter.
Reasoning for providing this alias? Seems inconsistent.
@Eric Traut<mailto:erictr@microsoft.com>, I assume this was added because attrs uses "hash" instead of "unsafe_hash". However, the attrs hashing documentation [1] strongly discourages users from setting hash to True. I assume that means that it is infrequently used. Perhaps we should remove this alias and if attrs feels that this is important they should add an unsafe_hash alias on their side?
Alternate form
Thanks for pointing this out. I just removed this section from the PEP. [2] Pyright's support of the alternate form was added so libraries could experiment with dataclass_transform before the official decorator was available, even before the PEP was written. Now that the decorator is in typing_extensions the alternate form should not be mentioned in the PEP.
@dataclass_tranform *could* be used on Django's models.Model base class.
This is great news! I've been trying to find a Django contributor who might be interested in experimenting with dataclass_transform and providing feedback. If you know a good contact, please let me know.
Is there potential openness to adding support for declaring that a particular dataclass_transform does autogenerate
certain "extra fields" with known names and types (like "id: int")? Either in this PEP or in a future PEP?
In future PEPs, yes. Pradeep suggested an add_attributes decorator during a discussion back in November [3]. Since this would be useful outside of dataclasses, I think it would be better to spec it separately from dataclass_transform. Thanks for your feedback David! -Erik [1] https://www.attrs.org/en/stable/hashing.html [2] https://github.com/python/peps/pull/2386 [3] https://mail.python.org/archives/list/typing-sig@python.org/message/I2XJ6TTZ... -----Original Message----- From: David Foster <davidfstr@gmail.com> Sent: Saturday, March 5, 2022 7:09 AM To: Erik De Bonte <Erik.DeBonte@microsoft.com>; typing-sig@python.org Subject: Re: [Typing-sig] Re: Dataclass Transform draft PEP [You don't often get email from davidfstr@gmail.com<mailto:davidfstr@gmail.com>. Learn why this is important at http://aka.ms/LearnAboutSenderIdentification.] Hi Erik, the dataclass_transform PEP looks great! I left some (mostly-stylistic) feedback in: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com... And here's additional feedback...
* ``hash`` is an alias for the ``unsafe_hash`` parameter.
Reasoning for providing this alias? Seems inconsistent. And perhaps unsafe to do if potentially disguising an unsafe feature as (by-default) safe.
Alternate form
--------------
To avoid delaying adoption of this proposal until after > ``dataclass_transform`` has been added to the ``typing`` module, type > checkers may support the alternative form ``__dataclass_transform__``.
(1) Could you provide an example of how this alternate form is actually used to mark a function, class, or metaclass? Perhaps the example could be extended with something like: ``` @__dataclass_transform__(kw_only_default=True, order_default=True) def create_model( *, frozen: bool = False, kw_only: bool = True, ) -> Callable[[Type[_T]], Type[_T]]: ... ``` (2) Is the above syntax accepted in a .pyi stub file by popular typecheckers that already exist? If I was a typechecker I *might* find it sketchy to see use of a stub decorator declared in the same file.
Rejected Ideas
==============
Django primary and foreign keys
-------------------------------
users of Django would need to explicitly declare the ``id`` field.
As a Django user this is a bit inconvenient, but seems fine. (No changes suggested.)
This limitation may make it impractical to use the > ``dataclass_transform`` mechanism with Django.
I wonder if this is too strong a statement... Everything I've read so far, minus the inconvenience of not autogenerating an "id" field, suggests that @dataclass_tranform *could* be used on Django's models.Model base class. Is there potential openness to adding support for declaring that a particular dataclass_transform does autogenerate certain "extra fields" with known names and types (like "id: int")? Either in this PEP or in a future PEP? Cheers, -- David Foster | Seattle, WA, USA Contributor to TypedDict, mypy, and Python's typing system On 3/4/22 3:42 PM, Erik De Bonte via Typing-sig wrote:
Reminder to provide feedback on the dataclass_transform PEP [1] if you
have any.
In particular, if you maintain a type checker and have any concerns,
please let me know.
Thanks,
Erik
[1]
https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.
python.org%2Fdev%2Fpeps%2Fpep-0681%2F&data=04%7C01%7CErik.DeBonte%
40microsoft.com%7C018f5884d1fd42b8cc3608d9feba2553%7C72f988bf86f141af9
1ab2d7cd011db47%7C1%7C0%7C637820897718143705%7CUnknown%7CTWFpbGZsb3d8e
yJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C30
00&sdata=y8o1w62SOJcUp%2Bs7DGquJFxeD2jFes%2BMadgVUdU1BK0%3D&re
served=0
<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww
.python.org%2Fdev%2Fpeps%2Fpep-0681%2F&data=04%7C01%7CErik.DeBonte
%40microsoft.com%7C018f5884d1fd42b8cc3608d9feba2553%7C72f988bf86f141af
91ab2d7cd011db47%7C1%7C0%7C637820897718143705%7CUnknown%7CTWFpbGZsb3d8
eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3
000&sdata=y8o1w62SOJcUp%2Bs7DGquJFxeD2jFes%2BMadgVUdU1BK0%3D&r
eserved=0>
*From:* Erik De Bonte
*Sent:* Monday, December 13, 2021 1:37 PM
*To:* 'typing-sig@python.org' <typing-sig@python.org<mailto:typing-sig@python.org>>
*Subject:* Dataclass Transform draft PEP
I've created a draft PEP for the "Dataclass Transforms" concept that
Eric Traut presented at the December 1^st Typing SIG meetup. Feedback
is welcome!
https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
ub.com%2Fdebonte%2Fpeps%2Fblob%2Fdataclass_transforms%2Fpep-9999.rst&a
mp;data=04%7C01%7CErik.DeBonte%40microsoft.com%7C018f5884d1fd42b8cc360
8d9feba2553%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C6378208977181
43705%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJB
TiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=B4rYfZbwlEhXWkhCjXKfoEzf98
5cwSg1Sz%2Bp%2BRddNZA%3D&reserved=0
<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
hub.com%2Fdebonte%2Fpeps%2Fblob%2Fdataclass_transforms%2Fpep-9999.rst&
amp;data=04%7C01%7CErik.DeBonte%40microsoft.com%7C018f5884d1fd42b8cc36
08d9feba2553%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637820897718
143705%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJ
BTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=B4rYfZbwlEhXWkhCjXKfoEzf9
85cwSg1Sz%2Bp%2BRddNZA%3D&reserved=0>
Thanks,
Erik
_______________________________________________
Typing-sig mailing list -- typing-sig@python.org<mailto:typing-sig@python.org> To unsubscribe send
an email to typing-sig-leave@python.org<mailto:typing-sig-leave@python.org>
https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail
.python.org%2Fmailman3%2Flists%2Ftyping-sig.python.org%2F&data=04%
7C01%7CErik.DeBonte%40microsoft.com%7C018f5884d1fd42b8cc3608d9feba2553
%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637820897718143705%7CUnk
nown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWw
iLCJXVCI6Mn0%3D%7C3000&sdata=oWXw220vLouj6mqsEU8ty%2F5LpXXd8HtxlSE
qGT7pJ%2FI%3D&reserved=0
Member address: davidfstr@gmail.com<mailto:davidfstr@gmail.com>
![](https://secure.gravatar.com/avatar/c278b7144feb496c731ee0514355548c.jpg?s=120&d=mm&r=g)
On 3/7/22 3:34 PM, Erik De Bonte wrote:
I would be in favor of removing the "hash" alias to "unsafe_hash" in @dataclass_transform, in favor of the attrs project instead adding a new "unsafe_hash" alias (to the now-attrs-specific "hash"). But to do that we would need buy-in from a maintainer of attrs. Know anyone we could ask?
I'm a Django contributor myself. However my bandwidth is limited while I'm shepherding my own PEP (655) in before the Python 3.11 alphas close, so I might not have enough time myself. What kinds of feedback are you looking for? I have a medium-sized Django-based project (~200,000 lines of Python code) at my disposal.
The @add_attributes decorator idea is quite interesting. Definitely worth revisiting later. Cheers, -- David Foster | Seattle, WA, USA Contributor to TypedDict, mypy, and Python's typing system
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Thanks David.
we would need buy-in from a maintainer of attrs. Know anyone we could ask?
Yes, I emailed Hynek Schlawack about this yesterday.
I'm a Django contributor myself...What kinds of feedback are you looking for?
I was hoping someone could try decorating the relevant functions/classes in Django with dataclass_transform and determine if the resulting user experience is acceptable. Btw, Carlton Gibson told me that Django's Field.default can be either a value or a callable, whereas the PEP expects it to be a value. Factory callables need to be provided via the default_factory parameter instead. So that's one issue, but I think as with the attrs hash/unsafe_hash issue, this would be best fixed by Django adding a default_factory (or factory) property. -Erik
![](https://secure.gravatar.com/avatar/c278b7144feb496c731ee0514355548c.jpg?s=120&d=mm&r=g)
I got a chance to play with @dataclass_transform and Django Models. Looks promising. Please see the following file - containing a lightweight reimplementation of Django's Model and Field classes - and its inline comments: # experiment.py import typing import typing_extensions class Field: # django.db.models.fields def __init__(self, *args, **kwargs): pass # NOTE: The following syntax is just a proposal. #@typing_extensions.dataclass_field_descriptor(value_type=str) class CharField(Field): # django.db.models.fields pass # NOTE: The following syntax is just a proposal. #@typing_extensions.dataclass_field_descriptor(value_type=int) class AutoField(Field): # django.db.models.fields pass @typing_extensions.dataclass_transform( # ⚠️ Forward-reference like 'Field' is NOT supported here, # but appears to be necessary in real Django field_descriptors=(Field,) ) class ModelBase(type): # django.db.models.base pass class Model(metaclass=ModelBase): # django.db.models.base # NOTE: Must explicitly define that an "id" AutoField exists by default. # # However sometimes it is actually a BigAutoField, depending on # the configuration of the Django app package that defines the # Model subclass. (However even if it IS a BigAutoField, it's # still of int type, which is convenient.) id: int = typing.cast(int, AutoField()) def __init__(self, *args, **kwargs): pass class Question(Model): # 😬 Must use cast() because otherwise pyright complains that # a CharField is not a str. # # 🌸 It would be nice if there was a way to derive that # a CharField(...) should result in a str, so you could just write: # question_text = CharField(max_length=200) # # Similarly a CharField(required=False, ...) should result # in an Optional[str]. question_text: str = typing.cast(str, CharField(max_length=200)) q = Question( id=1, # ✅ works, with "id" field defined on Model base class question_text=1, # ✅ error: "Literal[1]" cannot be assigned to "str" boom=2, # ✅ error: No parameter named "boom" ) Some patterns/comments: * dataclass_transform(field_descriptors=...) does not currently support string-based forward references to types, which it looks like Django will require. * It would be useful to have syntax to describe what the "value type" of a particular field descriptor is, so that I don't have to use cast()s everywhere. See the above proposed syntax: - @typing_extensions.dataclass_field_descriptor(value_type=...) * I managed to define an implicit "id" field by just putting it on Django's Model class directly. If this caused runtime problems I could additionally guard that field definition with an "if TYPE_CHECKING" block. I hope this experimental feedback is helpful! I'm very much looking forward to being able to use @dataclass_transform in real code. Best, --- David Foster | Seattle, WA, USA Contributor to TypedDict, mypy, and Python's typing system On 3/10/22 6:32 PM, Erik De Bonte wrote:
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Thanks for investigating this David!
dataclass_transform(field_descriptors=...) does not currently support string-based forward references to types, which it looks like Django will require.
What is it about Django's code that makes a forward reference required? Is there a circular reference?
It would be useful to have syntax to describe what the "value type" of a particular field descriptor is, so that I don't have to use cast()s everywhere. See the above proposed syntax:
Dataclass solves this by having a field() function that returns their Field objects rather than having consumers use the Field type directly. The field() function returns Any but has overloads to return a more specific type when default or default_factory are provided. Thanks, Erik
![](https://secure.gravatar.com/avatar/c278b7144feb496c731ee0514355548c.jpg?s=120&d=mm&r=g)
On 4/5/22 8:25 PM, Erik De Bonte wrote:
dataclass_transform(field_descriptors=...) does not currently support string-based forward references to types, which it looks like Django will require.
What is it about Django's code that makes a forward reference required? Is there a circular reference?
Looks like I was able to do a direct import of Field after all, rather than using a forward reference. 👌 I suppose my instincts were worried about introducing an import because I try very hard to not introduce imports from low-level "utility" modules (like django.db.models.base) to other modules that might be higher level (like django.db.models.fields). Such imports often create circular reference problems, although apparently not in this case.
It would be useful to have syntax to describe what the "value type" of a particular field descriptor is, so that I don't have to use cast()s everywhere. See the above proposed syntax:
Dataclass solves this by having a field() function that returns their Field objects rather than having consumers use the Field type directly. The field() function returns Any but has overloads to return a more specific type when default or default_factory are provided.
Oof. I expect it would be a bigger ask to introduce a similar field() function in Django. Django users have been accustomed to directly assigning Field instances to attributes, being able to write: class Question(Model): question_text = CharField(max_length=200) It sounds like introducing that kind of field() function would require users to write instead: class Question(Model): question_text = field(CharField(max_length=200)) That could be a larger ask. Granted it would only apply to users of Django who opt-in to using a type checker. For my own reference, I expect a field() method would be implemented as something like: V = TypeVar("V") class Field(Generic[V]): ... # django.db.models.fields class CharField(Field[str]): ... # django.db.models.fields def field(field: Field[T]) -> T: return typing.cast(T, field) -- David Foster | Seattle, WA, USA Contributor to TypedDict, mypy, and Python's typing system
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Hi David,
I was envisioning this instead: ```python class Question(Model): question_text = char_field(max_length=200) ```
`dataclasses.field()` looks like this: ```python def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True, hash=None, compare=True, metadata=None, kw_only=MISSING): return Field(default, default_factory, init, repr, hash, compare, metadata, kw_only) ``` It's just a wrapper for constructing a `Field` object, but it returns `Any` instead of `Field`, and has overloads to return a more specific type when `default` or `default_factory` are provided. See the stubs at https://github.com/python/typeshed/blob/master/stdlib/dataclasses.pyi#L148. -Erik
![](https://secure.gravatar.com/avatar/c278b7144feb496c731ee0514355548c.jpg?s=120&d=mm&r=g)
Hmm. That pattern would imply a set of parallel *_field() functions for all of Django's (current and future, 1st party and 3rd party) *Field classes. I think I like my proposal generic field() function better, even if it differs significantly in implementation from the similarly-named dataclasses.field(), because it only necessitates defining a *single* new generic function and a *single* new pattern that will work everywhere for all *Field() classes (which I don't expect to go away).
Cheers, David
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
* ``hash`` is an alias for the ``unsafe_hash`` parameter.
Reasoning for providing this alias? Seems inconsistent.
Thanks for asking about this David. I talked with Hynek (attrs) and he was ok with removing the hash alias. PR is here -- https://github.com/python/peps/pull/2454
![](https://secure.gravatar.com/avatar/aefb9d56c3e2dde2d269a6883004bb35.jpg?s=120&d=mm&r=g)
Hi Erik, I am implementing it in Pyre, and so far have not find any blockers -- so a +1 from that perspective. Thanks for the PEP (including proposed transform_descriptor_types[1]), it will be a great addition! Best regards, Kshitij [1] https://github.com/python/peps/pull/2369
![](https://secure.gravatar.com/avatar/870d613430249e453343efc9667ef636.jpg?s=120&d=mm&r=g)
I'll leave typing details to typing-sig regulars, but I have a few comments “from outside”: Replying to the Discourse post (https://discuss.python.org/t/rfc-on-pep-681-data-class-transforms/14116):
The PEP will not affect CPython directly except for the addition of the dataclass_transform decorator in typing.py. The decorator is currently in typing_extensions.
Could this be also said in the PEP itself? It would be nice if e.g. a maintainer of Python's parser could read the introduction and decide to skip the rest & leave it to typing-sig. Including this note would also serve to better qualify phrases like "cannot", "error", "resulting behavior" throughout the PEP. I assume they specify expected behavior of type checkers, and don't apply at runtime. Is that right? And regarding that statement: Do you not plan to apply the decorator to dataclass itself? Will dataclasses.dataclass not get a __dataclass_transform__ attribute at runtime? Abstract:
PEP 557 introduced the dataclass to the Python stdlib.
IMO it would be better to link to the current documentation (https://docs.python.org/3.11/library/dataclasses.html) than to the 4-year-old document that first proposed adding dataclasses? The rationale and discussion around the proposal don't seem relevant, and the specification may be out of date. Same for later references to that PEP. And in general: Are the semantics expected to evolve if new features are added to dataclasses? Or to other popular libraries that work like dataclasses?
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Thanks for your feedback Petr!
The PEP will not affect CPython directly except for the addition of the dataclass_transform decorator in typing.py.
Could this be also said in the PEP itself?
Yes, good point.
Do you not plan to apply the decorator to dataclass itself? Will dataclasses.dataclass not get a __dataclass_transform__ attribute at runtime?
No, we were not planning to decorate dataclass with dataclass_transform.
it would be better to link to the current documentation than to the 4-year-old document that first proposed adding dataclasses... Same for later references to that PEP.
That's fair, although I think the existing references to PEP 557 are ok because we're linking to specific, relevant parts of that document. Would adding a link to the docs in the abstract be satisfactory? I just created a PR for this and your first point above. [1]
Are the semantics expected to evolve if new features are added to dataclasses? Or to other popular libraries that work like dataclasses?
dataclass_transform is expected to evolve with dataclass. I recently added a paragraph to Rationale that explains this. We would consider evolving dataclass_transform based on new features in other dataclass-like libraries. But we would prefer that these libraries become more similar to stdlib dataclass either by changing their APIs or proposing new dataclass features. Thanks, Erik [1]: https://github.com/python/peps/pull/2390
![](https://secure.gravatar.com/avatar/a2bfd7c4e403ac42737c2dd285d63a21.jpg?s=120&d=mm&r=g)
I'm quite excited by this PEP, but I have one question: How to annotate decorators which can be applied both with options or not ? For example: ```python @my_dataclass # << Notice there is NO function call here class A: x: int @my_dataclass(frozen=True) class A: x: int ``` How should `my_dataclass` be annotated ? It's unclear to me. With the `Intersection` syntax, it would be some: ```python @typing.overload def my_dataclass( cls: None = ..., **options: Any, ) -> Callable[[_ClsT], _ClsT & Dataclass] ... @typing.overload def my_dataclass( cls: _ClsT, **options: Any, ) -> type[_ClsT & Dataclass] ... ``` This is how `dataclasses.dataclass`, `chex.dataclass`,... behave (can be applied as `@dataclass` or `@dataclass()`) I feel it would be nice to add an example in the PEP.
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Hi Étienne, Thanks for your feedback! The code below worked for me. Is this what you were aiming for? Was the use of Intersection important to your question? If so, was the Dataclass type supposed to represent the dataclass-like changes made by the my_dataclass decorator? That seems unnecessary to me, since dataclass_transform is already trying to describe those changes. If I'm missing your point, can you provide a more complete example? -Erik ```python from typing import Callable, Any, TypeVar, overload _ClsT = TypeVar("_ClsT") @overload def my_dataclass(cls: None = ..., **options: Any,) -> Callable[[_ClsT], _ClsT]: ... @overload def my_dataclass(cls: Callable[..., _ClsT], **options: Any,) -> type[_ClsT]: ... def my_dataclass(cls: Callable[..., _ClsT] | None = None, **options: Any) -> Callable[..., _ClsT]: # The implementation of the decorator was borrowed from dataclass def wrap(cls): return _process_class(cls, **options) # See if we're being called as @dataclass or @dataclass(). if cls is None: # We're called with parens. return wrap # We're called as @dataclass without parens. return wrap(cls) def _process_class(cls, **options: Any): return cls @my_dataclass class A: x: int @my_dataclass() class B: x: int @my_dataclass(frozen=True) class C: x: int ```
![](https://secure.gravatar.com/avatar/a2bfd7c4e403ac42737c2dd285d63a21.jpg?s=120&d=mm&r=g)
Thank you for your answer and sorry for the confusion. I wasn't asking about the implementation, I was asking how you would annotate such use-case using @dataclass_transform ? I'm a little confused, as your answer does not use dataclass_transform at all, so type checker would not detect that A, B & C are dataclass-like. Should the code be annotated as ? : ``` @overload @dataclass_transform def my_dataclass(cls: None = ..., **options: Any,) -> Callable[[_ClsT], _ClsT]: ... @overload @dataclass_transform def my_dataclass(cls: Callable[..., _ClsT], **options: Any,) -> type[_ClsT]: ... def my_dataclass(cls = None, **options: Any): ``` Or: ``` @overload def my_dataclass(cls: None = ..., **options: Any,) -> Callable[[_ClsT], _ClsT]: ... @overload def my_dataclass(cls: Callable[..., _ClsT], **options: Any,) -> type[_ClsT]: ... @dataclass_transform def my_dataclass(cls = None, **options: Any): ``` In the current proposal, it's not obvious to me what is the answer. Or even if this is supported. This is why I suggested it would be nice to specify this in the PEP and give an example. (you can ignore the section on Intersection, I was just showing an alternative syntax to @dataclass_transform which would make such use-case more explicit, using notation described in https://github.com/python/typing/issues/213)
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Hi Étienne, Thanks for clarifying. I completely misunderstood your question. Thanks for your feedback! This is an important point. We should be clear about where dataclass_transform can be applied for overloaded functions. I just created a PR which adds the following language to the PEP. https://github.com/python/peps/pull/2498 If the function has overloads, the ``dataclass_transform`` decorator can be applied to the implementation of the function or any one, but not more than one, of the overloads. The behavior is undefined if dataclass_transform is found in more than one of these locations. Type checkers can choose to report an error, use the first dataclass_transform decorator they find, etc. Thanks, Erik
![](https://secure.gravatar.com/avatar/a2bfd7c4e403ac42737c2dd285d63a21.jpg?s=120&d=mm&r=g)
Thank you for the update. So if I understand, `dataclass_transform` support this use-case which would then be annotated as: ``` @overload def my_dataclass(cls: None = ..., **options: Any,) -> Callable[[_ClsT], _ClsT]: ... @overload def my_dataclass(cls: Callable[..., _ClsT], **options: Any,) -> type[_ClsT]: ... @dataclass_transform def my_dataclass(cls=None, **options): ``` And `my_dataclass` could then be applied both as: * A decorator: `my_dataclass(cls)` * A decorator factory: `my_dataclass(**options)(cls)`
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Yes, although to make Pyright happy I had to add a return type annotation on your implementation: def my_dataclass(cls=None, **options) -> Callable[[_ClsT], _ClsT]: ... Btw, you could also place the @dataclass_transform decorator on either overload. If you were exposing my_dataclass() in a .pyi, you would need to put dataclass_transform on an overload. -Erik
![](https://secure.gravatar.com/avatar/a2bfd7c4e403ac42737c2dd285d63a21.jpg?s=120&d=mm&r=g)
Yes, although to make Pyright happy I had to add a return type annotation on your implementation:
If I understand, this is a Pyright bug right ? As implementations should not have typing annotation I believe.
If you were exposing my_dataclass() in a .pyi, you would need to put dataclass_transform on an overload.
Is it not a confusing ? I would intuitively expect the that only the `@overload` on which `@dataclass_transform` is applied transform the class. ``` @overload def create_model(cls: A) -> A: @overload @dataclass_transform def create_model(cls: B) -> B: ``` So in this case, I would expect `create_model` to transform B to dataclass, but not A. (this is just a dummy unrealistic example just to show my point) Why not have the overload explicitly be applied on each overload ? I feel this would be least ambiguous case. ``` @overload @dataclass_transform def create_model(cls: A) -> A: @overload @dataclass_transform def create_model(cls: B) -> B: @overload def create_model(cls: C) -> C: ``` Here A and B are transformed to dataclasses, but not C. Would there be a drawback to explicitly marking each overload as @dataclass_transform ?
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
If I understand, this is a Pyright bug right ? As implementations should not have typing annotation I believe.
I just played with this again to refresh my memory. Looks like the issue was that the function's implementation was empty and therefore Pyright was warning me that the implementation's return type of `None` was incompatible with the overloads. Once I implemented the implementation the return type annotation was no longer required. So I think there's no issue here. I just didn't read the error closely enough.
Why not have the overload explicitly be applied on each overload ? I feel this would be least ambiguous case. Would there be a drawback to explicitly marking each overload as @dataclass_transform ?
We decided to require `dataclass_transform` to be in only one location because: 1. Allowing a function's overloads to have different transform behaviors (ex. different `dataclass_transform` parameters, or some overloads that transform and some that do not) is an unnecessary complexity. We don't want to require type checkers to support that. 2. It's a maintenance hassle to keep the parameters in sync if the decorator is required on all overloads. -Erik
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
El lun, 13 dic 2021 a las 13:38, Erik De Bonte via Typing-sig (< typing-sig@python.org>) escribió:
Hi Erik, I was discussing the PEP with Guido and we had some concerns around locking ourselves into an overly specific API. For example, type checkers may want to experiment with additional options to the dataclass_transform() decorator. If we decide to add more options in the future after the PEP is accepted, users would have to rely on updating typing-extensions quickly to use the new option. Our idea is to make `@dataclass_transform()` accept and ignore arbitrary **kwargs at runtime. Type checkers would still give errors if users pass unrecognized parameters, but would be free to support additional experimental parameters without having to wait for changes to the runtime.
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
* Our idea is to make `@dataclass_transform()` accept and ignore arbitrary **kwargs at runtime. Type checkers would still give errors if users pass unrecognized parameters, but would be free to support additional experimental parameters without having to wait for changes to the runtime. Thanks, great suggestion! I can submit a PR for this later tonight. Should I do that? It's not clear to me if changes are still allowed at this point. * ...ignore arbitrary **kwargs at runtime... The only thing it does at runtime is set the __dataclass_transform__ attribute, right? Are you saying that you wouldn't want to include the extra kwargs in that dict? -Erik
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Tue, Apr 5, 2022 at 6:16 PM Jelle Zijlstra <jelle.zijlstra@gmail.com> wrote:
Maybe I'm overlooking something, but why couldn't the runtime definition be as simple as this? def dataclass_transform(**kwds): def decorator(thing): thing .__dataclass_transform__ = kwds return thing return decorator -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Tue, Apr 5, 2022 at 9:51 PM Erik De Bonte <Erik.DeBonte@microsoft.com> wrote:
Agreed. So in the typeshed stubs this should have the full specification, and we should update this whenever we've agreed on a new keyword argument. But the runtime implementation (whether in stdlib (typing.py) or typing-extensions) doesn't need to do anything except setting the dunder attribute. By not making it check the arguments at runtime, users won't have to install a new version of typing-extensions, and there will (eventually) be less reason to import the typing-extensions version rather than the stdlib version. This is a general trend for runtime behavior of typing features -- we're removing runtime checks for things that type checkers already check, reducing the runtime cost and minimizing the need to update the runtime code. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
So in the typeshed stubs this should have the full specification, and we should update this whenever we've agreed on a new keyword argument.
That makes sense. I actually didn't realize that there was a stub file for typing.py. :) I also didn't realize that keyword args and kwargs could be passed in all mixed together. Thanks for explaining. -Erik
![](https://secure.gravatar.com/avatar/a8b577699ee8eedc869a735dd521c88e.jpg?s=120&d=mm&r=g)
(I emailed Eric about this directly, but I thought it might be worth adding my feedback here too, I know it might be too late to alter the PEP, but think could still be helpful to document this issue) Pydantic has supported the "Alternate Form <https://github.com/microsoft/pyright/blob/main/specs/dataclass_transforms.md...>" of dataclass transforms for a while which is supported by pyright. As well as helping lots of people (I assume - happy people don't create issues, and I don't use pyright/pylance/vscode), we have had some issues with the "feature", see here <https://github.com/samuelcolvin/pydantic/issues/3753>. In summary: pydantic has a BaseSettings type which users inherit from to manage settings, fields are defined on a class, then can be configured using environment variables and other external sources. Because of this you can legitimately use "settings = Settings()" even when your Settings class has required fields - because they're filled from env variables. The problem is that dataclass transforms apply to BaseSettings, and therefore Settings because BaseSettings inherits from BaseModel (which is marked with the decorator), so users get an error from pyright on "settings = Settings()" saying required fields are missing. It would be great if there was a way to switch off dataclass transforms on some subclasses. The easiest way for users would be another magic decorator which marked the class (and its subclasses) as "not dataclass-like", but I'd be happy with any way to achieve this, e.g. a kwarg to dataclass_transform. Samuel -- Samuel Colvin On Wed, 6 Apr 2022 at 07:39, Erik De Bonte via Typing-sig < typing-sig@python.org> wrote:
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Hi Samuel,
Because of this you can legitimately use "settings = Settings()" even when your Settings class has required fields - because they're filled from env variables.
Since the parameters don't need to be provided when creating a `Settings` object, aren't these fields *not* required? I saw a comment on the issue suggesting adding default values as a workaround. [1] Why doesn't that work? I didn't see any responses to that idea. Alternatively, could you refactor your class hierarchy and relocate the `dataclass_transform` decorator so `BaseSettings` and `BaseModel` still share code, but BaseSettings's branch of the hierarchy was not decorated with `dataclass_transform`? -Erik [1] https://github.com/samuelcolvin/pydantic/issues/3753#issuecomment-1060850457
![](https://secure.gravatar.com/avatar/a8b577699ee8eedc869a735dd521c88e.jpg?s=120&d=mm&r=g)
Hi Erik, sorry for the late reply, somehow the task of replying to your email drifted into the unsorted set of background tasks I need to do someday, and only bubbled to the top by chance.
Providing a default value wouldn't solve the problem - when creating the Settings class you want to enforce that the value IS required albeit via an environment variable or an argument when initialising the class .e.g. with a class ```python class Settings(BaseSettings): db_password: str ``` You could either create your settings instance via ```python settings = Settings(db_password='foobar') ``` or via, ```bash export DB_PASSWORD=foobar ``` ```python settings = Settings() ``` But either way, the point is that the field is "required", just that it's not necessarily required as an argument. I don't expect detaclass transforms to understand this, just to provide an escape hatch so I can stop using them when the behaviour is too complex/easotetic to remotely match dataclass behaviour. Alternatively, could you refactor your class hierarchy and relocate the
I think that's what we'll end up doing in a future major release. But it'll be ugly, and probably involve duplicated code. I still think there's a real need for a way to disable dataclass transforms on some subclasses, both in pydantic and many other usage scenarios. Thanks, Samuel -- Samuel Colvin On Wed, 6 Apr 2022 at 16:46, Erik De Bonte <Erik.DeBonte@microsoft.com> wrote:
![](https://secure.gravatar.com/avatar/a8b577699ee8eedc869a735dd521c88e.jpg?s=120&d=mm&r=g)
Hi Erik, yes exactly. But it could also change the semantics when a reader is reviewing the Settings class. Of course we could add a `RequiredAtRuntime` type to use as the default to work around this, but it could be very unclear to someone new to pydantic. Samuel On Fri, 15 Apr 2022, 18:04 Erik De Bonte, <Erik.DeBonte@microsoft.com> wrote:
![](https://secure.gravatar.com/avatar/3247bfd67c8fa4c4a08b8d30e49eab39.jpg?s=120&d=mm&r=g)
That's a prudent measure and a good addition to the PEP. Thanks for suggesting this. -Eric
![](https://secure.gravatar.com/avatar/c278b7144feb496c731ee0514355548c.jpg?s=120&d=mm&r=g)
Is it expected that @dataclass_transform (PEP 681) will be ready to submit to the Steering Council, and a response received from them, by the Python 3.11 feature cutoff (Friday, 2022-05-06†)? That is 2 weeks from today. Between now and then, the SC is expected to meet only twice (on Monday 4/25 and 5/2) based on their prior meeting pattern. Context: I'm in the process of finalizing information about the expected set of typing-related PEPs that will make it into Python 3.11. † https://peps.python.org/pep-0664/#schedule -- David Foster | Seattle, WA, USA Contributor to TypedDict, mypy, and Python's typing system
![](https://secure.gravatar.com/avatar/1df2cf3cbe352ba5020668a9d278df2f.jpg?s=120&d=mm&r=g)
I know this isn't a common use case but why does the transformer not work on regular classes? With the added support for __init_subclass__ and __set_name__ I see no reason why someone shouldn't be able to make a dataclass-like class without the need for a metaclass.
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Hi James, Thanks for your feedback and sorry for the delayed response. I wasn't familiar with __init_subclass__, but I experimented with it and you are correct that it can be used to create dataclass-like subclasses. Eric Traut pointed out to me that this introduces the possibility of a class being deriving from multiple dataclass_transform classes (or a class and a metaclass). We could disallow that. But given that we're not aware of any existing dataclass libraries that use __init_subclass__, it may not be worth the extra complexity. Does anyone have any opinions on whether this should be supported or not? -Erik -----Original Message----- From: James H-B <gobot1234yt@gmail.com> Sent: Monday, December 13, 2021 2:13 PM To: typing-sig@python.org Subject: [Typing-sig] Re: Dataclass Transform draft PEP [You don't often get email from gobot1234yt@gmail.com. Learn why this is important at http://aka.ms/LearnAboutSenderIdentification.] I know this isn't a common use case but why does the transformer not work on regular classes? With the added support for __init_subclass__ and __set_name__ I see no reason why someone shouldn't be able to make a dataclass-like class without the need for a metaclass. _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.pytho... Member address: erikd@microsoft.com
![](https://secure.gravatar.com/avatar/1df2cf3cbe352ba5020668a9d278df2f.jpg?s=120&d=mm&r=g)
Funnily enough this is something that's actually in the current spec: Example of using dataclass_transform to decorate a metaclass. ```py # Indicate that classes that use this metaclass default to synthesizing # comparison methods. @typing.dataclass_transform(eq_default=True, order_default=True) class ModelMeta(type): def __init_subclass__( cls, *, init: bool = True, frozen: bool = False, eq: bool = True, order: bool = True, ): ... class ModelBase(metaclass=ModelMeta): ... # Example of how this class would be used by code that imports # from this library: class CustomerModel(ModelBase, init=False, frozen=True, eq=False, order=False): id: int name: str ``` To make this actually work you'd need to do something like this (or define __new__ for the metaclass) ```py @typing.dataclass_transform(eq_default=True, order_default=True) class ModelBase(metaclass=ModelMeta): def __init_subclass__( cls, *, init: bool = True, frozen: bool = False, eq: bool = True, order: bool = True, ): ... class CustomerModel(ModelBase, init=False, frozen=True, eq=False, order=False): id: int name: str ```
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Oh, thanks for pointing out that issue. I've replaced __init_subclass__ on that example metaclass with __new__. -Erik -----Original Message----- From: James H-B <gobot1234yt@gmail.com> Sent: Wednesday, January 5, 2022 3:24 AM To: typing-sig@python.org Subject: [Typing-sig] Re: Dataclass Transform draft PEP Funnily enough this is something that's actually in the current spec: Example of using dataclass_transform to decorate a metaclass. ```py # Indicate that classes that use this metaclass default to synthesizing # comparison methods. @typing.dataclass_transform(eq_default=True, order_default=True) class ModelMeta(type): def __init_subclass__( cls, *, init: bool = True, frozen: bool = False, eq: bool = True, order: bool = True, ): ... class ModelBase(metaclass=ModelMeta): ... # Example of how this class would be used by code that imports # from this library: class CustomerModel(ModelBase, init=False, frozen=True, eq=False, order=False): id: int name: str ``` To make this actually work you'd need to do something like this (or define __new__ for the metaclass) ```py @typing.dataclass_transform(eq_default=True, order_default=True) class ModelBase(metaclass=ModelMeta): def __init_subclass__( cls, *, init: bool = True, frozen: bool = False, eq: bool = True, order: bool = True, ): ... class CustomerModel(ModelBase, init=False, frozen=True, eq=False, order=False): id: int name: str ``` _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.pytho... Member address: erik.debonte@microsoft.com
![](https://secure.gravatar.com/avatar/0f393da4b8265592816178e5ff6c1c62.jpg?s=120&d=mm&r=g)
I think James is right. This should work with ordinary classes and inheritance. Using a metaclass when one isn't needed is simply bad design. Metaclasses are hard to mix and should be avoided unless necessary. If you can get away with using __init_subclass__, you should. Here's an example of a dataclass maker that is an ordinary class: https://github.com/google/flax/blob/main/flax/struct.py#L184. And as you can see they are forced to create an unnecessary metaclass merely to please the type-checker. At least, they don't do it unless TYPE_CHECKING is on, but it would be better for them not to have to do it at all. Please don't force dataclass-makers to be metaclasses.
![](https://secure.gravatar.com/avatar/3247bfd67c8fa4c4a08b8d30e49eab39.jpg?s=120&d=mm&r=g)
Thanks for providing a link to that example. I hadn't seen this pattern previously. Based on this, I agree that `dataclass_transform` should also apply to ordinary classes as well as metaclasses. Erik, if you agree with that conclusion, please update the draft PEP. I'll then update the reference implementation in pyright.
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Ok. Thanks for the example Neil! The draft PEP has been updated. https://github.com/debonte/peps/blob/dataclass_transforms/pep-9999.rst -Erik -----Original Message----- From: Eric Traut <eric@traut.com> Sent: Friday, January 7, 2022 9:07 AM To: typing-sig@python.org Subject: [Typing-sig] Re: Dataclass Transform draft PEP [You don't often get email from eric@traut.com. Learn why this is important at http://aka.ms/LearnAboutSenderIdentification.] Thanks for providing a link to that example. I hadn't seen this pattern previously. Based on this, I agree that `dataclass_transform` should also apply to ordinary classes as well as metaclasses. Erik, if you agree with that conclusion, please update the draft PEP. I'll then update the reference implementation in pyright. _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.pytho... Member address: erik.debonte@microsoft.com
![](https://secure.gravatar.com/avatar/3247bfd67c8fa4c4a08b8d30e49eab39.jpg?s=120&d=mm&r=g)
The reference implementation in pyright has also been updated to support base classes as well as metaclasses. This support will be included in version 1.1.206 of pyright. -Eric
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Is anyone willing to sponsor this PEP? Thanks, Erik From: Erik De Bonte Sent: Monday, December 13, 2021 1:37 PM To: 'typing-sig@python.org' <typing-sig@python.org> Subject: Dataclass Transform draft PEP I've created a draft PEP for the "Dataclass Transforms" concept that Eric Traut presented at the December 1st Typing SIG meetup. Feedback is welcome! https://github.com/debonte/peps/blob/dataclass_transforms/pep-9999.rst Thanks, Erik
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
Thanks Erik! I have a few small pieces of feedback: - The runtime implementation is currently an identity function. I'd prefer if it sets some flag on the decorated object, similar to what I'm proposing in https://github.com/python/cpython/pull/30530 for @final. I'd suggest setting `cls.__dataclass_transform__ = {"eq_default": True, ...}` on the decorated object. - dataclasses now supports the KW_ONLY marker to make only some fields kw-only ( https://docs.python.org/3/library/dataclasses.html#dataclasses.KW_ONLY). Should this be added to the spec? El lun, 13 dic 2021 a las 13:38, Erik De Bonte via Typing-sig (< typing-sig@python.org>) escribió:
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Thanks Jelle. For the introspection issue, does this change properly describe what you suggested? Change runtime behavior to support introspection · debonte/peps@ccfa9c8 (github.com)<https://github.com/debonte/peps/commit/ccfa9c847675cd97268bc98e813f41e7c00f7...>. I'm not sure if my description of the attribute value ("a serialized dict...") is pythonic. Seems reasonable to call out the KW_ONLY sentinel value in the "Dataclass semantics" section, especially since it's newish. Is there a PEP or GitHub issue that defines its behavior? I wasn't able to find one. -Erik From: Jelle Zijlstra <jelle.zijlstra@gmail.com> Sent: Wednesday, January 12, 2022 10:52 AM To: Erik De Bonte <Erik.DeBonte@microsoft.com> Cc: typing-sig@python.org Subject: Re: [Typing-sig] Dataclass Transform draft PEP Thanks Erik! I have a few small pieces of feedback: - The runtime implementation is currently an identity function. I'd prefer if it sets some flag on the decorated object, similar to what I'm proposing in https://github.com/python/cpython/pull/30530<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fpython%2Fcpython%2Fpull%2F30530&data=04%7C01%7CErik.DeBonte%40microsoft.com%7Cb08d42dc30444ec5e25f08d9d5fc9d0a%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776104727887761%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=oku1vXFDjZr%2FyPDEEGdjAF1D1%2BEEA0Y5mhh5i39lSXo%3D&reserved=0> for @final. I'd suggest setting `cls.__dataclass_transform__ = {"eq_default": True, ...}` on the decorated object. - dataclasses now supports the KW_ONLY marker to make only some fields kw-only (https://docs.python.org/3/library/dataclasses.html#dataclasses.KW_ONLY<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Fdataclasses.html%23dataclasses.KW_ONLY&data=04%7C01%7CErik.DeBonte%40microsoft.com%7Cb08d42dc30444ec5e25f08d9d5fc9d0a%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776104727937756%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=7r%2B7SFFshM0oqZE6cmJaRZlfCEJwLdW%2BcI%2BJpMTDdnI%3D&reserved=0>). Should this be added to the spec? El lun, 13 dic 2021 a las 13:38, Erik De Bonte via Typing-sig (<typing-sig@python.org<mailto:typing-sig@python.org>>) escribió: I've created a draft PEP for the "Dataclass Transforms" concept that Eric Traut presented at the December 1st Typing SIG meetup. Feedback is welcome! https://github.com/debonte/peps/blob/dataclass_transforms/pep-9999.rst<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdebonte%2Fpeps%2Fblob%2Fdataclass_transforms%2Fpep-9999.rst&data=04%7C01%7CErik.DeBonte%40microsoft.com%7Cb08d42dc30444ec5e25f08d9d5fc9d0a%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776104727937756%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=pVPLGMtrbgw8v0ZYfnxituMRvvu00%2FtMgHIi%2BWZvLOo%3D&reserved=0> Thanks, Erik _______________________________________________ Typing-sig mailing list -- typing-sig@python.org<mailto:typing-sig@python.org> To unsubscribe send an email to typing-sig-leave@python.org<mailto:typing-sig-leave@python.org> https://mail.python.org/mailman3/lists/typing-sig.python.org/<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.python.org%2Fmailman3%2Flists%2Ftyping-sig.python.org%2F&data=04%7C01%7CErik.DeBonte%40microsoft.com%7Cb08d42dc30444ec5e25f08d9d5fc9d0a%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776104727937756%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=Ez3960Gl3AShBSS%2B1X6RkhmpawzT2PZt5hxK4JnxI2w%3D&reserved=0> Member address: jelle.zijlstra@gmail.com<mailto:jelle.zijlstra@gmail.com>
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
Thanks! El jue, 13 ene 2022 a las 10:22, Erik De Bonte (<Erik.DeBonte@microsoft.com>) escribió:
I'm not sure why it needs to be a serialized dict; it can just be a dict.
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
* it can just be a dict Oh thanks, I just misunderstood what you originally requested. Both of your suggestions are addressed in the latest version. -Erik From: Jelle Zijlstra <jelle.zijlstra@gmail.com> Sent: Thursday, January 13, 2022 10:25 AM To: Erik De Bonte <Erik.DeBonte@microsoft.com> Cc: typing-sig@python.org Subject: Re: [Typing-sig] Dataclass Transform draft PEP Thanks! El jue, 13 ene 2022 a las 10:22, Erik De Bonte (<Erik.DeBonte@microsoft.com<mailto:Erik.DeBonte@microsoft.com>>) escribió: Thanks Jelle. For the introspection issue, does this change properly describe what you suggested? Change runtime behavior to support introspection · debonte/peps@ccfa9c8 (github.com)<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdebonte%2Fpeps%2Fcommit%2Fccfa9c847675cd97268bc98e813f41e7c00f781a&data=04%7C01%7CErik.DeBonte%40microsoft.com%7C97c66242ac2f4c46b05808d9d6c215eb%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776951662412658%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=CxZBM0SInwqWZAw1alug2k8HaVXEnb5F5vk21sFa%2Fzw%3D&reserved=0>. I'm not sure if my description of the attribute value ("a serialized dict...") is pythonic. I'm not sure why it needs to be a serialized dict; it can just be a dict. Seems reasonable to call out the KW_ONLY sentinel value in the "Dataclass semantics" section, especially since it's newish. Is there a PEP or GitHub issue that defines its behavior? I wasn't able to find one. https://bugs.python.org/issue43532<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugs.python.org%2Fissue43532&data=04%7C01%7CErik.DeBonte%40microsoft.com%7C97c66242ac2f4c46b05808d9d6c215eb%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776951662412658%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=myuD9jeNUS2MWJoij76TXVCvioSL8USIqfbVI2Krt00%3D&reserved=0> -Erik From: Jelle Zijlstra <jelle.zijlstra@gmail.com<mailto:jelle.zijlstra@gmail.com>> Sent: Wednesday, January 12, 2022 10:52 AM To: Erik De Bonte <Erik.DeBonte@microsoft.com<mailto:Erik.DeBonte@microsoft.com>> Cc: typing-sig@python.org<mailto:typing-sig@python.org> Subject: Re: [Typing-sig] Dataclass Transform draft PEP Thanks Erik! I have a few small pieces of feedback: - The runtime implementation is currently an identity function. I'd prefer if it sets some flag on the decorated object, similar to what I'm proposing in https://github.com/python/cpython/pull/30530<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fpython%2Fcpython%2Fpull%2F30530&data=04%7C01%7CErik.DeBonte%40microsoft.com%7C97c66242ac2f4c46b05808d9d6c215eb%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776951662412658%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=YPTcMwJwfyC4Bn4zclQkjR0ul6P%2FSKM2ucZAp4D7CM4%3D&reserved=0> for @final. I'd suggest setting `cls.__dataclass_transform__ = {"eq_default": True, ...}` on the decorated object. - dataclasses now supports the KW_ONLY marker to make only some fields kw-only (https://docs.python.org/3/library/dataclasses.html#dataclasses.KW_ONLY<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Fdataclasses.html%23dataclasses.KW_ONLY&data=04%7C01%7CErik.DeBonte%40microsoft.com%7C97c66242ac2f4c46b05808d9d6c215eb%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776951662412658%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=KtnxQoyRcQI8yrPEAQfjLC6rO9%2FMi1MNwnSewfi46co%3D&reserved=0>). Should this be added to the spec? El lun, 13 dic 2021 a las 13:38, Erik De Bonte via Typing-sig (<typing-sig@python.org<mailto:typing-sig@python.org>>) escribió: I've created a draft PEP for the "Dataclass Transforms" concept that Eric Traut presented at the December 1st Typing SIG meetup. Feedback is welcome! https://github.com/debonte/peps/blob/dataclass_transforms/pep-9999.rst<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdebonte%2Fpeps%2Fblob%2Fdataclass_transforms%2Fpep-9999.rst&data=04%7C01%7CErik.DeBonte%40microsoft.com%7C97c66242ac2f4c46b05808d9d6c215eb%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776951662412658%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=T46WppIdEnbEd0y1%2FDGS%2FiA2s2rQy7b31hMYet2RxiI%3D&reserved=0> Thanks, Erik _______________________________________________ Typing-sig mailing list -- typing-sig@python.org<mailto:typing-sig@python.org> To unsubscribe send an email to typing-sig-leave@python.org<mailto:typing-sig-leave@python.org> https://mail.python.org/mailman3/lists/typing-sig.python.org/<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.python.org%2Fmailman3%2Flists%2Ftyping-sig.python.org%2F&data=04%7C01%7CErik.DeBonte%40microsoft.com%7C97c66242ac2f4c46b05808d9d6c215eb%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637776951662412658%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=sw55JbZl624E%2FFFeV2h%2B07wZkrPrVoH1NeqfQoz4uck%3D&reserved=0> Member address: jelle.zijlstra@gmail.com<mailto:jelle.zijlstra@gmail.com>
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Reminder to provide feedback on the dataclass_transform PEP [1] if you have any. In particular, if you maintain a type checker and have any concerns, please let me know. Thanks, Erik [1] https://www.python.org/dev/peps/pep-0681/ From: Erik De Bonte Sent: Monday, December 13, 2021 1:37 PM To: 'typing-sig@python.org' <typing-sig@python.org> Subject: Dataclass Transform draft PEP I've created a draft PEP for the "Dataclass Transforms" concept that Eric Traut presented at the December 1st Typing SIG meetup. Feedback is welcome! https://github.com/debonte/peps/blob/dataclass_transforms/pep-9999.rst Thanks, Erik
![](https://secure.gravatar.com/avatar/c278b7144feb496c731ee0514355548c.jpg?s=120&d=mm&r=g)
Hi Erik, the dataclass_transform PEP looks great! I left some (mostly-stylistic) feedback in: https://github.com/python/peps/pull/2382 And here's additional feedback...
* ``hash`` is an alias for the ``unsafe_hash`` parameter.
Reasoning for providing this alias? Seems inconsistent. And perhaps unsafe to do if potentially disguising an unsafe feature as (by-default) safe.
(1) Could you provide an example of how this alternate form is actually used to mark a function, class, or metaclass? Perhaps the example could be extended with something like: ``` @__dataclass_transform__(kw_only_default=True, order_default=True) def create_model( *, frozen: bool = False, kw_only: bool = True, ) -> Callable[[Type[_T]], Type[_T]]: ... ``` (2) Is the above syntax accepted in a .pyi stub file by popular typecheckers that already exist? If I was a typechecker I *might* find it sketchy to see use of a stub decorator declared in the same file.
Rejected Ideas ==============
Django primary and foreign keys -------------------------------
users of Django would need to explicitly declare the ``id`` field.
As a Django user this is a bit inconvenient, but seems fine. (No changes suggested.)
This limitation may make it impractical to use the ``dataclass_transform`` mechanism with Django.
I wonder if this is too strong a statement... Everything I've read so far, minus the inconvenience of not autogenerating an "id" field, suggests that @dataclass_tranform *could* be used on Django's models.Model base class. Is there potential openness to adding support for declaring that a particular dataclass_transform does autogenerate certain "extra fields" with known names and types (like "id: int")? Either in this PEP or in a future PEP? Cheers, -- David Foster | Seattle, WA, USA Contributor to TypedDict, mypy, and Python's typing system On 3/4/22 3:42 PM, Erik De Bonte via Typing-sig wrote:
![](https://secure.gravatar.com/avatar/489cdabedd1112f98474038939668778.jpg?s=120&d=mm&r=g)
Does the PEP/implementation take into account the return type specified in the functions signature? For example, assuming we had Intersection as a type, would this work? class HasSomeAttr(typing.Protocol): attr: str @typing.dataclass_transform( kw_only_default=True, field_descriptors=(model_field, )) def create_model( *, init: bool = True, ) -> Callable[[Type[_T]], typing.Intersection[Type[_T], HasSomeAttr]]: ... On Sat, 5 Mar 2022 at 09:10, David Foster <davidfstr@gmail.com> wrote:
-- Patrick Arminio
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
That's an interesting idea, but no we do not consider the return type of decorators when looking for fields. -Erik From: Patrick Arminio <patrick.arminio@gmail.com> Sent: Sunday, March 6, 2022 5:23 PM To: David Foster <davidfstr@gmail.com> Cc: Erik De Bonte <Erik.DeBonte@microsoft.com>; typing-sig@python.org Subject: Re: [Typing-sig] Re: Dataclass Transform draft PEP Does the PEP/implementation take into account the return type specified in the functions signature? For example, assuming we had Intersection as a type, would this work? class HasSomeAttr(typing.Protocol): attr: str @typing.dataclass_transform( kw_only_default=True, field_descriptors=(model_field, )) def create_model( *, init: bool = True, ) -> Callable[[Type[_T]], typing.Intersection[Type[_T], HasSomeAttr]]: ... -- Patrick Arminio
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
* ``hash`` is an alias for the ``unsafe_hash`` parameter.
Reasoning for providing this alias? Seems inconsistent.
@Eric Traut<mailto:erictr@microsoft.com>, I assume this was added because attrs uses "hash" instead of "unsafe_hash". However, the attrs hashing documentation [1] strongly discourages users from setting hash to True. I assume that means that it is infrequently used. Perhaps we should remove this alias and if attrs feels that this is important they should add an unsafe_hash alias on their side?
Alternate form
Thanks for pointing this out. I just removed this section from the PEP. [2] Pyright's support of the alternate form was added so libraries could experiment with dataclass_transform before the official decorator was available, even before the PEP was written. Now that the decorator is in typing_extensions the alternate form should not be mentioned in the PEP.
@dataclass_tranform *could* be used on Django's models.Model base class.
This is great news! I've been trying to find a Django contributor who might be interested in experimenting with dataclass_transform and providing feedback. If you know a good contact, please let me know.
Is there potential openness to adding support for declaring that a particular dataclass_transform does autogenerate
certain "extra fields" with known names and types (like "id: int")? Either in this PEP or in a future PEP?
In future PEPs, yes. Pradeep suggested an add_attributes decorator during a discussion back in November [3]. Since this would be useful outside of dataclasses, I think it would be better to spec it separately from dataclass_transform. Thanks for your feedback David! -Erik [1] https://www.attrs.org/en/stable/hashing.html [2] https://github.com/python/peps/pull/2386 [3] https://mail.python.org/archives/list/typing-sig@python.org/message/I2XJ6TTZ... -----Original Message----- From: David Foster <davidfstr@gmail.com> Sent: Saturday, March 5, 2022 7:09 AM To: Erik De Bonte <Erik.DeBonte@microsoft.com>; typing-sig@python.org Subject: Re: [Typing-sig] Re: Dataclass Transform draft PEP [You don't often get email from davidfstr@gmail.com<mailto:davidfstr@gmail.com>. Learn why this is important at http://aka.ms/LearnAboutSenderIdentification.] Hi Erik, the dataclass_transform PEP looks great! I left some (mostly-stylistic) feedback in: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com... And here's additional feedback...
* ``hash`` is an alias for the ``unsafe_hash`` parameter.
Reasoning for providing this alias? Seems inconsistent. And perhaps unsafe to do if potentially disguising an unsafe feature as (by-default) safe.
Alternate form
--------------
To avoid delaying adoption of this proposal until after > ``dataclass_transform`` has been added to the ``typing`` module, type > checkers may support the alternative form ``__dataclass_transform__``.
(1) Could you provide an example of how this alternate form is actually used to mark a function, class, or metaclass? Perhaps the example could be extended with something like: ``` @__dataclass_transform__(kw_only_default=True, order_default=True) def create_model( *, frozen: bool = False, kw_only: bool = True, ) -> Callable[[Type[_T]], Type[_T]]: ... ``` (2) Is the above syntax accepted in a .pyi stub file by popular typecheckers that already exist? If I was a typechecker I *might* find it sketchy to see use of a stub decorator declared in the same file.
Rejected Ideas
==============
Django primary and foreign keys
-------------------------------
users of Django would need to explicitly declare the ``id`` field.
As a Django user this is a bit inconvenient, but seems fine. (No changes suggested.)
This limitation may make it impractical to use the > ``dataclass_transform`` mechanism with Django.
I wonder if this is too strong a statement... Everything I've read so far, minus the inconvenience of not autogenerating an "id" field, suggests that @dataclass_tranform *could* be used on Django's models.Model base class. Is there potential openness to adding support for declaring that a particular dataclass_transform does autogenerate certain "extra fields" with known names and types (like "id: int")? Either in this PEP or in a future PEP? Cheers, -- David Foster | Seattle, WA, USA Contributor to TypedDict, mypy, and Python's typing system On 3/4/22 3:42 PM, Erik De Bonte via Typing-sig wrote:
Reminder to provide feedback on the dataclass_transform PEP [1] if you
have any.
In particular, if you maintain a type checker and have any concerns,
please let me know.
Thanks,
Erik
[1]
https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.
python.org%2Fdev%2Fpeps%2Fpep-0681%2F&data=04%7C01%7CErik.DeBonte%
40microsoft.com%7C018f5884d1fd42b8cc3608d9feba2553%7C72f988bf86f141af9
1ab2d7cd011db47%7C1%7C0%7C637820897718143705%7CUnknown%7CTWFpbGZsb3d8e
yJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C30
00&sdata=y8o1w62SOJcUp%2Bs7DGquJFxeD2jFes%2BMadgVUdU1BK0%3D&re
served=0
<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww
.python.org%2Fdev%2Fpeps%2Fpep-0681%2F&data=04%7C01%7CErik.DeBonte
%40microsoft.com%7C018f5884d1fd42b8cc3608d9feba2553%7C72f988bf86f141af
91ab2d7cd011db47%7C1%7C0%7C637820897718143705%7CUnknown%7CTWFpbGZsb3d8
eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3
000&sdata=y8o1w62SOJcUp%2Bs7DGquJFxeD2jFes%2BMadgVUdU1BK0%3D&r
eserved=0>
*From:* Erik De Bonte
*Sent:* Monday, December 13, 2021 1:37 PM
*To:* 'typing-sig@python.org' <typing-sig@python.org<mailto:typing-sig@python.org>>
*Subject:* Dataclass Transform draft PEP
I've created a draft PEP for the "Dataclass Transforms" concept that
Eric Traut presented at the December 1^st Typing SIG meetup. Feedback
is welcome!
https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
ub.com%2Fdebonte%2Fpeps%2Fblob%2Fdataclass_transforms%2Fpep-9999.rst&a
mp;data=04%7C01%7CErik.DeBonte%40microsoft.com%7C018f5884d1fd42b8cc360
8d9feba2553%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C6378208977181
43705%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJB
TiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=B4rYfZbwlEhXWkhCjXKfoEzf98
5cwSg1Sz%2Bp%2BRddNZA%3D&reserved=0
<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
hub.com%2Fdebonte%2Fpeps%2Fblob%2Fdataclass_transforms%2Fpep-9999.rst&
amp;data=04%7C01%7CErik.DeBonte%40microsoft.com%7C018f5884d1fd42b8cc36
08d9feba2553%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637820897718
143705%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJ
BTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=B4rYfZbwlEhXWkhCjXKfoEzf9
85cwSg1Sz%2Bp%2BRddNZA%3D&reserved=0>
Thanks,
Erik
_______________________________________________
Typing-sig mailing list -- typing-sig@python.org<mailto:typing-sig@python.org> To unsubscribe send
an email to typing-sig-leave@python.org<mailto:typing-sig-leave@python.org>
https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail
.python.org%2Fmailman3%2Flists%2Ftyping-sig.python.org%2F&data=04%
7C01%7CErik.DeBonte%40microsoft.com%7C018f5884d1fd42b8cc3608d9feba2553
%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637820897718143705%7CUnk
nown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWw
iLCJXVCI6Mn0%3D%7C3000&sdata=oWXw220vLouj6mqsEU8ty%2F5LpXXd8HtxlSE
qGT7pJ%2FI%3D&reserved=0
Member address: davidfstr@gmail.com<mailto:davidfstr@gmail.com>
![](https://secure.gravatar.com/avatar/c278b7144feb496c731ee0514355548c.jpg?s=120&d=mm&r=g)
On 3/7/22 3:34 PM, Erik De Bonte wrote:
I would be in favor of removing the "hash" alias to "unsafe_hash" in @dataclass_transform, in favor of the attrs project instead adding a new "unsafe_hash" alias (to the now-attrs-specific "hash"). But to do that we would need buy-in from a maintainer of attrs. Know anyone we could ask?
I'm a Django contributor myself. However my bandwidth is limited while I'm shepherding my own PEP (655) in before the Python 3.11 alphas close, so I might not have enough time myself. What kinds of feedback are you looking for? I have a medium-sized Django-based project (~200,000 lines of Python code) at my disposal.
The @add_attributes decorator idea is quite interesting. Definitely worth revisiting later. Cheers, -- David Foster | Seattle, WA, USA Contributor to TypedDict, mypy, and Python's typing system
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Thanks David.
we would need buy-in from a maintainer of attrs. Know anyone we could ask?
Yes, I emailed Hynek Schlawack about this yesterday.
I'm a Django contributor myself...What kinds of feedback are you looking for?
I was hoping someone could try decorating the relevant functions/classes in Django with dataclass_transform and determine if the resulting user experience is acceptable. Btw, Carlton Gibson told me that Django's Field.default can be either a value or a callable, whereas the PEP expects it to be a value. Factory callables need to be provided via the default_factory parameter instead. So that's one issue, but I think as with the attrs hash/unsafe_hash issue, this would be best fixed by Django adding a default_factory (or factory) property. -Erik
![](https://secure.gravatar.com/avatar/c278b7144feb496c731ee0514355548c.jpg?s=120&d=mm&r=g)
I got a chance to play with @dataclass_transform and Django Models. Looks promising. Please see the following file - containing a lightweight reimplementation of Django's Model and Field classes - and its inline comments: # experiment.py import typing import typing_extensions class Field: # django.db.models.fields def __init__(self, *args, **kwargs): pass # NOTE: The following syntax is just a proposal. #@typing_extensions.dataclass_field_descriptor(value_type=str) class CharField(Field): # django.db.models.fields pass # NOTE: The following syntax is just a proposal. #@typing_extensions.dataclass_field_descriptor(value_type=int) class AutoField(Field): # django.db.models.fields pass @typing_extensions.dataclass_transform( # ⚠️ Forward-reference like 'Field' is NOT supported here, # but appears to be necessary in real Django field_descriptors=(Field,) ) class ModelBase(type): # django.db.models.base pass class Model(metaclass=ModelBase): # django.db.models.base # NOTE: Must explicitly define that an "id" AutoField exists by default. # # However sometimes it is actually a BigAutoField, depending on # the configuration of the Django app package that defines the # Model subclass. (However even if it IS a BigAutoField, it's # still of int type, which is convenient.) id: int = typing.cast(int, AutoField()) def __init__(self, *args, **kwargs): pass class Question(Model): # 😬 Must use cast() because otherwise pyright complains that # a CharField is not a str. # # 🌸 It would be nice if there was a way to derive that # a CharField(...) should result in a str, so you could just write: # question_text = CharField(max_length=200) # # Similarly a CharField(required=False, ...) should result # in an Optional[str]. question_text: str = typing.cast(str, CharField(max_length=200)) q = Question( id=1, # ✅ works, with "id" field defined on Model base class question_text=1, # ✅ error: "Literal[1]" cannot be assigned to "str" boom=2, # ✅ error: No parameter named "boom" ) Some patterns/comments: * dataclass_transform(field_descriptors=...) does not currently support string-based forward references to types, which it looks like Django will require. * It would be useful to have syntax to describe what the "value type" of a particular field descriptor is, so that I don't have to use cast()s everywhere. See the above proposed syntax: - @typing_extensions.dataclass_field_descriptor(value_type=...) * I managed to define an implicit "id" field by just putting it on Django's Model class directly. If this caused runtime problems I could additionally guard that field definition with an "if TYPE_CHECKING" block. I hope this experimental feedback is helpful! I'm very much looking forward to being able to use @dataclass_transform in real code. Best, --- David Foster | Seattle, WA, USA Contributor to TypedDict, mypy, and Python's typing system On 3/10/22 6:32 PM, Erik De Bonte wrote:
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Thanks for investigating this David!
dataclass_transform(field_descriptors=...) does not currently support string-based forward references to types, which it looks like Django will require.
What is it about Django's code that makes a forward reference required? Is there a circular reference?
It would be useful to have syntax to describe what the "value type" of a particular field descriptor is, so that I don't have to use cast()s everywhere. See the above proposed syntax:
Dataclass solves this by having a field() function that returns their Field objects rather than having consumers use the Field type directly. The field() function returns Any but has overloads to return a more specific type when default or default_factory are provided. Thanks, Erik
![](https://secure.gravatar.com/avatar/c278b7144feb496c731ee0514355548c.jpg?s=120&d=mm&r=g)
On 4/5/22 8:25 PM, Erik De Bonte wrote:
dataclass_transform(field_descriptors=...) does not currently support string-based forward references to types, which it looks like Django will require.
What is it about Django's code that makes a forward reference required? Is there a circular reference?
Looks like I was able to do a direct import of Field after all, rather than using a forward reference. 👌 I suppose my instincts were worried about introducing an import because I try very hard to not introduce imports from low-level "utility" modules (like django.db.models.base) to other modules that might be higher level (like django.db.models.fields). Such imports often create circular reference problems, although apparently not in this case.
It would be useful to have syntax to describe what the "value type" of a particular field descriptor is, so that I don't have to use cast()s everywhere. See the above proposed syntax:
Dataclass solves this by having a field() function that returns their Field objects rather than having consumers use the Field type directly. The field() function returns Any but has overloads to return a more specific type when default or default_factory are provided.
Oof. I expect it would be a bigger ask to introduce a similar field() function in Django. Django users have been accustomed to directly assigning Field instances to attributes, being able to write: class Question(Model): question_text = CharField(max_length=200) It sounds like introducing that kind of field() function would require users to write instead: class Question(Model): question_text = field(CharField(max_length=200)) That could be a larger ask. Granted it would only apply to users of Django who opt-in to using a type checker. For my own reference, I expect a field() method would be implemented as something like: V = TypeVar("V") class Field(Generic[V]): ... # django.db.models.fields class CharField(Field[str]): ... # django.db.models.fields def field(field: Field[T]) -> T: return typing.cast(T, field) -- David Foster | Seattle, WA, USA Contributor to TypedDict, mypy, and Python's typing system
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Hi David,
I was envisioning this instead: ```python class Question(Model): question_text = char_field(max_length=200) ```
`dataclasses.field()` looks like this: ```python def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True, hash=None, compare=True, metadata=None, kw_only=MISSING): return Field(default, default_factory, init, repr, hash, compare, metadata, kw_only) ``` It's just a wrapper for constructing a `Field` object, but it returns `Any` instead of `Field`, and has overloads to return a more specific type when `default` or `default_factory` are provided. See the stubs at https://github.com/python/typeshed/blob/master/stdlib/dataclasses.pyi#L148. -Erik
![](https://secure.gravatar.com/avatar/c278b7144feb496c731ee0514355548c.jpg?s=120&d=mm&r=g)
Hmm. That pattern would imply a set of parallel *_field() functions for all of Django's (current and future, 1st party and 3rd party) *Field classes. I think I like my proposal generic field() function better, even if it differs significantly in implementation from the similarly-named dataclasses.field(), because it only necessitates defining a *single* new generic function and a *single* new pattern that will work everywhere for all *Field() classes (which I don't expect to go away).
Cheers, David
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
* ``hash`` is an alias for the ``unsafe_hash`` parameter.
Reasoning for providing this alias? Seems inconsistent.
Thanks for asking about this David. I talked with Hynek (attrs) and he was ok with removing the hash alias. PR is here -- https://github.com/python/peps/pull/2454
![](https://secure.gravatar.com/avatar/aefb9d56c3e2dde2d269a6883004bb35.jpg?s=120&d=mm&r=g)
Hi Erik, I am implementing it in Pyre, and so far have not find any blockers -- so a +1 from that perspective. Thanks for the PEP (including proposed transform_descriptor_types[1]), it will be a great addition! Best regards, Kshitij [1] https://github.com/python/peps/pull/2369
![](https://secure.gravatar.com/avatar/870d613430249e453343efc9667ef636.jpg?s=120&d=mm&r=g)
I'll leave typing details to typing-sig regulars, but I have a few comments “from outside”: Replying to the Discourse post (https://discuss.python.org/t/rfc-on-pep-681-data-class-transforms/14116):
The PEP will not affect CPython directly except for the addition of the dataclass_transform decorator in typing.py. The decorator is currently in typing_extensions.
Could this be also said in the PEP itself? It would be nice if e.g. a maintainer of Python's parser could read the introduction and decide to skip the rest & leave it to typing-sig. Including this note would also serve to better qualify phrases like "cannot", "error", "resulting behavior" throughout the PEP. I assume they specify expected behavior of type checkers, and don't apply at runtime. Is that right? And regarding that statement: Do you not plan to apply the decorator to dataclass itself? Will dataclasses.dataclass not get a __dataclass_transform__ attribute at runtime? Abstract:
PEP 557 introduced the dataclass to the Python stdlib.
IMO it would be better to link to the current documentation (https://docs.python.org/3.11/library/dataclasses.html) than to the 4-year-old document that first proposed adding dataclasses? The rationale and discussion around the proposal don't seem relevant, and the specification may be out of date. Same for later references to that PEP. And in general: Are the semantics expected to evolve if new features are added to dataclasses? Or to other popular libraries that work like dataclasses?
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Thanks for your feedback Petr!
The PEP will not affect CPython directly except for the addition of the dataclass_transform decorator in typing.py.
Could this be also said in the PEP itself?
Yes, good point.
Do you not plan to apply the decorator to dataclass itself? Will dataclasses.dataclass not get a __dataclass_transform__ attribute at runtime?
No, we were not planning to decorate dataclass with dataclass_transform.
it would be better to link to the current documentation than to the 4-year-old document that first proposed adding dataclasses... Same for later references to that PEP.
That's fair, although I think the existing references to PEP 557 are ok because we're linking to specific, relevant parts of that document. Would adding a link to the docs in the abstract be satisfactory? I just created a PR for this and your first point above. [1]
Are the semantics expected to evolve if new features are added to dataclasses? Or to other popular libraries that work like dataclasses?
dataclass_transform is expected to evolve with dataclass. I recently added a paragraph to Rationale that explains this. We would consider evolving dataclass_transform based on new features in other dataclass-like libraries. But we would prefer that these libraries become more similar to stdlib dataclass either by changing their APIs or proposing new dataclass features. Thanks, Erik [1]: https://github.com/python/peps/pull/2390
![](https://secure.gravatar.com/avatar/a2bfd7c4e403ac42737c2dd285d63a21.jpg?s=120&d=mm&r=g)
I'm quite excited by this PEP, but I have one question: How to annotate decorators which can be applied both with options or not ? For example: ```python @my_dataclass # << Notice there is NO function call here class A: x: int @my_dataclass(frozen=True) class A: x: int ``` How should `my_dataclass` be annotated ? It's unclear to me. With the `Intersection` syntax, it would be some: ```python @typing.overload def my_dataclass( cls: None = ..., **options: Any, ) -> Callable[[_ClsT], _ClsT & Dataclass] ... @typing.overload def my_dataclass( cls: _ClsT, **options: Any, ) -> type[_ClsT & Dataclass] ... ``` This is how `dataclasses.dataclass`, `chex.dataclass`,... behave (can be applied as `@dataclass` or `@dataclass()`) I feel it would be nice to add an example in the PEP.
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Hi Étienne, Thanks for your feedback! The code below worked for me. Is this what you were aiming for? Was the use of Intersection important to your question? If so, was the Dataclass type supposed to represent the dataclass-like changes made by the my_dataclass decorator? That seems unnecessary to me, since dataclass_transform is already trying to describe those changes. If I'm missing your point, can you provide a more complete example? -Erik ```python from typing import Callable, Any, TypeVar, overload _ClsT = TypeVar("_ClsT") @overload def my_dataclass(cls: None = ..., **options: Any,) -> Callable[[_ClsT], _ClsT]: ... @overload def my_dataclass(cls: Callable[..., _ClsT], **options: Any,) -> type[_ClsT]: ... def my_dataclass(cls: Callable[..., _ClsT] | None = None, **options: Any) -> Callable[..., _ClsT]: # The implementation of the decorator was borrowed from dataclass def wrap(cls): return _process_class(cls, **options) # See if we're being called as @dataclass or @dataclass(). if cls is None: # We're called with parens. return wrap # We're called as @dataclass without parens. return wrap(cls) def _process_class(cls, **options: Any): return cls @my_dataclass class A: x: int @my_dataclass() class B: x: int @my_dataclass(frozen=True) class C: x: int ```
![](https://secure.gravatar.com/avatar/a2bfd7c4e403ac42737c2dd285d63a21.jpg?s=120&d=mm&r=g)
Thank you for your answer and sorry for the confusion. I wasn't asking about the implementation, I was asking how you would annotate such use-case using @dataclass_transform ? I'm a little confused, as your answer does not use dataclass_transform at all, so type checker would not detect that A, B & C are dataclass-like. Should the code be annotated as ? : ``` @overload @dataclass_transform def my_dataclass(cls: None = ..., **options: Any,) -> Callable[[_ClsT], _ClsT]: ... @overload @dataclass_transform def my_dataclass(cls: Callable[..., _ClsT], **options: Any,) -> type[_ClsT]: ... def my_dataclass(cls = None, **options: Any): ``` Or: ``` @overload def my_dataclass(cls: None = ..., **options: Any,) -> Callable[[_ClsT], _ClsT]: ... @overload def my_dataclass(cls: Callable[..., _ClsT], **options: Any,) -> type[_ClsT]: ... @dataclass_transform def my_dataclass(cls = None, **options: Any): ``` In the current proposal, it's not obvious to me what is the answer. Or even if this is supported. This is why I suggested it would be nice to specify this in the PEP and give an example. (you can ignore the section on Intersection, I was just showing an alternative syntax to @dataclass_transform which would make such use-case more explicit, using notation described in https://github.com/python/typing/issues/213)
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Hi Étienne, Thanks for clarifying. I completely misunderstood your question. Thanks for your feedback! This is an important point. We should be clear about where dataclass_transform can be applied for overloaded functions. I just created a PR which adds the following language to the PEP. https://github.com/python/peps/pull/2498 If the function has overloads, the ``dataclass_transform`` decorator can be applied to the implementation of the function or any one, but not more than one, of the overloads. The behavior is undefined if dataclass_transform is found in more than one of these locations. Type checkers can choose to report an error, use the first dataclass_transform decorator they find, etc. Thanks, Erik
![](https://secure.gravatar.com/avatar/a2bfd7c4e403ac42737c2dd285d63a21.jpg?s=120&d=mm&r=g)
Thank you for the update. So if I understand, `dataclass_transform` support this use-case which would then be annotated as: ``` @overload def my_dataclass(cls: None = ..., **options: Any,) -> Callable[[_ClsT], _ClsT]: ... @overload def my_dataclass(cls: Callable[..., _ClsT], **options: Any,) -> type[_ClsT]: ... @dataclass_transform def my_dataclass(cls=None, **options): ``` And `my_dataclass` could then be applied both as: * A decorator: `my_dataclass(cls)` * A decorator factory: `my_dataclass(**options)(cls)`
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Yes, although to make Pyright happy I had to add a return type annotation on your implementation: def my_dataclass(cls=None, **options) -> Callable[[_ClsT], _ClsT]: ... Btw, you could also place the @dataclass_transform decorator on either overload. If you were exposing my_dataclass() in a .pyi, you would need to put dataclass_transform on an overload. -Erik
![](https://secure.gravatar.com/avatar/a2bfd7c4e403ac42737c2dd285d63a21.jpg?s=120&d=mm&r=g)
Yes, although to make Pyright happy I had to add a return type annotation on your implementation:
If I understand, this is a Pyright bug right ? As implementations should not have typing annotation I believe.
If you were exposing my_dataclass() in a .pyi, you would need to put dataclass_transform on an overload.
Is it not a confusing ? I would intuitively expect the that only the `@overload` on which `@dataclass_transform` is applied transform the class. ``` @overload def create_model(cls: A) -> A: @overload @dataclass_transform def create_model(cls: B) -> B: ``` So in this case, I would expect `create_model` to transform B to dataclass, but not A. (this is just a dummy unrealistic example just to show my point) Why not have the overload explicitly be applied on each overload ? I feel this would be least ambiguous case. ``` @overload @dataclass_transform def create_model(cls: A) -> A: @overload @dataclass_transform def create_model(cls: B) -> B: @overload def create_model(cls: C) -> C: ``` Here A and B are transformed to dataclasses, but not C. Would there be a drawback to explicitly marking each overload as @dataclass_transform ?
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
If I understand, this is a Pyright bug right ? As implementations should not have typing annotation I believe.
I just played with this again to refresh my memory. Looks like the issue was that the function's implementation was empty and therefore Pyright was warning me that the implementation's return type of `None` was incompatible with the overloads. Once I implemented the implementation the return type annotation was no longer required. So I think there's no issue here. I just didn't read the error closely enough.
Why not have the overload explicitly be applied on each overload ? I feel this would be least ambiguous case. Would there be a drawback to explicitly marking each overload as @dataclass_transform ?
We decided to require `dataclass_transform` to be in only one location because: 1. Allowing a function's overloads to have different transform behaviors (ex. different `dataclass_transform` parameters, or some overloads that transform and some that do not) is an unnecessary complexity. We don't want to require type checkers to support that. 2. It's a maintenance hassle to keep the parameters in sync if the decorator is required on all overloads. -Erik
![](https://secure.gravatar.com/avatar/57da4d2e2a527026baaaab35e6872fa5.jpg?s=120&d=mm&r=g)
El lun, 13 dic 2021 a las 13:38, Erik De Bonte via Typing-sig (< typing-sig@python.org>) escribió:
Hi Erik, I was discussing the PEP with Guido and we had some concerns around locking ourselves into an overly specific API. For example, type checkers may want to experiment with additional options to the dataclass_transform() decorator. If we decide to add more options in the future after the PEP is accepted, users would have to rely on updating typing-extensions quickly to use the new option. Our idea is to make `@dataclass_transform()` accept and ignore arbitrary **kwargs at runtime. Type checkers would still give errors if users pass unrecognized parameters, but would be free to support additional experimental parameters without having to wait for changes to the runtime.
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
* Our idea is to make `@dataclass_transform()` accept and ignore arbitrary **kwargs at runtime. Type checkers would still give errors if users pass unrecognized parameters, but would be free to support additional experimental parameters without having to wait for changes to the runtime. Thanks, great suggestion! I can submit a PR for this later tonight. Should I do that? It's not clear to me if changes are still allowed at this point. * ...ignore arbitrary **kwargs at runtime... The only thing it does at runtime is set the __dataclass_transform__ attribute, right? Are you saying that you wouldn't want to include the extra kwargs in that dict? -Erik
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Tue, Apr 5, 2022 at 6:16 PM Jelle Zijlstra <jelle.zijlstra@gmail.com> wrote:
Maybe I'm overlooking something, but why couldn't the runtime definition be as simple as this? def dataclass_transform(**kwds): def decorator(thing): thing .__dataclass_transform__ = kwds return thing return decorator -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Tue, Apr 5, 2022 at 9:51 PM Erik De Bonte <Erik.DeBonte@microsoft.com> wrote:
Agreed. So in the typeshed stubs this should have the full specification, and we should update this whenever we've agreed on a new keyword argument. But the runtime implementation (whether in stdlib (typing.py) or typing-extensions) doesn't need to do anything except setting the dunder attribute. By not making it check the arguments at runtime, users won't have to install a new version of typing-extensions, and there will (eventually) be less reason to import the typing-extensions version rather than the stdlib version. This is a general trend for runtime behavior of typing features -- we're removing runtime checks for things that type checkers already check, reducing the runtime cost and minimizing the need to update the runtime code. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
So in the typeshed stubs this should have the full specification, and we should update this whenever we've agreed on a new keyword argument.
That makes sense. I actually didn't realize that there was a stub file for typing.py. :) I also didn't realize that keyword args and kwargs could be passed in all mixed together. Thanks for explaining. -Erik
![](https://secure.gravatar.com/avatar/a8b577699ee8eedc869a735dd521c88e.jpg?s=120&d=mm&r=g)
(I emailed Eric about this directly, but I thought it might be worth adding my feedback here too, I know it might be too late to alter the PEP, but think could still be helpful to document this issue) Pydantic has supported the "Alternate Form <https://github.com/microsoft/pyright/blob/main/specs/dataclass_transforms.md...>" of dataclass transforms for a while which is supported by pyright. As well as helping lots of people (I assume - happy people don't create issues, and I don't use pyright/pylance/vscode), we have had some issues with the "feature", see here <https://github.com/samuelcolvin/pydantic/issues/3753>. In summary: pydantic has a BaseSettings type which users inherit from to manage settings, fields are defined on a class, then can be configured using environment variables and other external sources. Because of this you can legitimately use "settings = Settings()" even when your Settings class has required fields - because they're filled from env variables. The problem is that dataclass transforms apply to BaseSettings, and therefore Settings because BaseSettings inherits from BaseModel (which is marked with the decorator), so users get an error from pyright on "settings = Settings()" saying required fields are missing. It would be great if there was a way to switch off dataclass transforms on some subclasses. The easiest way for users would be another magic decorator which marked the class (and its subclasses) as "not dataclass-like", but I'd be happy with any way to achieve this, e.g. a kwarg to dataclass_transform. Samuel -- Samuel Colvin On Wed, 6 Apr 2022 at 07:39, Erik De Bonte via Typing-sig < typing-sig@python.org> wrote:
![](https://secure.gravatar.com/avatar/be78c7dd640e15b8ec61877b619e8034.jpg?s=120&d=mm&r=g)
Hi Samuel,
Because of this you can legitimately use "settings = Settings()" even when your Settings class has required fields - because they're filled from env variables.
Since the parameters don't need to be provided when creating a `Settings` object, aren't these fields *not* required? I saw a comment on the issue suggesting adding default values as a workaround. [1] Why doesn't that work? I didn't see any responses to that idea. Alternatively, could you refactor your class hierarchy and relocate the `dataclass_transform` decorator so `BaseSettings` and `BaseModel` still share code, but BaseSettings's branch of the hierarchy was not decorated with `dataclass_transform`? -Erik [1] https://github.com/samuelcolvin/pydantic/issues/3753#issuecomment-1060850457
![](https://secure.gravatar.com/avatar/a8b577699ee8eedc869a735dd521c88e.jpg?s=120&d=mm&r=g)
Hi Erik, sorry for the late reply, somehow the task of replying to your email drifted into the unsorted set of background tasks I need to do someday, and only bubbled to the top by chance.
Providing a default value wouldn't solve the problem - when creating the Settings class you want to enforce that the value IS required albeit via an environment variable or an argument when initialising the class .e.g. with a class ```python class Settings(BaseSettings): db_password: str ``` You could either create your settings instance via ```python settings = Settings(db_password='foobar') ``` or via, ```bash export DB_PASSWORD=foobar ``` ```python settings = Settings() ``` But either way, the point is that the field is "required", just that it's not necessarily required as an argument. I don't expect detaclass transforms to understand this, just to provide an escape hatch so I can stop using them when the behaviour is too complex/easotetic to remotely match dataclass behaviour. Alternatively, could you refactor your class hierarchy and relocate the
I think that's what we'll end up doing in a future major release. But it'll be ugly, and probably involve duplicated code. I still think there's a real need for a way to disable dataclass transforms on some subclasses, both in pydantic and many other usage scenarios. Thanks, Samuel -- Samuel Colvin On Wed, 6 Apr 2022 at 16:46, Erik De Bonte <Erik.DeBonte@microsoft.com> wrote:
![](https://secure.gravatar.com/avatar/a8b577699ee8eedc869a735dd521c88e.jpg?s=120&d=mm&r=g)
Hi Erik, yes exactly. But it could also change the semantics when a reader is reviewing the Settings class. Of course we could add a `RequiredAtRuntime` type to use as the default to work around this, but it could be very unclear to someone new to pydantic. Samuel On Fri, 15 Apr 2022, 18:04 Erik De Bonte, <Erik.DeBonte@microsoft.com> wrote:
![](https://secure.gravatar.com/avatar/3247bfd67c8fa4c4a08b8d30e49eab39.jpg?s=120&d=mm&r=g)
That's a prudent measure and a good addition to the PEP. Thanks for suggesting this. -Eric
![](https://secure.gravatar.com/avatar/c278b7144feb496c731ee0514355548c.jpg?s=120&d=mm&r=g)
Is it expected that @dataclass_transform (PEP 681) will be ready to submit to the Steering Council, and a response received from them, by the Python 3.11 feature cutoff (Friday, 2022-05-06†)? That is 2 weeks from today. Between now and then, the SC is expected to meet only twice (on Monday 4/25 and 5/2) based on their prior meeting pattern. Context: I'm in the process of finalizing information about the expected set of typing-related PEPs that will make it into Python 3.11. † https://peps.python.org/pep-0664/#schedule -- David Foster | Seattle, WA, USA Contributor to TypedDict, mypy, and Python's typing system
participants (12)
-
David Foster
-
encukou@gmail.com
-
Eric Traut
-
Erik De Bonte
-
Guido van Rossum
-
James H-B
-
Jelle Zijlstra
-
mail@kshitij.io
-
Neil Girdhar
-
Patrick Arminio
-
Samuel Colvin
-
Étienne Pot