[python-hdf5storage] 111/152: Added ability to discard or throw an error when writing a matlab incompatible type when doing matlab compatibility.
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Mon Feb 29 08:24:39 UTC 2016
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to annotated tag 0.1
in repository python-hdf5storage.
commit 742f1eba2208ebab8553e7426fd5684085b04a1e
Author: Freja Nordsiek <fnordsie at gmail.com>
Date: Thu Feb 13 17:36:52 2014 -0500
Added ability to discard or throw an error when writing a matlab incompatible type when doing matlab compatibility.
---
hdf5storage/Marshallers.py | 38 ++++++++++++++++++++----------
hdf5storage/__init__.py | 58 ++++++++++++++++++++++++++++++++++++++++++----
hdf5storage/lowlevel.py | 22 ++++++++++++++++++
3 files changed, 102 insertions(+), 16 deletions(-)
diff --git a/hdf5storage/Marshallers.py b/hdf5storage/Marshallers.py
index 752eef3..8390115 100644
--- a/hdf5storage/Marshallers.py
+++ b/hdf5storage/Marshallers.py
@@ -35,6 +35,7 @@ import numpy as np
import h5py
from hdf5storage.utilities import *
+from hdf5storage import lowlevel
from hdf5storage.lowlevel import write_data, read_data
@@ -375,6 +376,18 @@ class NumpyScalarArrayMarshaller(TypeMarshaller):
self.matlab_classes = list(self.__MATLAB_classes.values())
def write(self, f, grp, name, data, type_string, options):
+ # If we are doing matlab compatibility and the data type is not
+ # one of those that is supported for matlab, skip writing the
+ # data or throw an error if appropriate.
+ if options.matlab_compatible \
+ and data.dtype.type not in self.__MATLAB_classes:
+ if options.action_for_matlab_incompatible == 'error':
+ raise lowlevel.TypeNotMatlabCompatibleError( \
+ 'Data type ' + data.dtype.name
+ + ' not supported by MATLAB.')
+ elif options.action_for_matlab_incompatible == 'discard':
+ return
+
# Need to make a set of data that will be stored. It will start
# out as a copy of data and then be steadily manipulated.
@@ -579,19 +592,19 @@ class NumpyScalarArrayMarshaller(TypeMarshaller):
# bytes each element takes up (dtype.itemsize). Otherwise,
# the attributes must be deleted.
- if options.matlab_compatible:
- tp = data.dtype.type
- if tp in self.__MATLAB_classes:
- set_attribute_string(grp[name], 'MATLAB_class',
- self.__MATLAB_classes[tp])
- else:
- set_attribute_string(grp[name], 'MATLAB_class', '')
-
+ tp = data.dtype.type
+ if options.matlab_compatible and tp in self.__MATLAB_classes:
+ set_attribute_string(grp[name], 'MATLAB_class',
+ self.__MATLAB_classes[tp])
if tp in (np.bytes_, np.str_, np.bool_):
set_attribute(grp[name], 'MATLAB_int_decode', np.int64(
grp[name].dtype.itemsize))
else:
del_attribute(grp[name], 'MATLAB_int_decode')
+ else:
+ del_attribute(grp[name], 'MATLAB_class')
+ del_attribute(grp[name], 'MATLAB_empty')
+ del_attribute(grp[name], 'MATLAB_int_decode')
def read(self, f, grp, name, options):
# If name is not present or is not a Dataset, then we can't read
@@ -933,10 +946,11 @@ class PythonDictMarshaller(TypeMarshaller):
# be deleted).
for k, v in data.items():
write_data(f, grp2, k, v, None, options)
- if options.matlab_compatible:
- set_attribute_string(grp2[k], 'H5PATH', grp2.name)
- else:
- del_attribute(grp2[k], 'H5PATH')
+ if k in grp2:
+ if options.matlab_compatible:
+ set_attribute_string(grp2[k], 'H5PATH', grp2.name)
+ else:
+ del_attribute(grp2[k], 'H5PATH')
def write_metadata(self, f, grp, name, data, type_string, options):
# First, call the inherited version to do most of the work.
diff --git a/hdf5storage/__init__.py b/hdf5storage/__init__.py
index 1f29927..a02d535 100644
--- a/hdf5storage/__init__.py
+++ b/hdf5storage/__init__.py
@@ -43,7 +43,9 @@ import datetime
import h5py
from . import lowlevel
-from hdf5storage.lowlevel import Hdf5storageError, CantReadError
+from hdf5storage.lowlevel import Hdf5storageError, CantReadError, \
+ TypeNotMatlabCompatibleError
+
from . import Marshallers
@@ -81,6 +83,9 @@ class Options(object):
See Attributes.
matlab_compatible : bool, optional
See Attributes.
+ action_for_matlab_incompatible: str, optional
+ See Attributes. Only valid values are 'ignore', 'discard', and
+ 'error'.
delete_unused_variables: : bool, optional
See Attributes.
make_atleast_2d : bool, optional
@@ -108,6 +113,7 @@ class Options(object):
----------
store_python_metadata : bool
matlab_compatible : bool
+ action_for_matlab_incompatible: {'ignore', 'discard', 'error'}
delete_unused_variables : bool
make_atleast_2d : bool
convert_numpy_bytes_to_utf16 : bool
@@ -128,6 +134,7 @@ class Options(object):
"""
def __init__(self, store_python_metadata=True,
matlab_compatible=True,
+ action_for_matlab_incompatible='error',
delete_unused_variables=False,
make_atleast_2d=False,
convert_numpy_bytes_to_utf16=False,
@@ -142,6 +149,7 @@ class Options(object):
# Set the defaults.
self._store_python_metadata = True
+ self._action_for_matlab_incompatible = 'error'
self._delete_unused_variables = False
self._make_atleast_2d = False
self._convert_numpy_bytes_to_utf16 = False
@@ -159,6 +167,8 @@ class Options(object):
# other ones.
self.store_python_metadata = store_python_metadata
+ self.action_for_matlab_incompatible = \
+ action_for_matlab_incompatible
self.delete_unused_variables = delete_unused_variables
self.make_atleast_2d = make_atleast_2d
self.convert_numpy_bytes_to_utf16 = convert_numpy_bytes_to_utf16
@@ -261,6 +271,33 @@ class Options(object):
self._group_for_references = "/#refs#"
@property
+ def action_for_matlab_incompatible(self):
+ """ The action to do when writing non-MATLAB compatible data.
+
+ {'ignore', 'discard', 'error'}
+
+ The action to perform when doing MATLAB compatibility but a type
+ being written is not MATLAB compatible. The actions are to write
+ the data anyways ('ignore'), don't write the incompatible data
+ ('discard'), or throw a ``TypeNotMatlabCompatibleError``
+ exception. The default is 'error'.
+
+ See Also
+ --------
+ matlab_compatible
+ hdf5storage.lowlevel.TypeNotMatlabCompatibleError
+
+ """
+ return self._action_for_matlab_incompatible
+
+ @action_for_matlab_incompatible.setter
+ def action_for_matlab_incompatible(self, value):
+ # Check that it is one of the allowed values, and then set
+ # it. This option does not effect MATLAB compatibility.
+ if value in ('ignore', 'discard', 'error'):
+ self._action_for_matlab_incompatible = value
+
+ @property
def delete_unused_variables(self):
""" Whether or not to delete file variables not written to.
@@ -818,6 +855,9 @@ def write(data, path='/', filename='data.h5', truncate_existing=False,
------
NotImplementedError
If writing `data` is not supported.
+ TypeNotMatlabCompatibleError
+ If writing a type not compatible with MATLAB and
+ `options.action_for_matlab_incompatible` is set to ``'error'``.
See Also
--------
@@ -1037,6 +1077,7 @@ def read(path='/', filename='data.h5',
def savemat(file_name, mdict, appendmat=True, format='7.3',
oned_as='row', store_python_metadata=True,
+ action_for_matlab_incompatible='error',
marshaller_collection=None, truncate_existing=False,
truncate_invalid_matlab=False, **keywords):
""" Save a dictionary of python types to a MATLAB MAT file.
@@ -1073,6 +1114,11 @@ def savemat(file_name, mdict, appendmat=True, format='7.3',
Whether or not to store Python type information. Doing so allows
most types to be read back perfectly. Only applicable if not
dispatching to SciPy (`format` >= 7.3).
+ action_for_matlab_incompatible: str, optional
+ The action to perform writing data that is not MATLAB
+ compatible. The actions are to write the data anyways
+ ('ignore'), don't write the incompatible data ('discard'), or
+ throw a ``TypeNotMatlabCompatibleError`` exception.
marshaller_collection : MarshallerCollection, optional
Collection of marshallers to disk to use. Only applicable if
not dispatching to SciPy (`format` >= 7.3).
@@ -1093,6 +1139,9 @@ def savemat(file_name, mdict, appendmat=True, format='7.3',
If `format` < 7.3 and the ``scipy`` module can't be found.
NotImplementedError
If writing a variable in `mdict` is not supported.
+ TypeNotMatlabCompatibleError
+ If writing a type not compatible with MATLAB and
+ `action_for_matlab_incompatible` is set to ``'error'``.
Notes
-----
@@ -1126,9 +1175,10 @@ def savemat(file_name, mdict, appendmat=True, format='7.3',
file_name = file_name + '.mat'
# Make the options with matlab compatibility forced.
- options = Options(store_python_metadata=store_python_metadata,
- matlab_compatible=True, oned_as=oned_as,
- marshaller_collection=marshaller_collection)
+ options = Options(store_python_metadata=store_python_metadata, \
+ matlab_compatible=True, oned_as=oned_as, \
+ action_for_matlab_incompatible=action_for_matlab_incompatible, \
+ marshaller_collection=marshaller_collection)
# Write the variables in the dictionary to file one at a time. For
# the first one, the file needs to be truncated or truncated if not
diff --git a/hdf5storage/lowlevel.py b/hdf5storage/lowlevel.py
index baf3832..379dbfa 100644
--- a/hdf5storage/lowlevel.py
+++ b/hdf5storage/lowlevel.py
@@ -42,6 +42,25 @@ class Hdf5storageError(IOError):
class CantReadError(Hdf5storageError):
""" Exception for a failure to read the desired data."""
+ pass
+
+
+class TypeNotMatlabCompatibleError(Hdf5storageError):
+ """ Exception for trying to write non-MATLAB compatible data.
+
+ In the event that MATLAB compatibility is being done
+ (``Options.matlab_compatible``) and a Python type is not importable
+ by MATLAB, the data is either not written or this exception is
+ thrown depending on the value of
+ ``Options.action_for_matlab_incompatible``.
+
+ See Also
+ --------
+ hdf5storage.Options.matlab_compatible
+ hdf5storage.Options.action_for_matlab_incompatible
+
+ """
+ pass
def write_data(f, grp, name, data, type_string, options):
@@ -70,6 +89,9 @@ def write_data(f, grp, name, data, type_string, options):
------
NotImplementedError
If writing `data` is not supported.
+ TypeNotMatlabCompatibleError
+ If writing a type not compatible with MATLAB and
+ `options.action_for_matlab_incompatible` is set to ``'error'``.
See Also
--------
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/python-hdf5storage.git
More information about the debian-science-commits
mailing list