diff options
Diffstat (limited to 'silx/gui/data/TextFormatter.py')
-rw-r--r-- | silx/gui/data/TextFormatter.py | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/silx/gui/data/TextFormatter.py b/silx/gui/data/TextFormatter.py index 37e1f48..332625c 100644 --- a/silx/gui/data/TextFormatter.py +++ b/silx/gui/data/TextFormatter.py @@ -27,12 +27,13 @@ data module to format data as text in the same way.""" __authors__ = ["V. Valls"] __license__ = "MIT" -__date__ = "27/09/2017" +__date__ = "13/12/2017" import numpy import numbers from silx.third_party import six from silx.gui import qt +import logging try: import h5py @@ -40,6 +41,9 @@ except ImportError: h5py = None +_logger = logging.getLogger(__name__) + + class TextFormatter(qt.QObject): """Formatter to convert data to string. @@ -203,8 +207,9 @@ class TextFormatter(qt.QObject): data = [ord(d) for d in data.item()] else: data = data.item().astype(numpy.uint8) - else: + elif six.PY2: data = [ord(d) for d in data] + # In python3 data is already a bytes array data = ["\\x%02X" % d for d in data] if self.__useQuoteForText: return "b\"%s\"" % "".join(data) @@ -221,6 +226,30 @@ class TextFormatter(qt.QObject): else: return "".join(data) + def __formatCharString(self, data): + """Format text of char. + + From the specifications we expect to have ASCII, but we also allow + CP1252 in some ceases as fallback. + + If no encoding fits, it will display a readable ASCII chars, with + escaped chars (using the python syntax) for non decoded characters. + + :param data: A binary string of char expected in ASCII + :rtype: str + """ + try: + text = "%s" % data.decode("ascii") + return self.__formatText(text) + except UnicodeDecodeError: + # Here we can spam errors, this is definitly a badly + # generated file + _logger.error("Invalid ASCII string %s.", data) + if data == b"\xB0": + _logger.error("Fallback using cp1252 encoding") + return self.__formatText(u"\u00B0") + return self.__formatSafeAscii(data) + def __formatH5pyObject(self, data, dtype): # That's an HDF5 object ref = h5py.check_dtype(ref=dtype) @@ -236,11 +265,7 @@ class TextFormatter(qt.QObject): return self.__formatText(data) elif vlen == six.binary_type: # HDF5 ASCII - try: - text = "%s" % data.decode("ascii") - return self.__formatText(text) - except UnicodeDecodeError: - return self.__formatSafeAscii(data) + return self.__formatCharString(data) return None def toString(self, data, dtype=None): @@ -276,14 +301,12 @@ class TextFormatter(qt.QObject): elif isinstance(data, (numpy.unicode_, six.text_type)): return self.__formatText(data) elif isinstance(data, (numpy.string_, six.binary_type)): + if dtype is None and hasattr(data, "dtype"): + dtype = data.dtype if dtype is not None: # Maybe a sub item from HDF5 if dtype.kind == 'S': - try: - text = "%s" % data.decode("ascii") - return self.__formatText(text) - except UnicodeDecodeError: - return self.__formatSafeAscii(data) + return self.__formatCharString(data) elif dtype.kind == 'O': if h5py is not None: text = self.__formatH5pyObject(data, dtype) |