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

xoraxax at codespeak.net xoraxax at codespeak.net
Sat Mar 27 19:34:54 CET 2010


Author: xoraxax
Date: Sat Mar 27 19:34:53 2010
New Revision: 72965

Modified:
   pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py
   pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py
   pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py
   pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py
Log:
Remove indirection via wrappers, rpythonize the interface a bit more, add support for kwargs in slot wrappers.

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py	Sat Mar 27 19:34:53 2010
@@ -4,7 +4,7 @@
 from pypy.interpreter.argument import Arguments
 from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w
 from pypy.interpreter.gateway import interp2app, unwrap_spec
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.interpreter.function import BuiltinFunction, Method
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import PyObject, from_ref, \
@@ -44,18 +44,25 @@
 
 
 class W_PyCWrapperObject(Wrappable):
-    def __init__(self, space, pto, method_name, wrapper_func, doc, flags, func):
+    def __init__(self, space, pto, method_name, wrapper_func, wrapper_func_kwds,
+            doc, func):
         self.space = space
         self.method_name = method_name
         self.wrapper_func = wrapper_func
+        self.wrapper_func_kwds = wrapper_func_kwds
         self.doc = doc
-        self.flags = flags
         self.func = func
-        assert flags == 0
         self.w_objclass = from_ref(space, pto)
 
-    def call(self, w_self, w_args):
-        return generic_cpy_call(self.space, self.wrapper_func, w_self, w_args, self.func)
+    def call(self, w_self, w_args, w_kw):
+        if self.wrapper_func is None:
+            assert self.wrapper_func_kwds is not None
+            return self.wrapper_func_kwds(self.space, w_self, w_args, self.func, w_kw)
+        if self.space.is_true(w_kw):
+            raise operationerrfmt(space.w_TypeError,
+                                 "wrapper %s doesn't take any keyword arguments",
+                                 self.method_name)
+        return self.wrapper_func(self.space, w_self, w_args, self.func)
 
 
 @unwrap_spec(ObjSpace, W_Root, Arguments)
@@ -64,10 +71,10 @@
     args_w, kw_w = __args__.unpack()
     w_args = space.newtuple(args_w[1:])
     w_self = args_w[0]
-    if kw_w:
-        raise OperationError(space.w_TypeError,
-                             space.wrap("keywords not yet supported"))
-    return self.call(w_self, w_args)
+    w_kw = space.newdict()
+    for key, w_obj in kw_w.items():
+        space.setitem(w_kw, space.wrap(key), w_obj)
+    return self.call(w_self, w_args, w_kw)
 
 
 @unwrap_spec(ObjSpace, W_Root, Arguments)

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py	Sat Mar 27 19:34:53 2010
@@ -3,15 +3,13 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import generic_cpy_call, cpython_api, \
         PyObject
-from pypy.module.cpyext.typeobjectdefs import unaryfunc, wrapperfunc
+from pypy.module.cpyext.typeobjectdefs import unaryfunc, wrapperfunc,\
+        ternaryfunc
 from pypy.module.cpyext.state import State
 from pypy.interpreter.error import OperationError, operationerrfmt
 
 space = None
 
-def is_wrapper_func(func):
-    deco = cpython_api([PyObject, PyObject, rffi.VOIDP_real], PyObject, external=False)
-    return deco(func)
 
 def check_num_args(space, ob, n):
     from pypy.module.cpyext.tupleobject import PyTuple_CheckExact, \
@@ -24,30 +22,30 @@
     raise operationerrfmt(space.w_TypeError,
         "expected %d arguments, got %zd", n, PyTuple_GET_SIZE(ob))
 
-def wrap_binaryfunc_l(space, w_self, w_args, func):
-    pass
-
-def wrap_binaryfunc_r(space, w_self, w_args, func):
-    pass
-
- at is_wrapper_func
 def wrap_unaryfunc(space, w_self, w_args, func):
     func_unary = rffi.cast(unaryfunc, func)
     check_num_args(space, w_args, 0)
     return generic_cpy_call(space, func_unary, w_self)
 
+def wrap_call(space, w_self, w_args, func, w_kwds):
+    func_target = rffi.cast(ternaryfunc, func)
+    return generic_cpy_call(space, func_target, w_self, w_args, w_kwds)
+
 
 PyWrapperFlag_KEYWORDS = 1
 
 # adopted from typeobject.c
 def FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS):
     wrapper = globals().get(WRAPPER, None)
