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-le...@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/

Reply via email to