Ticket #11753: 11753.diff
File 11753.diff, 24.0 KB (added by , 15 years ago) |
---|
-
django/contrib/admin/widgets.py
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index fb5acb5..f0ecb38 100644
a b 2 2 Form Widget classes specific to the Django admin site. 3 3 """ 4 4 5 import copy5 import django.utils.copycompat as copy 6 6 7 7 from django import forms 8 8 from django.forms.widgets import RadioFieldRenderer -
django/contrib/gis/geos/tests/test_geos.py
diff --git a/django/contrib/gis/geos/tests/test_geos.py b/django/contrib/gis/geos/tests/test_geos.py index 440075d..4f2e33f 100644
a b class GEOSTest(unittest.TestCase): 821 821 822 822 def test22_copy(self): 823 823 "Testing use with the Python `copy` module." 824 import copy824 import django.utils.copycompat as copy 825 825 poly = GEOSGeometry('POLYGON((0 0, 0 23, 23 23, 23 0, 0 0), (5 5, 5 10, 10 10, 10 5, 5 5))') 826 826 cpy1 = copy.copy(poly) 827 827 cpy2 = copy.deepcopy(poly) -
django/contrib/gis/geos/tests/test_geos_mutation.py
diff --git a/django/contrib/gis/geos/tests/test_geos_mutation.py b/django/contrib/gis/geos/tests/test_geos_mutation.py index 260a468..28f484d 100644
a b 2 2 # Modified from original contribution by Aryeh Leib Taurog, which was 3 3 # released under the New BSD license. 4 4 import unittest 5 6 import django.utils.copycompat as copy 7 5 8 from django.contrib.gis.geos import * 6 9 from django.contrib.gis.geos.error import GEOSIndexError 7 import copy8 10 9 11 def getItem(o,i): return o[i] 10 12 def delItem(o,i): del o[i] -
django/contrib/gis/tests/layermap/tests.py
diff --git a/django/contrib/gis/tests/layermap/tests.py b/django/contrib/gis/tests/layermap/tests.py index b17e7b9..ed5e011 100644
a b 1 1 import os, unittest 2 from copy import copy3 2 from decimal import Decimal 4 3 from models import City, County, CountyFeat, Interstate, ICity1, ICity2, State, city_mapping, co_mapping, cofeat_mapping, inter_mapping 5 4 from django.contrib.gis.db.backend import SpatialBackend 6 5 from django.contrib.gis.utils.layermapping import LayerMapping, LayerMapError, InvalidDecimal, MissingForeignKey 7 6 from django.contrib.gis.gdal import DataSource 7 from django.utils.copycompat import copy 8 8 9 9 shp_path = os.path.dirname(__file__) 10 10 city_shp = os.path.join(shp_path, '../data/cities/cities.shp') -
django/db/models/base.py
diff --git a/django/db/models/base.py b/django/db/models/base.py index 47c1772..5b727a0 100644
a b 1 import copy2 1 import types 3 2 import sys 4 3 import os … … from django.db.models.options import Options 13 12 from django.db import connection, transaction, DatabaseError 14 13 from django.db.models import signals 15 14 from django.db.models.loading import register_models, get_model 15 import django.utils.copycompat as copy 16 16 from django.utils.functional import curry 17 17 from django.utils.encoding import smart_str, force_unicode, smart_unicode 18 18 from django.conf import settings -
django/db/models/expressions.py
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index e54aaba..68abf9d 100644
a b 1 from copy import deepcopy2 1 from datetime import datetime 3 2 4 3 from django.utils import tree 4 from django.utils.copycompat import deepcopy 5 5 6 6 class ExpressionNode(tree.Node): 7 7 """ -
django/db/models/fields/__init__.py
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index a3007a7..0835ceb 100644
a b 1 import copy2 1 import datetime 2 import decimal 3 3 import os 4 4 import re 5 5 import time 6 try: 7 import decimal 8 except ImportError: 9 from django.utils import _decimal as decimal # for Python 2.3 6 7 import django.utils.copycompat as copy 10 8 11 9 from django.db import connection 12 10 from django.db.models import signals -
django/db/models/fields/files.py
diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index aab4f37..66b5040 100644
a b 1 import copy2 1 import datetime 3 2 import os 4 3 4 import django.utils.copycompat as copy 5 5 6 from django.conf import settings 6 7 from django.db.models.fields import Field 7 8 from django.core.files.base import File, ContentFile -
django/db/models/manager.py
diff --git a/django/db/models/manager.py b/django/db/models/manager.py index 7487fa0..2eeb98b 100644
a b 1 import copy1 import django.utils.copycompat as copy 2 2 from django.db.models.query import QuerySet, EmptyQuerySet, insert_query 3 3 from django.db.models import signals 4 4 from django.db.models.fields import FieldDoesNotExist -
django/db/models/query.py
diff --git a/django/db/models/query.py b/django/db/models/query.py index 6a16ce1..9cc7659 100644
a b 2 2 The main QuerySet implementation. This provides the public API for the ORM. 3 3 """ 4 4 5 from copy import deepcopy6 5 from django.db import connection, transaction, IntegrityError 7 6 from django.db.models.aggregates import Aggregate 8 7 from django.db.models.fields import DateField 9 8 from django.db.models.query_utils import Q, select_related_descend, CollectedObjects, CyclicDependency, deferred_class_factory 10 9 from django.db.models import signals, sql 10 from django.utils.copycompat import deepcopy 11 11 12 12 # Used to control how many objects are worked with at once in some cases (e.g. 13 13 # when deleting objects). -
django/db/models/query_utils.py
diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py index 6a6b690..c5cb336 100644
a b circular import difficulties. 7 7 """ 8 8 9 9 import weakref 10 from copyimport deepcopy10 from django.utils.copycompat import deepcopy 11 11 12 12 from django.utils import tree 13 13 from django.utils.datastructures import SortedDict 14 14 15 try:16 sorted17 except NameError:18 from django.utils.itercompat import sorted # For Python 2.3.19 20 15 21 16 class CyclicDependency(Exception): 22 17 """ -
django/db/models/sql/query.py
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 7bc45cb..f3e24ed 100644
a b databases). The abstraction barrier only works one way: this module has to know 7 7 all about the internals of models in order to get the information it needs. 8 8 """ 9 9 10 from copyimport deepcopy10 from django.utils.copycompat import deepcopy 11 11 from django.utils.tree import Node 12 12 from django.utils.datastructures import SortedDict 13 13 from django.utils.encoding import force_unicode -
django/forms/fields.py
diff --git a/django/forms/fields.py b/django/forms/fields.py index 0aef355..c0ee2f0 100644
a b 2 2 Field classes. 3 3 """ 4 4 5 import copy6 5 import datetime 7 6 import os 8 7 import re 9 8 import time 10 9 import urlparse 10 from decimal import Decimal, DecimalException 11 11 try: 12 12 from cStringIO import StringIO 13 13 except ImportError: 14 14 from StringIO import StringIO 15 15 16 # Python 2.3 fallbacks17 try:18 from decimal import Decimal, DecimalException19 except ImportError:20 from django.utils._decimal import Decimal, DecimalException21 try:22 set23 except NameError:24 from sets import Set as set25 26 16 import django.core.exceptions 17 import django.utils.copycompat as copy 27 18 from django.utils.translation import ugettext_lazy as _ 28 19 from django.utils.encoding import smart_unicode, smart_str 29 20 -
django/forms/forms.py
diff --git a/django/forms/forms.py b/django/forms/forms.py index 0b7c2e2..a08dd1b 100644
a b 2 2 Form classes 3 3 """ 4 4 5 from copy import deepcopy 6 5 from django.utils.copycompat import deepcopy 7 6 from django.utils.datastructures import SortedDict 8 7 from django.utils.html import conditional_escape 9 8 from django.utils.encoding import StrAndUnicode, smart_unicode, force_unicode -
django/forms/widgets.py
diff --git a/django/forms/widgets.py b/django/forms/widgets.py index b1d2cb7..d59e634 100644
a b 2 2 HTML Widget classes 3 3 """ 4 4 5 try: 6 set 7 except NameError: 8 from sets import Set as set # Python 2.3 fallback 9 10 import copy 5 import django.utils.copycompat as copy 11 6 from itertools import chain 12 7 from django.conf import settings 13 8 from django.utils.datastructures import MultiValueDict, MergeDict -
django/http/__init__.py
diff --git a/django/http/__init__.py b/django/http/__init__.py index 446659b..7b0c469 100644
a b class QueryDict(MultiValueDict): 183 183 return result 184 184 185 185 def __deepcopy__(self, memo): 186 import copy186 import django.utils.copycompat as copy 187 187 result = self.__class__('', mutable=True) 188 188 memo[id(self)] = result 189 189 for key, value in dict.items(self): -
django/utils/_decimal.py
diff --git a/django/utils/_decimal.py b/django/utils/_decimal.py index 677d26b..2801046 100644
a b __all__ = [ 134 134 'setcontext', 'getcontext' 135 135 ] 136 136 137 import copyas _copy137 import django.utils.copycompat as _copy 138 138 139 139 #Rounding 140 140 ROUND_DOWN = 'ROUND_DOWN' -
new file django/utils/copy_26.py
diff --git a/django/utils/copy_26.py b/django/utils/copy_26.py new file mode 100644 index 0000000..3f2033f
- + 1 """Generic (shallow and deep) copying operations. 2 3 Interface summary: 4 5 import copy 6 7 x = copy.copy(y) # make a shallow copy of y 8 x = copy.deepcopy(y) # make a deep copy of y 9 10 For module specific errors, copy.Error is raised. 11 12 The difference between shallow and deep copying is only relevant for 13 compound objects (objects that contain other objects, like lists or 14 class instances). 15 16 - A shallow copy constructs a new compound object and then (to the 17 extent possible) inserts *the same objects* into it that the 18 original contains. 19 20 - A deep copy constructs a new compound object and then, recursively, 21 inserts *copies* into it of the objects found in the original. 22 23 Two problems often exist with deep copy operations that don't exist 24 with shallow copy operations: 25 26 a) recursive objects (compound objects that, directly or indirectly, 27 contain a reference to themselves) may cause a recursive loop 28 29 b) because deep copy copies *everything* it may copy too much, e.g. 30 administrative data structures that should be shared even between 31 copies 32 33 Python's deep copy operation avoids these problems by: 34 35 a) keeping a table of objects already copied during the current 36 copying pass 37 38 b) letting user-defined classes override the copying operation or the 39 set of components copied 40 41 This version does not copy types like module, class, function, method, 42 nor stack trace, stack frame, nor file, socket, window, nor array, nor 43 any similar types. 44 45 Classes can use the same interfaces to control copying that they use 46 to control pickling: they can define methods called __getinitargs__(), 47 __getstate__() and __setstate__(). See the documentation for module 48 "pickle" for information on these methods. 49 """ 50 51 import types 52 from copy_reg import dispatch_table 53 54 class Error(Exception): 55 pass 56 error = Error # backward compatibility 57 58 try: 59 from org.python.core import PyStringMap 60 except ImportError: 61 PyStringMap = None 62 63 __all__ = ["Error", "copy", "deepcopy"] 64 65 def copy(x): 66 """Shallow copy operation on arbitrary Python objects. 67 68 See the module's __doc__ string for more info. 69 """ 70 71 cls = type(x) 72 73 copier = _copy_dispatch.get(cls) 74 if copier: 75 return copier(x) 76 77 copier = getattr(cls, "__copy__", None) 78 if copier: 79 return copier(x) 80 81 reductor = dispatch_table.get(cls) 82 if reductor: 83 rv = reductor(x) 84 else: 85 reductor = getattr(x, "__reduce_ex__", None) 86 if reductor: 87 rv = reductor(2) 88 else: 89 reductor = getattr(x, "__reduce__", None) 90 if reductor: 91 rv = reductor() 92 else: 93 raise Error("un(shallow)copyable object of type %s" % cls) 94 95 return _reconstruct(x, rv, 0) 96 97 98 _copy_dispatch = d = {} 99 100 def _copy_immutable(x): 101 return x 102 for t in (type(None), int, long, float, bool, str, tuple, 103 frozenset, type, xrange, types.ClassType, 104 types.BuiltinFunctionType, type(Ellipsis), 105 types.FunctionType): 106 d[t] = _copy_immutable 107 for name in ("ComplexType", "UnicodeType", "CodeType"): 108 t = getattr(types, name, None) 109 if t is not None: 110 d[t] = _copy_immutable 111 112 def _copy_with_constructor(x): 113 return type(x)(x) 114 for t in (list, dict, set): 115 d[t] = _copy_with_constructor 116 117 def _copy_with_copy_method(x): 118 return x.copy() 119 if PyStringMap is not None: 120 d[PyStringMap] = _copy_with_copy_method 121 122 def _copy_inst(x): 123 if hasattr(x, '__copy__'): 124 return x.__copy__() 125 if hasattr(x, '__getinitargs__'): 126 args = x.__getinitargs__() 127 y = x.__class__(*args) 128 else: 129 y = _EmptyClass() 130 y.__class__ = x.__class__ 131 if hasattr(x, '__getstate__'): 132 state = x.__getstate__() 133 else: 134 state = x.__dict__ 135 if hasattr(y, '__setstate__'): 136 y.__setstate__(state) 137 else: 138 y.__dict__.update(state) 139 return y 140 d[types.InstanceType] = _copy_inst 141 142 del d 143 144 def deepcopy(x, memo=None, _nil=[]): 145 """Deep copy operation on arbitrary Python objects. 146 147 See the module's __doc__ string for more info. 148 """ 149 150 if memo is None: 151 memo = {} 152 153 d = id(x) 154 y = memo.get(d, _nil) 155 if y is not _nil: 156 return y 157 158 cls = type(x) 159 160 copier = _deepcopy_dispatch.get(cls) 161 if copier: 162 y = copier(x, memo) 163 else: 164 try: 165 issc = issubclass(cls, type) 166 except TypeError: # cls is not a class (old Boost; see SF #502085) 167 issc = 0 168 if issc: 169 y = _deepcopy_atomic(x, memo) 170 else: 171 copier = getattr(x, "__deepcopy__", None) 172 if copier: 173 y = copier(memo) 174 else: 175 reductor = dispatch_table.get(cls) 176 if reductor: 177 rv = reductor(x) 178 else: 179 reductor = getattr(x, "__reduce_ex__", None) 180 if reductor: 181 rv = reductor(2) 182 else: 183 reductor = getattr(x, "__reduce__", None) 184 if reductor: 185 rv = reductor() 186 else: 187 raise Error( 188 "un(deep)copyable object of type %s" % cls) 189 y = _reconstruct(x, rv, 1, memo) 190 191 memo[d] = y 192 _keep_alive(x, memo) # Make sure x lives at least as long as d 193 return y 194 195 _deepcopy_dispatch = d = {} 196 197 def _deepcopy_atomic(x, memo): 198 return x 199 d[type(None)] = _deepcopy_atomic 200 d[type(Ellipsis)] = _deepcopy_atomic 201 d[int] = _deepcopy_atomic 202 d[long] = _deepcopy_atomic 203 d[float] = _deepcopy_atomic 204 d[bool] = _deepcopy_atomic 205 try: 206 d[complex] = _deepcopy_atomic 207 except NameError: 208 pass 209 d[str] = _deepcopy_atomic 210 try: 211 d[unicode] = _deepcopy_atomic 212 except NameError: 213 pass 214 try: 215 d[types.CodeType] = _deepcopy_atomic 216 except AttributeError: 217 pass 218 d[type] = _deepcopy_atomic 219 d[xrange] = _deepcopy_atomic 220 d[types.ClassType] = _deepcopy_atomic 221 d[types.BuiltinFunctionType] = _deepcopy_atomic 222 d[types.FunctionType] = _deepcopy_atomic 223 224 def _deepcopy_list(x, memo): 225 y = [] 226 memo[id(x)] = y 227 for a in x: 228 y.append(deepcopy(a, memo)) 229 return y 230 d[list] = _deepcopy_list 231 232 def _deepcopy_tuple(x, memo): 233 y = [] 234 for a in x: 235 y.append(deepcopy(a, memo)) 236 d = id(x) 237 try: 238 return memo[d] 239 except KeyError: 240 pass 241 for i in range(len(x)): 242 if x[i] is not y[i]: 243 y = tuple(y) 244 break 245 else: 246 y = x 247 memo[d] = y 248 return y 249 d[tuple] = _deepcopy_tuple 250 251 def _deepcopy_dict(x, memo): 252 y = {} 253 memo[id(x)] = y 254 for key, value in x.iteritems(): 255 y[deepcopy(key, memo)] = deepcopy(value, memo) 256 return y 257 d[dict] = _deepcopy_dict 258 if PyStringMap is not None: 259 d[PyStringMap] = _deepcopy_dict 260 261 def _keep_alive(x, memo): 262 """Keeps a reference to the object x in the memo. 263 264 Because we remember objects by their id, we have 265 to assure that possibly temporary objects are kept 266 alive by referencing them. 267 We store a reference at the id of the memo, which should 268 normally not be used unless someone tries to deepcopy 269 the memo itself... 270 """ 271 try: 272 memo[id(memo)].append(x) 273 except KeyError: 274 # aha, this is the first one :-) 275 memo[id(memo)]=[x] 276 277 def _deepcopy_inst(x, memo): 278 if hasattr(x, '__deepcopy__'): 279 return x.__deepcopy__(memo) 280 if hasattr(x, '__getinitargs__'): 281 args = x.__getinitargs__() 282 args = deepcopy(args, memo) 283 y = x.__class__(*args) 284 else: 285 y = _EmptyClass() 286 y.__class__ = x.__class__ 287 memo[id(x)] = y 288 if hasattr(x, '__getstate__'): 289 state = x.__getstate__() 290 else: 291 state = x.__dict__ 292 state = deepcopy(state, memo) 293 if hasattr(y, '__setstate__'): 294 y.__setstate__(state) 295 else: 296 y.__dict__.update(state) 297 return y 298 d[types.InstanceType] = _deepcopy_inst 299 300 def _reconstruct(x, info, deep, memo=None): 301 if isinstance(info, str): 302 return x 303 assert isinstance(info, tuple) 304 if memo is None: 305 memo = {} 306 n = len(info) 307 assert n in (2, 3, 4, 5) 308 callable, args = info[:2] 309 if n > 2: 310 state = info[2] 311 else: 312 state = {} 313 if n > 3: 314 listiter = info[3] 315 else: 316 listiter = None 317 if n > 4: 318 dictiter = info[4] 319 else: 320 dictiter = None 321 if deep: 322 args = deepcopy(args, memo) 323 y = callable(*args) 324 memo[id(x)] = y 325 if listiter is not None: 326 for item in listiter: 327 if deep: 328 item = deepcopy(item, memo) 329 y.append(item) 330 if dictiter is not None: 331 for key, value in dictiter: 332 if deep: 333 key = deepcopy(key, memo) 334 value = deepcopy(value, memo) 335 y[key] = value 336 if state: 337 if deep: 338 state = deepcopy(state, memo) 339 if hasattr(y, '__setstate__'): 340 y.__setstate__(state) 341 else: 342 if isinstance(state, tuple) and len(state) == 2: 343 state, slotstate = state 344 else: 345 slotstate = None 346 if state is not None: 347 y.__dict__.update(state) 348 if slotstate is not None: 349 for key, value in slotstate.iteritems(): 350 setattr(y, key, value) 351 return y 352 353 del d 354 355 del types 356 357 # Helper for instance creation without calling __init__ 358 class _EmptyClass: 359 pass 360 361 def _test(): 362 l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'], 363 {'abc': 'ABC'}, (), [], {}] 364 l1 = copy(l) 365 print l1==l 366 l1 = map(copy, l) 367 print l1==l 368 l1 = deepcopy(l) 369 print l1==l 370 class C: 371 def __init__(self, arg=None): 372 self.a = 1 373 self.arg = arg 374 if __name__ == '__main__': 375 import sys 376 file = sys.argv[0] 377 else: 378 file = __file__ 379 self.fp = open(file) 380 self.fp.close() 381 def __getstate__(self): 382 return {'a': self.a, 'arg': self.arg} 383 def __setstate__(self, state): 384 for key, value in state.iteritems(): 385 setattr(self, key, value) 386 def __deepcopy__(self, memo=None): 387 new = self.__class__(deepcopy(self.arg, memo)) 388 new.a = self.a 389 return new 390 c = C('argument sketch') 391 l.append(c) 392 l2 = copy(l) 393 print l == l2 394 print l 395 print l2 396 l2 = deepcopy(l) 397 print l == l2 398 print l 399 print l2 400 l.append({l[1]: l, 'xyz': l[2]}) 401 l3 = copy(l) 402 import repr 403 print map(repr.repr, l) 404 print map(repr.repr, l1) 405 print map(repr.repr, l2) 406 print map(repr.repr, l3) 407 l3 = deepcopy(l) 408 import repr 409 print map(repr.repr, l) 410 print map(repr.repr, l1) 411 print map(repr.repr, l2) 412 print map(repr.repr, l3) 413 414 if __name__ == '__main__': 415 _test() -
new file django/utils/copycompat.py
diff --git a/django/utils/copycompat.py b/django/utils/copycompat.py new file mode 100644 index 0000000..6b389c4
- + 1 """ 2 Python 2.4's deepcopy isn't able to copy unbound functions that 3 are attributes on an object. 4 """ 5 from copy import deepcopy 6 7 8 class TestClass(object): 9 pass 10 11 test = TestClass() 12 test.func = lambda :1 13 try: 14 deepcopy(test) 15 except TypeError: 16 from django.utils.copy_26 import * 17 else: 18 from copy import * -
django/utils/datastructures.py
diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py index 2b586d7..06cf6c6 100644
a b 1 from copyimport deepcopy1 from django.utils.copycompat import deepcopy 2 2 3 3 4 4 class MergeDict(object): … … class MultiValueDict(dict): 214 214 return self.__class__(super(MultiValueDict, self).items()) 215 215 216 216 def __deepcopy__(self, memo=None): 217 import copy217 import django.utils.copycompat as copy 218 218 if memo is None: 219 219 memo = {} 220 220 result = self.__class__() -
django/utils/functional.py
diff --git a/django/utils/functional.py b/django/utils/functional.py index 434b6b7..28d3b2e 100644
a b class SimpleLazyObject(LazyObject): 328 328 memo[id(self)] = result 329 329 return result 330 330 else: 331 import copy 332 return copy.deepcopy(self._wrapped, memo) 331 # Changed to use deepcopy from copycompat, instead of copy 332 # For Python 2.4. 333 from django.utils.copycompat import deepcopy 334 return deepcopy(self._wrapped, memo) 333 335 334 336 # Need to pretend to be the wrapped class, for the sake of objects that care 335 337 # about this (especially in equality tests) -
django/utils/tree.py
diff --git a/django/utils/tree.py b/django/utils/tree.py index a9028b8..a6cfec2 100644
a b A class for storing a tree graph. Primarily used for filter constructs in the 3 3 ORM. 4 4 """ 5 5 6 from copyimport deepcopy6 from django.utils.copycompat import deepcopy 7 7 8 8 class Node(object): 9 9 """ -
tests/regressiontests/dispatch/tests/test_dispatcher.py
diff --git a/tests/regressiontests/dispatch/tests/test_dispatcher.py b/tests/regressiontests/dispatch/tests/test_dispatcher.py index adf7603..ad3a05f 100644
a b 1 1 from django.dispatch import Signal 2 2 import unittest 3 import copy4 3 import sys 5 4 import gc 5 import django.utils.copycompat as copy 6 6 7 7 if sys.platform.startswith('java'): 8 8 def garbage_collect(): -
tests/regressiontests/extra_regress/models.py
diff --git a/tests/regressiontests/extra_regress/models.py b/tests/regressiontests/extra_regress/models.py index 5d22d6c..76eb549 100644
a b 1 import copy2 1 import datetime 3 2 3 import django.utils.copycompat as copy 4 4 5 from django.contrib.auth.models import User 5 6 from django.db import models 6 7 from django.db.models.query import Q -
tests/regressiontests/utils/tests.py
diff --git a/tests/regressiontests/utils/tests.py b/tests/regressiontests/utils/tests.py index a7a6e4c..6258b81 100644
a b class TestUtilsSimpleLazyObject(TestCase): 220 220 self.assertEqual(_ComplexObject, SimpleLazyObject(complex_object).__class__) 221 221 222 222 def test_deepcopy(self): 223 import copy223 import django.utils.copycompat as copy 224 224 # Check that we *can* do deep copy, and that it returns the right 225 225 # objects. 226 226