Are there objects for which it is impossible to create a deep copy?
Asked Answered
B

3

7

I get an error message when I execute the following line:

img = copy.deepcopy(img_file_obj)

The img_file_obj has the following type:

<class 'werkzeug.datastructures.FileStorage'>

Is it not allowed to create a deep copy of a file storage object?

ADDED

I probably need to explain why I am trying to create a copy of a file-storage object. In the end of my code I execute:

img_obj.save(fname)

But before that I check how big the file is. I do it in the following way:

img_obj.seek(0, os.SEEK_END)
size = img.tell()

The problem is that the checking of the size "destroys" the file. If I check the file size and then save it, I get an empty file on the disk. It is why I wanted to create a copy of the file-object, check the size of the copy and, if the size is acceptable, save the original file-object on the disk.

Barret answered 6/9, 2014 at 4:59 Comment(2)
Is this a duplicate of Python: deepcopy does not work on user-defined classes??Shermy
It's not a duplicate, because there are different reasons for FileStorage not being deepcopy-able and for that question's deepcopy working but not doing as the OP expected.Barghest
B
5

Are there objects for which it is impossible to create a deep copy?

Yes.

Any object whose type overrides the standard __deepcopy__ with (or registers with copyreg) a function that raises an exception can't be deep-copied.

Any object whose type uses the standard __deepcopy__ but can't be (shallow-)copied cannot be deep-copied.

Any object with sub-elements (whether selected by the standard __deepcopy__ or its own implementation) that cannot be deep-copied cannot be deep-copied.

And there are many kinds of objects that can't be even shallow-copied. The documentation for the copy module gives some examples:

This module does not copy types like module, method, stack trace, stack frame, file, socket, window, array, or any similar types.

Not that it would be impossible to copy a file, but what it would mean is pretty ambiguous (should it dup the file handle, reopen the file, or share the handle? should it start with the same file pointer? does its buffer or stateful encoder have to be in the same state?), so it would be more misleading than helpful to make them copyable.

Of course the Werkzeug framework could have chosen to make its FileStorage objects copyable even though standard Python file objects aren't, but they presumably had the same reasons not to.

Barghest answered 6/9, 2014 at 5:8 Comment(0)
D
2

It's certainly possible to create a type that can't be deepcopied. The documentation says:

In order for a class to define its own copy implementation, it can define special methods __copy__() and __deepcopy__().

So a class can make itself undeepcopyable by raising an exception there.

Conceptually, something like a file is just the type of thing that is unlikely to be deepcopyable. Making a deep copy of something like a file would presumably involve copying the actual file on disk. If the file is large, that could be expensive; it might not be possible if the user doesn't have the right permissions, or if the disk is full, etc.. There are a whole host of possible problems that could arise when trying to copy some resource that isn't confined to the program itself. Because of that, objects that reference external resources may not be deep copyable; if you really want to deepcopy them, you'd have to manually copy the external resource and create a new object.

Dollar answered 6/9, 2014 at 5:7 Comment(0)
K
1

From the copy module's documentation:

This module does not copy types like module, method, stack trace, stack frame, file, socket, window, array, or any similar types.

Since werkzeug.datastructures.FileStorage is "a thin wrapper over incoming files", I'd say it counts as a "similar type" to a file per the text quoted above.

Kaufman answered 6/9, 2014 at 5:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.