[pypy-svn] r72584 - in pypy/trunk/pypy/module/cpyext: . test

xoraxax at codespeak.net xoraxax at codespeak.net
Mon Mar 22 19:16:17 CET 2010


Author: xoraxax
Date: Mon Mar 22 19:16:15 2010
New Revision: 72584

Modified:
   pypy/trunk/pypy/module/cpyext/api.py
   pypy/trunk/pypy/module/cpyext/methodobject.py
   pypy/trunk/pypy/module/cpyext/modsupport.py
   pypy/trunk/pypy/module/cpyext/test/test_typeobject.py
   pypy/trunk/pypy/module/cpyext/typeobject.py
Log:
Make getset properties working. Also pulled out from_ref_ex and generic_cpy_call,
changed interface to convert_method_defs, changed debugging output.


Modified: pypy/trunk/pypy/module/cpyext/api.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/api.py	(original)
+++ pypy/trunk/pypy/module/cpyext/api.py	Mon Mar 22 19:16:15 2010
@@ -14,6 +14,7 @@
 from pypy.translator import platform
 from pypy.module.cpyext.state import State
 from pypy.interpreter.error import OperationError
+from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.gateway import ObjSpace, unwrap_spec
 
 
@@ -124,6 +125,7 @@
     if w_obj is None:
         return lltype.nullptr(PyObject.TO)
         #raise NullPointerException("Trying to pass a NULL reference")
+    assert isinstance(w_obj, W_Root)
     state = space.fromcache(State)
     py_obj = state.py_objects_w2r.get(w_obj)
     if py_obj is None:
@@ -281,7 +283,7 @@
         def wrapper(*args):
             boxed_args = []
             # XXX use unrolling_iterable here
-            print >>sys.stderr, callable
+            print >>sys.stderr, callable,
             for i, typ in enumerate(callable.api_func.argtypes):
                 arg = args[i]
                 if typ is PyObject:
@@ -290,7 +292,7 @@
             state = space.fromcache(State)
             try:
                 retval = callable(space, *boxed_args)
-                print "Callable worked"
+                print >>sys.stderr, " DONE"
             except OperationError, e:
                 e.normalize_exception(space)
                 state.exc_type = e.w_type

Modified: pypy/trunk/pypy/module/cpyext/methodobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/methodobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/methodobject.py	Mon Mar 22 19:16:15 2010
@@ -1,4 +1,4 @@
-from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.baseobjspace import Wrappable, W_Root
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.gateway import ObjSpace, W_Root
 from pypy.interpreter.argument import Arguments
@@ -12,6 +12,38 @@
 from pypy.rlib.objectmodel import we_are_translated
 
 
+def from_ref_ex(space, result):
+    try:
+        ret = from_ref(space, result)
+    except NullPointerException:
+        state = space.fromcache(State)
+        state.check_and_raise_exception()
+        assert False, "NULL returned but no exception set"
+    except InvalidPointerException:
+        if not we_are_translated():
+            import sys
+            print >>sys.stderr, "Calling a C function return an invalid PyObject" \
+                    " pointer."
+        raise
+    return ret
+
+def generic_cpy_call(space, func, *args):
+    boxed_args = []
+    for arg in args: # XXX ur needed
+        if isinstance(arg, W_Root) or arg is None:
+            boxed_args.append(make_ref(space, arg))
+        else:
+            boxed_args.append(arg)
+    result = func(*boxed_args)
+    try:
+        ret = from_ref_ex(space, result)
+        Py_DECREF(space, ret)
+        return ret
+    finally:
+        for arg in args: # XXX ur needed
+            if arg is not None and isinstance(arg, W_Root):
+                Py_DECREF(space, arg)
+
 # XXX use Function as a parent class?
 class W_PyCFunctionObject(Wrappable):
     acceptable_as_base_class = False
@@ -25,26 +57,11 @@
         # Call the C function
         if w_self is None:
             w_self = self.w_self
-        result = self.ml.c_ml_meth(make_ref(space, w_self), make_ref(space, args_tuple))
-        try:
-            ret = from_ref(space, result)
-            Py_DECREF(space, ret)
-            if w_self:
-                Py_DECREF(space, w_self)
-            Py_DECREF(space, args_tuple)
-        except NullPointerException:
-            state = space.fromcache(State)
-            state.check_and_raise_exception()
-            assert False, "NULL returned but no exception set"
-        except InvalidPointerException:
-            if not we_are_translated():
-                import sys
-                print >>sys.stderr, "Calling a C function return an invalid PyObject" \
-                        " pointer."
-            raise
-        return ret
+        return generic_cpy_call(space, self.ml.c_ml_meth, w_self, args_tuple)
+
 
 class W_PyCMethodObject(W_PyCFunctionObject):
+    w_self = None
     def __init__(self, space, ml):
         self.space = space
         self.ml = ml

Modified: pypy/trunk/pypy/module/cpyext/modsupport.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/modsupport.py	(original)
+++ pypy/trunk/pypy/module/cpyext/modsupport.py	Mon Mar 22 19:16:15 2010
@@ -26,15 +26,15 @@
 def Py_InitModule(space, name, methods):
     modname = rffi.charp2str(name)
     w_mod = PyImport_AddModule(space, modname)
-    dict_w = convert_method_defs(space, methods, None)
+    dict_w = {}
+    convert_method_defs(space, dict_w, methods, None)
     for key, w_value in dict_w.items():
         space.setattr(w_mod, space.wrap(key), w_value)
     return w_mod
 
 
-def convert_method_defs(space, methods, pto):
+def convert_method_defs(space, dict_w, methods, pto):
     methods = rffi.cast(rffi.CArrayPtr(PyMethodDef), methods)
