I wanted to double check my assumption, that the content of a weakref.proxy is not deepcopied when performing a deepcopy of it. To that end, I wrote the following code snippet:
import copy
import weakref
class A:
def __init__(self, val=3):
self.val = val
def identify(self):
return id(self)
a = A()
proxy = weakref.proxy(a)
proxy.val = 4
proxy_deepcopy = copy.deepcopy(proxy)
proxy_deepcopy.val = 5
print(a.val, a.identify()) # 4 139732708115984
print(proxy.val, proxy.identify()) # 4 139732708115984
print(proxy_deepcopy.val, proxy_deepcopy.identify()) # 5 139732690146640
However my assumption seems to be incorrect; a deepcopy of a is performed when deepcopying the proxy. Am I misinterpreting the results of the tests or do I have a misconception of how the weakref.proxy is supposed to work? Shouldn't the copied instance of A be immediately be GCed?
I checked on the internet and found that the expected behavior occurs when using weakref.ref instead of the weakref.proxy (which I thought was mainly semantic sugar).
Because of this line in the CPython copy module that I found reading up on this stack overflow answer on weakref.ref utilizing weakref.ref yields the results I would have expected:
proxy = weakref.ref(a)
proxy().val = 4
proxy_deepcopy = copy.deepcopy(proxy)
proxy_deepcopy().val = 5
print(a.val, a.identify()) # 5 140323837493200
print(proxy().val, proxy().identify()) # 5 140323837493200
print(proxy_deepcopy().val, proxy_deepcopy().identify()) # 5 140323837493200
Is this discrepancy between weakref.proxy and weakref.ref intended?
Who is the owner of the deepcopied instance of A, that is still accessible through the proxy_deepcopy?
Executed with CPython 3.8.18 and 3.10.13.