PyTables/PyTables — pull request #208 by iMichka (2013-02-10 17:01:35+00:00)
Title: Bug fix for renameNode

Hello.

I think I found a bug in the renameNode method. Here is a small example showing what I want to achieve :

import tables

# Create file and groups
file = tables.openFile("test.hdf5", "w")
file.createGroup("/", "data", "Data")
file.createGroup("/data", "id", "Single Data")
file.createGroup("/data/id/", "curves1", "Curve 1")
file.createGroup("/data/id/", "curves2", "Curve 2")

# Rename (works)
file.renameNode("/data/id/curves1", "newcurve1")

# Rename (doesn't work)
file.renameNode("/data/id", "newid")

The first rename will work and rename "/data/id/curves1" to "/data/id/newcurve1"
The second rename will fail with the following traceback :

Traceback (most recent call last):
File "Rename.py", line 14, in
file.renameNode("/data/id", "newid")
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tables/file.py", line 1157, in renameNode
obj._f_rename(newname, overwrite)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tables/node.py", line 590, in _f_rename
self._f_move(newname=newname, overwrite=overwrite)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tables/node.py", line 674, in _f_move
self._g_move(newparent, newname)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tables/group.py", line 565, in _g_move
self._v_file._updateNodeLocations(oldPath, newPath)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tables/file.py", line 2368, in _updateNodeLocations
descendentNode._g_updateLocation(newNodePPath)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tables/node.py", line 414, in _g_updateLocation
file_._refNode(self, newPath)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tables/file.py", line 2287, in _refNode
"file already has a node with path ``%s``" % nodePath
AssertionError: file already has a node with path ``/data``
Closing remaining open files: test.hdf5... done
Exception AttributeError: "'File' object has no attribute '_aliveNodes'" in ignored

I found out that in file.py, there are deadNodes stored which will make the second rename fail. If you print self._deadNodes in the _updateNodeLocations method, you will get these nodes (from my example):

/data/id//curves1
/data/id/
/data/id//curves2

I wonder why there are nodes with // in them ? But most importantly for my problem, the line nodePath.startswith(oldPrefix) will return True for :
nodePath = /data/id//curves1
oldPrefix = /data/id/

This leads to a call to _g_updateLocation ... which will fail.

So I propose to check if nodePath != oldPrefix. Perhaps the bug is due to these deadNodes with //, but I do not know enough about pytable's internals to find out if this is normal or not.