GrahamDumpleton / wrapt

A Python module for decorators, wrappers and monkey patching.
BSD 2-Clause "Simplified" License
2.04k stars 230 forks source link

ObjectProxy and `self` when overwriting methods #213

Closed blankjul closed 1 year ago

blankjul commented 2 years ago

Thank you for this great framework! I am trying to use the ObjectProxy to overwrite a method of an object. It works perfectly if the method is called from the outside. However, calling it through self does still cause the old method to be called.

Please see the following Minimum Working Example (MWO) below:

class MyObject:

    def value(self):
        return "from MyObject"

    def get(self):
        return self.value()

class MyProxy(wrapt.ObjectProxy):

    def value(self):
        return "from MyProxy"

obj = MyProxy(MyObject())

print("public", obj.value())     # this will print from MyProxy
print("self", obj.get()) # this will print from MyObject

I was wondering if this behavior is desired? I was expecting since the value function should be overwritten that both result in from MyProxy. Any ideas on how to change this behavior of the proxy?

Thank you in advance!

GrahamDumpleton commented 2 years ago

Yes that is how it works. It is not inheritance, it is wrapping the inner object, so the inner object knows nothing about what it is wrapped by.

Sounds like you want normal class inheritance.

blankjul commented 2 years ago

Thank you for your quick answer. I want something close to class inheritance but based on an object. Let us say I have an instance p of a class P. Then, I would like to wrap the object, let us say with class Q by doing Q(p) where I would like to overwrite only a few methods and potentially implement some new ones.

Any recommendation on how to achieve that? (originally I thought the ObjectProxy will do exactly that for me).

GrahamDumpleton commented 2 years ago

You shouldn't be using an object wrapper then. You should be monkey patching the original object instance.

Watch:

GrahamDumpleton commented 1 year ago

Did you come up with a solution for this?

blankjul commented 1 year ago

I found an entirely different solution. The issue can be closed.