On Nov 7, 11:03 pm, "[email protected]"
<[email protected]> wrote:
...
> These quick fixes aren't ideal as they rely on too much knowledge by the
> subclass, but they shed light on what's going on.  I'll leave a better fix
> as an exercise for the reader ... ;)

The exercise for the reader is that the problem is that the Proxy
class needed to have the same __class__ as the object it's wrapping.
The "obvious" way to do this though results in infinite mutual
recursion.

ie you can't do this:

def mydec(klass):
    class Proxy(object):
        __metaclass__ = AttributeProxying
        ...
    return Proxy

class AttributeProxying(type):
    def __new__(meta, name, bases, Dict):
        ... snip...
        return mydec(klass, name, bases, newdict)

class Proxied(object):
    __metaclass__ = AttributeProxying
    ...

class SafeStore(Proxied):
   pass

Since that results in mutual recursion and blows the stack.

What you can do though is this:

def mydec(klass, name, bases, newdict):
    def __init__(self, *args,**argd):
        ....
    def __getattribute__(self, key):
        ....
    # Build a dict for the proxy class containing __module__
    # (matching klass), __init__ and __getattribute__

    # We add in one attribute:
    proxy_dict["__norecurse__"] = True

    # Then make the Proxy class
    Proxy = klass.__class__(name +"_Proxy", bases, proxy_dict)
    return Proxy

class AttributeProxying(type):
    def __new__(meta, name, bases, Dict):
        ... snip...
        # We then modify things such that if we detect we're
        # being called by mydec we only return the klass
        if newdict.get("__norecurse__", False):
            return klass

        # Otherwise we call the class decorator, and return that
        return mydec(klass, name, bases, newdict)

class Proxied(object):
    __metaclass__ = AttributeProxying
    ...

class SafeStore(Proxied):
   pass

And then that does work as expected, with inheritance of the metaclass
re-enabled.

Pastebin of working minimal example:
    * http://pastebin.com/04RcPwPT

Pastebin of the output of that minimal working example:
    * http://pastebin.com/TXvGLES3

Thanks for the feedback earlier in the week, much appreciated :-)


Michael.

-- 
To post: [email protected]
To unsubscribe: [email protected]
Feeds: http://groups.google.com/group/python-north-west/feeds
More options: http://groups.google.com/group/python-north-west

Reply via email to