copy.py 8.78 KB
Newer Older
1
"""Generic (shallow and deep) copying operations.
2

3 4
Interface summary:

Tim Peters's avatar
Tim Peters committed
5
        import copy
6

Tim Peters's avatar
Tim Peters committed
7 8
        x = copy.copy(y)        # make a shallow copy of y
        x = copy.deepcopy(y)    # make a deep copy of y
9

10
For module specific errors, copy.Error is raised.
11 12 13 14 15 16

The difference between shallow and deep copying is only relevant for
compound objects (objects that contain other objects, like lists or
class instances).

- A shallow copy constructs a new compound object and then (to the
17
  extent possible) inserts *the same objects* into it that the
18 19 20 21 22 23 24 25
  original contains.

- A deep copy constructs a new compound object and then, recursively,
  inserts *copies* into it of the objects found in the original.

Two problems often exist with deep copy operations that don't exist
with shallow copy operations:

26
 a) recursive objects (compound objects that, directly or indirectly,
27 28
    contain a reference to themselves) may cause a recursive loop

29
 b) because deep copy copies *everything* it may copy too much, e.g.
30 31 32 33 34
    administrative data structures that should be shared even between
    copies

Python's deep copy operation avoids these problems by:

35 36
 a) keeping a table of objects already copied during the current
    copying pass
37

38
 b) letting user-defined classes override the copying operation or the
39 40 41 42 43 44 45 46
    set of components copied

This version does not copy types like module, class, function, method,
nor stack trace, stack frame, nor file, socket, window, nor array, nor
any similar types.

Classes can use the same interfaces to control copying that they use
to control pickling: they can define methods called __getinitargs__(),
47
__getstate__() and __setstate__().  See the documentation for module
48 49
"pickle" for information on these methods.
"""
50 51

import types
52
import weakref
53
from copyreg import dispatch_table
54
import builtins
55

56
class Error(Exception):
Tim Peters's avatar
Tim Peters committed
57 58
    pass
error = Error   # backward compatibility
59

60 61 62 63 64
try:
    from org.python.core import PyStringMap
except ImportError:
    PyStringMap = None

65
__all__ = ["Error", "copy", "deepcopy"]
66

67
def copy(x):
Tim Peters's avatar
Tim Peters committed
68 69 70 71 72
    """Shallow copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

73 74 75 76 77 78
    cls = type(x)

    copier = _copy_dispatch.get(cls)
    if copier:
        return copier(x)

79 80 81 82 83 84 85 86
    try:
        issc = issubclass(cls, type)
    except TypeError: # cls is not a class
        issc = False
    if issc:
        # treat it as a regular class:
        return _copy_immutable(x)

87 88 89 90 91
    copier = getattr(cls, "__copy__", None)
    if copier:
        return copier(x)

    reductor = dispatch_table.get(cls)
92 93 94 95 96 97 98 99 100 101 102 103 104 105
    if reductor:
        rv = reductor(x)
    else:
        reductor = getattr(x, "__reduce_ex__", None)
        if reductor:
            rv = reductor(2)
        else:
            reductor = getattr(x, "__reduce__", None)
            if reductor:
                rv = reductor()
            else:
                raise Error("un(shallow)copyable object of type %s" % cls)

    return _reconstruct(x, rv, 0)
Tim Peters's avatar
Tim Peters committed
106

107

108 109
_copy_dispatch = d = {}

110
def _copy_immutable(x):
Tim Peters's avatar
Tim Peters committed
111
    return x
112
for t in (type(None), int, float, bool, str, tuple,
113
          bytes, frozenset, type, range,
Christian Heimes's avatar
Christian Heimes committed
114
          types.BuiltinFunctionType, type(Ellipsis),
115
          types.FunctionType, weakref.ref):
116
    d[t] = _copy_immutable
117 118 119 120
t = getattr(types, "CodeType", None)
if t is not None:
    d[t] = _copy_immutable
for name in ("complex", "unicode"):
121
    t = getattr(builtins, name, None)
122 123 124 125 126 127 128 129 130
    if t is not None:
        d[t] = _copy_immutable

def _copy_with_constructor(x):
    return type(x)(x)
for t in (list, dict, set):
    d[t] = _copy_with_constructor

def _copy_with_copy_method(x):
Tim Peters's avatar
Tim Peters committed
131
    return x.copy()
132
if PyStringMap is not None:
133
    d[PyStringMap] = _copy_with_copy_method
134 135 136

del d

137
def deepcopy(x, memo=None, _nil=[]):
Tim Peters's avatar
Tim Peters committed
138 139 140 141 142 143 144
    """Deep copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    if memo is None:
        memo = {}
145

Tim Peters's avatar
Tim Peters committed
146
    d = id(x)
147 148 149 150 151 152 153 154 155 156
    y = memo.get(d, _nil)
    if y is not _nil:
        return y

    cls = type(x)

    copier = _deepcopy_dispatch.get(cls)
    if copier:
        y = copier(x, memo)
    else:
Tim Peters's avatar
Tim Peters committed
157
        try:
158 159
            issc = issubclass(cls, type)
        except TypeError: # cls is not a class (old Boost; see SF #502085)
160 161
            issc = 0
        if issc:
162
            y = _deepcopy_atomic(x, memo)
163
        else:
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
            copier = getattr(x, "__deepcopy__", None)
            if copier:
                y = copier(memo)
            else:
                reductor = dispatch_table.get(cls)
                if reductor:
                    rv = reductor(x)
                else:
                    reductor = getattr(x, "__reduce_ex__", None)
                    if reductor:
                        rv = reductor(2)
                    else:
                        reductor = getattr(x, "__reduce__", None)
                        if reductor:
                            rv = reductor()
                        else:
                            raise Error(
                                "un(deep)copyable object of type %s" % cls)
                y = _reconstruct(x, rv, 1, memo)
