Example #1
0
    def copy(self, source, dest, name=None):
        """ Copy an object or group.

        The source can be a path, Group, Dataset, or Datatype object.  The
        destination can be either a path or a Group object.  The source and
        destinations need not be in the same file.

        If the source is a Group object, all objects contained in that group
        will be copied recursively.

        When the destination is a Group object, by default the target will
        be created in that group with its current name (basename of obj.name).
        You can override that by setting "name" to a string.

        Example:

        >>> f = File('myfile.hdf5')
        >>> f.listnames()
        ['MyGroup']
        >>> f.copy('MyGroup', 'MyCopy')
        >>> f.listnames()
        ['MyGroup', 'MyCopy']

        """
        if isinstance(source, HLObject):
            source_path = '.'
        else:
            # Interpret source as a path relative to this group
            source_path = source
            source = self

        if isinstance(dest, Group):
            if name is not None:
                dest_path = name
            else:
                # copy source into dest group: dest_name/source_name
                dest_path = pp.basename(h5i.get_name(source[source_path].id))

        elif isinstance(dest, HLObject):
            raise TypeError("Destination must be path or Group object")
        else:
            # Interpret destination as a path relative to this group
            dest_path = dest
            dest = self

        h5o.copy(source.id, self._e(source_path), dest.id, self._e(dest_path))
Example #2
0
    def copy(self, source, dest, name=None,
             shallow=False, expand_soft=False, expand_external=False,
             expand_refs=False, without_attrs=False):
        """Copy an object or group.

        The source can be a path, Group, Dataset, or Datatype object.  The
        destination can be either a path or a Group object.  The source and
        destinations need not be in the same file.

        If the source is a Group object, all objects contained in that group
        will be copied recursively.

        When the destination is a Group object, by default the target will
        be created in that group with its current name (basename of obj.name).
        You can override that by setting "name" to a string.

        There are various options which all default to "False":

         - shallow: copy only immediate members of a group.

         - expand_soft: expand soft links into new objects.

         - expand_external: expand external links into new objects.

         - expand_refs: copy objects that are pointed to by references.

         - without_attrs: copy object without copying attributes.

       Example:

        >>> f = File('myfile.hdf5')
        >>> f.listnames()
        ['MyGroup']
        >>> f.copy('MyGroup', 'MyCopy')
        >>> f.listnames()
        ['MyGroup', 'MyCopy']

        """
        if isinstance(source, HLObject):
            source_path = '.'
        else:
            # Interpret source as a path relative to this group
            source_path = source
            source = self

        if isinstance(dest, Group):
            if name is not None:
                dest_path = name
            else:
                # copy source into dest group: dest_name/source_name
                dest_path = pp.basename(h5i.get_name(source[source_path].id))

        elif isinstance(dest, HLObject):
            raise TypeError("Destination must be path or Group object")
        else:
            # Interpret destination as a path relative to this group
            dest_path = dest
            dest = self

        flags = 0
        if shallow:
            flags |= h5o.COPY_SHALLOW_HIERARCHY_FLAG
        if expand_soft:
            flags |= h5o.COPY_EXPAND_SOFT_LINK_FLAG
        if expand_external:
            flags |= h5o.COPY_EXPAND_EXT_LINK_FLAG
        if expand_refs:
            flags |= h5o.COPY_EXPAND_REFERENCE_FLAG
        if without_attrs:
            flags |= h5o.COPY_WITHOUT_ATTR_FLAG
        if flags:
            copypl = h5p.create(h5p.OBJECT_COPY)
            copypl.set_copy_object(flags)
        else:
            copypl = None

        h5o.copy(source.id, self._e(source_path), dest.id, self._e(dest_path),
                 copypl, base.dlcpl)
Example #3
0
 def name(self):
     """ Return the full name of this object.  None if anonymous. """
     return self._d(h5i.get_name(self.id))
Example #4
0
File: base.py Project: B-Rich/h5py
 def name(self):
     """ Return the full name of this object.  None if anonymous. """
     return self._d(h5i.get_name(self.id))
Example #5
0
def swap(old, new):
    """
    Swap every dataset in old with the corresponding one in new

    Datasets in old that aren't in new are ignored.
    """
    move_names = []

    def _move(name, object):
        if isinstance(object, Dataset):
            if name in new:
                move_names.append(name)

    old.visititems(_move)
    for name in move_names:
        if new[name].is_virtual:
            # We cannot simply move virtual datasets, because they will still
            # point to the old raw_data location. So instead, we have to
            # recreate them, pointing to the new raw_data.
            oldd = old[name]
            newd = new[name]

            def _normalize(path):
                return path if path.endswith('/') else path + '/'

            def _replace_prefix(path, name1, name2):
                """Replace the prefix name1 with name2 in path"""
                name1 = _normalize(name1)
                name2 = _normalize(name2)
                return name2 + path[len(name1):]

            def _new_vds_layout(d, name1, name2):
                """Recreate a VirtualLayout for d, replacing name1 with name2 in the source dset name"""
                virtual_sources = d.virtual_sources()
                layout = VirtualLayout(d.shape, dtype=d.dtype)
                for vmap in virtual_sources:
                    vspace, fname, dset_name, src_space = vmap
                    assert dset_name.startswith(name1)
                    dset_name = _replace_prefix(dset_name, name1, name2)
                    fname = fname.encode('utf-8')
                    new_vmap = VDSmap(vspace, fname, dset_name, src_space)
                    # h5py 3.3 changed the VirtualLayout code. See
                    # https://github.com/h5py/h5py/pull/1905.
                    if hasattr(layout, 'sources'):
                        layout.sources.append(new_vmap)
                    else:
                        layout.dcpl.set_virtual(vspace, fname,
                                                dset_name.encode('utf-8'),
                                                src_space)
                return layout

            old_layout = _new_vds_layout(oldd, old.name, new.name)
            new_layout = _new_vds_layout(newd, new.name, old.name)
            old_fillvalue = old[name].fillvalue
            new_fillvalue = new[name].fillvalue
            old_attrs = dict(old[name].attrs)
            new_attrs = dict(new[name].attrs)
            del old[name]
            old.create_virtual_dataset(name,
                                       new_layout,
                                       fillvalue=new_fillvalue)
            for k, v in new_attrs.items():
                if isinstance(v, str) and v.startswith(new.name):
                    v = _replace_prefix(v, new.name, old.name)
                old[name].attrs[k] = v
            del new[name]
            new.create_virtual_dataset(name,
                                       old_layout,
                                       fillvalue=old_fillvalue)
            for k, v in old_attrs.items():
                if isinstance(v, str) and v.startswith(old.name):
                    v = _replace_prefix(v, old.name, new.name)
                new[name].attrs[k] = v
        else:
            # Invalidate any InMemoryGroups that point to these groups
            delete = []
            for bind in _groups:
                if get_name(bind) and (
                        get_name(bind).startswith(get_name(old.id))
                        or get_name(bind).startswith(get_name(new.id))):
                    delete.append(bind)
            for d in delete:
                del _groups[d]
            old.move(name, pp.join(new.name, name + '__tmp'))
            new.move(name, pp.join(old.name, name))
            new.move(name + '__tmp', name)