On 12/29/20 8:59 AM, Guido van Rossum wrote:
> On Mon, Dec 28, 2020 at 10:24 PM Ethan Furman wrote:
>> The `__init_subclass__` and `__set_name__` protocols are intended to be run before a new type is finished, but creating
>> a new type has three major steps:
>>
>> - `__prepare__` to get the namespace
>> - `__new__` to get the memory and data structures
>> - `__init__` for any final polishing
>>
>> We can easily move the calls from `type_new()` to `type_init`.
>
> No, we can't. There is a window where the subclass is initialized after `typing_new()` returned before `__init__`
> starts, and you propose to move the subclass after that window. There may be code that depends on the class being
> initialized at that point, and you will break that code.
True, there will be a few custom metaclasses that need to move some code from their `__new__` to `__init__` instead, and
a few that need to add an `__init__` to consume any keyword arguments that don't need to get passed to
`__init_subclass__`. That seems like a small price to pay to be able to write custom metaclasses that are able to fully
participate in the `__set_name__` and `__init_subclass__` protocols.
Just in the stdlib we have two custom metaclasses that would start working correctly with this change (for the
`__init_subclass__` case).
> Honestly I disapprove of the shenanigans you're committing in enum.py, and if those are in in the 3.10 (master) branch I
> recommend that you take them out. It just looks too fragile and obscure.
Trust me, I don't like them either. But I like even less that a custom `__init_subclass__` for an Enum would fail if it
tried to do anything with the members. That's one of the reasons why I would like to see this fix put in (the
shenanigans would be unnecessary then).
From the point of view of a metaclass author, the current behavior feels buggy. In theory, `__init_subclass__` and
`__set_name__` are supposed to be called after a class is created, and yet they are being called somewhere in the middle
of my metaclass' `__new__`.
Looked at another way, `__init_subclass__` should be receiving a `cls` that is ready for use, i.e. done and fully
constructed and complete. But if that class is being created by a custom metaclass, then the thing that is being given
to `__init_subclass__` could easily be only partial.
--
~Ethan~
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/7WPNGL267FDGN6WWCHZQUAXWVBTUJOMN/
Code of Conduct: http://python.org/psf/codeofconduct/