[pypy-svn] r74064 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test

afa at codespeak.net afa at codespeak.net
Mon Apr 26 13:23:25 CEST 2010


Author: afa
Date: Mon Apr 26 13:23:23 2010
New Revision: 74064

Modified:
   pypy/branch/cpython-extension/pypy/module/cpyext/api.py
   pypy/branch/cpython-extension/pypy/module/cpyext/include/pycobject.h
   pypy/branch/cpython-extension/pypy/module/cpyext/pycobject.py
   pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pycobject.py
Log:
Expose the PyCObject structure to C code.


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	Mon Apr 26 13:23:23 2010
@@ -49,7 +49,8 @@
 class CConfig:
     _compilation_info_ = ExternalCompilationInfo(
         include_dirs=include_dirs,
-        includes=['Python.h', 'stdarg.h']
+        includes=['Python.h', 'stdarg.h'],
+        compile_extra=['-DPy_BUILD_CORE'],
         )
 
 class CConfig_constants:
@@ -646,12 +647,14 @@
     kwds = {}
     export_symbols_eci = export_symbols[:]
 
+    compile_extra=['-DPy_BUILD_CORE']
+
     if building_bridge:
         if sys.platform == "win32":
             # '%s' undefined; assuming extern returning int
-            kwds["compile_extra"] = ["/we4013"]
+            compile_extra.append("/we4013")
         else:
-            kwds["compile_extra"] = ["-Werror=implicit-function-declaration"]
+            compile_extra.append("-Werror=implicit-function-declaration")
         export_symbols_eci.append('pypyAPI')
     else:
         kwds["includes"] = ['Python.h'] # this is our Python.h
@@ -670,6 +673,7 @@
                                ],
         separate_module_sources = [code],
         export_symbols=export_symbols_eci,
+        compile_extra=compile_extra,
         **kwds
         )
     return eci

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/pycobject.h
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/include/pycobject.h	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/include/pycobject.h	Mon Apr 26 13:23:23 2010
@@ -1,5 +1,19 @@
+#ifndef Py_COBJECT_H
+#define Py_COBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if (PY_VERSION_HEX >= 0x02060000 || defined(Py_BUILD_CORE))
 typedef struct {
     PyObject_HEAD
+    void *cobject;
+    void *desc;
     void (*destructor)(void *);
 } PyCObject;
-
+#endif
+ 
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_COBJECT_H */

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pycobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/pycobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/pycobject.py	Mon Apr 26 13:23:23 2010
@@ -8,7 +8,12 @@
 
 destructor_short = lltype.Ptr(lltype.FuncType([rffi.VOIDP_real], lltype.Void))
 destructor_long = lltype.Ptr(lltype.FuncType([rffi.VOIDP_real, rffi.VOIDP_real], lltype.Void))
-PyCObjectStruct = cpython_struct('PyCObject', PyObjectFields + (("destructor", destructor_short), ))
+PyCObjectStruct = cpython_struct('PyCObject',
+                                 PyObjectFields + (
+                                     ("cobject", rffi.VOIDP_real),
+                                     ("desc", rffi.VOIDP_real),
+                                     ("destructor", destructor_short),
+                                     ))
 PyCObject = lltype.Ptr(PyCObjectStruct)
 
 
@@ -27,35 +32,31 @@
                    basestruct=PyCObjectStruct)
 
 class W_PyCObjectFromVoidPtr(W_PyCObject):
-    def __init__(self, space, voidp, desc):
-        W_PyCObject.__init__(self, space)
-        self.voidp = voidp
-        self.pyo = lltype.nullptr(PyCObject.TO)
-        self.desc = desc
-        self.space = space
+    pyo = lltype.nullptr(PyCObjectStruct)
 
     def set_pycobject(self, pyo):
         self.pyo = pyo
 
     def __del__(self):
-        if self.pyo and self.pyo.c_destructor:
-            if self.desc:
+        pyo = self.pyo
+        if pyo and pyo.c_destructor:
+            if pyo.c_desc:
                 generic_cpy_call(self.space, rffi.cast(destructor_long,
-                    self.pyo.c_destructor), self.voidp, self.desc)
+                    pyo.c_destructor), pyo.c_cobject, pyo.c_desc)
             else:
-                generic_cpy_call(self.space, self.pyo.c_destructor, self.voidp)
+                generic_cpy_call(self.space, pyo.c_destructor, pyo.c_cobject)
 
 
 @cpython_api([rffi.VOIDP_real, destructor_short], PyObject)
 def PyCObject_FromVoidPtr(space, cobj, destr):
     """Create a PyCObject from the void * cobj.  The destr function
     will be called when the object is reclaimed, unless it is NULL."""
-    w_pycobject = space.wrap(W_PyCObjectFromVoidPtr(space, cobj,
-        lltype.nullptr(rffi.VOIDP_real.TO)))
+    w_pycobject = space.wrap(W_PyCObjectFromVoidPtr(space))
     assert isinstance(w_pycobject, W_PyCObjectFromVoidPtr)
     pyo = make_ref(space, w_pycobject)
     pycobject = rffi.cast(PyCObject, pyo)
     w_pycobject.set_pycobject(pycobject)
+    pycobject.c_cobject = cobj
     pycobject.c_destructor = destr
     return pyo
 
@@ -64,12 +65,13 @@
     """Create a PyCObject from the void * cobj.  The destr
     function will be called when the object is reclaimed. The desc argument can
     be used to pass extra callback data for the destructor function."""
-    w_pycobject = space.wrap(W_PyCObjectFromVoidPtr(space, cobj,
-        desc))
+    w_pycobject = space.wrap(W_PyCObjectFromVoidPtr(space))
     assert isinstance(w_pycobject, W_PyCObjectFromVoidPtr)
     pyo = make_ref(space, w_pycobject)
     pycobject = rffi.cast(PyCObject, pyo)
     w_pycobject.set_pycobject(pycobject)
+    pycobject.c_cobject = cobj
+    pybobject.c_desc = desc
     pycobject.c_destructor = rffi.cast(destructor_short, destr)
     return pyo
 

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pycobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pycobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pycobject.py	Mon Apr 26 13:23:23 2010
@@ -2,9 +2,13 @@
 
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.test.test_api import BaseApiTest
-from pypy.module.cpyext.pycobject import destructor_short
+from pypy.module.cpyext.pycobject import destructor_short, PyCObject
 
 class TestPyCObject(BaseApiTest):
     def test_pycobject(self, space, api):
-        obj = api.PyCObject_FromVoidPtr(rffi.cast(rffi.VOIDP_real, 0), lltype.nullptr(destructor_short.TO))
-        api.Py_DecRef(obj)
+        ptr = rffi.cast(rffi.VOIDP_real, 1234)
+        obj = api.PyCObject_FromVoidPtr(ptr, lltype.nullptr(destructor_short.TO))
+        try:
+            assert rffi.cast(PyCObject, obj).c_cobject == ptr
+        finally:
+            api.Py_DecRef(obj)



More information about the Pypy-commit mailing list