[pypy-svn] r73900 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include src test
afa at codespeak.net
afa at codespeak.net
Tue Apr 20 12:00:57 CEST 2010
Author: afa
Date: Tue Apr 20 12:00:55 2010
New Revision: 73900
Modified:
pypy/branch/cpython-extension/pypy/module/cpyext/api.py
pypy/branch/cpython-extension/pypy/module/cpyext/eval.py
pypy/branch/cpython-extension/pypy/module/cpyext/include/eval.h
pypy/branch/cpython-extension/pypy/module/cpyext/src/modsupport.c
pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py
pypy/branch/cpython-extension/pypy/module/cpyext/test/test_eval.py
Log:
Add PyObject_CallFunction and PyObject_CallMethod
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Tue Apr 20 12:00:55 2010
@@ -241,6 +241,8 @@
'PyArg_ParseTuple', 'PyArg_UnpackTuple', 'PyArg_ParseTupleAndKeywords',
'PyString_FromFormat', 'PyString_FromFormatV', 'PyModule_AddObject',
'Py_BuildValue', 'PyTuple_Pack', 'PyErr_Format',
+ 'PyEval_CallFunction', 'PyEval_CallMethod', 'PyObject_CallFunction',
+ 'PyObject_CallMethod',
'PyBuffer_FromMemory', 'PyBuffer_Type', 'init_bufferobject',
'_PyArg_NoKeywords', 'PyObject_AsReadBuffer', 'PyObject_CheckReadBuffer',
]
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/eval.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/eval.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/eval.py Tue Apr 20 12:00:55 2010
@@ -14,3 +14,14 @@
of the Python expression apply(callable_object, args) or
callable_object(*args)."""
return space.call(w_obj, w_arg)
+
+ at cpython_api([PyObject, PyObject, PyObject], PyObject)
+def PyObject_Call(space, w_obj, w_args, w_kw):
+ """
+ Call a callable Python object, with arguments given by the
+ tuple args, and named arguments given by the dictionary kw. If no named
+ arguments are needed, kw may be NULL. args must not be NULL, use an
+ empty tuple if no arguments are needed. Returns the result of the call on
+ success, or NULL on failure. This is the equivalent of the Python expression
+ apply(callable_object, args, kw) or callable_object(*args, **kw)."""
+ return space.call(w_obj, w_args, w_kw)
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/eval.h
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/include/eval.h (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/include/eval.h Tue Apr 20 12:00:55 2010
@@ -12,6 +12,11 @@
#define PyEval_CallObject(func,arg) \
PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL)
+PyObject * PyEval_CallFunction(PyObject *obj, const char *format, ...);
+PyObject * PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...);
+PyObject * PyObject_CallFunction(PyObject *obj, char *format, ...);
+PyObject * PyObject_CallMethod(PyObject *obj, char *name, char *format, ...);
+
#ifdef __cplusplus
}
#endif
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/src/modsupport.c
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/src/modsupport.c (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/src/modsupport.c Tue Apr 20 12:00:55 2010
@@ -518,6 +518,80 @@
return res;
}
+static PyObject*
+call_function_tail(PyObject *callable, PyObject *args)
+{
+ PyObject *retval;
+
+ if (args == NULL)
+ return NULL;
+
+ if (!PyTuple_Check(args)) {
+ PyObject *a;
+
+ a = PyTuple_New(1);
+ if (a == NULL) {
+ Py_DECREF(args);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(a, 0, args);
+ args = a;
+ }
+ retval = PyObject_Call(callable, args, NULL);
+
+ Py_DECREF(args);
+
+ return retval;
+}
+
+PyObject *
+PyObject_CallFunction(PyObject *callable, char *format, ...)
+{
+ va_list va;
+ PyObject *args;
+
+ if (format && *format) {
+ va_start(va, format);
+ args = Py_VaBuildValue(format, va);
+ va_end(va);
+ }
+ else
+ args = PyTuple_New(0);
+
+ return call_function_tail(callable, args);
+}
+
+PyObject *
+PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
+{
+ va_list va;
+ PyObject *args;
+ PyObject *func = NULL;
+ PyObject *retval = NULL;
+
+ func = PyObject_GetAttrString(o, name);
+ if (func == NULL) {
+ PyErr_SetString(PyExc_AttributeError, name);
+ return 0;
+ }
+
+ if (format && *format) {
+ va_start(va, format);
+ args = Py_VaBuildValue(format, va);
+ va_end(va);
+ }
+ else
+ args = PyTuple_New(0);
+
+ retval = call_function_tail(func, args);
+
+ exit:
+ /* args gets consumed in call_function_tail */
+ Py_XDECREF(func);
+
+ return retval;
+}
+
int
PyModule_AddObject(PyObject *m, const char *name, PyObject *o)
{
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py Tue Apr 20 12:00:55 2010
@@ -4411,21 +4411,6 @@
and 0 otherwise. This function always succeeds."""
raise NotImplementedError
- at cpython_api([PyObject, PyObject, PyObject], PyObject)
-def PyObject_Call(space, callable_object, args, kw):
- """
-
-
-
- Call a callable Python object callable_object, with arguments given by the
- tuple args, and named arguments given by the dictionary kw. If no named
- arguments are needed, kw may be NULL. args must not be NULL, use an
- empty tuple if no arguments are needed. Returns the result of the call on
- success, or NULL on failure. This is the equivalent of the Python expression
- apply(callable_object, args, kw) or callable_object(*args, **kw).
- """
- raise NotImplementedError
-
@cpython_api([PyObject, rffi.CCHARP, ...], PyObject)
def PyObject_CallFunction(space, callable, format, ):
"""
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_eval.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_eval.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_eval.py Tue Apr 20 12:00:55 2010
@@ -1,4 +1,4 @@
-
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
from pypy.module.cpyext.test.test_api import BaseApiTest
class TestEval(BaseApiTest):
@@ -55,3 +55,22 @@
w_res = api.PyObject_CallObject(w_f, w_t)
assert space.int_w(w_res) == 10
+
+class AppTestCall(AppTestCpythonExtensionBase):
+ def test_CallFunction(self):
+ module = self.import_extension('foo', [
+ ("call_func", "METH_VARARGS",
+ """
+ return PyObject_CallFunction(PyTuple_GetItem(args, 0),
+ "siO", "text", 42, Py_None);
+ """),
+ ("call_method", "METH_VARARGS",
+ """
+ return PyObject_CallMethod(PyTuple_GetItem(args, 0),
+ "count", "s", "t");
+ """),
+ ])
+ def f(*args):
+ return args
+ assert module.call_func(f) == ("text", 42, None)
+ assert module.call_method("text") == 2
More information about the Pypy-commit
mailing list