diff options
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/_dtype.py | 49 | ||||
-rw-r--r-- | numpy/core/src/multiarray/descriptor.c | 73 | ||||
-rw-r--r-- | numpy/core/tests/test_defchararray.py | 26 | ||||
-rw-r--r-- | numpy/core/tests/test_errstate.py | 14 | ||||
-rw-r--r-- | numpy/core/tests/test_numeric.py | 9 | ||||
-rw-r--r-- | numpy/core/tests/test_regression.py | 21 |
6 files changed, 65 insertions, 127 deletions
diff --git a/numpy/core/_dtype.py b/numpy/core/_dtype.py index ca2c1eaff..26c44eaaf 100644 --- a/numpy/core/_dtype.py +++ b/numpy/core/_dtype.py @@ -20,10 +20,10 @@ def __str__(dtype): def __repr__(dtype): - if dtype.fields is not None: - return _struct_repr(dtype) - else: - return "dtype({})".format(_construction_repr(dtype, include_align=True)) + arg_str = _construction_repr(dtype, include_align=False) + if dtype.isalignedstruct: + arg_str = arg_str + ", align=True" + return "dtype({})".format(arg_str) def _unpack_field(dtype, offset, title=None): @@ -73,8 +73,11 @@ def _construction_repr(dtype, include_align=False, short=False): return _struct_str(dtype, include_align=include_align) elif dtype.subdtype: return _subarray_str(dtype) + else: + return _scalar_str(dtype, short=short) +def _scalar_str(dtype, short): byteorder = _byte_order_str(dtype) if dtype.type == np.bool_: @@ -161,8 +164,14 @@ def _byte_order_str(dtype): def _datetime_metadata_str(dtype): - # This is a hack since the data is not exposed to python in any other way - return dtype.name[dtype.name.rfind('['):] + # TODO: this duplicates the C append_metastr_to_string + unit, count = np.datetime_data(dtype) + if unit == 'generic': + return '' + elif count == 1: + return '[{}]'.format(unit) + else: + return '[{}{}]'.format(count, unit) def _struct_dict_str(dtype, includealignedflag): @@ -283,12 +292,26 @@ def _subarray_str(dtype): ) -def _struct_repr(dtype): - s = "dtype(" - s += _struct_str(dtype, include_align=False) - if dtype.isalignedstruct: - s += ", align=True" - s += ")" - return s +def _name_get(dtype): + # provides dtype.name.__get__ + + if dtype.isbuiltin == 2: + # user dtypes don't promise to do anything special + return dtype.type.__name__ + + # Builtin classes are documented as returning a "bit name" + name = dtype.type.__name__ + + # handle bool_, str_, etc + if name[-1] == '_': + name = name[:-1] + + # append bit counts to str, unicode, and void + if np.issubdtype(dtype, np.flexible) and not _isunsized(dtype): + name += "{}".format(dtype.itemsize * 8) + # append metadata to datetimes + elif dtype.type in (np.datetime64, np.timedelta64): + name += _datetime_metadata_str(dtype) + return name diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c index 8c8c0b61c..439980877 100644 --- a/numpy/core/src/multiarray/descriptor.c +++ b/numpy/core/src/multiarray/descriptor.c @@ -1859,72 +1859,17 @@ arraydescr_protocol_typestr_get(PyArray_Descr *self) } static PyObject * -arraydescr_typename_get(PyArray_Descr *self) +arraydescr_name_get(PyArray_Descr *self) { - static const char np_prefix[] = "numpy."; - const int np_prefix_len = sizeof(np_prefix) - 1; - PyTypeObject *typeobj = self->typeobj; + /* let python handle this */ + PyObject *_numpy_dtype; PyObject *res; - char *s; - int len; - int prefix_len; - int suffix_len; - - if (PyTypeNum_ISUSERDEF(self->type_num)) { - s = strrchr(typeobj->tp_name, '.'); - if (s == NULL) { - res = PyUString_FromString(typeobj->tp_name); - } - else { - res = PyUString_FromStringAndSize(s + 1, strlen(s) - 1); - } - return res; - } - else { - /* - * NumPy type or subclass - * - * res is derived from typeobj->tp_name with the following rules: - * - if starts with "numpy.", that prefix is removed - * - if ends with "_", that suffix is removed - */ - len = strlen(typeobj->tp_name); - - if (! strncmp(typeobj->tp_name, np_prefix, np_prefix_len)) { - prefix_len = np_prefix_len; - } - else { - prefix_len = 0; - } - - if (typeobj->tp_name[len - 1] == '_') { - suffix_len = 1; - } - else { - suffix_len = 0; - } - - len -= prefix_len; - len -= suffix_len; - res = PyUString_FromStringAndSize(typeobj->tp_name+prefix_len, len); - } - if (PyTypeNum_ISFLEXIBLE(self->type_num) && !PyDataType_ISUNSIZED(self)) { - PyObject *p; - p = PyUString_FromFormat("%d", self->elsize * 8); - PyUString_ConcatAndDel(&res, p); - } - if (PyDataType_ISDATETIME(self)) { - PyArray_DatetimeMetaData *meta; - - meta = get_datetime_metadata_from_dtype(self); - if (meta == NULL) { - Py_DECREF(res); - return NULL; - } - - res = append_metastr_to_string(meta, 0, res); + _numpy_dtype = PyImport_ImportModule("numpy.core._dtype"); + if (_numpy_dtype == NULL) { + return NULL; } - + res = PyObject_CallMethod(_numpy_dtype, "_name_get", "O", self); + Py_DECREF(_numpy_dtype); return res; } @@ -2218,7 +2163,7 @@ static PyGetSetDef arraydescr_getsets[] = { (getter)arraydescr_protocol_typestr_get, NULL, NULL, NULL}, {"name", - (getter)arraydescr_typename_get, + (getter)arraydescr_name_get, NULL, NULL, NULL}, {"base", (getter)arraydescr_base_get, diff --git a/numpy/core/tests/test_defchararray.py b/numpy/core/tests/test_defchararray.py index 43f1b71c7..7b0e6f8a4 100644 --- a/numpy/core/tests/test_defchararray.py +++ b/numpy/core/tests/test_defchararray.py @@ -6,7 +6,7 @@ import numpy as np from numpy.core.multiarray import _vec_string from numpy.testing import ( assert_, assert_equal, assert_array_equal, assert_raises, - suppress_warnings, + assert_raises_regex, suppress_warnings, ) kw_unicode_true = {'unicode': True} # make 2to3 work properly @@ -626,12 +626,9 @@ class TestOperations(object): assert_array_equal(Ar, (self.A * r)) for ob in [object(), 'qrs']: - try: - A * ob - except ValueError: - pass - else: - self.fail("chararray can only be multiplied by integers") + with assert_raises_regex(ValueError, + 'Can only multiply by integers'): + A*ob def test_rmul(self): A = self.A @@ -641,12 +638,9 @@ class TestOperations(object): assert_array_equal(Ar, (r * self.A)) for ob in [object(), 'qrs']: - try: + with assert_raises_regex(ValueError, + 'Can only multiply by integers'): ob * A - except ValueError: - pass - else: - self.fail("chararray can only be multiplied by integers") def test_mod(self): """Ticket #856""" @@ -668,13 +662,9 @@ class TestOperations(object): assert_(("%r" % self.A) == repr(self.A)) for ob in [42, object()]: - try: + with assert_raises_regex( + TypeError, "unsupported operand type.* and 'chararray'"): ob % self.A - except TypeError: - pass - else: - self.fail("chararray __rmod__ should fail with " - "non-string objects") def test_slice(self): """Regression test for https://github.com/numpy/numpy/issues/5982""" diff --git a/numpy/core/tests/test_errstate.py b/numpy/core/tests/test_errstate.py index 4f6111921..670d485c1 100644 --- a/numpy/core/tests/test_errstate.py +++ b/numpy/core/tests/test_errstate.py @@ -4,7 +4,7 @@ import platform import pytest import numpy as np -from numpy.testing import assert_ +from numpy.testing import assert_, assert_raises class TestErrstate(object): @@ -16,12 +16,8 @@ class TestErrstate(object): with np.errstate(invalid='ignore'): np.sqrt(a) # While this should fail! - try: + with assert_raises(FloatingPointError): np.sqrt(a) - except FloatingPointError: - pass - else: - self.fail("Did not raise an invalid error") def test_divide(self): with np.errstate(all='raise', under='ignore'): @@ -30,12 +26,8 @@ class TestErrstate(object): with np.errstate(divide='ignore'): a // 0 # While this should fail! - try: + with assert_raises(FloatingPointError): a // 0 - except FloatingPointError: - pass - else: - self.fail("Did not raise divide by zero error") def test_errcall(self): def foo(*args): diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py index e7181736f..7e2d6d1d1 100644 --- a/numpy/core/tests/test_numeric.py +++ b/numpy/core/tests/test_numeric.py @@ -13,7 +13,7 @@ from numpy.random import rand, randint, randn from numpy.testing import ( assert_, assert_equal, assert_raises, assert_raises_regex, assert_array_equal, assert_almost_equal, assert_array_almost_equal, - suppress_warnings, HAS_REFCOUNT + assert_raises, suppress_warnings, HAS_REFCOUNT ) @@ -471,12 +471,9 @@ class TestSeterr(object): @pytest.mark.skipif(platform.machine() == "armv5tel", reason="See gh-413.") def test_divide_err(self): with np.errstate(divide='raise'): - try: + with assert_raises(FloatingPointError): np.array([1.]) / np.array([0.]) - except FloatingPointError: - pass - else: - self.fail() + np.seterr(divide='ignore') np.array([1.]) / np.array([0.]) diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index c38625dac..8be00dad6 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -16,7 +16,8 @@ import numpy as np from numpy.testing import ( assert_, assert_equal, IS_PYPY, assert_almost_equal, assert_array_equal, assert_array_almost_equal, assert_raises, - assert_warns, suppress_warnings, _assert_valid_refcount, HAS_REFCOUNT, + assert_raises_regex, assert_warns, suppress_warnings, + _assert_valid_refcount, HAS_REFCOUNT, ) from numpy.compat import asbytes, asunicode, long @@ -1309,28 +1310,18 @@ class TestRegression(object): # Regression test for #1061. # Set a size which cannot fit into a 64 bits signed integer sz = 2 ** 64 - good = 'Maximum allowed dimension exceeded' - try: + with assert_raises_regex(ValueError, + 'Maximum allowed dimension exceeded'): np.empty(sz) - except ValueError as e: - if not str(e) == good: - self.fail("Got msg '%s', expected '%s'" % (e, good)) - except Exception as e: - self.fail("Got exception of type %s instead of ValueError" % type(e)) def test_huge_arange(self): # Regression test for #1062. # Set a size which cannot fit into a 64 bits signed integer sz = 2 ** 64 - good = 'Maximum allowed size exceeded' - try: + with assert_raises_regex(ValueError, + 'Maximum allowed size exceeded'): np.arange(sz) assert_(np.size == sz) - except ValueError as e: - if not str(e) == good: - self.fail("Got msg '%s', expected '%s'" % (e, good)) - except Exception as e: - self.fail("Got exception of type %s instead of ValueError" % type(e)) def test_fromiter_bytes(self): # Ticket #1058 |