deepcopy problem

Stephen C Phillips news at scphillips.co.uk
Mon Mar 10 09:55:54 EST 2003


Hi,
	I am having a problem with copy.deepcopy() in Python 2.2.2.  
The problem only arises when I use classes derived from the object 
class.  Apologies if this is a known bug - I hope it is just my 
own incompetence.

Sorry about the long example listing:


import copy

class Node:

    count = 1
    
    def __init__(self):
        self.paths = []
        self.index = Node.count
        Node.count += 1
        pass

    def __str__(self):
        paths = ', '.join(map(lambda n: str(n.index), self.paths))
        return "(%s) Node %s: paths [%s]" % (hex(id(self)), self.index, paths)

    def __getstate__(self):
        print 'getting node state'
        print self
        return self.__dict__

    def __setstate__(self, state):
        print 'setting node state', hex(id(self))
        print state
        self.__dict__.update(state)

    def add_path(self, path):
        self.paths.append(path)

class Path:

    count = 1
    
    def __init__(self, nodes):
        self.nodes = nodes
        self.index = Path.count
        Path.count += 1
        for node in nodes:
            node.add_path(self)

    def __str__(self):
        nodes = ', '.join(map(lambda n: str(n.index), self.nodes))
        return "(%s) Path %s: nodes [%s]" % (hex(id(self)), self.index, nodes)

    def __getstate__(self):
        print 'getting path state'
        print self
        return self.__dict__

    def __setstate__(self, state):
        print 'setting path state', hex(id(self))
        print state
        self.__dict__.update(state)


n = Node()
m = Node()
p = Path([n,m])
print n
print m
print p

print '-----'

x = copy.deepcopy(n)

print '-----'

print x
print x.paths[0]
for node in x.paths[0].nodes: print node


----------------------------------------
The output of this is as you would hope:


(0x8180c5c) Node 1: paths [1]
(0x8184484) Node 2: paths [1]
(0x819441c) Path 1: nodes [1, 2]
-----
getting node state
(0x8180c5c) Node 1: paths [1]
getting path state
(0x819441c) Path 1: nodes [1, 2]
getting node state
(0x8184484) Node 2: paths [1]
setting node state 0x8181ab4
{'paths': [<__main__.Path instance at 0x818463c>], 'index': 2}
setting path state 0x818463c
{'index': 1, 'nodes': [<__main__.Node instance at 0x81097b4>, <__main__.Node instance at 0x8181ab4>]}
setting node state 0x81097b4
{'paths': [<__main__.Path instance at 0x818463c>], 'index': 1}
-----
(0x81097b4) Node 1: paths [1]
(0x818463c) Path 1: nodes [1, 2]
(0x81097b4) Node 1: paths [1]
(0x8181ab4) Node 2: paths [1]



If you change the classes to be derived from object, e.g.
class Node(object):
    etc
class Path(object):
    etc

then the output is this:

(0x8101484) Node 1: paths [1]
(0x811f6bc) Node 2: paths [1]
(0x81844f4) Path 1: nodes [1, 2]
-----
getting node state
(0x8101484) Node 1: paths [1]
getting path state
(0x81844f4) Path 1: nodes [1, 2]
getting node state
(0x8101484) Node 1: paths [1]
setting node state 0x8181824
{}
getting node state
(0x811f6bc) Node 2: paths [1]
getting path state
(0x81844f4) Path 1: nodes [1, 2]
setting path state 0x81858ac
{'index': 1}
setting node state 0x818189c
{'paths': [<__main__.Path object at 0x81858ac>], 'index': 2}
setting path state 0x819354c
{'index': 1, 'nodes': [<__main__.Node object at 0x8181824>, <__main__.Node object at 0x818189c>]}
setting node state 0x8111eb4
{'paths': [<__main__.Path object at 0x819354c>], 'index': 1}
-----
(0x8111eb4) Node 1: paths [1]

Traceback (most recent call last):
  File "/steve/project/debug/stick.py", line 72, in ?
    print x.paths[0]
  File "/steve/project/debug/stick.py", line 44, in __str__
    nodes = ', '.join(map(lambda n: str(n.index), self.nodes))
  File "/steve/project/debug/stick.py", line 44, in <lambda>
    nodes = ', '.join(map(lambda n: str(n.index), self.nodes))
AttributeError: 'Node' object has no attribute 'index'



The error is still present when the __getstate__ and __setstate__ methods
are removed.  Their only purpose is for illustration.

Can anyone help?

Stephen Phillips.




More information about the Python-list mailing list