[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