summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c66
-rw-r--r--numpy/core/tests/test_multiarray.py27
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):