Forum Archive

Deep copy issue

shaun-h

I'm not sure why but I have made a basic example or an issue I'm having with deep copy and a NSData object in another project. I'm pretty sure this has worked its been a while since I used it. Anyway here is my snippet

from objc_util import *
import copy

d = NSData.alloc().init()

b = copy.deepcopy(d)

Here is a copy of the trace back from the error

Traceback (most recent call last):
  File "/private/var/mobile/Containers/Shared/AppGroup/831181D5-300F-4A12-BF91-9737C689FE30/Pythonista3/Documents/test.py", line 6, in <module>
    b = copy.deepcopy(d)
  File "/var/containers/Bundle/Application/35ADEEB8-25F6-4382-BEAF-82545DF5D05E/Pythonista3.app/Frameworks/PythonistaKit3.framework/pylib/copy.py", line 183, in deepcopy
    y = _reconstruct(x, rv, 1, memo)
  File "/var/containers/Bundle/Application/35ADEEB8-25F6-4382-BEAF-82545DF5D05E/Pythonista3.app/Frameworks/PythonistaKit3.framework/pylib/copy.py", line 294, in _reconstruct
    y = callable(*args)
  File "/var/containers/Bundle/Application/35ADEEB8-25F6-4382-BEAF-82545DF5D05E/Pythonista3.app/Frameworks/PythonistaKit3.framework/pylib/copyreg.py", line 89, in __newobj__
    return cls.__new__(cls, *args)
TypeError: __new__() missing 1 required positional argument: 'ptr'
omz

ObjCInstance doesn't really support deepcopy, just use the ObjC copy() method instead (NSData implements the NSCopying protocol).

shaun-h

@omz thanks for that, I have changed my code to use the copy method of NSData. Is this something that has changed recently or would a deepcopy / copy have never worked with a ObjCInstance?

dgelessus

From the Python side, an ObjCInstance is only a simple object with a ptr attribute, which stores a ctypes.c_void_p pointing to the corresponding Objective-C object in memory. Since ObjCInstance does not implement custom __copy__ and __deepcopy__ methods, the default copy.copy or copy.deepcopy is used, which only creates a new ObjCInstance (and, in the case of deepcopy, also a new c_void_p with the same value as the old one). The underlying Objective-C object is the same for both the original and the copy, so the two objects are basically equivalent and nothing is really copied.

So the short answer is no, even if copy and deepcopy didn't raise any errors before, they didn't actually copy properly.

shaun-h

@dgelessus thanks for the explanation that makes sense.