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