-    if wrapper is not None:
-        wrapper = wrapper.api_func.get_llhelper(space)
-    else:
-        wrapper = lltype.nullptr(wrapperfunc.TO)
     slotname = ("c_" + SLOT).split(".")
-    return (NAME, slotname, FUNCTION, wrapper, DOC, FLAGS)
+    assert FLAGS == 0 or FLAGS == PyWrapperFlag_KEYWORDS
+    if FLAGS:
+        wrapper1 = None
+        wrapper2 = wrapper
+    else:
+        wrapper1 = wrapper
+        wrapper2 = None
+    return (NAME, slotname, FUNCTION, wrapper1, wrapper2, DOC)
 
 def TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC):
     return FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, 0)
@@ -67,19 +65,18 @@
     return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, WRAPPER,
             "x." + NAME + "(y) <==> x" + DOC + "y")
 def BINSLOT(NAME, SLOT, FUNCTION, DOC):
-    return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, wrap_binaryfunc_l, \
+    return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, "wrap_binaryfunc_l", \
             "x." + NAME + "(y) <==> x" + DOC + "y")
 def RBINSLOT(NAME, SLOT, FUNCTION, DOC):
-    return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, wrap_binaryfunc_r, \
+    return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, "wrap_binaryfunc_r", \
             "x." + NAME + "(y) <==> y" + DOC + "x")
 def BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC):
-    return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, wrap_binaryfunc_l, \
+    return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, "wrap_binaryfunc_l", \
             "x." + NAME + "(y) <==> " + DOC)
 def RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC):
-    return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, wrap_binaryfunc_r, \
+    return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, "wrap_binaryfunc_r", \
             "x." + NAME + "(y) <==> " + DOC)
 
-# TODO remove all casts
 slotdef_replacements = (
         ("\s+", " "),
         ("static [^{]*{", "("),
@@ -88,6 +85,7 @@
         (r"(?P<start> *R?[^ ]{3}SLOT(NOTINFIX)?\([^,]*, )(?P<fname>[^,]*), (?P<slotcname>[^,]*)", r"\g<start>'\g<fname>', '\g<slotcname>'"),
         ("'NULL'", "None"),
         ("{NULL}", ""),
+        ("\(wrapperfunc\)", ""),
         ("\),", "),\n"),
     )
 
@@ -101,7 +99,7 @@
 # Instructions for update:
 # Copy new slotdefs from typeobject.c
 # Remove comments
-# Done
+# Done.
 slotdefs = """
 static slotdef slotdefs[] = {
 	SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc,
@@ -304,3 +302,5 @@
     finally:
         space = None
 
+if __name__ == "__main__":
+    print slotdefs

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	Sat Mar 27 19:34:53 2010
@@ -21,3 +21,5 @@
         assert "copy" in repr(module.fooType.copy)
         assert repr(module.fooType) == "<type 'foo.foo'>"
         assert repr(obj2) == "<Foo>"
+        print module.fooType.__call__
+        assert obj2(foo=1, bar=2) == dict(foo=1, bar=2)

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	Sat Mar 27 19:34:53 2010
@@ -62,8 +62,8 @@
 def add_operators(space, dict_w, pto):
     # XXX support PyObject_HashNotImplemented
     state = space.fromcache(State)
-    for method_name, slot_name, _, wrapper_func, doc, flags in state.slotdefs: # XXX use UI
-        if method_name in dict_w or wrapper_func is None:
+    for method_name, slot_name, _, wrapper_func, wrapper_func_kwds, doc in state.slotdefs: # XXX use UI
+        if method_name in dict_w or (wrapper_func is None and wrapper_func_kwds is None):
             continue
         # XXX is this rpython?
         if len(slot_name) == 1:
@@ -78,7 +78,7 @@
         if not func:
             continue
         dict_w[method_name] = PyDescr_NewWrapper(space, pto, method_name, wrapper_func,
-                doc, flags, func_voidp)
+                wrapper_func_kwds, doc, func_voidp)
 
 
 class W_PyCTypeObject(W_TypeObject):



More information about the Pypy-commit mailing list