[Python-ideas] A way out of Meta-hell (was: A (meta)class algebra)

Martin Teichmann lkb.teichmann at gmail.com
Sat Feb 14 16:16:26 CET 2015


Hi Petr, Hi all,

>> Well said, and yes, it needs ironing out. I just realized it doesn't work
>> since I'm calling __init_class__ before its __class__ is set. But this
>> is a solvable problem: Let's rewrite PEP 422 so that the initialization
>> is done on subclasses, not the class itself. This is actually a very
>> important usecase anyways, and if you need your method to be
>> called on yourself, just call it after the class definition! One line of
>> code should not be such a big deal.
>
> -1, that would be quite surprising behavior.

Honestly, the opposite would be (actually was to me) surprising
behavior. One standard usage for PEP 422 are registry classes
that register their subclasses. From my experience I can tell you
it's just annoying having to assure not to register the registry class
itself...

It also makes a lot of sense: what should __init_class__ do?
Initializing the class? But that's what the class body is already
doing! The point is that we want to initialize the subclasses of a
class, why should we initialize the class?

>> I also simplified the code, requiring now that decorates __init_subclass__
>> with @classmethod.
>
> You're writing library code. A bit more complexity here i worth it.
> See again the Rejected Design Options in the PEP.

I'm fine with or without explicit classmethod, I can put it back in
if people prefer it. I had just realized that at least the test code
for the currently proposed C implementation still uses classmethod.

> I think it's time you put this in a repository; e-mailing successive
> versions is inefficient.

Done. It's at https://github.com/tecki/metaclasses

> Also, run the tests on it -- that might uncover more problems.

Done. For sure I had to modify the tests so that my
approach that subclasses get initialized is tested - which makes
the tests ugly, but they run.

I also took out the part where other metaclasses may block
__init_class__, that doesn't really make sense in an approach
like mine, it's much more easy to simply circumvent my metaclass.

If it is really desired it should be no problem to put it in as well.

Greetings

Martin


More information about the Python-ideas mailing list