[pypy-svn] r79785 - in pypy/branch/fast-forward/pypy/module/cpyext: . test

afa at codespeak.net afa at codespeak.net
Fri Dec 3 17:56:22 CET 2010


Author: afa
Date: Fri Dec  3 17:56:20 2010
New Revision: 79785

Modified:
   pypy/branch/fast-forward/pypy/module/cpyext/api.py
   pypy/branch/fast-forward/pypy/module/cpyext/complexobject.py
   pypy/branch/fast-forward/pypy/module/cpyext/methodobject.py
   pypy/branch/fast-forward/pypy/module/cpyext/modsupport.py
   pypy/branch/fast-forward/pypy/module/cpyext/test/test_methodobject.py
   pypy/branch/fast-forward/pypy/module/cpyext/typeobject.py
   pypy/branch/fast-forward/pypy/module/cpyext/typeobjectdefs.py
Log:
Implement PyCFunction_GetFunction().
Works only with functions defined in extension modules, not with pypy built-in functions!


Modified: pypy/branch/fast-forward/pypy/module/cpyext/api.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/api.py	(original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/api.py	Fri Dec  3 17:56:20 2010
@@ -193,7 +193,7 @@
       the API headers.
     """
     if error is _NOT_SPECIFIED:
-        if restype is PyObject:
+        if isinstance(restype, lltype.Ptr):
             error = lltype.nullptr(restype.TO)
         elif restype is lltype.Void:
             error = CANNOT_FAIL

Modified: pypy/branch/fast-forward/pypy/module/cpyext/complexobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/complexobject.py	(original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/complexobject.py	Fri Dec  3 17:56:20 2010
@@ -36,7 +36,7 @@
 
 # lltype does not handle functions returning a structure.  This implements a
 # helper function, which takes as argument a reference to the return value.
- at cpython_api([PyObject, Py_complex_ptr], lltype.Void, error=None)
+ at cpython_api([PyObject, Py_complex_ptr], lltype.Void)
 def _PyComplex_AsCComplex(space, w_obj, result):
     """Return the Py_complex value of the complex number op.
 

Modified: pypy/branch/fast-forward/pypy/module/cpyext/methodobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/methodobject.py	(original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/methodobject.py	Fri Dec  3 17:56:20 2010
@@ -16,13 +16,14 @@
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.objspace.std.tupleobject import W_TupleObject
 
+PyCFunction_typedef = rffi.COpaquePtr('PyCFunction')
 PyCFunction = lltype.Ptr(lltype.FuncType([PyObject, PyObject], PyObject))
 PyCFunctionKwArgs = lltype.Ptr(lltype.FuncType([PyObject, PyObject, PyObject], PyObject))
 
 PyMethodDef = cpython_struct(
     'PyMethodDef',
     [('ml_name', rffi.CCHARP),
-     ('ml_meth', PyCFunction),
+     ('ml_meth', PyCFunction_typedef),
      ('ml_flags', rffi.INT_real),
      ('ml_doc', rffi.CCHARP),
      ])
@@ -70,12 +71,14 @@
         if space.is_true(w_kw) and not flags & METH_KEYWORDS:
             raise OperationError(space.w_TypeError, space.wrap(
                 rffi.charp2str(self.ml.c_ml_name) + "() takes no keyword arguments"))
+
+        func = rffi.cast(PyCFunction, self.ml.c_ml_meth)
         if flags & METH_KEYWORDS:
             func = rffi.cast(PyCFunctionKwArgs, self.ml.c_ml_meth)
             return generic_cpy_call(space, func, w_self, w_args, w_kw)
         elif flags & METH_NOARGS:
             if len(w_args.wrappeditems) == 0:
-                return generic_cpy_call(space, self.ml.c_ml_meth, w_self, None)
+                return generic_cpy_call(space, func, w_self, None)
             raise OperationError(space.w_TypeError, space.wrap(
                 rffi.charp2str(self.ml.c_ml_name) + "() takes no arguments"))
         elif flags & METH_O:
@@ -86,9 +89,9 @@
                         rffi.charp2str(self.ml.c_ml_name), 
                         len(w_args.wrappeditems))))
             w_arg = w_args.wrappeditems[0]
-            return generic_cpy_call(space, self.ml.c_ml_meth, w_self, w_arg)
+            return generic_cpy_call(space, func, w_self, w_arg)
         elif flags & METH_VARARGS:
-            return generic_cpy_call(space, self.ml.c_ml_meth, w_self, w_args)
+            return generic_cpy_call(space, func, w_self, w_args)
         else: # METH_OLDARGS, the really old style
             size = len(w_args.wrappeditems)
             if size == 1:
@@ -97,7 +100,7 @@
                 w_arg = None
             else:
                 w_arg = w_args
-            return generic_cpy_call(space, self.ml.c_ml_meth, w_self, w_arg)
+            return generic_cpy_call(space, func, w_self, w_arg)
 
     def get_doc(space, self):
         doc = self.ml.c_ml_doc
@@ -231,6 +234,11 @@
 def PyCFunction_NewEx(space, ml, w_self, w_name):
     return space.wrap(W_PyCFunctionObject(space, ml, w_self, w_name))
 
