[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