183

184 185 186 187
    # If is its own copy, don't memoize.
    if y is not x:
        memo[d] = y
        _keep_alive(x, memo) # Make sure x lives at least as long as d
Tim Peters's avatar
Tim Peters committed
188
    return y
189 190 191 192

_deepcopy_dispatch = d = {}

def _deepcopy_atomic(x, memo):
Tim Peters's avatar
Tim Peters committed
193
    return x
194
d[type(None)] = _deepcopy_atomic
Christian Heimes's avatar
Christian Heimes committed
195
d[type(Ellipsis)] = _deepcopy_atomic
196 197 198
d[int] = _deepcopy_atomic
d[float] = _deepcopy_atomic
d[bool] = _deepcopy_atomic
199
try:
200
    d[complex] = _deepcopy_atomic
201
except NameError:
202
    pass
203
d[bytes] = _deepcopy_atomic
204
d[str] = _deepcopy_atomic
205 206 207 208
try:
    d[types.CodeType] = _deepcopy_atomic
except AttributeError:
    pass
209
d[type] = _deepcopy_atomic
210
d[range] = _deepcopy_atomic
211
d[types.BuiltinFunctionType] = _deepcopy_atomic
Guido van Rossum's avatar
Guido van Rossum committed
212
d[types.FunctionType] = _deepcopy_atomic
213
d[weakref.ref] = _deepcopy_atomic
214 215

def _deepcopy_list(x, memo):
Tim Peters's avatar
Tim Peters committed
216 217 218 219 220
    y = []
    memo[id(x)] = y
    for a in x:
        y.append(deepcopy(a, memo))
    return y
221
d[list] = _deepcopy_list
222 223

def _deepcopy_tuple(x, memo):
Tim Peters's avatar
Tim Peters committed
224 225 226
    y = []
    for a in x:
        y.append(deepcopy(a, memo))
227 228
    # We're not going to put the tuple in the memo, but it's still important we
    # check for it, in case the tuple contains recursive mutable structures.
Tim Peters's avatar
Tim Peters committed
229
    try:
230
        return memo[id(x)]
Tim Peters's avatar
Tim Peters committed
231 232 233 234 235 236 237 238 239
    except KeyError:
        pass
    for i in range(len(x)):
        if x[i] is not y[i]:
            y = tuple(y)
            break
    else:
        y = x
    return y
240
d[tuple] = _deepcopy_tuple
241 242

def _deepcopy_dict(x, memo):
Tim Peters's avatar
Tim Peters committed
243 244
    y = {}
    memo[id(x)] = y
245
    for key, value in x.items():
246
        y[deepcopy(key, memo)] = deepcopy(value, memo)
Tim Peters's avatar
Tim Peters committed
247
    return y
248
d[dict] = _deepcopy_dict
249 250
if PyStringMap is not None:
    d[PyStringMap] = _deepcopy_dict
251

252 253 254 255
def _deepcopy_method(x, memo): # Copy instance methods
    return type(x)(x.__func__, deepcopy(x.__self__, memo))
_deepcopy_dispatch[types.MethodType] = _deepcopy_method

256
def _keep_alive(x, memo):
Tim Peters's avatar
Tim Peters committed
257 258 259 260 261 262 263 264 265 266 267 268 269 270
    """Keeps a reference to the object x in the memo.

    Because we remember objects by their id, we have
    to assure that possibly temporary objects are kept
    alive by referencing them.
    We store a reference at the id of the memo, which should
    normally not be used unless someone tries to deepcopy
    the memo itself...
    """
    try:
        memo[id(memo)].append(x)
    except KeyError:
        # aha, this is the first one :-)
        memo[id(memo)]=[x]
271

272
def _reconstruct(x, info, deep, memo=None):
273 274 275
    if isinstance(info, str):
        return x
    assert isinstance(info, tuple)
276 277
    if memo is None:
        memo = {}
278
    n = len(info)
279
    assert n in (2, 3, 4, 5)
280 281 282 283 284
    callable, args = info[:2]
    if n > 2:
        state = info[2]
    else:
        state = {}
285 286 287 288 289 290 291 292
    if n > 3:
        listiter = info[3]
    else:
        listiter = None
    if n > 4:
        dictiter = info[4]
    else:
        dictiter = None
293
    if deep:
294
        args = deepcopy(args, memo)
295
    y = callable(*args)
296
    memo[id(x)] = y
297

298 299
    if state:
        if deep:
300
            state = deepcopy(state, memo)
301 302 303
        if hasattr(y, '__setstate__'):
            y.__setstate__(state)
        else:
304 305 306 307 308 309 310
            if isinstance(state, tuple) and len(state) == 2:
                state, slotstate = state
            else:
                slotstate = None
            if state is not None:
                y.__dict__.update(state)
            if slotstate is not None:
311
                for key, value in slotstate.items():
312
                    setattr(y, key, value)
313 314 315 316 317 318 319 320 321 322 323 324

    if listiter is not None:
        for item in listiter:
            if deep:
                item = deepcopy(item, memo)
            y.append(item)
    if dictiter is not None:
        for key, value in dictiter:
            if deep:
                key = deepcopy(key, memo)
                value = deepcopy(value, memo)
            y[key] = value
325 326
    return y

327 328 329 330
del d

del types

331 332 333
# Helper for instance creation without calling __init__
class _EmptyClass:
    pass