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 -- https://mail.python.org/mailman/listinfo/python-list