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

Reply via email to