Question on metaclasses

Diez B. Roggisch deetsNOSPAM at web.de
Sun Apr 24 11:32:19 EDT 2005


Reinhold Birkenfeld wrote:

> Diez B. Roggisch wrote:
>>> class Foo(type):
>>>     def __new__(cls, name, bases, dict):
>>> 
>>>         for k,v in [(k, v) for k,v in dict.items() if callable(v)]:
>>>             cls.wrap(k,v,cls.get_directives(v), dict)
>>> 
>>>         return super(Foo, self).__new__(self, name, bases, dict)
>> 
>> There is a confusion of self and cls above - rename self with cls.
> 
> And remove the first argument to __new__.

Ehm, no, I don't think so. The code was copied and pasted from a working
metaclass (at least I hope so...), and in the original code a underscore
was used for the first argument. I've been following that bad habit for a
while but recently started to be more following to the established
conventions. So I rewrote that code on the fly. 

This is the full metaclass:

class TransactionAware(type):
    TAS_REX = re.compile("tas::([^, ]+(, *[^, ]+)*)")


    WRAPPERS = {
        "create" : w_create,
        "active" : w_active,
        "bind" : w_bind,
        "sync" : w_sync,
        "autocommit" : w_autocommit,
        }
    def __new__(_, name, bases, dict):

        for k,v in [(k, v) for k,v in dict.items() if callable(v)]:
            _.wrap(k,v,_.get_directives(v), dict)

        return super(TransactionAware, _).__new__(_, name, bases, dict)

    def wrap(_, name, fun, ds, dict, level=0):
        if ds:
            d, rest = ds[0], ds[1:]
            key = "_taw_%s_%i" % (name, level)
            try:
                w_fun = _.WRAPPERS[d](key)
                dict[key] = fun
                _.wrap(name, w_fun, rest, dict, level+1)
            except KeyError, e:
                print "No transaction aware property named %s" % d
                raise e
        else:

            dict[name] = fun

    wrap = classmethod(wrap)

    def get_directives(_, v):
        try:
            doc = v.__doc__
            res = []
            if doc:
                for l in doc.split("\n"):
                    m = _.TAS_REX.match(l.strip())
                    if m:
                        res += [s.strip() for s in m.group(1 ).split(",")]
            res.reverse()
            return res
        except KeyError:
            return []
    get_directives = classmethod(get_directives)



-- 
Regards,

Diez B. Roggisch



More information about the Python-list mailing list