[Python-Dev] PEP 560: bases classes / confusion

Ivan Levkivskyi levkivskyi at gmail.com
Thu Nov 16 17:57:06 EST 2017


On 16 November 2017 at 18:58, Ethan Furman <ethan at stoneleaf.us> wrote:

> On 11/16/2017 04:22 AM, Ivan Levkivskyi wrote:
>
>> On 16 November 2017 at 07:56, Nick Coghlan wrote:
>>
>
> Jim also raised an important point that needs clarification at the spec
>>>
>> >> level: given multiple entries in "orig_bases" with __mro_entries__
> methods,
> >> do all such methods get passed the *same* orig_bases tuple? Or do they
>
>> receive partially resolved ones, such that bases listed before them have
>>>
>> >> already been resolved to their MRO entries by the time they run.
>
>>
>> Yes, they all get the same initial bases tuple as an argument. Passing
>>
> > updated ones will cost a bit more and I don't think it will be needed
> > (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):
        pass

    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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20171116/5df896b7/attachment.html>


More information about the Python-Dev mailing list