Author: Antonio Cuni <[email protected]>
Branch: cpyext-refactor-methodobject
Changeset: r92782:17fd1d984f1d
Date: 2017-10-17 00:47 +0200
http://bitbucket.org/pypy/pypy/changeset/17fd1d984f1d/
Log: write a specialized function to convert args_w into a py_tuple,
which sets directly c_ob_item[*] instead of going through the
slowish PyTuple_SetItem
diff --git a/pypy/module/cpyext/methodobject.py
b/pypy/module/cpyext/methodobject.py
--- a/pypy/module/cpyext/methodobject.py
+++ b/pypy/module/cpyext/methodobject.py
@@ -16,7 +16,7 @@
from pypy.module.cpyext.pyobject import (
decref, from_ref, make_ref, as_pyobj, make_typedescr)
from pypy.module.cpyext.state import State
-from pypy.module.cpyext.tupleobject import PyTuple_SetItem
+from pypy.module.cpyext.tupleobject import tuple_from_args_w
PyMethodDef = cts.gettype('PyMethodDef')
PyCFunction = cts.gettype('PyCFunction')
@@ -133,11 +133,7 @@
state = space.fromcache(State)
w_self = self.w_self
func = self.ml.c_ml_meth
- n = len(args_w)
- py_args = state.C.PyTuple_New(n)
- for i, w_item in enumerate(args_w):
- py_item = make_ref(space, w_item)
- PyTuple_SetItem(space, py_args, i, py_item)
+ py_args = tuple_from_args_w(space, args_w)
try:
return generic_cpy_call(space, func, w_self, py_args)
finally:
diff --git a/pypy/module/cpyext/test/test_tupleobject.py
b/pypy/module/cpyext/test/test_tupleobject.py
--- a/pypy/module/cpyext/test/test_tupleobject.py
+++ b/pypy/module/cpyext/test/test_tupleobject.py
@@ -6,7 +6,8 @@
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rlib.debug import FatalError
from pypy.module.cpyext.tupleobject import (
- PyTupleObject, PyTuple_Check, PyTuple_SetItem, PyTuple_Size)
+ PyTupleObject, PyTuple_Check, PyTuple_SetItem, PyTuple_Size,
+ tuple_from_args_w)
from pypy.module.cpyext.state import State
class TestTupleObject(BaseApiTest):
@@ -77,6 +78,16 @@
assert py_b == py_a
assert py_b.c_ob_pypy_link == 0
+ def test_tuple_from_args_w(self, space, api):
+ args_w = [space.newint(i) for i in (40, 41, 42)]
+ py_tuple = tuple_from_args_w(space, args_w)
+ assert py_tuple.c_ob_refcnt == 1
+ assert api.PyTuple_Size(py_tuple) == 3
+ py_items = [api.PyTuple_GetItem(py_tuple, i) for i in range(3)]
+ items = [api.PyInt_AsLong(py_obj) for py_obj in py_items]
+ assert items == [40, 41, 42]
+ decref(space, py_tuple)
+
def test_tuple_resize(self, space, api):
state = space.fromcache(State)
w_42 = space.wrap(42)
diff --git a/pypy/module/cpyext/tupleobject.py
b/pypy/module/cpyext/tupleobject.py
--- a/pypy/module/cpyext/tupleobject.py
+++ b/pypy/module/cpyext/tupleobject.py
@@ -113,6 +113,14 @@
track_reference(space, py_obj, w_obj)
return w_obj
+def tuple_from_args_w(space, args_w):
+ state = space.fromcache(State)
+ n = len(args_w)
+ py_tuple = state.C.PyTuple_New(n) # XXX: check for errors?
+ py_tuple = rffi.cast(PyTupleObject, py_tuple)
+ for i, w_obj in enumerate(args_w):
+ py_tuple.c_ob_item[i] = make_ref(space, w_obj)
+ return rffi.cast(PyObject, py_tuple)
@cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real, error=-1)
def PyTuple_SetItem(space, ref, index, py_obj):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit