summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2018-09-14 09:33:26 -0700
committerGitHub <noreply@github.com>2018-09-14 09:33:26 -0700
commitdbfeb060a31cc625519289c7f07941c0ddfc7146 (patch)
tree3b1d03ed4abe62cda90e4fb115bbc69ac946cd69 /numpy/core
parent2c061739859c84632f31ba08b61f405a05ac07f4 (diff)
parent15775ffc18937471c5c19bbd8389f4e0ccd0adeb (diff)
downloadnumpy-dbfeb060a31cc625519289c7f07941c0ddfc7146.tar.gz
Merge branch 'master' into gufunc-signature-modification2
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/_dtype.py49
-rw-r--r--numpy/core/src/multiarray/descriptor.c73
-rw-r--r--numpy/core/tests/test_defchararray.py26
-rw-r--r--numpy/core/tests/test_errstate.py14
-rw-r--r--numpy/core/tests/test_numeric.py9
-rw-r--r--numpy/core/tests/test_regression.py21
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