[Python-Dev] copy() and deepcopy()

Guido van Rossum guido at python.org
Sat Nov 22 17:48:22 EST 2003

> I would like to confirm my understanding of copying and its
> implications.
> A shallow copy builds only a new outer shell and leaves the inner
> references unchanged.  If the outer object is immutable, then a copy
> might as well be the original object. So, in the copy module, the copy
> function for tuples should just return the original object (the function
> looks like it does more but actually does return itself). And, since a
> frozenset is immutable, its copy function should also just return self.

Right.  (I have no idea why _copy_tuple(x) doesn't return x; it feels
like superstition or copy-paste from _copy_list().)

> The point of a deepcopy is to replace each sub-component (at every
> nesting level) that could possibly change.  Since sets can only contain
> hashable objects which in turn can only contain hashable objects, I
> surmise that a shallowcopy of a set would also suffice as its deepcopy.

No.  Look at what _deepcopy_tuple() does.  There could be an object
that implements __hash__ but has some instance variable that could be
mutated but isn't part of the hash.

> IOW:
>    For frozensets,  shallowcopy == deepcopy == self
>    For sets, shallowcopy == deepcopy == set(list(self))  # done with
> PyDict_Copy()


For frozensets, shallow copy should return self; for sets, shallow
copy should return set(self).

In both cases, deepcopy() should do something like _deepcopy_list()
and _deepcopy_tuple(), respectively.  That is, deepcopying a set is
pretty straightforward, but must store self in the memo first, so that
(circular!) references to self are correctly deepcopied.  Deepcopying
a frozenset will be a little harder, because there can still be
circular references!  _deepcopy_tuple() shows how to do it.

--Guido van Rossum (home page: http://www.python.org/~guido/)

More information about the Python-Dev mailing list