[pypy-commit] pypy cpyext-injection: (arigato, plan_rich) hijack getitem of the minimal numpy module
plan_rich
pypy.commits at gmail.com
Thu Oct 20 09:07:50 EDT 2016
Author: Richard Plangger <planrichi at gmail.com>
Branch: cpyext-injection
Changeset: r87893:fb5a66c1d78a
Date: 2016-10-20 15:07 +0200
http://bitbucket.org/pypy/pypy/changeset/fb5a66c1d78a/
Log: (arigato, plan_rich) hijack getitem of the minimal numpy module
diff --git a/pypy/module/cpyext/injection/injection.py b/pypy/module/cpyext/injection/injection.py
--- a/pypy/module/cpyext/injection/injection.py
+++ b/pypy/module/cpyext/injection/injection.py
@@ -4,6 +4,10 @@
if not we_are_translated() and name == 'test_module.test_mytype':
from pypy.module.cpyext.injection._test_module import inject
inject(space, name, dict_w, pto)
+
+ if name == 'numpy.ndarray':
+ from pypy.module.cpyext.injection.numpy import inject_operator
+ inject_operator(space, name, dict_w, pto)
def inject_global(space, w_func, modulename, funcname):
if (not we_are_translated() and modulename == 'injection'
diff --git a/pypy/module/cpyext/injection/numpy.py b/pypy/module/cpyext/injection/numpy.py
--- a/pypy/module/cpyext/injection/numpy.py
+++ b/pypy/module/cpyext/injection/numpy.py
@@ -6,11 +6,12 @@
from pypy.interpreter import typedef
from pypy.objspace.std.intobject import W_IntObject
from pypy.module.cpyext.api import bootstrap_function
+from pypy.interpreter.error import oefmt
PyArrayObject = lltype.Ptr(lltype.Struct(
'PyArrayObject',
*(PyObjectFields +
- (("data", rffi.CHARP),
+ (("data", rffi.CCHARP),
("nd", rffi.INT),
("dimensions", rffi.SIGNEDP),
("strides", rffi.SIGNEDP),
@@ -39,3 +40,22 @@
make_typedescr(W_ArrayObject.typedef,
basestruct=mytype_object.TO,
realize=mything_realize)
+
+ at unwrap_spec(index=int)
+def injected_getitem(space, w_self, index):
+ py_obj = rffi.cast(PyArrayObject, as_pyobj(space, w_self))
+ if index < 0 or index >= py_obj.dimensions[0]:
+ raise oefmt(space.w_IndexError, "index out of bounds")
+ data = rffi.cast(rffi.DOUBLEP, py_obj.data)
+ return space.newfloat(data[index])
+
+injected_methods = {
+ '__getitem__': interp2app(injected_getitem),
+}
+
+def inject_operator(space, name, dict_w, pto):
+ assert name == 'numpy.ndarray'
+ org = space.fromcache(Original)
+ org.w_original_getitem = dict_w['__getitem__']
+ for key, value in injected_methods.items():
+ dict_w[key] = space.wrap(value)
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
@@ -79,6 +79,10 @@
}
double * data = (double*)self->data;
double value = data[i];
+ if (i == 10) {
+ // we try to modify this behaviour on the pypy level
+ value += 42;
+ }
return PyFloat_FromDouble(value);
}
More information about the pypy-commit
mailing list