Class construction

Marcin Szamotulski mszamot at gmail.com
Mon Oct 21 18:57:41 EDT 2013


You can inspect the process in this way:

>>> c = 'class A: pass'
>>> code = compile(c, '<stdin>', 'exec')
>>> from dis import dis
>>> dis(code)
1           0 LOAD_BUILD_CLASS     
            1 LOAD_CONST               0 (<code object A at 0x7effeef1c300, file "<stdin>", line 1>) 
            4 LOAD_CONST               1 ('A') 
            7 MAKE_FUNCTION            0 
           10 LOAD_CONST               1 ('A') 
           13 CALL_FUNCTION            2 (2 positional, 0 keyword pair) 
           16 STORE_NAME               0 (A) 
           19 LOAD_CONST               2 (None) 
           22 RETURN_VALUE

(this is in Python3.3, in Python2.7 the result will be different)

Now you can check ceval.c (PyEval_EvalFrameEx function) what are the
above opcode's doing.  For example LOAD_BUILD_CLASS pushes the buildin
function builtins.__build_class__ to the stack and then CALL_FUNCTION
calls it.  the c implementation of __build_class__ is in
Python/bltinmodule.c (builtin___build_class__).  Indeed this function
will call the metaclass->tb_new `method` (but before it will also call
the __prepare__ method on metaclass to get the namespace).  The first
argument on builtin__build_class__ is a function object which correspond
to the class body, and it is evaluated in the class namespace.

So the process (with some simplifications) goes like this:

    1. get metaclass: meta
    2. call meta.__prepare__ to get namespace (class __dict__)
    3. evaluate the class body in the namespace
    4. call meta with arguemnts: name, bases, namespace
	(when you instantiate any class in Python, metaclass is just
	a class, first its __new__ method is called, and then its __init__) 

All this is in builtin__build_class__.

I hope it helps,
Regards,
Marcin

On 08:08 Mon 21 Oct     , Demian Brecht wrote:
> Hi all,
> 
> I'm trying to wrap my head around how classes are constructed at the
> interpreter level (as a side effect of digging into metaclasses) and
> I'm hoping to have my investigation either validated or ridiculed ;)
> 
> The pipeline that I've figured through some gdb debugging (starting at
> type_call):
> 
> + type_call
>   + is there a metaclass for this object?
>     + return metaclass->tp_new
>   + roughly 350 LOC constructing the type
>   + is object is not a subclass of type?
>      + return object
>    + call obj->tp_init
> 
> Does that sound correct? My C/gdb skills are horribly rusty at this
> point so expert insight would help :)
> 
> Thanks,
> 
> -- 
> 
> Demian Brecht
> http://demianbrecht.github.com
> -- 
> https://mail.python.org/mailman/listinfo/python-list



More information about the Python-list mailing list