After monkey patching an instance method (using types.MethodType) I pass the monkey patched object to a library which copies it (using copy.copy) and calls the monkey patched method. The monkey patched method gets called successfully but the self parameter references to the old (not copied object).
import copy
import types
class Person:
def __init__(self, lang):
self.lang = lang
def hello(self, n):
print(id(self), f"{n} times hello in {self.lang}")
def mean_hello(self, n):
print(id(self), f"{n} times mean hello in {self.lang}")
a = Person('English')
b = copy.copy(a)
b.lang = "French"
print(id(a), id(b)) # 139885310130440 139885310130720
a.hello(1) # 139885310130440 1 times hello in English
b.hello(1) # 139885310130720 1 times hello in French
a.hello = types.MethodType(mean_hello, a)
c = copy.copy(a)
c.lang = 'German'
print(id(a), id(c)) # 139885310130440 139885310130664
a.hello(2) # 139885310130440 2 times mean hello in English
c.hello(2) # 139885310130440 2 times mean hello in English
From the example it can be seen that the last line c.hello(2) calls the monkey patched method with self referencing to a. Why does this happen? Is there a way to avoid this?