On 28 September 2017 at 08:27, Nick Coghlan <ncogh...@gmail.com> wrote:
> On 27 September 2017 at 19:28, Ivan Levkivskyi <levkivs...@gmail.com> > wrote: > > If an object that is not a class object appears in the bases of a class > > definition, the ``__subclass_base__`` is searched on it. If found, > > it is called with the original tuple of bases as an argument. If the > result > > of the call is not ``None``, then it is substituted instead of this > object. > > Otherwise (if the result is ``None``), the base is just removed. This is > > necessary to avoid inconsistent MRO errors, that are currently prevented > by > > manipulations in ``GenericMeta.__new__``. After creating the class, > > the original bases are saved in ``__orig_bases__`` (currently this is > also > > done by the metaclass). > > How would you feel about calling it "__mro_entry__", as a mnemonic for > "the substitute entry to use instead of this object when calculating a > subclass MRO"? > > I don't have any preferences for the name, __mro_entry__ sounds equally OK to me. I think the other thing that needs to be clarified is whether or not > the actual metaclass can expect to receive an already-resolved > sequence of MRO entries as its list of bases, or if it will need to > repeat the base resolution process executed while figuring out the > metaclass. > > There are three points for discussion here: 1) It is necessary to make the bases resolution soon, before the metaclass is calculated. This is why I do this at the beginning of __build_class__ in the reference implementation. 2) Do we need to update type.__new__ to be able to accept non-classes as bases? I think no. One might be a bit surprised that class C(Iterable[int]): pass works, but type('C', (Iterable[int],), {}) fails with a metaclass conflict, but I think it is natural that static typing and dynamic class creation should not be used together. I propose to update ``type.__new__`` to just give a better error message explaining this. 3) Do we need to update types.new_class and types.prepare_class? Here I am not sure. These functions are rather utility functions and are designed to mimic in Python what __build_class__ does in C. I think we might add types._update_bases that does the same as its C counterpart. Then we can update types.new_class and types.prepare_class like you proposed, this will preserve their current API while types.new_class will match behaviour of __build_class__ If you and others agree with this, then I will update the PEP text and the reference implementation. Thanks for comments! -- Ivan
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/