(original) (raw)
On 16 November 2017 at 18:58, Ethan Furman <ethan@stoneleaf.us> wrote:
On 11/16/2017 04:22 AM, Ivan Levkivskyi wrote:
On 16 November 2017 at 07:56, Nick Coghlan wrote:
\>> level: given multiple entries in "orig\_bases" with \_\_mro\_entries\_\_ methods,Jim also raised an important point that needs clarification at the spec
\>> do all such methods get passed the \*same\* orig\_bases tuple? Or do they
\>> already been resolved to their MRO entries by the time they run.receive partially resolved ones, such that bases listed before them have
\> updated ones will cost a bit more and I don't think it will be needed
Yes, they all get the same initial bases tuple as an argument. Passing
\> (in the worst case a base can resolve another base by calling its
\> \_\_mro\_entries\_\_ manually). I will clarify this in the PEP.
If the extra complexity is to:
\> - given orig\_bases, a method could avoid injecting bases already listed
\> if it wanted to
\> - allowing multiple items to be returned provides a way to programmatically
\> combine mixins without having to define a new subclass for each combination
And each method is passed the same original tuple (without other methods' updates) then don't we end up in a situation where we can have duplicates base classes?
Not that it is impossible now (in certain sense):
class MultiMeta(type):
def \_\_new\_\_(mcls, name, bases, ns):
return super().\_\_new\_\_(mcls, name, (), ns)
class MultiBase(metaclass=MultiMeta):
def \_\_new\_\_(mcls, name, bases, ns):
return super().\_\_new\_\_(mcls, name, (), ns)
class MultiBase(metaclass=MultiMeta):
pass
class C(MultiBase, list, list, MultiBase, dict, dict, dict): # OK
class C(MultiBase, list, list, MultiBase, dict, dict, dict): # OK
pass
What is probably confusing in the current PEP text, is that it doesn't say clearly that
the substitution happens before any other steps in \_\_build\_class\_\_.
Therefore all normal checks (like duplicate bases and MRO consistency) happen and e.g.
class C(List\[int\], List\[str\]):
pass
will fail with:
TypeError: duplicate base class list
(by the way while playing with this I have found a bug in the reference implementation)
--
Ivan