Josh Rosenberg <shadowranger+pyt...@gmail.com> added the comment:

Ah, you're right on __call__; I've never bothered to override it on a 
metaclass, but yes, since a class using a metaclass is an instance of the 
metaclass, like all instances, calling it invokes the __call__ of its type 
(it's just that the default metaclass, type, has a __call__ that turns around 
and calls the __new__ and __init__ of the "instance", which is a class). The 
nomenclature is hard here.

In any event, yes, overriding __call__ will let you hook into the construction 
of each individual instance of the classes using the metaclass. That's not 
generally true of all uses of metaclasses (if __call__ is inherited from type, 
then while new instances are technically created using the metaclass, the 
metaclass is just letting the normal __new__/__init__ calls take place without 
interference).

There is very little in the way of Python official documentation on 
metaclasses; the line you proposed to change is one of the few places it's 
mentioned (most references to metaclasses are on that Data Model page). There 
are a couple of mentions in the PEPs, and a lot of off-site tutorials, but it's 
a poorly documented feature in general.

It's pretty easy to demonstrate the current wording is correct though:

>>> class Meta(type):
...     pass
...
>>> class MyMeta(metaclass=Meta):
...     pass
...
>>> isinstance(MyMeta, Meta)
True

Note that we're using isinstance, not issubclass, and we're not constructing a 
MyMeta instance. MyMeta itself is an instance of Meta.

I really think the problem here is that the documentation is correct, but so 
bare it's easy to miss the implications of "MyClass and MySubclass are 
instances of Meta"; since the classes are instances of another class, the 
metaclass has the same power over them that normal classes have over their 
instances. That's why __call__ can hook the creation of instances, __new__ can 
hook the creation of the class itself, __getitem__ can be used to perform 
lookups on the child class (in at least of the few iterations of the typing 
framework, that's how List[int] and the like worked; not sure if it's still 
that way), and properties defined on the metaclass can be accessed on classes 
that use it, but not their instances. It's enormously powerful, but so complex 
that the Python docs tend to encourage simpler, more targeted ways of tweaking 
classes (e.g. decorators).

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue36947>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to