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

trundle at codespeak.net trundle at codespeak.net
Thu Apr 1 16:11:09 CEST 2010


Author: trundle
Date: Thu Apr  1 16:11:08 2010
New Revision: 73246

Added:
   pypy/branch/cpython-extension/pypy/module/cpyext/structmember.py
   pypy/branch/cpython-extension/pypy/module/cpyext/structmemberdefs.py
Modified:
   pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h
   pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c
   pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py
   pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py
   pypy/branch/cpython-extension/pypy/module/cpyext/typeobjectdefs.py
Log:
Add structmembers; only int members are implemented for now.


Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h	Thu Apr  1 16:11:08 2010
@@ -42,6 +42,9 @@
 #include "dictobject.h"
 #include "intobject.h"
 
+// XXX This shouldn't be included here
+#include "structmember.h"
+
 #include <pypy_decl.h>
 
 #endif

Added: pypy/branch/cpython-extension/pypy/module/cpyext/structmember.py
==============================================================================
--- (empty file)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/structmember.py	Thu Apr  1 16:11:08 2010
@@ -0,0 +1,38 @@
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.typedef import TypeDef, GetSetProperty
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext import structmemberdefs
+from pypy.module.cpyext.api import ADDR, cpython_api
+from pypy.module.cpyext.intobject import PyInt_AsLong
+from pypy.module.cpyext.pyerrors import PyErr_Occurred
+from pypy.module.cpyext.pyobject import PyObject
+from pypy.module.cpyext.typeobjectdefs import PyMemberDef
+
+
+ at cpython_api([PyObject, lltype.Ptr(PyMemberDef)], PyObject)
+def PyMember_GetOne(space, obj, w_member):
+    ptr = rffi.cast(ADDR, obj)
+    member_type = w_member.c_type
+    if member_type == structmemberdefs.T_INT:
+        result = rffi.cast(rffi.INTP, ptr + w_member.c_offset)
+        w_result = space.wrap(result[0])
+    else:
+        raise OperationError(space.w_SystemError,
+                             space.wrap("bad memberdescr type"))
+    return w_result
+
+
+ at cpython_api([PyObject, lltype.Ptr(PyMemberDef), PyObject], rffi.INT_real, error=-1)
+def PyMember_SetOne(space, obj, w_member, w_value):
+    ptr = rffi.cast(ADDR, obj)
+    member_type = w_member.c_type
+    if member_type == structmemberdefs.T_INT:
+        w_long_value = PyInt_AsLong(space, w_value)
+        if w_long_value == -1 and PyErr_Occurred(space):
+            return -1
+        array = rffi.cast(rffi.INTP, ptr + w_member.c_offset)
+        array[0] = rffi.cast(rffi.INT, w_long_value)
+    else:
+        raise OperationError(space.w_SystemError,
+                             space.wrap("bad memberdescr type"))
+    return 0

Added: pypy/branch/cpython-extension/pypy/module/cpyext/structmemberdefs.py
==============================================================================
--- (empty file)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/structmemberdefs.py	Thu Apr  1 16:11:08 2010
@@ -0,0 +1,3 @@
+T_INT = 1
+
+READONLY = RO = 1

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c	Thu Apr  1 16:11:08 2010
@@ -1,4 +1,5 @@
 #include "Python.h"
+#include "structmember.h"
 
 typedef struct {
 	PyObject_HEAD
@@ -92,6 +93,15 @@
     return kwds;
 }
 
+static PyMemberDef foo_members[] = {
+    {"int_member", T_INT, offsetof(fooobject, foo), 0,
+     "A helpful docstring."},
+    {"int_member_readonly", T_INT, offsetof(fooobject, foo), READONLY,
+     "A helpful docstring."},
+    {"broken_member", 0xaffe, 0, 0, ""},
+    {NULL}  /* Sentinel */
+};
+
 static PyTypeObject footype = {
 	PyVarObject_HEAD_INIT(NULL, 0)
 	"foo.foo",		  /*tp_name*/
@@ -122,7 +132,7 @@
         0,			  /*tp_iter*/
         0,			  /*tp_iternext*/
         foo_methods,	          /*tp_methods*/
-        0,      	          /*tp_members*/
+        foo_members,              /*tp_members*/
         foo_getseters,            /*tp_getset*/
 };
 

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py	Thu Apr  1 16:11:08 2010
@@ -28,3 +28,9 @@
 
         print obj.foo
         assert obj.foo == 42
