diff options
author | Eric Wieser <wieser.eric@gmail.com> | 2018-01-11 22:15:01 -0800 |
---|---|---|
committer | Eric Wieser <wieser.eric@gmail.com> | 2018-02-15 00:53:20 -0800 |
commit | 7a3344a461fdb25c55cd5e4fa52abda895f01e20 (patch) | |
tree | ff2d9a32f57f9cb180f573de6c28e8599e691de2 /numpy/core | |
parent | a30b29466087997255737bd2ae04ede0c4f71448 (diff) | |
download | numpy-7a3344a461fdb25c55cd5e4fa52abda895f01e20.tar.gz |
BUG: Fix crash on non-void structured array repr
Fixes gh-9821
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/arrayprint.py | 32 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 4 |
2 files changed, 29 insertions, 7 deletions
diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index 62f967131..3554fe3c4 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -365,9 +365,6 @@ def _get_format_function(data, **options): find the right formatting function for the dtype_ """ dtype_ = data.dtype - if dtype_.fields is not None: - return StructureFormat.from_data(data, **options) - dtypeobj = dtype_.type formatdict = _get_formatdict(data, **options) if issubclass(dtypeobj, _nt.bool_): @@ -394,7 +391,10 @@ def _get_format_function(data, **options): elif issubclass(dtypeobj, _nt.object_): return formatdict['object']() elif issubclass(dtypeobj, _nt.void): - return formatdict['void']() + if dtype_.names is not None: + return StructuredVoidFormat.from_data(data, **options) + else: + return formatdict['void']() else: return formatdict['numpystr']() @@ -1164,14 +1164,21 @@ class SubArrayFormat(object): return "[" + ", ".join(self.__call__(a) for a in arr) + "]" -class StructureFormat(object): +class StructuredVoidFormat(object): + """ + Formatter for structured np.void objects. + + This does not work on structured alias types like np.dtype(('i4', 'i2,i2')), + as alias scalars lose their field information, and the implementation + relies upon np.void.__getitem__. + """ def __init__(self, format_functions): self.format_functions = format_functions @classmethod def from_data(cls, data, **options): """ - This is a second way to initialize StructureFormat, using the raw data + This is a second way to initialize StructuredVoidFormat, using the raw data as input. Added to avoid changing the signature of __init__. """ format_functions = [] @@ -1192,13 +1199,24 @@ class StructureFormat(object): else: return "({})".format(", ".join(str_fields)) + +# for backwards compatibility +class StructureFormat(StructuredVoidFormat): + def __init__(self, *args, **kwargs): + # NumPy 1.14, 2018-02-14 + warnings.warn( + "StructureFormat has been replaced by StructuredVoidFormat", + DeprecationWarning, stacklevel=2) + super(StructureFormat, self).__init__(*args, **kwargs) + + def _void_scalar_repr(x): """ Implements the repr for structured-void scalars. It is called from the scalartypes.c.src code, and is placed here because it uses the elementwise formatters defined above. """ - return StructureFormat.from_data(array(x), **_format_options)(x) + return StructuredVoidFormat.from_data(array(x), **_format_options)(x) _typelessdata = [int_, float_, complex_, bool_] diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index d80eaf8d5..f17fa573e 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -483,6 +483,10 @@ class TestDtypedescr(object): dt_int = np.dtype(('i4', fields)) assert_equal(str(dt_int), "(numpy.int32, [('a', '<i2'), ('b', '<i2')])") + # gh-9821 + arr_int = np.zeros(4, dt_int) + assert_equal(repr(arr_int), "array([0, 0, 0, 0])") + class TestZeroRank(object): def setup(self): |