Author: Antonio Cuni <[email protected]>
Branch: cpyext-refactor-methodobject
Changeset: r92766:e06951cd3fe6
Date: 2017-10-14 18:11 +0200
http://bitbucket.org/pypy/pypy/changeset/e06951cd3fe6/

Log:    introduce a specialized class for METH_VARARGS functions

diff --git a/pypy/module/cpyext/methodobject.py 
b/pypy/module/cpyext/methodobject.py
--- a/pypy/module/cpyext/methodobject.py
+++ b/pypy/module/cpyext/methodobject.py
@@ -100,6 +100,7 @@
 class W_PyCFunctionObject_NOARGS(W_PyCFunctionObject):
     # METH_NOARGS
 
+    # CCC I think we can condense descr_call and call into one, can't we?
     def descr_call(self, space):
         return self.call(space, None, None, None)
 
@@ -113,6 +114,7 @@
 class W_PyCFunctionObject_O(W_PyCFunctionObject):
     # METH_O
 
+    # CCC I think we can condense descr_call and call into one, can't we?
     def descr_call(self, space, w_o):
         return self.call(space, None, w_o, None)
 
@@ -122,6 +124,15 @@
         func = self.ml.c_ml_meth
         return generic_cpy_call(space, func, w_self, w_o)
 
+class W_PyCFunctionObject_VARARGS(W_PyCFunctionObject):
+    # METH_VARARGS
+
+    def descr_call(self, space, args_w):
+        w_self = self.w_self
+        func = self.ml.c_ml_meth
+        w_args = space.newtuple(args_w)
+        return generic_cpy_call(space, func, w_self, w_args)
+
 class W_PyCMethodObject(W_PyCFunctionObject):
     w_self = None
     def __init__(self, space, ml, w_type):
@@ -325,6 +336,16 @@
     )
 W_PyCFunctionObject_O.typedef.acceptable_as_base_class = False
 
+W_PyCFunctionObject_VARARGS.typedef = TypeDef(
+    'builtin_function_or_method', W_PyCFunctionObject.typedef,
+    __call__ = interp2app(W_PyCFunctionObject_VARARGS.descr_call),
+    __doc__ = GetSetProperty(W_PyCFunctionObject_VARARGS.get_doc),
+    __module__ = interp_attrproperty_w('w_module', 
cls=W_PyCFunctionObject_VARARGS),
+    __name__ = interp_attrproperty('name', cls=W_PyCFunctionObject_VARARGS,
+        wrapfn="newtext_or_none"),
+    )
+W_PyCFunctionObject_VARARGS.typedef.acceptable_as_base_class = False
+
 W_PyCMethodObject.typedef = TypeDef(
     'method_descriptor',
     __get__ = interp2app(cmethod_descr_get),
diff --git a/pypy/module/cpyext/modsupport.py b/pypy/module/cpyext/modsupport.py
--- a/pypy/module/cpyext/modsupport.py
+++ b/pypy/module/cpyext/modsupport.py
@@ -1,13 +1,14 @@
 from rpython.rtyper.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import cpython_api, cpython_struct, \
         METH_STATIC, METH_CLASS, METH_COEXIST, CANNOT_FAIL, CONST_STRING, \
-        METH_NOARGS, METH_O
+        METH_NOARGS, METH_O, METH_VARARGS
 from pypy.module.cpyext.pyobject import PyObject, as_pyobj
 from pypy.interpreter.module import Module
 from pypy.module.cpyext.methodobject import (
     W_PyCFunctionObject, PyCFunction_NewEx, PyDescr_NewMethod,
     PyMethodDef, PyDescr_NewClassMethod, PyStaticMethod_New,
-    W_PyCFunctionObject_NOARGS, W_PyCFunctionObject_O)
+    W_PyCFunctionObject_NOARGS, W_PyCFunctionObject_O,
+    W_PyCFunctionObject_VARARGS)
 from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
 from pypy.module.cpyext.state import State
 from pypy.interpreter.error import oefmt
@@ -87,6 +88,8 @@
         return W_PyCFunctionObject_NOARGS(space, method, w_self, w_name)
     if flags == METH_O:
         return W_PyCFunctionObject_O(space, method, w_self, w_name)
+    if flags == METH_VARARGS:
+        return W_PyCFunctionObject_VARARGS(space, method, w_self, w_name)
     return W_PyCFunctionObject(space, method, w_self, w_name)
 
 def convert_method_defs(space, dict_w, methods, w_type, w_self=None, 
name=None):
diff --git a/pypy/module/cpyext/test/test_methodobject.py 
b/pypy/module/cpyext/test/test_methodobject.py
--- a/pypy/module/cpyext/test/test_methodobject.py
+++ b/pypy/module/cpyext/test/test_methodobject.py
@@ -65,15 +65,19 @@
         mod = self.import_extension('MyModule', [
             ('getarg_VARARGS', 'METH_VARARGS',
              '''
-             PyObject * i;
-             i = PyLong_FromLong((long)PyObject_Length(args));
-             Py_INCREF(i);
-             return i;
+             return Py_BuildValue("Ol", args, args->ob_refcnt);
              '''
              ),
             ])
-        assert mod.getarg_VARARGS() == 0
-        assert mod.getarg_VARARGS(1) == 1
+        tup, _ = mod.getarg_VARARGS()
+        assert tup == ()
+        #
+        tup, _ = mod.getarg_VARARGS(1)
+        assert tup == (1,)
+        #
+        tup, _ = mod.getarg_VARARGS(1, 2, 3)
+        assert tup == (1, 2, 3)
+        #
         raises(TypeError, mod.getarg_VARARGS, k=1)
 
     def test_func_attributes(self):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to