+        assert obj.int_member == obj.foo
+        obj.int_member = 23
+        assert obj.int_member == 23
+        raises(TypeError, "obj.int_member_readonly = 42")
+        raises(SystemError, "obj.broken_member")
+        raises(SystemError, "obj.broken_member = 42")

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py	Thu Apr  1 16:11:08 2010
@@ -15,12 +15,14 @@
     Py_TPFLAGS_READY, Py_TPFLAGS_HEAPTYPE, PyStringObject, ADDR
 from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref
 from pypy.interpreter.module import Module
+from pypy.module.cpyext import structmemberdefs
 from pypy.module.cpyext.modsupport import  convert_method_defs
 from pypy.module.cpyext.state import State
 from pypy.module.cpyext.methodobject import PyDescr_NewWrapper
 from pypy.module.cpyext.pyobject import Py_IncRef, Py_DecRef
+from pypy.module.cpyext.structmember import PyMember_GetOne, PyMember_SetOne
 from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr, PyTypeObject, \
-        PyGetSetDef
+        PyGetSetDef, PyMemberDef
 from pypy.module.cpyext.slotdefs import slotdefs
 from pypy.rlib.rstring import rsplit
 
@@ -42,6 +44,19 @@
 def PyDescr_NewGetSet(space, getset, pto):
     return space.wrap(W_GetSetPropertyEx(getset))
 
+class W_MemberDescr(GetSetProperty):
+    def __init__(self, member):
+        self.member = member
+        self.name = rffi.charp2str(member.c_name)
+        doc = set = None
+        if doc:
+            doc = rffi.charp2str(getset.c_doc)
+        get = W_PyCObject.member_getter
+        if not (member.c_flags & structmemberdefs.READONLY):
+            set = W_PyCObject.member_setter
+        GetSetProperty.__init__(self, get, set, None, doc,
+                                cls=W_PyCObject, use_closure=True)
+
 def convert_getset_defs(space, dict_w, getsets, pto):
     getsets = rffi.cast(rffi.CArrayPtr(PyGetSetDef), getsets)
     if getsets:
@@ -56,6 +71,20 @@
             w_descr = PyDescr_NewGetSet(space, getset, pto)
             dict_w[name] = w_descr
 
+def convert_member_defs(space, dict_w, members, pto):
+    members = rffi.cast(rffi.CArrayPtr(PyMemberDef), members)
+    if members:
+        i = 0
+        while True:
+            member = members[i]
+            name = member.c_name
+            if not name:
+                break
+            name = rffi.charp2str(name)
+            w_descr = space.wrap(W_MemberDescr(member))
+            dict_w[name] = w_descr
+            i += 1
+
 def add_operators(space, dict_w, pto):
     # XXX support PyObject_HashNotImplemented
     state = space.fromcache(State)
@@ -90,7 +119,7 @@
         add_operators(space, dict_w, pto)
         convert_method_defs(space, dict_w, pto.c_tp_methods, pto)
         convert_getset_defs(space, dict_w, pto.c_tp_getset, pto)
-        # XXX missing: convert_member_defs
+        convert_member_defs(space, dict_w, pto.c_tp_members, pto)
 
         full_name = rffi.charp2str(pto.c_tp_name)
         module_name, extension_name = rsplit(full_name, ".", 1)
@@ -120,6 +149,11 @@
             space, self.getset.c_set, w_self, w_value,
             self.getset.c_closure)
 
+    def member_getter(self, space, w_self):
+        return PyMember_GetOne(space, w_self, self.member)
+
+    def member_setter(self, space, w_self, w_value):
+        PyMember_SetOne(space, w_self, self.member, w_value)
 
 class W_PyCObjectDual(W_PyCObject):
     def __init__(self, space):

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobjectdefs.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/typeobjectdefs.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobjectdefs.py	Thu Apr  1 16:11:08 2010
@@ -15,7 +15,7 @@
 
 
 # XXX
-PyBufferProcs = PyMemberDef = rffi.VOIDP.TO
+PyBufferProcs = rffi.VOIDP.TO
 
 freefunc = P(FT([rffi.VOIDP_real], Void))
 destructor = P(FT([PyO], Void))
@@ -144,6 +144,14 @@
 ))
 """
 
+PyMemberDef = cpython_struct("PyMemberDef", (
+    ("name", rffi.CCHARP),
+    ("type",  rffi.INT_real),
+    ("offset", Py_ssize_t),
+    ("flags", rffi.INT_real),
+    ("doc", rffi.CCHARP),
+))
+
 PyTypeObjectFields = []
 PyTypeObjectFields.extend(PyVarObjectFields)
 PyTypeObjectFields.extend([



More information about the Pypy-commit mailing list