<div dir="ltr">On 29 September 2017 at 08:57, Nick Coghlan <span dir="ltr"><<a href="mailto:ncoghlan@gmail.com" target="_blank">ncoghlan@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 29 September 2017 at 08:04, Ivan Levkivskyi <<a href="mailto:levkivskyi@gmail.com">levkivskyi@gmail.com</a>> wrote:<br>
>> 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>
> I don't have any preferences for the name, __mro_entry__ sounds equally OK<br>
> to me.<br>
<br>
</span>I'd propose changing it then, as searching for "Python mro entry" is<br>
likely to get people to the right place faster than searching for<br>
"Python subclass base".<br>
<span class=""><br></span></blockquote><div><br></div><div>OK, will do.<br></div><div>Â </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""></span><span class="">> I propose to update<br>
> ``type.__new__`` to just give<br>
> a better error message explaining this.<br>
<br>
</span>+1 from me, since that avoids ever resolving the list of bases twice.<br>
<span class=""><br></span></blockquote><div><br></div><div>OK, I will update the reference implementation.<br></div><div>Â </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
> 3) Do we need to update types.new_class and types.prepare_class?<br>
> Here I am not sure. These functions are rather utility functions and are<br>
> designed to<br>
> mimic in Python what __build_class__ does in C. I think we might add<br>
> types._update_bases<br>
> that does the same as its C counterpart. Then we can update types.new_class<br>
> and types.prepare_class<br>
> like you proposed, this will preserve their current API while<br>
> types.new_class will match behaviour of __build_class__<br>
<br>
</span>Your suggestion for `types.__new__` gave me a different idea: what if<br>
`types.prepare_class` *also* just raised an error when given a<br>
non-class as a nominal base class?<br>
<br>
Then if we added `types.resolve_bases` as a public API, a full<br>
reimplementation of `types.new_class` would now look like:<br>
<br>
  resolved_bases = types.resolve_bases(bases)<br>
  mcl, ns, updated_kwds = types.prepare_class(name, resolved_bases, kwds)<br>
  exec_body(ns)<br>
  ns["__orig_bases__"] = bases<br>
  mcl(name, resolved_bases, ns, **updated_kwds)<br>
<br>
That way, `types.new_class` would transparently switch to the new<br>
behaviour, while clients of any other dynamic type creation API could<br>
do their own base class resolution, even if the type creation API they<br>
were using didn't implicitly support MRO entry resolution.<br>
<div class="HOEnZb"><div class="h5"><br></div></div></blockquote><div><br></div><div>Yes, makes sense. I no one is against adding new public ``types.resolve_bases``</div><div>then I will add this to the PEP.</div><div><br></div><div>--</div><div>Ivan</div><div><br></div><div><br></div></div></div></div>