I can call prepare and then update dict?

2010/11/4 Vitja Makarov <[email protected]>:
> Here is my first try with metaclasses in py3. It does not handle
> __prepare__ I don't understand what function should I call to create
> cell... and what is that func
>
> 2010/11/4 Stefan Behnel <[email protected]>:
>> Vitja Makarov, 03.11.2010 23:03:
>>> 2010/11/4 Stefan Behnel:
>>>> Vitja Makarov, 03.11.2010 22:13:
>>>>> Now it seems to me that class declaration is more like function call
>>>>> with special case for metaclass keyword and positional arguments:
>>>>>
>>>>> class Base(type):
>>>>>       def __new__(cls, name, bases, attrs, **kwargs):
>>>>>           print(cls, name, bases, attrs, kwargs)
>>>>>
>>>>> class Foo(1, 2, 3, metaclass=Base, foo='bar'):
>>>>>       def hello(self):
>>>>>           pass
>>>>
>>>> Yes, I think that's exactly how this should work. Want to give it another 
>>>> try?
>>>
>>> Yes, I want to finish this part ;)
>>
>> Great! :)
>>
>> BTW, thanks for doing all this. Even your first patch was pretty good for a
>> "first patch".
>>
>>
>>>> It seems that the number of positional arguments is fixed, but you can pass
>>>> any number of keyword arguments, out of which only "metaclass" is special
>>>> cased and removed (from a copy of the dict, BTW). There is also an
>>>> additional protocol if the metaclass has a "__prepare__" class method. See
>>>> "__build_class__".
>>>
>>> Yes, all positional arguments are turned into bases. So we can make it this 
>>> way:
>>>
>>> Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
>>> PyObject *modname, PyObject *kwargs);
>>>
>>> And then
>>>
>>> args = (metaclass, bases, name, dict)
>>> PyEval_CallObjectWithKeywords(metaclass, args, kwargs)
>>
>> Except for the first 'metaclass' in args (args has length 3). Again, see
>> the __build_class__ implementation.
>>
>>
>>>> I think the Python 2 protocol in Cython should work as in Py3. Metaclasses
>>>> in Py2 won't generally support kwargs, but if a user explicitly provides
>>>> them, it's best to assume that that's intentional. In the worst case, there
>>>> will be a runtime TypeError.
>>>
>>> Do you mean that new syntax should be used for Py2?
>>
>> No, just what happens behind the syntax. A __metaclass__ field can easily
>> be mapped to a metaclass keyword argument (or the equivalent representation
>> on a PyClassDefNode in Cython) and from that point on, it's the same thing
>> in both cases.
>>
>>
>>>> So, kwargs should pass through, except for __metaclass__. If both the
>>>> __metaclass__ class field and the metaclass kwarg are passed, I'd lean
>>>> towards ignoring the field and prefer the kwarg, just like Py3 does. It can
>>>> be argued that this is worth a warning, though.
>>>>
>>> Py3 doesn't support __metaclass__ attribute, so if metaclass is set that
>>> seems to be mostly Py3 so __metaclass__ should be ignored.
>>
>> If I'm not mistaken, the __metaclass__ field can always be handled by the
>> compiler during type analysis (or maybe in a transform, see the classes in
>> ParseTreeTransforms.py, for example). You can't dynamically add an
>> attribute to a class at definition time without letting the parser see its
>> name. So you just have to check the class body and you'll know if the field
>> is there or not.
>>
>> Cython also has a Python 3 syntax mode (look out for "language_level") in
>> which we can disable this field lookup, so that you get semantic
>> equivalence with Python 3 even before the code generation phase. So we
>> don't need any runtime support for the __metaclass__ field, not even in Py2.
>>
>>
>>>> I also think that the parser should extract the metaclass keyword, not the
>>>> runtime code. So, if provided, it should be passed into __Pyx_CreateClass()
>>>> as an argument and not in the kwargs.
>>>
>>> I think parser can't extract metaclass keyword, try this code:
>>>
>>> class Base(type):
>>>      def __new__(cls, name, bases, attrs, **kwargs):
>>>          print(cls, name, bases, attrs, kwargs)
>>>
>>> myargs={'metaclass': Base}
>>> class Foo(1, 2, 3, **myargs):
>>>      def hello(self):
>>>          pass
>>
>> Well, it can if it's passed explicitly, though.
>>
>> We already need to support an explicit metaclass to handle the
>> __metaclass__ field. In most cases, the keyword argument will be spelled
>> out explicitly, so we can reduce the runtime overhead in that case. But
>> that sounds like an optimisation, not a required feature.
>>
>> Stefan
>> _______________________________________________
>> Cython-dev mailing list
>> [email protected]
>> http://codespeak.net/mailman/listinfo/cython-dev
>>
>
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to