diff options
Diffstat (limited to 'numpy/lib/_iotools.py')
-rw-r--r-- | numpy/lib/_iotools.py | 149 |
1 files changed, 49 insertions, 100 deletions
diff --git a/numpy/lib/_iotools.py b/numpy/lib/_iotools.py index c392929fd..ff5b94342 100644 --- a/numpy/lib/_iotools.py +++ b/numpy/lib/_iotools.py @@ -1,20 +1,11 @@ """A collection of functions designed to help I/O with ascii files. """ -from __future__ import division, absolute_import, print_function - __docformat__ = "restructuredtext en" -import sys import numpy as np import numpy.core.numeric as nx -from numpy.compat import asbytes, asunicode, bytes, basestring - -if sys.version_info[0] >= 3: - from builtins import bool, int, float, complex, object, str - unicode = str -else: - from __builtin__ import bool, int, float, complex, object, unicode, str +from numpy.compat import asbytes, asunicode, bytes def _decode_line(line, encoding=None): @@ -65,40 +56,6 @@ def _is_bytes_like(obj): return True -def _to_filehandle(fname, flag='r', return_opened=False): - """ - Returns the filehandle corresponding to a string or a file. - If the string ends in '.gz', the file is automatically unzipped. - - Parameters - ---------- - fname : string, filehandle - Name of the file whose filehandle must be returned. - flag : string, optional - Flag indicating the status of the file ('r' for read, 'w' for write). - return_opened : boolean, optional - Whether to return the opening status of the file. - """ - if _is_string_like(fname): - if fname.endswith('.gz'): - import gzip - fhd = gzip.open(fname, flag) - elif fname.endswith('.bz2'): - import bz2 - fhd = bz2.BZ2File(fname) - else: - fhd = file(fname, flag) - opened = True - elif hasattr(fname, 'seek'): - fhd = fname - opened = False - else: - raise ValueError('fname must be a string or file handle') - if return_opened: - return fhd, opened - return fhd - - def has_nested_fields(ndtype): """ Returns whether one or several fields of a dtype are nested. @@ -173,7 +130,7 @@ def flatten_dtype(ndtype, flatten_base=False): return types -class LineSplitter(object): +class LineSplitter: """ Object to split a string at a given delimiter or at given places. @@ -210,14 +167,15 @@ class LineSplitter(object): return lambda input: [_.strip() for _ in method(input)] # - def __init__(self, delimiter=None, comments='#', autostrip=True, encoding=None): + def __init__(self, delimiter=None, comments='#', autostrip=True, + encoding=None): delimiter = _decode_line(delimiter) comments = _decode_line(comments) self.comments = comments # Delimiter is a character - if (delimiter is None) or isinstance(delimiter, basestring): + if (delimiter is None) or isinstance(delimiter, str): delimiter = delimiter or None _handyman = self._delimited_splitter # Delimiter is a list of field widths @@ -273,7 +231,7 @@ class LineSplitter(object): return self._handyman(_decode_line(line, self.encoding)) -class NameValidator(object): +class NameValidator: """ Object to validate a list of strings to use as field names. @@ -387,7 +345,7 @@ class NameValidator(object): if (nbfields is None): return None names = [] - if isinstance(names, basestring): + if isinstance(names, str): names = [names, ] if nbfields is not None: nbnames = len(names) @@ -496,7 +454,7 @@ class ConversionWarning(UserWarning): pass -class StringConverter(object): +class StringConverter: """ Factory class for function transforming a string into another object (int, float). @@ -546,18 +504,23 @@ class StringConverter(object): """ # _mapper = [(nx.bool_, str2bool, False), - (nx.integer, int, -1)] + (nx.int_, int, -1),] # On 32-bit systems, we need to make sure that we explicitly include - # nx.int64 since ns.integer is nx.int32. - if nx.dtype(nx.integer).itemsize < nx.dtype(nx.int64).itemsize: + # nx.int64 since ns.int_ is nx.int32. + if nx.dtype(nx.int_).itemsize < nx.dtype(nx.int64).itemsize: _mapper.append((nx.int64, int, -1)) - _mapper.extend([(nx.floating, float, nx.nan), - (nx.complexfloating, complex, nx.nan + 0j), + _mapper.extend([(nx.float64, float, nx.nan), + (nx.complex128, complex, nx.nan + 0j), (nx.longdouble, nx.longdouble, nx.nan), (nx.unicode_, asunicode, '???'), - (nx.string_, asbytes, '???')]) + (nx.string_, asbytes, '???'), + # If a non-default dtype is passed, fall back to generic + # ones (should only be used for the converter) + (nx.integer, int, -1), + (nx.floating, float, nx.nan), + (nx.complexfloating, complex, nx.nan + 0j),]) (_defaulttype, _defaultfunc, _defaultfill) = zip(*_mapper) @@ -701,7 +664,7 @@ class StringConverter(object): if missing_values is None: self.missing_values = {''} else: - if isinstance(missing_values, basestring): + if isinstance(missing_values, str): missing_values = missing_values.split(",") self.missing_values = set(list(missing_values) + ['']) # @@ -748,6 +711,26 @@ class StringConverter(object): return self._callingfunction(value) # + def _do_upgrade(self): + # Raise an exception if we locked the converter... + if self._locked: + errmsg = "Converter is locked and cannot be upgraded" + raise ConverterLockError(errmsg) + _statusmax = len(self._mapper) + # Complains if we try to upgrade by the maximum + _status = self._status + if _status == _statusmax: + errmsg = "Could not find a valid conversion function" + raise ConverterError(errmsg) + elif _status < _statusmax - 1: + _status += 1 + self.type, self.func, default = self._mapper[_status] + self._status = _status + if self._initial_default is not None: + self.default = self._initial_default + else: + self.default = default + def upgrade(self, value): """ Find the best converter for a given string, and return the result. @@ -773,24 +756,7 @@ class StringConverter(object): try: return self._strict_call(value) except ValueError: - # Raise an exception if we locked the converter... - if self._locked: - errmsg = "Converter is locked and cannot be upgraded" - raise ConverterLockError(errmsg) - _statusmax = len(self._mapper) - # Complains if we try to upgrade by the maximum - _status = self._status - if _status == _statusmax: - errmsg = "Could not find a valid conversion function" - raise ConverterError(errmsg) - elif _status < _statusmax - 1: - _status += 1 - (self.type, self.func, default) = self._mapper[_status] - self._status = _status - if self._initial_default is not None: - self.default = self._initial_default - else: - self.default = default + self._do_upgrade() return self.upgrade(value) def iterupgrade(self, value): @@ -802,25 +768,7 @@ class StringConverter(object): for _m in value: _strict_call(_m) except ValueError: - # Raise an exception if we locked the converter... - if self._locked: - errmsg = "Converter is locked and cannot be upgraded" - raise ConverterLockError(errmsg) - _statusmax = len(self._mapper) - # Complains if we try to upgrade by the maximum - _status = self._status - if _status == _statusmax: - raise ConverterError( - "Could not find a valid conversion function" - ) - elif _status < _statusmax - 1: - _status += 1 - (self.type, self.func, default) = self._mapper[_status] - if self._initial_default is not None: - self.default = self._initial_default - else: - self.default = default - self._status = _status + self._do_upgrade() self.iterupgrade(value) def update(self, func, default=None, testing_value=None, @@ -876,7 +824,7 @@ class StringConverter(object): else: if not np.iterable(missing_values): missing_values = [missing_values] - if not all(isinstance(v, basestring) for v in missing_values): + if not all(isinstance(v, str) for v in missing_values): raise TypeError("missing_values must be strings or unicode") self.missing_values.update(missing_values) @@ -926,7 +874,7 @@ def easy_dtype(ndtype, names=None, defaultfmt="f%i", **validationargs): nbfields = len(ndtype) if names is None: names = [''] * len(ndtype) - elif isinstance(names, basestring): + elif isinstance(names, str): names = names.split(",") names = validate(names, nbfields=nbfields, defaultfmt=defaultfmt) ndtype = np.dtype(dict(formats=ndtype, names=names)) @@ -934,7 +882,7 @@ def easy_dtype(ndtype, names=None, defaultfmt="f%i", **validationargs): # Explicit names if names is not None: validate = NameValidator(**validationargs) - if isinstance(names, basestring): + if isinstance(names, str): names = names.split(",") # Simple dtype: repeat to match the nb of names if ndtype.names is None: @@ -949,9 +897,10 @@ def easy_dtype(ndtype, names=None, defaultfmt="f%i", **validationargs): elif ndtype.names is not None: validate = NameValidator(**validationargs) # Default initial names : should we change the format ? - if ((ndtype.names == tuple("f%i" % i for i in range(len(ndtype.names)))) and - (defaultfmt != "f%i")): - ndtype.names = validate([''] * len(ndtype.names), defaultfmt=defaultfmt) + numbered_names = tuple("f%i" % i for i in range(len(ndtype.names))) + if ((ndtype.names == numbered_names) and (defaultfmt != "f%i")): + ndtype.names = validate([''] * len(ndtype.names), + defaultfmt=defaultfmt) # Explicit initial names : just validate else: ndtype.names = validate(ndtype.names, defaultfmt=defaultfmt) |