diff options
-rw-r--r-- | numpy/core/src/multiarray/arraytypes.c.src | 5 | ||||
-rw-r--r-- | numpy/core/src/multiarray/methods.c | 18 | ||||
-rw-r--r-- | numpy/core/src/multiarray/scalartypes.c.src | 19 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 52 | ||||
-rw-r--r-- | numpy/core/tests/test_scalarmath.py | 13 | ||||
-rw-r--r-- | numpy/lib/tests/test_format.py | 32 |
6 files changed, 121 insertions, 18 deletions
diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src index 8a0b1826b..876529a1f 100644 --- a/numpy/core/src/multiarray/arraytypes.c.src +++ b/numpy/core/src/multiarray/arraytypes.c.src @@ -3696,6 +3696,7 @@ static int * #align = char, char, npy_ucs4# * #NAME = Void, String, Unicode# * #endian = |, |, =# + * #flags = 0, 0, NPY_NEEDS_INIT# */ static PyArray_ArrFuncs _Py@NAME@_ArrFuncs = { { @@ -3775,8 +3776,8 @@ static PyArray_Descr @from@_Descr = { NPY_@from@LTR, /* byteorder */ '@endian@', - /* flags */ - 0, + /* flags, unicode needs init as py3.3 does not like printing garbage */ + @flags@, /* type_num */ NPY_@from@, /* elsize */ diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c index a791c2c22..bfd3bc3c1 100644 --- a/numpy/core/src/multiarray/methods.c +++ b/numpy/core/src/multiarray/methods.c @@ -1901,6 +1901,19 @@ array_dumps(PyArrayObject *self, PyObject *args) static PyObject * +array_sizeof(PyArrayObject *self) +{ + /* object + dimension and strides */ + Py_ssize_t nbytes = NPY_SIZEOF_PYARRAYOBJECT + + PyArray_NDIM(self) * sizeof(npy_intp) * 2; + if (PyArray_CHKFLAGS(self, NPY_ARRAY_OWNDATA)) { + nbytes += PyArray_NBYTES(self); + } + return PyLong_FromSsize_t(nbytes); +} + + +static PyObject * array_transpose(PyArrayObject *self, PyObject *args) { PyObject *shape = Py_None; @@ -2308,6 +2321,11 @@ NPY_NO_EXPORT PyMethodDef array_methods[] = { (PyCFunction)array_wraparray, METH_VARARGS, NULL}, + /* for the sys module */ + {"__sizeof__", + (PyCFunction) array_sizeof, + METH_NOARGS, NULL}, + /* for the copy module */ {"__copy__", (PyCFunction)array_copy_keeporder, diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src index 4fa634098..54f57bcf4 100644 --- a/numpy/core/src/multiarray/scalartypes.c.src +++ b/numpy/core/src/multiarray/scalartypes.c.src @@ -1193,6 +1193,20 @@ gentype_size_get(PyObject *NPY_UNUSED(self)) return PyInt_FromLong(1); } +static PyObject * +gentype_sizeof(PyObject *self) +{ + Py_ssize_t nbytes; + PyObject * isz = gentype_itemsize_get(self); + if (isz == NULL) { + return NULL; + } + nbytes = PyLong_AsLong(isz) + Py_TYPE(self)->tp_basicsize + + Py_SIZE(self) * Py_TYPE(self)->tp_itemsize; + Py_DECREF(isz); + return PyLong_FromSsize_t(nbytes); +} + #if PY_VERSION_HEX >= 0x03000000 NPY_NO_EXPORT void gentype_struct_free(PyObject *ptr) @@ -1921,6 +1935,11 @@ static PyMethodDef gentype_methods[] = { (PyCFunction)gentype_wraparray, METH_VARARGS, doc_sc_wraparray}, + /* for the sys module */ + {"__sizeof__", + (PyCFunction)gentype_sizeof, + METH_NOARGS, NULL}, + /* for the copy module */ {"__copy__", (PyCFunction)gentype_copy, diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 70398ee84..96db8cde3 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -586,6 +586,12 @@ class TestCreation(TestCase): assert_array_equal(zeros_like(d), d) assert_equal(zeros_like(d).dtype, d.dtype) + def test_empty_unicode(self): + # don't throw decode errors on garbage memory + for i in range(5, 100, 5): + d = np.empty(i, dtype='U') + str(d) + def test_sequence_non_homogenous(self): assert_equal(np.array([4, 2**80]).dtype, np.object) assert_equal(np.array([4, 2**80, 4]).dtype, np.object) @@ -4566,5 +4572,51 @@ class TestWhere(TestCase): assert_equal(np.where(False, b, a), "abcd") +class TestSizeOf(TestCase): + + def test_empty_array(self): + x = np.array([]) + assert_(sys.getsizeof(x) > 0) + + def check_array(self, dtype): + elem_size = dtype(0).itemsize + + for length in [10, 50, 100, 500]: + x = np.arange(length, dtype=dtype) + assert_(sys.getsizeof(x) > length * elem_size) + + def test_array_int32(self): + self.check_array(np.int32) + + def test_array_int64(self): + self.check_array(np.int64) + + def test_array_float32(self): + self.check_array(np.float32) + + def test_array_float64(self): + self.check_array(np.float64) + + def test_view(self): + d = np.ones(100) + assert_(sys.getsizeof(d[...]) < sys.getsizeof(d)) + + def test_reshape(self): + d = np.ones(100) + assert_(sys.getsizeof(d) < sys.getsizeof(d.reshape(100, 1, 1).copy())) + + def test_resize(self): + d = np.ones(100) + old = sys.getsizeof(d) + d.resize(50) + assert_(old > sys.getsizeof(d)) + d.resize(150) + assert_(old < sys.getsizeof(d)) + + def test_error(self): + d = np.ones(100) + assert_raises(TypeError, d.__sizeof__, "a") + + if __name__ == "__main__": run_module_suite() diff --git a/numpy/core/tests/test_scalarmath.py b/numpy/core/tests/test_scalarmath.py index afdc06c03..3ba3beff9 100644 --- a/numpy/core/tests/test_scalarmath.py +++ b/numpy/core/tests/test_scalarmath.py @@ -271,5 +271,18 @@ class TestRepr(object): for t in [np.float32, np.float64]: yield self._test_type_repr, t + +class TestSizeOf(TestCase): + + def test_equal_nbytes(self): + for type in types: + x = type(0) + assert_(sys.getsizeof(x) > x.nbytes) + + def test_error(self): + d = np.float32() + assert_raises(TypeError, d.__sizeof__, "a") + + if __name__ == "__main__": run_module_suite() diff --git a/numpy/lib/tests/test_format.py b/numpy/lib/tests/test_format.py index eea6f1e5c..c09386789 100644 --- a/numpy/lib/tests/test_format.py +++ b/numpy/lib/tests/test_format.py @@ -678,28 +678,28 @@ def test_bad_header(): def test_large_file_support(): from nose import SkipTest + if (sys.platform == 'win32' or sys.platform == 'cygwin'): + raise SkipTest("Unknown if Windows has sparse filesystems") # try creating a large sparse file - with tempfile.NamedTemporaryFile() as tf: - try: - # seek past end would work too, but linux truncate somewhat - # increases the chances that we have a sparse filesystem and can - # avoid actually writing 5GB - import subprocess as sp - sp.check_call(["truncate", "-s", "5368709120", tf.name]) - except: - raise SkipTest("Could not create 5GB large file") - # write a small array to the end - f = open(tf.name, "wb") + tf_name = os.path.join(tempdir, 'sparse_file') + try: + # seek past end would work too, but linux truncate somewhat + # increases the chances that we have a sparse filesystem and can + # avoid actually writing 5GB + import subprocess as sp + sp.check_call(["truncate", "-s", "5368709120", tf_name]) + except: + raise SkipTest("Could not create 5GB large file") + # write a small array to the end + with open(tf_name, "wb") as f: f.seek(5368709120) d = np.arange(5) np.save(f, d) - f.close() - # read it back - f = open(tf.name, "rb") + # read it back + with open(tf_name, "rb") as f: f.seek(5368709120) r = np.load(f) - f.close() - assert_array_equal(r, d) + assert_array_equal(r, d) if __name__ == "__main__": |