diff options
Diffstat (limited to 'numpy/lib/format.py')
-rw-r--r-- | numpy/lib/format.py | 72 |
1 files changed, 36 insertions, 36 deletions
diff --git a/numpy/lib/format.py b/numpy/lib/format.py index 1ecd72815..2afa4ac10 100644 --- a/numpy/lib/format.py +++ b/numpy/lib/format.py @@ -161,15 +161,12 @@ alternatives, is described in the `"npy-format" NEP evolved with time and this document is more current. """ -from __future__ import division, absolute_import, print_function - import numpy -import sys import io import warnings from numpy.lib.utils import safe_eval from numpy.compat import ( - isfileobj, long, os_fspath, pickle + isfileobj, os_fspath, pickle ) @@ -215,10 +212,7 @@ def magic(major, minor): raise ValueError("major version must be 0 <= major < 256") if minor < 0 or minor > 255: raise ValueError("minor version must be 0 <= minor < 256") - if sys.version_info[0] < 3: - return MAGIC_PREFIX + chr(major) + chr(minor) - else: - return MAGIC_PREFIX + bytes([major, minor]) + return MAGIC_PREFIX + bytes([major, minor]) def read_magic(fp): """ Read the magic string to get the version of the file format. @@ -236,12 +230,19 @@ def read_magic(fp): if magic_str[:-2] != MAGIC_PREFIX: msg = "the magic string is not correct; expected %r, got %r" raise ValueError(msg % (MAGIC_PREFIX, magic_str[:-2])) - if sys.version_info[0] < 3: - major, minor = map(ord, magic_str[-2:]) - else: - major, minor = magic_str[-2:] + major, minor = magic_str[-2:] return major, minor +def _has_metadata(dt): + if dt.metadata is not None: + return True + elif dt.names is not None: + return any(_has_metadata(dt[k]) for k in dt.names) + elif dt.subdtype is not None: + return _has_metadata(dt.base) + else: + return False + def dtype_to_descr(dtype): """ Get a serializable descriptor from the dtype. @@ -265,6 +266,10 @@ def dtype_to_descr(dtype): replicate the input dtype. """ + if _has_metadata(dtype): + warnings.warn("metadata on a dtype may be saved or ignored, but will " + "raise if saved when read. Use another form of storage.", + UserWarning, stacklevel=2) if dtype.names is not None: # This is a record array. The .descr is fine. XXX: parts of the # record array with an empty name, like padding bytes, still get @@ -290,7 +295,11 @@ def descr_to_dtype(descr): # subtype, will always have a shape descr[1] dt = descr_to_dtype(descr[0]) return numpy.dtype((dt, descr[1])) - fields = [] + + titles = [] + names = [] + formats = [] + offsets = [] offset = 0 for field in descr: if len(field) == 2: @@ -304,14 +313,13 @@ def descr_to_dtype(descr): # Once support for blank names is removed, only "if name == ''" needed) is_pad = (name == '' and dt.type is numpy.void and dt.names is None) if not is_pad: - fields.append((name, dt, offset)) - + title, name = name if isinstance(name, tuple) else (None, name) + titles.append(title) + names.append(name) + formats.append(dt) + offsets.append(offset) offset += dt.itemsize - names, formats, offsets = zip(*fields) - # names may be (title, names) tuples - nametups = (n if isinstance(n, tuple) else (None, n) for n in names) - titles, names = zip(*nametups) return numpy.dtype({'names': names, 'formats': formats, 'titles': titles, 'offsets': offsets, 'itemsize': offset}) @@ -530,16 +538,11 @@ def _filter_header(s): """ import tokenize - if sys.version_info[0] >= 3: - from io import StringIO - else: - from StringIO import StringIO + from io import StringIO tokens = [] last_token_was_number = False - # adding newline as python 2.7.5 workaround - string = s + "\n" - for token in tokenize.generate_tokens(StringIO(string).readline): + for token in tokenize.generate_tokens(StringIO(s).readline): token_type = token[0] token_string = token[1] if (last_token_was_number and @@ -549,8 +552,7 @@ def _filter_header(s): else: tokens.append(token) last_token_was_number = (token_type == tokenize.NUMBER) - # removing newline (see above) as python 2.7.5 workaround - return tokenize.untokenize(tokens)[:-1] + return tokenize.untokenize(tokens) def _read_array_header(fp, version): @@ -592,7 +594,7 @@ def _read_array_header(fp, version): # Sanity-check the values. if (not isinstance(d['shape'], tuple) or - not numpy.all([isinstance(x, (int, long)) for x in d['shape']])): + not numpy.all([isinstance(x, int) for x in d['shape']])): msg = "shape is not valid: {!r}" raise ValueError(msg.format(d['shape'])) if not isinstance(d['fortran_order'], bool): @@ -600,7 +602,7 @@ def _read_array_header(fp, version): raise ValueError(msg.format(d['fortran_order'])) try: dtype = descr_to_dtype(d['descr']) - except TypeError as e: + except TypeError: msg = "descr is not a valid dtype descriptor: {!r}" raise ValueError(msg.format(d['descr'])) @@ -729,12 +731,10 @@ def read_array(fp, allow_pickle=False, pickle_kwargs=None): try: array = pickle.load(fp, **pickle_kwargs) except UnicodeError as err: - if sys.version_info[0] >= 3: - # Friendlier error message - raise UnicodeError("Unpickling a python object failed: %r\n" - "You may need to pass the encoding= option " - "to numpy.load" % (err,)) - raise + # Friendlier error message + raise UnicodeError("Unpickling a python object failed: %r\n" + "You may need to pass the encoding= option " + "to numpy.load" % (err,)) else: if isfileobj(fp): # We can use the fast fromfile() function. |