[pypy-commit] pypy cpyext-injection: (arigato, plan_rich) implement parts of numpy (tiny parts, i.e. getitem & setitem)

plan_rich pypy.commits at gmail.com
Thu Oct 20 08:48:12 EDT 2016


Author: Richard Plangger <planrichi at gmail.com>
Branch: cpyext-injection
Changeset: r87892:556fde4a7bcb
Date: 2016-10-20 14:47 +0200
http://bitbucket.org/pypy/pypy/changeset/556fde4a7bcb/

Log:	(arigato, plan_rich) implement parts of numpy (tiny parts, i.e.
	getitem & setitem)

diff --git a/pypy/module/cpyext/injection/test/multiarray.c b/pypy/module/cpyext/injection/test/multiarray.c
--- a/pypy/module/cpyext/injection/test/multiarray.c
+++ b/pypy/module/cpyext/injection/test/multiarray.c
@@ -46,10 +46,58 @@
 
 static
 void array_dealloc(PyArrayObject * self){
+    free(self->data);
+    free(self->dimensions);
+    free(self->strides);
     Py_TYPE(self)->tp_free((PyObject *)self);
 }
 
 static
+PyObject * array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds);
+
+static int
+array_assign_item(PyArrayObject *self, Py_ssize_t i, PyObject *op)
+{
+   if (i < 0 || i >= self->dimensions[0]) {
+       PyErr_SetString(PyExc_IndexError, "index out of bounds");
+       return -1;
+   }
+
+   double * data = (double*)self->data;
+   double value = PyFloat_AsDouble(op);
+   data[i] = value;
+
+   return 0;
+}
+
+static PyObject *
+array_item(PyArrayObject *self, Py_ssize_t i)
+{
+   if (i < 0 || i >= self->dimensions[0]) {
+       PyErr_SetString(PyExc_IndexError, "index out of bounds");
+       return NULL;
+   }
+   double * data = (double*)self->data;
+   double value = data[i];
+
+   return PyFloat_FromDouble(value);
+}
+
+static
+PySequenceMethods array_as_sequence = {
+    (lenfunc)NULL,                  /*sq_length*/
+    (binaryfunc)NULL,                       /*sq_concat is handled by nb_add*/
+    (ssizeargfunc)NULL,
+    (ssizeargfunc)array_item,
+    (ssizessizeargfunc)NULL,
+    (ssizeobjargproc)array_assign_item,        /*sq_ass_item*/
+    (ssizessizeobjargproc)NULL,               /*sq_ass_slice*/
+    (objobjproc) NULL,                         /*sq_contains */
+    (binaryfunc) NULL,                      /*sg_inplace_concat */
+    (ssizeargfunc)NULL,
+};
+
+static
 PyTypeObject PyArray_Type = {
 #if defined(NPY_PY3K)
     PyVarObject_HEAD_INIT(NULL, 0)
@@ -73,8 +121,7 @@
     (reprfunc)NULL,                       /* tp_repr */
     0,
     //&array_as_number,                           /* tp_as_number */
-    0,
-    //&array_as_sequence,                         /* tp_as_sequence */
+    &array_as_sequence,                         /* tp_as_sequence */
     0,
     //&array_as_mapping,                          /* tp_as_mapping */
     /*
@@ -118,8 +165,7 @@
     (initproc)0,                                /* tp_init */
     0,
     //(allocfunc)array_alloc,                     /* tp_alloc */
-    0,
-    //(newfunc)array_new,                         /* tp_new */
+    (newfunc)array_new,                         /* tp_new */
     0,
     //(freefunc)array_free,                       /* tp_free */
     0,                                          /* tp_is_gc */
@@ -132,6 +178,32 @@
     0,                                          /* tp_version_tag */
 };
 
+static PyObject *
+array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
+{
+    Py_ssize_t size;
+    if (!PyArg_ParseTuple(args, "n", &size)) {
+        goto fail;
+    }
+
+    PyArrayObject * array = PyObject_New(PyArrayObject, &PyArray_Type);
+    array->data = malloc(sizeof(double)*size);
+    array->nd = 1;
+    npy_intp * dims = malloc(sizeof(npy_intp)*1);
+    dims[0] = size;
+    array->dimensions = dims;
+    npy_intp * strides = malloc(sizeof(npy_intp)*1);
+    strides[0] = 0;
+    array->strides = strides;
+    array->base = NULL;
+    array->descr = NULL;
+    array->flags = 0;
+    array->weakreflist = NULL;
+    return (PyObject*)array;
+fail:
+    return NULL;
+}
+
 /* List of functions exported by this module */
 
 static PyMethodDef multiarray_functions[] = {
diff --git a/pypy/module/cpyext/injection/test/test_numpy.py b/pypy/module/cpyext/injection/test/test_numpy.py
--- a/pypy/module/cpyext/injection/test/test_numpy.py
+++ b/pypy/module/cpyext/injection/test/test_numpy.py
@@ -8,4 +8,7 @@
         AppTestCpythonExtensionBase.setup_class.im_func(cls)
 
     def test_getitem_basic(self):
-        module = self.import_module(name='multiarray', filename='../injection/test/multiarray')
+        np = self.import_module(name='multiarray', filename='../injection/test/multiarray')
+        array = np.ndarray(100)
+        array[10] = 1.0
+        assert array[10] == 1.0


More information about the pypy-commit mailing list