aparo/pyes — Issue #114: DotDict instances can't be deep-copied by copy.deepcopy()
Author: alambert
Created: 2011-10-17 20:59:19+00:00
State: open

Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05)
Type "copyright", "credits" or "license" for more information.

IPython 0.11 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.

In [1]: from pyes.es import DotDict

In [2]: a = DotDict()

In [3]: b = dict()

In [4]: from copy import deepcopy

In [5]: deepcopy(b)
Out[5]: {}

In [6]: deepcopy(a)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/Users/alambert/biff/grok/ in ()
----> 1 deepcopy(a)

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
180 reductor = getattr(x, "__reduce_ex__", None)
181 if reductor:
--> 182 rv = reductor(2)
183 else:
184 reductor = getattr(x, "__reduce__", None)

TypeError: 'NoneType' object is not callable

Looking at copy.py from Python 2.7.1 (http://svn.python.org/view/python/tags/r271/Lib/copy.py?view=markup) gives a bit more detail on what's going wrong:

78	copier = getattr(cls, "__copy__", None)
79	if copier:
80	return copier(x)
81
82	reductor = dispatch_table.get(cls)
83	if reductor:
84	rv = reductor(x)
85	else:
86	reductor = getattr(x, "__reduce_ex__", None)
87	if reductor:
88	rv = reductor(2)
89	else:
90	reductor = getattr(x, "__reduce__", None)
91	if reductor:
92	rv = reductor()
93	else:
94	raise Error("un(shallow)copyable object of type %s" % cls)
95

In [2]: from pyes.es import DotDict

In [3]: a = DotDict()

In [4]: reductor = getattr(a, "__reduce_ex__")

In [5]: reductor(2)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/Users/alambert/biff/grok/ in ()
----> 1 reductor(2)

TypeError: 'NoneType' object is not callable

In [6]: reductor == None
Out[6]: False

In [7]: type(reductor)
Out[7]: builtin_function_or_method

In [8]: