On 28 July 2016 at 23:12, Joao S. O. Bueno <jsbu...@python.org.br> wrote: > Although I know it is not straightforward to implement (as the > "metaclass" parameter is not passed to the metaclass __new__ or > __init__), wouldn't it make sense to make it be passed to > __init_subclass__ just like all other keywords? (the default > __init_subclass__ then could swallow it, if it reaches there). > > I am putting the question now, because it is a matter of "now" or > "never" - I can see it can does make sense if it is not passed down.
It would complicate the implementation, and has the potential to be confusing (since the explicit metaclass hint and the actual metaclass aren't guaranteed to be the same), so I don't think it makes sense to pass it down. I'll make sure we note it in the documentation for the new protocol method, though. > Anyway, do you have any remarks on the first issue I raised? About > __init_subclass__ being called in the class it is defined in, not just > on it's descendant subclasses? That's already covered in the PEP: https://www.python.org/dev/peps/pep-0487/#calling-the-hook-on-the-class-itself We want to make it easy for mixin classes to use __init_subclass__ to define "required attributes" on subclasses, and that's straightforward with the current definition: class MyMixin: def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) if not hasattr(cls, "mixin_required_attribute"): raise TypeError(f"Subclasses of {__class__} must define a 'mixin_required_attribute' attribute") If you actually do want the init_subclass__ method to also run on the "base" class, then you'll need to tweak the class hierarchy a bit to look like: class _PrivateInitBase: def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) ... def MyOriginalClass(_PrivateInitBase): ... (You don't want to call __init_subclass__ from a class decorator, as that would call any parent __init_subclass__ implementations a second time) By contrast, when we had the default the other way around, opting *out* of self-application required boilerplate inside of __init_subclass__ to special case the situation where "cls is __class__": class MyMixin: def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) if cls is __class__: return # Don't init the base class if not getattr(cls, "mixin_required_attribute", None) is None: raise TypeError(f"Subclasses of {__class__} must define a non-None 'mixin_required_attribute' attribute") This raises exciting new opportunities for subtle bugs, like bailing out *before* calling the parent __init_subclass__ method, and then figure out that a later error from an apparently unrelated method is because your __init_subclass__ implementation is buggy. There's still an opportunity for bugs with the current design decision (folks expecting __init_subclass__ to be called on the class defining it when that isn't the case), but they should be relatively shallow ones, and once people learn the rule that __init_subclass__ is only called on *strict* subclasses, it's a pretty easy behaviour to remember. Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia _______________________________________________ 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