summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPauli Virtanen <pav@iki.fi>2018-02-24 22:18:57 +0100
committerCharles Harris <charlesr.harris@gmail.com>2018-03-11 09:39:17 -0600
commit0fbeba21e6b83dabe5cf8548ca724575a47e87f0 (patch)
tree9085864236db5217681a9be5a22b6c4a884b93c6
parentc0f864c89c1ec52a3431268189eee520dd2332d1 (diff)
downloadnumpy-0fbeba21e6b83dabe5cf8548ca724575a47e87f0.tar.gz
BUG: f2py: fix f2py generated code to work on Pypy
F2py generates code that uses PyTuple_SetItem on a tuple that has been "used", which is invalid on Pypy. Add #ifdefs that make the generated code convert the object to a list, use PyList_SetItem, and then convert it back to a tuple.
-rw-r--r--numpy/f2py/cb_rules.py30
1 files changed, 25 insertions, 5 deletions
diff --git a/numpy/f2py/cb_rules.py b/numpy/f2py/cb_rules.py
index e68fdc17d..183d7c2f9 100644
--- a/numpy/f2py/cb_rules.py
+++ b/numpy/f2py/cb_rules.py
@@ -44,6 +44,7 @@ jmp_buf #name#_jmpbuf;
\tPyTupleObject *capi_arglist = #name#_args_capi;
\tPyObject *capi_return = NULL;
\tPyObject *capi_tmp = NULL;
+\tPyObject *capi_arglist_list = NULL;
\tint capi_j,capi_i = 0;
\tint capi_longjmp_ok = 1;
#decl#
@@ -85,13 +86,31 @@ f2py_cb_start_clock();
\t\tgoto capi_fail;
\t}
#setdims#
+#ifdef PYPY_VERSION
+#define CAPI_ARGLIST_SETITEM(idx, value) PyList_SetItem((PyObject *)capi_arglist_list, idx, value)
+\tcapi_arglist_list = PySequence_List(capi_arglist);
+\tif (capi_arglist_list == NULL) goto capi_fail;
+#else
+#define CAPI_ARGLIST_SETITEM(idx, value) PyTuple_SetItem((PyObject *)capi_arglist, idx, value)
+#endif
#pyobjfrom#
+#undef CAPI_ARGLIST_SETITEM
+#ifdef PYPY_VERSION
+\tCFUNCSMESSPY(\"cb:capi_arglist=\",capi_arglist_list);
+#else
\tCFUNCSMESSPY(\"cb:capi_arglist=\",capi_arglist);
+#endif
\tCFUNCSMESS(\"cb:Call-back calling Python function #argname#.\\n\");
#ifdef F2PY_REPORT_ATEXIT
f2py_cb_start_call_clock();
#endif
+#ifdef PYPY_VERSION
+\tcapi_return = PyObject_CallObject(#name#_capi,(PyObject *)capi_arglist_list);
+\tPy_DECREF(capi_arglist_list);
+\tcapi_arglist_list = NULL;
+#else
\tcapi_return = PyObject_CallObject(#name#_capi,(PyObject *)capi_arglist);
+#endif
#ifdef F2PY_REPORT_ATEXIT
f2py_cb_stop_call_clock();
#endif
@@ -119,6 +138,7 @@ f2py_cb_stop_clock();
capi_fail:
\tfprintf(stderr,\"Call-back #name# failed.\\n\");
\tPy_XDECREF(capi_return);
+\tPy_XDECREF(capi_arglist_list);
\tif (capi_longjmp_ok)
\t\tlongjmp(#name#_jmpbuf,-1);
capi_return_pt:
@@ -318,11 +338,11 @@ cb_arg_rules = [
}, {
'pyobjfrom': [{isintent_in: """\
\tif (#name#_nofargs>capi_i)
-\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyobj_from_#ctype#1(#varname_i#)))
+\t\tif (CAPI_ARGLIST_SETITEM(capi_i++,pyobj_from_#ctype#1(#varname_i#)))
\t\t\tgoto capi_fail;"""},
{isintent_inout: """\
\tif (#name#_nofargs>capi_i)
-\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyarr_from_p_#ctype#1(#varname_i#_cb_capi)))
+\t\tif (CAPI_ARGLIST_SETITEM(capi_i++,pyarr_from_p_#ctype#1(#varname_i#_cb_capi)))
\t\t\tgoto capi_fail;"""}],
'need': [{isintent_in: 'pyobj_from_#ctype#1'},
{isintent_inout: 'pyarr_from_p_#ctype#1'},
@@ -343,12 +363,12 @@ cb_arg_rules = [
'pyobjfrom': [{debugcapi: '\tfprintf(stderr,"debug-capi:cb:#varname#=\\"#showvalueformat#\\":%d:\\n",#varname_i#,#varname_i#_cb_len);'},
{isintent_in: """\
\tif (#name#_nofargs>capi_i)
-\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyobj_from_#ctype#1size(#varname_i#,#varname_i#_cb_len)))
+\t\tif (CAPI_ARGLIST_SETITEM(capi_i++,pyobj_from_#ctype#1size(#varname_i#,#varname_i#_cb_len)))
\t\t\tgoto capi_fail;"""},
{isintent_inout: """\
\tif (#name#_nofargs>capi_i) {
\t\tint #varname_i#_cb_dims[] = {#varname_i#_cb_len};
-\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,pyarr_from_p_#ctype#1(#varname_i#,#varname_i#_cb_dims)))
+\t\tif (CAPI_ARGLIST_SETITEM(capi_i++,pyarr_from_p_#ctype#1(#varname_i#,#varname_i#_cb_dims)))
\t\t\tgoto capi_fail;
\t}"""}],
'need': [{isintent_in: 'pyobj_from_#ctype#1size'},
@@ -381,7 +401,7 @@ cb_arg_rules = [
"""
\t\tif (tmp_arr==NULL)
\t\t\tgoto capi_fail;
-\t\tif (PyTuple_SetItem((PyObject *)capi_arglist,capi_i++,(PyObject *)tmp_arr))
+\t\tif (CAPI_ARGLIST_SETITEM(capi_i++,(PyObject *)tmp_arr))
\t\t\tgoto capi_fail;
}"""],
'_check': l_and(isarray, isintent_nothide, l_or(isintent_in, isintent_inout)),