[Python-ideas] Simpler Customization of Class Creation - PEP 487

Martin Teichmann lkb.teichmann at gmail.com
Sat Feb 6 06:02:44 EST 2016


Hi Andrew, Hi List,

thanks for the quick review. You brought up very interesting points which should
be discussed here.

>> Most metaclasses, however, serve only some of the following three
>> purposes: a) run some code after a class is created b) initialize descriptors
>> of a class or c) keep the order in which class attributes have been defined.
>
> How is c) not served by just defining a __prepare__ method that returns an OrderedDict? That seems easier to use than a separate dict and __attribute_order__ tuple. You later mention that many people already do this, but don't explain what's wrong with it or why your idea is better. It's not like a one-line __prepare__ is difficult to write, or like OrderedDict is too slow (especially in 3.6), so you're just adding a cost (less convenient to use) for no benefit that I can see.

In my implementation this is exactly what I do: I create a OrderedDict
in __prepare__. The question
is just: how dow we get that information to the user? The __prepare__d
namespace only exists during
class creation, type.__new__ cripples it into a normal dict. (that is
done here: https://github.com/python/cpython/blob/master/Objects/typeobject.c#L2343)

An older version of the PEP introduced a namespace parameter to the
__init_subclass__ hook which
would still get the OrderedDict. This is a neat way of doing so, but I
did not want to exclude the option
that this metaclass once becomes the default metaclass. And then
suddenly OrderedDict turns from
just another standard library class into a type built into the
language. Maybe this is not a big deal, maybe
it is, what are other people thinking about that?

> It sounds like you're trying to have it both ways here: it seems like if your proposal really is better because it works with Python 2.7 rather than just 3.x, then your proposal being in the stdlib is probably a bad idea, because it will mislead rather than help people trying to write version-straddling code.

This is a very complicated issue. In order for my proposal to make any
sense, everyone has to use exactly
the same metaclass, not just a look-alike. I don't see another way to
do that than putting it into the standard
library, or directly into the Python language.

While Python 2 compatibility is not such a big deal anymore (this is
2016, and I figure 2015 really has been the
year of Python 3), the problem is that this proposal is targetting
authors of libraries, not just applications.
Libraries are, for a good reason, very reluctant to drop backwards
compatibility. So trying to convince them
to do something which is not backwards portable won't fly. My idea is
that libraries just use the PyPI
implementation of this PEP, which will use the standard library
implementation once it is existing.

But library developers are also very reluctant to add any additional
dependencies, my module is certainly
no exception. Instead they have the option to copy my library into
theirs. That means that they won't have
the benefit of compatibility with other libraries while the metaclass
is not in the standard library, but once
it is, they are automatically compatible with the rest of the world.
The best option for compatiblity probably
is that this metaclass is also added to compatibility libraries like
six, so that different libraries are at
least compatible if they use the same compatibility library (and are
automatically compatible with
everyone else once the metaclass is in the standard library).

Greetings

Martin


More information about the Python-ideas mailing list