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/

Reply via email to