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