> This is an area of exceeding subtlety (and also not very well > documented/specified, probably). I'd worry that changing anything here > might break some code. When a metaclass overrides neither __init__ nor > __new__, keyword args will not work because type.__init__ forbids > them. However when a metaclass overrides them and calls them using > super(), it's quite possible that someone ended up calling > super().__init__() with three positional args but super().__new__() > with keyword args, since the call sites are distinct (in the overrides > for __init__ and __new__ respectively). > > What's your argument for changing this, apart from a desire for more > regularity?
The implementation gets much simpler if __new__ doesn't take keyword arguments. It's simply that if it does, I have to filter out __new__'s three arguments. That's easily done in Python, unfortunately not so much in C. So we have two options: either type.__new__ is limited to accepting positional arguments only, possibly breaking some code, but which could be changed easily. This leads to a pretty simple implementation: pass over keyword arguments to __init_subclass__, that's it. The other option is: filter out name, bases and dict from the keyword arguments If people think that backwards compatibility is that important, I could do that. But that just leaves quite some code in places where there is already a lot of complicated code. Nick proposed a compromise, just don't filter for name, bases and dict, and pass them over to __init_subclass__. Then the default implementation of __init_subclass__ must support those three keyword arguments and do nothing with them. I'm fine with all three solutions, although I have a preference for the first. I think passing keyword arguments to type.__new__ is already really rare and if it does exist, it's super easy to fix. > I'm confused. In the above example it would seem that the keyword args > {'a': 1, 'b': 2} are passed right on to super9).__init_subclass__(). > Do you mean that it ignores all keyword args? Or that it has no > positional args? (Both of which would be consistent with the example.) The example is just wrong. I'll fix it. > Can you state exactly at which point during class initialization > __init_class__() is called? (Surely by now, having implemented it, you > know exactly where. :-) Further down in the PEP I give the exact > [This is as far as I got reviewing when the weekend activities > interrupted me. In the light of ongoing discussion I'm posting this > now -- I'll continue later.] I hope you had a good weekend not thinking too much about metaclasses... Greetings Martin _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com