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

Reply via email to