2010/11/13 Vitja Makarov <[email protected]>:
> 2010/11/13 Vitja Makarov <[email protected]>:
>> 2010/11/13 Stefan Behnel <[email protected]>:
>>> Stefan Behnel, 08.11.2010 15:51:
>>>> Hi,
>>>>
>>>> I looked through your code and pushed a slightly cleaned up version of your
>>>> latest patch.
>>>>
>>>> Vitja Makarov, 07.11.2010 12:39:
>>>>> 2010/11/7 Vitja Makarov:
>>>>>> 2010/11/7 Stefan Behnel:
>>>>>>> Vitja Makarov, 06.11.2010 21:37:
>>>>>>>> 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.
>>>>>>>
>>>>>>> Why do you think these new classes are necessary?
>>>>>>
>>>>>> I think this objects are required to represent metaclass and namespace.
>>>>>> If we want real support for __prepare__ (simple version is attached in 
>>>>>> trac)
>>>>>>
>>>>>> 1. extract metaclass from bases and keywordargs
>>>>>> 2. create namespace by calling metaclass __preapre__
>>>>>> 3. fill namespace with class body
>>>>>> 4. create class
>>>>>>
>>>>>> I don't want to reuse ClassDefNode as it differs too much. To many 
>>>>>> if/else.
>>>>>> So Py3ClassNode should hold metaclass and namespace objects, I add
>>>>>> Py3MetaclassNode and Py3NamespaceNode.
>>>>>>
>>>>>> Can I use PyTempNode for metaclass and namespace?
>>>>>>
>>>>>> Is there another way?
>>>>>
>>>>> Another way:
>>>>>
>>>>> if py3_metaclass:
>>>>>        mkw = keyword_args.copy()
>>>>>        mkw.update(starstar_args)
>>>>>        metaclass = py3_metaclass_get(bases, mkw)
>>>>>        dict = py3_namespace_prepare(metaclass, bases, name, mkw)
>>>>> else:
>>>>>        dict = dict()
>>>>>
>>>>> # construct class body here...
>>>>> dict['foo'] = 'bar'
>>>>>
>>>>> if py3_metaclass:
>>>>>       classobj = py3_metaclass_new(metaclass, name, bases, dict, mkw, 
>>>>> modname)
>>>>> else:
>>>>>       classobj = create_class(bases, dict, name, modname)
>>>>>
>>>>> 2 new object types here: metaclass, namespace.
>>>>
>>>> Yes, I think that's the way to go. The two new nodes should go into
>>>> ExprNodes, maybe named "PyClassMetaclassNode" and "PyClassNamespaceNode".
>>>> Both must have their "is_temp" set to True.
>>>>
>>>> The metaclass node will look up the metaclass in the type keywords and use
>>>> it as its node result value.
>>>>
>>>> The namespace node will be used by ExprNodes.ClassNode just like before but
>>>> should do the "prepare() or dict()" dance above. It obviously needs a
>>>> reference to the metaclass node to do that, in order to access its result
>>>> value.
>>>>
>>>> Using two new node classes here is the easiest way to do it as you only
>>>> need to pass around references to them. Otherwise, you'd have to manually
>>>> allocate temporary variables and pass around their names. That's not any
>>>> harder to do, but it's a lot more ugly.
>>>>
>>>> Note the disposal code call at the end of
>>>> PyClassDefNode.generate_execution_code(). You need to do that for both
>>>> nodes here, that will automatically take care to properly clean up the
>>>> Python references to their results (based on the value of their "is_temp"
>>>> attribute).
>>>
>>> Any news here? Anything I can help with?
>>>
>>> Stefan
>>> _______________________________________________
>>> Cython-dev mailing list
>>> [email protected]
>>> http://codespeak.net/mailman/listinfo/cython-dev
>>>
>>
>> No time this week, I'll try on weekend.
>> Think there will be three new nodes:
>>
>>  * PyClassKeywordArgsNode - will hold keyword args (keywords and
>> starstar), need this because dict should be used in __prepare__ and
>> class creation.
>>  * PyClassMetaclassNode
>>  * PyClassNamespaceNode
>>
>> Also new utility code will be added.
>> Btw that doesn't seems to be a big change ;)
>>
>
> I've added patch in trac.
>
> It introduces new nodes:
>
> Py3ClassNode
> KeywordArgsNode
> PyClassBasesNode
> PyClassMetaclassNode
> PyClassNamespaceNode
>

Here is test case that fails now, because of decorators implementation.
Bar attribute is assigned twice.

class ODict(dict):
    def __init__(self):
        dict.__init__(self)
        self._order = []
        dict.__setitem__(self, '_order', self._order)

    def __setitem__(self, key, value):
        dict.__setitem__(self, key, value)
        self._order.append(key)

class Base(type):
    @staticmethod
    def __prepare__(*args, **kwargs):
        return ODict()

class Foo(metaclass=Base):
    """
    >>> Foo._order
    ['__module__', '__doc__', 'bar']
    """
    @property
    def bar(self):
        return 0
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to