Author: Armin Rigo <ar...@tunes.org> Branch: cpyext-ext Changeset: r82643:df19cf072629 Date: 2016-03-01 20:49 +0100 http://bitbucket.org/pypy/pypy/changeset/df19cf072629/
Log: test and fix: slot_tp_call diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py --- a/pypy/module/cpyext/slotdefs.py +++ b/pypy/module/cpyext/slotdefs.py @@ -336,10 +336,6 @@ space.get_and_call_args(w_descr, w_self, args) return 0 -@cpython_api([PyObject, PyObject, PyObject], PyObject, header=None) -def slot_tp_call(space, w_self, w_args, w_kwds): - return space.call(w_self, w_args, w_kwds) - @cpython_api([PyObject], PyObject, header=None) def slot_tp_str(space, w_self): return space.str(w_self) @@ -402,6 +398,7 @@ def slot_tp_getattro(space, w_self, w_name): return space.call_function(getattr_fn, w_self, w_name) api_func = slot_tp_getattro.api_func + elif name == 'tp_as_number.c_nb_float': float_fn = w_type.getdictvalue(space, '__float__') if float_fn is None: @@ -412,6 +409,20 @@ def slot_nb_float(space, w_self): return space.call_function(float_fn, w_self) api_func = slot_nb_float.api_func + + elif name == 'tp_call': + call_fn = w_type.getdictvalue(space, '__call__') + if call_fn is None: + return + + @cpython_api([PyObject, PyObject, PyObject], PyObject, header=header) + @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name)) + def slot_tp_call(space, w_self, w_args, w_kwds): + args = Arguments(space, [w_self], + w_stararg=w_args, w_starstararg=w_kwds) + return space.call_args(call_fn, args) + api_func = slot_tp_call.api_func + else: return diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py --- a/pypy/module/cpyext/test/test_typeobject.py +++ b/pypy/module/cpyext/test/test_typeobject.py @@ -526,21 +526,28 @@ module = self.import_extension('foo', [ ("tp_call", "METH_VARARGS", ''' - PyObject *obj = PyTuple_GET_ITEM(args, 0); - PyObject *c_args = PyTuple_GET_ITEM(args, 1); - if (!obj->ob_type->tp_call) + PyTypeObject *type = (PyTypeObject *)PyTuple_GET_ITEM(args, 0); + PyObject *obj = PyTuple_GET_ITEM(args, 1); + PyObject *c_args = PyTuple_GET_ITEM(args, 2); + if (!type->tp_call) { PyErr_SetNone(PyExc_ValueError); return NULL; } - return obj->ob_type->tp_call(obj, c_args, NULL); + return type->tp_call(obj, c_args, NULL); ''' ) ]) class C: def __call__(self, *args): return args - assert module.tp_call(C(), ('x', 2)) == ('x', 2) + assert module.tp_call(type(C()), C(), ('x', 2)) == ('x', 2) + class D(type): + def __call__(self, *args): + return "foo! %r" % (args,) + typ1 = D('d', (), {}) + #assert module.tp_call(D, typ1, ()) == "foo! ()" XXX not working so far + assert isinstance(module.tp_call(type, typ1, ()), typ1) def test_tp_str(self): module = self.import_extension('foo', [ _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit