silx-kit / silx

silx toolkit
http://www.silx.org/doc/silx/latest/
MIT License
130 stars 73 forks source link

[H5Node] soft link to external link bug #3219

Open woutdenolf opened 4 years ago

woutdenolf commented 4 years ago

There is a bug in getting the physical target of a softlink that points to on external link

import h5py

with h5py.File("source.h5", mode="w") as f:
    f["data"] = 10

with h5py.File("dest.h5", mode="w") as f:
    f["external"] = h5py.ExternalLink("source.h5", "/data")
    f["soft"] = h5py.SoftLink("/external")  # H5Node.h5py_target exception
woutdenolf commented 4 years ago

@vallsv The Hdf5Item.obj is already the dereferenced link so how is H5Node supposed to work?

class Hdf5Item(Hdf5Node):
    @property
    def obj(self):
        if self.__key:
            self.__initH5Object()
        return self.__obj  # This is the dereferenced link

    def __initH5Object(self):
        self.__obj = parent_obj.get(self.__key)  # Links are already dereferenced !!! (if the destination exists)

class H5Node(object):
    def __init__(self, h5py_item=None):
        """Constructor

        :param Hdf5Item h5py_item: An Hdf5Item
        """
        self.__h5py_object = h5py_item.obj # This is the dereferenced link
woutdenolf commented 4 years ago

@vallsv It seems the implementation assumes that parent.get("name").parent is the same as parent which is not the case.

vallsv commented 4 years ago

Objects and paths are 2 different things. Here we just store both. The path is based on the item tree of the view. And failing nodes are specific node.

As far as i remember.

woutdenolf commented 4 years ago

Ok it's in fact an h5py bug:

import h5py

with h5py.File("source.h5", mode="w") as f:
    f["/group/data"] = 10

with h5py.File("dest.h5", mode="w") as f:
    f["/link/external"] = h5py.ExternalLink("source.h5", "/group/data")
    f["/link/soft"] = h5py.SoftLink("external")

with h5py.File("dest.h5", mode="r") as f:
    f["/link/soft"].parent

Traceback (most recent call last):
  File "test.py", line 11, in <module>
    f["/link/soft"].parent
  File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper
  File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper
  File "/users/denolf/virtualenvs/silx/py38/lib/python3.8/site-packages/h5py/_hl/base.py", line 239, in parent
    return self.file[posixpath.dirname(self.name)]
  File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper
  File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper
  File "/users/denolf/virtualenvs/silx/py38/lib/python3.8/site-packages/h5py/_hl/group.py", line 264, in __getitem__
    oid = h5o.open(self.id, self._e(name), lapl=self._lapl)
  File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper
  File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper
  File "h5py/h5o.pyx", line 190, in h5py.h5o.open
KeyError: "Unable to open object (object 'link' doesn't exist)"
woutdenolf commented 4 years ago

https://github.com/h5py/h5py/issues/1706

vallsv commented 4 years ago

Then I guess the h5py property view entirely fail?

At least this part could easily be designed stronger. It should always display something.

woutdenolf commented 4 years ago

When clicking on the node in the tree view, you get a pop-up with an exception but for the rest everything works (except that the node info is not correct, but that's normal).