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

Popular posts from this blog

SPSS keyboard combination alters encoding -

Add new record to the table by click on the button in Microsoft Access -

CSS3 Transition to highlight new elements created in JQuery -