Skip to content Skip to sidebar Skip to footer

Who Calls The Metaclass

This actually stems from a discussion here on SO. Short version def meta(name, bases, class_dict) return type(name, bases, class_dict) class Klass(object): __metaclass__ =

Solution 1:

You can find the answer relatively easily. First, lets find the opcode for building a class.

>>> deff():
    classA(object):
        __metaclass__ = type>>> import dis
>>> dis.dis(f)
  20 LOAD_CONST               1 ('A')
              3 LOAD_GLOBAL              0 (object)
              6 BUILD_TUPLE              19 LOAD_CONST               2 (<code object A at 0000000001EBDA30, file "<pyshell#3>", line 2>)
             12 MAKE_FUNCTION            015 CALL_FUNCTION            018 BUILD_CLASS         
             19 STORE_FAST               0 (A)
             22 LOAD_CONST               0 (None)
             25 RETURN_VALUE    

So the opcode is BUILD_CLASS. Now let's search the source for that term (easily done on the github mirror).

You get a couple of results, but the most interesting of which is Python/ceval.c which declares the function static PyObject * build_class(PyObject *, PyObject *, PyObject *); and has a case statement for BUILD_CLASS. Search through the file and you can find the function definition of build_class starting at line 4430. And on line 4456 we find the bit of code you are looking for:

result= PyObject_CallFunctionObjArgs(metaclass, name, bases, methods,
                      NULL);

So the answer is the metaclass is resolved and called by the function that is responsible for executing the BUILD_CLASS opcode.

Solution 2:

In Python 3, the metaclass is called in the code for the __build_class__ builtin function (which is called to handle class statements). This function is new in Python 3, and the equivalent C function build_class in Python 2 is not publicly exposed at the Python level. You can however find the source in python/ceval.c

Anyway, here's the relevant call to the metaclass object in the Python 3 __build_class__ implementation:

cls = PyEval_CallObjectWithKeywords(meta, margs, mkw);

The variable meta is the metaclass (either type or another metaclass found from an argument or from the type of a base class). margs is a tuple with the positional arguments (name, bases, dct) and mkw is a dictionary with the keyword arguments to the metaclass (a Python 3 only thing).

The Python 2 code does something similar:

result= PyObject_CallFunctionObjArgs(metaclass, name, bases, methods,
                                      NULL);

Solution 3:

Meta classes are "instantiated" by interpreter when class definition is executed.

Post a Comment for "Who Calls The Metaclass"