This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author gward
Recipients
Date 2000-09-15.23:22:04
SpamBayes Score
Marked as misclassified
Message-id
In-reply-to
Content
The 'copy.deepcopy()' function blows up if it stumbles across class, function, or method objects as it recurses into objects.  This is (at least partly) because of an inconsistency between the dispatch table used for plain-vanilla 'copy()' and for 'deepcopy()': the 'copy()' dispatch table has an entry for ClassType, but the 'deepcopy()' dispatch table does not.

Also, neither dispatch table has entries for FunctionType or MethodType.  This isn't a big deal for 'copy()', since it's unlikely that you'd do 'copy(my_func)', but it's inconsistent since you can do 'copy(my_class)' -- and the class object my_class is *not* copied, it's treated atomically, like strings or ints.  For consistency, functions and methods should probably be treated the same as class objects.

Here's a script that demonstrates the problem:

from copy import copy, deepcopy

def f(): pass
class K: pass

# can copy a list that contains a function, since we don't
# dive into the list
l = [1, 2, f]
try: copy(l)
except: print "error copying list with function"
else: print "ok copying list with function"

# but we can't copy the function
try: copy(f)
except: print "error copying function"
else: print "ok copying function"

# also can't deep copy a list with a function because deepcopy() dives in
try: deepcopy(l)
except: print "error deep-copying list with function"
else: print "ok deep-copying list with function"

# nor can we deepcopy the function alone
try: deepcopy(f)
except: print "error deep-copying function"
else: print "ok deep-copying function"

# can copy list with class object
l = ["foo", K]
try: copy(l)
except: print "error copying list with class object"
else: print "ok copying list with class object"

# but can't deepcopy it
try: deepcopy(l)
except: print "error deep-copying list with class object"
else: print "ok deep-copying list with class object"

(Hmm, I don't see a test script for the 'copy' module -- perhaps this would be a good start.)

This gives the same output for me with Python 1.5.2, 1.6, and 2.0b1 (all on Linux):

ok copying list with function
error copying function
error deep-copying list with function
error deep-copying function
ok copying list with class object
error deep-copying list with class object

And here's a patch that makes everything come out OK:

--- copy.py.orig        Fri Sep 15 19:19:05 2000
+++ copy.py.hacked      Fri Sep 15 19:20:20 2000
@@ -92,6 +92,8 @@
 d[types.TypeType] = _copy_atomic
 d[types.XRangeType] = _copy_atomic
 d[types.ClassType] = _copy_atomic
+d[types.FunctionType] = _copy_atomic
+d[types.MethodType] = _copy_atomic
 
 def _copy_list(x):
        return x[:]
@@ -165,6 +167,9 @@
 d[types.CodeType] = _deepcopy_atomic
 d[types.TypeType] = _deepcopy_atomic
 d[types.XRangeType] = _deepcopy_atomic
+d[types.ClassType] = _deepcopy_atomic
+d[types.FunctionType] = _deepcopy_atomic
+d[types.MethodType] = _deepcopy_atomic
 
 def _deepcopy_list(x, memo):
        y = []
History
Date User Action Args
2007-08-23 13:50:35adminlinkissue214553 messages
2007-08-23 13:50:35admincreate