diff options
-rw-r--r-- | numpy/core/src/multiarray/multiarraymodule.c | 66 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 27 |
2 files changed, 93 insertions, 0 deletions
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c index 463acbebd..a31751ec6 100644 --- a/numpy/core/src/multiarray/multiarraymodule.c +++ b/numpy/core/src/multiarray/multiarraymodule.c @@ -1616,6 +1616,72 @@ _array_fromobject(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kws) "only 2 non-keyword arguments accepted"); return NULL; } + + /* super-fast path for ndarray argument calls */ + if (PyTuple_GET_SIZE(args) == 0) { + goto full_path; + } + op = PyTuple_GET_ITEM(args, 0); + if (PyArray_CheckExact(op)) { + PyObject * dtype_obj = Py_None; + oparr = (PyArrayObject *)op; + /* get dtype which can be positional */ + if (PyTuple_GET_SIZE(args) == 2) { + dtype_obj = PyTuple_GET_ITEM(args, 1); + } + else if (kws) { + dtype_obj = PyDict_GetItem(kws, npy_ma_str_dtype); + if (dtype_obj == NULL) { + dtype_obj = Py_None; + } + } + if (dtype_obj != Py_None) { + goto full_path; + } + + /* array(ndarray) */ + if (kws == NULL) { + ret = (PyArrayObject *)PyArray_NewCopy(oparr, order); + goto finish; + } + else { + /* fast path for copy=False rest default (np.asarray) */ + PyObject * copy_obj, * order_obj, *ndmin_obj; + copy_obj = PyDict_GetItem(kws, npy_ma_str_copy); + if (copy_obj != Py_False) { + goto full_path; + } + copy = NPY_FALSE; + + /* order does not matter for 1d arrays */ + if (PyArray_NDIM(op) > 1) { + order_obj = PyDict_GetItem(kws, npy_ma_str_order); + if (order_obj != Py_None && order_obj != NULL) { + goto full_path; + } + } + + ndmin_obj = PyDict_GetItem(kws, npy_ma_str_ndmin); + if (ndmin_obj) { + ndmin = PyLong_AsLong(ndmin_obj); + if (ndmin == -1 && PyErr_Occurred()) { + goto clean_type; + } + else if (ndmin > NPY_MAXDIMS) { + goto full_path; + } + } + + /* copy=False with default dtype, order and ndim */ + if (STRIDING_OK(oparr, order)) { + ret = oparr; + Py_INCREF(ret); + goto finish; + } + } + } + +full_path: if(!PyArg_ParseTupleAndKeywords(args, kws, "O|O&O&O&O&i", kwd, &op, PyArray_DescrConverter2, &type, diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 4c0bc428a..221a930c2 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -246,6 +246,33 @@ class TestArrayConstruction(TestCase): r = np.array([[True, False], [True, False], [False, True]]) assert_equal(r, tgt.T) + def test_array_empty(self): + assert_raises(TypeError, np.array) + + def test_array_copy_false(self): + d = np.array([1, 2, 3]) + e = np.array(d, copy=False) + d[1] = 3 + assert_array_equal(e, [1, 3, 3]) + e = np.array(d, copy=False, order='F') + d[1] = 4 + assert_array_equal(e, [1, 4, 3]) + e[2] = 7 + assert_array_equal(d, [1, 4, 7]) + + def test_array_copy_true(self): + d = np.array([[1,2,3], [1, 2, 3]]) + e = np.array(d, copy=True) + d[0, 1] = 3 + e[0, 2] = -7 + assert_array_equal(e, [[1, 2, -7], [1, 2, 3]]) + assert_array_equal(d, [[1, 3, 3], [1, 2, 3]]) + e = np.array(d, copy=True, order='F') + d[0, 1] = 5 + e[0, 2] = 7 + assert_array_equal(e, [[1, 3, 7], [1, 2, 3]]) + assert_array_equal(d, [[1, 5, 3], [1,2,3]]) + class TestAssignment(TestCase): def test_assignment_broadcasting(self): |