2010/11/4 Vitja Makarov <[email protected]>: > 2010/11/4 Stefan Behnel <[email protected]>: >> Stefan Behnel, 04.11.2010 14:17: >>> BTW, I'll ask on python-dev about the way __build_class__ works here. >> >> ;) writing e-mails about a problem without sending them away is the best >> way to understand the topic. >> >> Ok, so, __build_class__ is actually ok, because it *is* the point where the >> class body is evaluated. So, __prepare__ is really called before the >> evaluation of the body (which is done in a "function" call near the end) >> and the metaclass is called afterwards. >> >> We could essentially do the same thing in Cython. At the point where the >> class dict is now getting instantiated, we need to put the code of the >> first part of __build_class__, i.e. look up the metaclass from the keywords >> and find and call its __prepare__ method. Then, evaluate the class body >> into the class namespace object that __prepare__ returned, followed by the >> call to __Pyx_CreateClass(). >> >> If we don't find a metaclass in the keywords, we do not support __prepare__ >> but try to look up the __metaclass__ field in the class namespace during >> __Pyx_CreateClass(). >> >> Stefan >> >> _______________________________________________ >> Cython-dev mailing list >> [email protected] >> http://codespeak.net/mailman/listinfo/cython-dev >> > > I have attached patch (in trac) for python3 metaclass support, > __prepare__ now works this way: > > if metaclass is defined py3 way and it has __prepare__, namespace is > merged into dict. > This is wrong but it's much easy to implement, right behavior could be > imlemented later. > > This could be done this way: > > 1. PyClassDefNode detect that class definition is py3 style and has > metaclass keyword defined, it sets some flag > 2. then code generation should work this way: > > name = <class name> > bases = <tuple of bases> > metaclass = <metaclass> > mkw = <metaclass keywords dict> > > if hasattr(metaclass, '__prepare__'): > dict = __Pyx_PrepareClass(metaclass, bases, name, mkw) > else: > dict = {} > # now fill dict with attributes > > margs = tuple(name, bases, dict) > klass = PyEval_CallObjectWithKeywords(metaclass, margs, mkw) > > > This is interesting to implement, I'll try... >
I'm now trying to implement this: Is it correct: If parser detect use of kwargs in class definition it creates Py3ClassDefNode I add this classes: Nodes.Py3ClassDefNode - ClassDefNode replacement for python3 style classes ExprNodes.Py3ClassNode - ClassNode replacement for python3 style classes ExprNdoes.Py3MetaclassNode - contains metaclass Holds value returned by __Pyx_Py3MetaclassGet(bases, mkw) ExprNodes.Py3NamespaceNode - contains namespace object Value returned by __Pyx_Py3MetaclassPrepare(metaclass, base, name, mkw), that calls __prepare__ if any. _______________________________________________ Cython-dev mailing list [email protected] http://codespeak.net/mailman/listinfo/cython-dev
