[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