+ at cpython_api([PyObject], PyCFunction_typedef)
+def PyCFunction_GetFunction(space, w_obj):
+    cfunction = space.interp_w(W_PyCFunctionObject, w_obj)
+    return cfunction.ml.c_ml_meth
+
 @cpython_api([PyObject], PyObject)
 def PyStaticMethod_New(space, w_func):
     return space.wrap(StaticMethod(w_func))

Modified: pypy/branch/fast-forward/pypy/module/cpyext/modsupport.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/modsupport.py	(original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/modsupport.py	Fri Dec  3 17:56:20 2010
@@ -5,7 +5,7 @@
 from pypy.interpreter.module import Module
 from pypy.module.cpyext.methodobject import (
     W_PyCFunctionObject, PyCFunction_NewEx, PyDescr_NewMethod,
-    PyMethodDef, PyCFunction, PyStaticMethod_New)
+    PyMethodDef, PyStaticMethod_New)
 from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
 from pypy.module.cpyext.state import State
 from pypy.interpreter.error import OperationError

Modified: pypy/branch/fast-forward/pypy/module/cpyext/test/test_methodobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/test/test_methodobject.py	(original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/test/test_methodobject.py	Fri Dec  3 17:56:20 2010
@@ -3,7 +3,8 @@
 from pypy.module.cpyext.methodobject import PyMethodDef
 from pypy.module.cpyext.api import ApiFunction
 from pypy.module.cpyext.pyobject import PyObject, make_ref, Py_DecRef
-from pypy.module.cpyext.methodobject import PyDescr_NewMethod
+from pypy.module.cpyext.methodobject import (
+    PyDescr_NewMethod, PyCFunction_typedef)
 from pypy.rpython.lltypesystem import rffi, lltype
 
 class AppTestMethodObject(AppTestCpythonExtensionBase):
@@ -50,6 +51,16 @@
              }
              '''
              ),
+            ('isSameFunction', 'METH_O',
+             '''
+             PyCFunction ptr = PyCFunction_GetFunction(args);
+             if (!ptr) return NULL;
+             if (ptr == foo_getarg_O)
+                 Py_RETURN_TRUE;
+             else
+                 Py_RETURN_FALSE;
+             '''
+             ),
             ])
         assert mod.getarg_O(1) == 1
         raises(TypeError, mod.getarg_O)
@@ -64,6 +75,8 @@
         assert mod.getarg_OLD(1, 2) == (1, 2)
 
         assert mod.isCFunction(mod.getarg_O) == "getarg_O"
+        assert mod.isSameFunction(mod.getarg_O)
+        raises(TypeError, mod.isSameFunction, 1)
 
 class TestPyCMethodObject(BaseApiTest):
     def test_repr(self, space):
@@ -78,7 +91,8 @@
         ml = lltype.malloc(PyMethodDef, flavor='raw', zero=True)
         namebuf = rffi.str2charp('func')
         ml.c_ml_name = namebuf
-        ml.c_ml_meth = c_func.get_llhelper(space)
+        ml.c_ml_meth = rffi.cast(PyCFunction_typedef,
+                                 c_func.get_llhelper(space))
 
         method = PyDescr_NewMethod(space, space.w_str, ml)
         assert repr(method).startswith(

Modified: pypy/branch/fast-forward/pypy/module/cpyext/typeobject.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/typeobject.py	(original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/typeobject.py	Fri Dec  3 17:56:20 2010
@@ -16,10 +16,10 @@
     track_reference, RefcountState, borrow_from)
 from pypy.interpreter.module import Module
 from pypy.module.cpyext import structmemberdefs
-from pypy.module.cpyext.modsupport import convert_method_defs, PyCFunction
+from pypy.module.cpyext.modsupport import convert_method_defs
 from pypy.module.cpyext.state import State
 from pypy.module.cpyext.methodobject import (
-    PyDescr_NewWrapper, PyCFunction_NewEx)
+    PyDescr_NewWrapper, PyCFunction_NewEx, PyCFunction_typedef)
 from pypy.module.cpyext.pyobject import Py_IncRef, Py_DecRef, _Py_Dealloc
 from pypy.module.cpyext.structmember import PyMember_GetOne, PyMember_SetOne
 from pypy.module.cpyext.typeobjectdefs import (
@@ -208,7 +208,7 @@
 
 def setup_new_method_def(space):
     ptr = get_new_method_def(space)
-    ptr.c_ml_meth = rffi.cast(PyCFunction,
+    ptr.c_ml_meth = rffi.cast(PyCFunction_typedef,
         llhelper(tp_new_wrapper.api_func.functype,
                  tp_new_wrapper.api_func.get_wrapper(space)))
 

Modified: pypy/branch/fast-forward/pypy/module/cpyext/typeobjectdefs.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/cpyext/typeobjectdefs.py	(original)
+++ pypy/branch/fast-forward/pypy/module/cpyext/typeobjectdefs.py	Fri Dec  3 17:56:20 2010
@@ -8,7 +8,6 @@
 from pypy.module.cpyext.modsupport import PyMethodDef
 
 
-PyCFunction = Ptr(FuncType([PyObject, PyObject], PyObject))
 P, FT, PyO = Ptr, FuncType, PyObject
 PyOPtr = Ptr(lltype.Array(PyO, hints={'nolength': True}))
 



More information about the Pypy-commit mailing list