-    dict_w = {}
     if methods:
         i = -1
         while True:
@@ -63,7 +63,6 @@
                 else:
                     w_obj = PyDescr_NewMethod(space, pto, method)
             dict_w[methodname] = w_obj
-    return dict_w
 
 
 @cpython_api([PyObject], rffi.INT_real)

Modified: pypy/trunk/pypy/module/cpyext/test/test_typeobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/test/test_typeobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/test/test_typeobject.py	Mon Mar 22 19:16:15 2010
@@ -14,6 +14,6 @@
         assert type(obj) is module.fooType
         print "type of obj has type", type(type(obj))
         obj2 = obj.copy()
+        assert module.new().name == "Foo Example"
         skip("In progress")
         assert "copy" in repr(module.fooType.copy)
-        assert module.new().name == "Foo Example"

Modified: pypy/trunk/pypy/module/cpyext/typeobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/typeobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/typeobject.py	Mon Mar 22 19:16:15 2010
@@ -7,13 +7,15 @@
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.objspace.std.typeobject import W_TypeObject
 from pypy.objspace.std.objectobject import W_ObjectObject
-from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.typedef import TypeDef, GetSetProperty
 from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct
 from pypy.module.cpyext.api import PyObject, PyVarObjectFields, Py_ssize_t
 from pypy.module.cpyext.api import Py_TPFLAGS_READYING, Py_TPFLAGS_READY
 from pypy.interpreter.module import Module
 from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs
 from pypy.module.cpyext.state import State
+from pypy.module.cpyext.methodobject import from_ref_ex, generic_cpy_call
+
 
 PyTypeObject = lltype.ForwardReference()
 PyTypeObjectPtr = lltype.Ptr(PyTypeObject)
@@ -24,7 +26,7 @@
 
 # XXX
 PyNumberMethods = PySequenceMethods = PyMappingMethods = \
-                  PyBufferProcs = PyMemberDef = PyGetSetDef = rffi.VOIDP.TO
+                  PyBufferProcs = PyMemberDef = rffi.VOIDP.TO
 
 freefunc = P(FT([rffi.VOIDP], Void))
 destructor = P(FT([PyO], Void))
@@ -64,6 +66,17 @@
 visitproc = P(FT([PyO, rffi.VOIDP], rffi.INT_real))
 traverseproc = P(FT([PyO, visitproc, rffi.VOIDP], rffi.INT_real))
 
+getter = P(FT([PyO, rffi.VOIDP_real], PyO))
+setter = P(FT([PyO, PyO, rffi.VOIDP_real], rffi.INT_real))
+
+PyGetSetDef = cpython_struct("PyGetSetDef", (
+	("name", rffi.CCHARP),
+    ("get", getter),
+    ("set", setter),
+    ("doc", rffi.CCHARP),
+    ("closure", rffi.VOIDP_real),
+))
+
 PyTypeObjectFields = []
 PyTypeObjectFields.extend(PyVarObjectFields)
 PyTypeObjectFields.extend([
@@ -138,16 +151,55 @@
     ("tp_weaklist", PyObject),
     ("tp_del", destructor),
     ])
-PyTypeObject = cpython_struct(
-    "PyTypeObject",
-    PyTypeObjectFields, PyTypeObject)
+cpython_struct("PyTypeObject", PyTypeObjectFields, PyTypeObject)
+
+
+
+class W_GetSetPropertyEx(GetSetProperty): # XXX fix this to be rpython
+    def getter(self, space, w_self):
+        return generic_cpy_call(space, self.getset.c_get, w_self, self.getset.c_closure)
+
+    def setter(self, space, w_self, w_value):
+        return generic_cpy_call(space, self.getset.c_set, w_self, w_value,
+                self.getset.c_closure)
+
+    def __init__(self, getset):
+        self.getset = getset
+        self.name = rffi.charp2str(getset.c_name)
+        doc = set = get = None
+        if doc:
+            doc = rffi.charp2str(getset.c_doc)
+        if getset.c_get:
+            get = self.getter.im_func
+        if getset.c_set:
+            set = self.setter.im_func
+        GetSetProperty.__init__(self, get, set, None, doc, W_PyCObject, True)
+
+def PyDescr_NewGetSet(space, getset, pto):
+    return space.wrap(W_GetSetPropertyEx(getset))
+
+def convert_getset_defs(space, dict_w, getsets, pto):
+    getsets = rffi.cast(rffi.CArrayPtr(PyGetSetDef), getsets)
+    if getsets:
+        i = -1
+        while True:
+            i = i + 1
+            getset = getsets[i]
+            name = getset.c_name
+            if not name:
+                break
+            name = rffi.charp2str(name)
+            w_descr = PyDescr_NewGetSet(space, getset, pto)
+            dict_w[name] = w_descr
 
 
 class W_PyCTypeObject(W_TypeObject):
     def __init__(self, space, pto):
         self.pto = pto
         bases_w = []
-        dict_w = convert_method_defs(space, pto.c_tp_methods, pto)
+        dict_w = {}
+        convert_method_defs(space, dict_w, pto.c_tp_methods, pto)
+        convert_getset_defs(space, dict_w, pto.c_tp_getset, pto)
         W_TypeObject.__init__(self, space, rffi.charp2str(pto.c_tp_name),
             bases_w or [space.w_object], dict_w)
 
@@ -166,7 +218,6 @@
     return pto
 
 def create_type_object(space, pto):
-
     w_type = space.allocate_instance(W_PyCTypeObject, space.gettypeobject(W_PyCTypeObject.typedef))
     w_type.__init__(space, pto)
     w_type.ready()



More information about the Pypy-commit mailing list