django - Python 2 and 3 metaclass compatibility when kwargs are used -
i making metaclass customize __new__
method customize how new class created according provided values in kwargs
. makes more sense in example:
class foometa(type): def __new__(cls, name, bases, kwargs): # kwargs... # example: if 'foo' in kwargs: kwargs.update({ 'fooattr': 'foovalue' }) return super(foometa, cls).__new__(cls, name, bases, kwargs)
my problem how can make compatible both python 2 , 3. six great compatibility library not solve problem. use as:
class fooclass(six.with_metaclass(foometa, foobase)): pass
this not work because 6 creates new base class using given metaclass. below six's code (link) (as of 1.3):
def with_metaclass(meta, base=object): return meta("newbase", (base,), {})
as result, __new__
method called without kwargs
hence "breaking" function. question how can accomplish behavior want without breaking compatibility both python 2 , 3. please note don't need python 2.6 support if possible python 2.7.x , 3.x fine that.
background
i need work in django. want create model factory metaclass depending on model attributes customize how model created.
class modelmeta(modelbase): def __new__(cls, name, bases, kwargs): # depending on kwargs different model constructed # ... class foomodel(six.with_metaclass(modelmeta, models.model): # attrs here passed metaclass
if understand right, there no problem , works. did check whether metaclass has desired effect? because think does.
the class returned with_metaclass
not meant play role of class fooclass. dummy class used base class of class. since base class of metaclass foometa, derived class have metaclass foometa , metaclass called again appropriate arguments.
class foometa(type): def __new__(cls, name, bases, attrs): # kwargs... # example: if 'foo' in attrs: attrs['fooattr'] = 'foovalue' return super(foometa, cls).__new__(cls, name, bases, attrs) class foobase(object): pass class fooclass(with_metaclass(foometa, foobase)): foo = "yes" >>> fooclass.fooattr 'foovalue'
incidentally, confusing call third argument of metaclass kwargs
. isn't keyword arguments. __dict__
of class created --- is, class's attributes , values. in experience attribute conventionally called attrs
or perhaps dct
(see e.g., here , here).
Comments
Post a Comment