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

xoraxax at codespeak.net xoraxax at codespeak.net
Tue Apr 6 01:30:39 CEST 2010


Author: xoraxax
Date: Tue Apr  6 01:30:37 2010
New Revision: 73423

Added:
   pypy/branch/cpython-extension/pypy/module/cpyext/include/pycobject.h   (contents, props changed)
   pypy/branch/cpython-extension/pypy/module/cpyext/pycobject.py   (contents, props changed)
   pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pycobject.py   (contents, props changed)
Modified:
   pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py
Log:
Add support for PyCObjects.


Added: pypy/branch/cpython-extension/pypy/module/cpyext/include/pycobject.h
==============================================================================
--- (empty file)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/include/pycobject.h	Tue Apr  6 01:30:37 2010
@@ -0,0 +1,5 @@
+typedef struct {
+    PyObject_HEAD
+    void (*destructor)(void *);
+} PyCObject;
+

Added: pypy/branch/cpython-extension/pypy/module/cpyext/pycobject.py
==============================================================================
--- (empty file)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/pycobject.py	Tue Apr  6 01:30:37 2010
@@ -0,0 +1,48 @@
+from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.typedef import TypeDef
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.pyobject import make_ref
+from pypy.module.cpyext.api import generic_cpy_call, cpython_api, PyObject,\
+        cpython_struct, PyObjectFields
+
+
+destructor = lltype.Ptr(lltype.FuncType([rffi.VOIDP_real], lltype.Void))
+PyCObjectStruct = cpython_struct('PyCObject', PyObjectFields + (("destructor", destructor), ))
+PyCObject = lltype.Ptr(PyCObjectStruct)
+
+
+class W_PyCObject(Wrappable):
+    def __init__(self, space):
+        self.space = space
+
+class W_PyCObjectFromVoidPtr(W_PyCObject):
+    def __init__(self, space, voidp):
+        W_PyCObject.__init__(self, space)
+        self.voidp = voidp
+        self.pyo = lltype.nullptr(PyObject.TO)
+
+    def set_pycobject(self, pyo):
+        self.pyo = pyo
+
+    def __del__(self):
+        if self.pyo and self.pyo.c_destructor:
+            self.pyo.c_destructor(self.voidp)
+
+ at cpython_api([rffi.VOIDP_real, destructor], 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))
+    pyo = make_ref(space, w_pycobject)
+    pycobject = rffi.cast(PyCObject, pyo)
+    w_pycobject.set_pycobject(pycobject)
+    pycobject.c_destructor = destr
+    return pyo
+
+
+W_PyCObject.typedef = TypeDef(
+    'PyCObject',
+    )
+W_PyCObject.typedef.acceptable_as_base_class = False
+
+

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py	Tue Apr  6 01:30:37 2010
@@ -33,6 +33,7 @@
 def make_ref(space, w_obj, borrowed=False, steal=False):
     from pypy.module.cpyext.typeobject import allocate_type_obj,\
             W_PyCTypeObject, PyOLifeline
+    from pypy.module.cpyext.pycobject import W_PyCObject, PyCObject
     if w_obj is None:
         return lltype.nullptr(PyObject.TO)
     assert isinstance(w_obj, W_Root)
@@ -81,6 +82,12 @@
             py_obj = rffi.cast(PyObject, py_obj_unicode)
             py_obj.c_ob_refcnt = 1
             py_obj.c_ob_type = rffi.cast(PyTypeObjectPtr, pto)
+        elif isinstance(w_obj, W_PyCObject): # a PyCObject
+            py_cobj = lltype.malloc(PyCObject.TO, flavor='raw', zero=True)
+            pto = make_ref(space, space.type(w_obj))
+            py_obj = rffi.cast(PyObject, py_cobj)
+            py_obj.c_ob_refcnt = 1
+            py_obj.c_ob_type = rffi.cast(PyTypeObjectPtr, pto)
         else:
             py_obj = lltype.malloc(PyObject.TO, flavor="raw", zero=True)
             py_obj.c_ob_refcnt = 1

Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pycobject.py
==============================================================================
--- (empty file)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pycobject.py	Tue Apr  6 01:30:37 2010
@@ -0,0 +1,10 @@
+import py
+
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.pycobject import destructor
+
+class TestPyCObject(BaseApiTest):
+    def test_pycobject(self, space, api):
+        obj = api.PyCObject_FromVoidPtr(rffi.cast(rffi.VOIDP_real, 0), lltype.nullptr(destructor.TO))
+        api.Py_DecRef(obj)



More information about the Pypy-commit mailing list