Hi Sylvain, thanks for the example, it's a great example to illustrate PEP 487 and its design decisions.
> What it does is setting some class attributes that are required for certain > types of descriptors to be able to initialize themselves. > > class MetaHasTraits(MetaHasDescriptors): > > """A metaclass for HasTraits.""" > def setup_class(cls, classdict): > cls._trait_default_generators = {} > super(MetaHasTraits, cls).setup_class(classdict) While in a metaclass solution this does need that the metaclass needs to execute code on the first class it is used for, in a PEP 487 solution this is not the case. A PEP 487 class HasTraits (no Meta here) would not have Traits-descriptors itself, the classes inheriting from it would have traits to be initialized. The PEP 487 HasTraits takes the role of the metaclass. A completely different problem shows up here. In your example, HasTraits needs to initialize things on the class before the Descriptors are run. This is not possible with PEP 487, where the descriptors are initialized before __init_subclass__ is even called. There are two ways to mitigate that problem: - the first initialized descriptor could do the necessary initialization, or - the descriptors are initialized from within __init_subclass__ At first sight, the first option seems hackish and the second option looks much saner. Nonetheless PEP 487 proposes the second solution. The rationale behind that is that people tend to forget to call super(), and suddenly descriptors don't work anymore. I realized later there is another benefit to this: if the first initialized descriptor is doing the class initialization, often __init_subclass__ isn't needed at all anymore, which means that those kind of descriptors can be used on any class, without the need to tell users that they have to inherit from a certain base class for the descriptors to work. Only if some finalizing code needs to run after the last descriptor is initialized one needs to write an __init_subclass__. This is unavoidable as the last descriptor doesn't know that it is the last. 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