Author: mattip <[email protected]>
Branch: cpyext-ext
Changeset: r83281:6bf99bc91614
Date: 2016-03-22 22:03 +0200
http://bitbucket.org/pypy/pypy/changeset/6bf99bc91614/
Log: test, implement slot for __pow__, which is called 'ternary' but
accepts two arguments as well
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
@@ -7,7 +7,7 @@
cpython_api, generic_cpy_call, PyObject, Py_ssize_t, Py_TPFLAGS_CHECKTYPES,
mangle_name, pypy_decl)
from pypy.module.cpyext.typeobjectdefs import (
- unaryfunc, wrapperfunc, ternaryfunc, PyTypeObjectPtr, binaryfunc,
+ unaryfunc, wrapperfunc, ternaryfunc, PyTypeObjectPtr, binaryfunc,
ternaryfunc,
getattrfunc, getattrofunc, setattrofunc, lenfunc, ssizeargfunc, inquiry,
ssizessizeargfunc, ssizeobjargproc, iternextfunc, initproc, richcmpfunc,
cmpfunc, hashfunc, descrgetfunc, descrsetfunc, objobjproc, objobjargproc,
@@ -43,6 +43,17 @@
"expected %d arguments, got %d",
n, space.len_w(w_ob))
+def check_num_argsv(space, w_ob, low, high):
+ from pypy.module.cpyext.tupleobject import PyTuple_CheckExact
+ if not PyTuple_CheckExact(space, w_ob):
+ raise OperationError(space.w_SystemError,
+ space.wrap("PyArg_UnpackTuple() argument list is not a tuple"))
+ if low <=space.len_w(w_ob) <= high:
+ return
+ raise oefmt(space.w_TypeError,
+ "expected %d-%d arguments, got %d",
+ low, high, space.len_w(w_ob))
+
def wrap_init(space, w_self, w_args, func, w_kwargs):
func_init = rffi.cast(initproc, func)
res = generic_cpy_call(space, func_init, w_self, w_args, w_kwargs)
@@ -85,6 +96,33 @@
Py_DecRef(space, ref)
return generic_cpy_call(space, func_binary, args_w[0], w_self)
+def wrap_ternaryfunc(space, w_self, w_args, func):
+ # The third argument is optional
+ func_ternary = rffi.cast(ternaryfunc, func)
+ check_num_argsv(space, w_args, 1, 2)
+ args_w = space.fixedview(w_args)
+ arg3 = space.w_None
+ if len(args_w) > 1:
+ arg3 = args_w[1]
+ return generic_cpy_call(space, func_ternary, w_self, args_w[0], arg3)
+
+def wrap_ternaryfunc_r(space, w_self, w_args, func):
+ # The third argument is optional
+ func_ternary = rffi.cast(ternaryfunc, func)
+ check_num_argsv(space, w_args, 1, 2)
+ args_w = space.fixedview(w_args)
+ ref = make_ref(space, w_self)
+ if (not ref.c_ob_type.c_tp_flags & Py_TPFLAGS_CHECKTYPES and
+ not space.is_true(space.issubtype(space.type(args_w[0]),
+ space.type(w_self)))):
+ return space.w_NotImplemented
+ Py_DecRef(space, ref)
+ arg3 = space.w_None
+ if len(args_w) > 1:
+ arg3 = args_w[1]
+ return generic_cpy_call(space, func_ternary, args_w[0], w_self, arg3)
+
+
def wrap_inquirypred(space, w_self, w_args, func):
func_inquiry = rffi.cast(inquiry, func)
check_num_args(space, w_args, 0)
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
@@ -775,7 +775,7 @@
raises(SystemError, bool, module.newInt(-1))
raises(ValueError, bool, module.newInt(-42))
- def test_binaryfunc(self):
+ def test_mathfunc(self):
module = self.import_extension('foo', [
("newInt", "METH_VARARGS",
"""
@@ -788,6 +788,7 @@
IntLike_Type.tp_as_number = &intlike_as_number;
IntLike_Type.tp_flags |= Py_TPFLAGS_DEFAULT |
Py_TPFLAGS_CHECKTYPES;
intlike_as_number.nb_add = intlike_nb_add;
+ intlike_as_number.nb_power = intlike_nb_pow;
if (PyType_Ready(&IntLike_Type) < 0) return NULL;
intObj = PyObject_New(IntLikeObject, &IntLike_Type);
if (!intObj) {
@@ -814,8 +815,9 @@
intObjNoOp->ival = intval;
return (PyObject *)intObjNoOp;
- """)],
+ """)], prologue=
"""
+ #include <math.h>
typedef struct
{
PyObject_HEAD
@@ -835,6 +837,19 @@
return PyInt_FromLong(val1+val2);
}
+ static PyObject *
+ intlike_nb_pow(PyObject *self, PyObject *other, PyObject * z)
+ {
+ long val2, val1 = ((IntLikeObject *)(self))->ival;
+ if (PyInt_Check(other)) {
+ long val2 = PyInt_AsLong(other);
+ return PyInt_FromLong(val1+val2);
+ }
+
+ val2 = ((IntLikeObject *)(other))->ival;
+ return PyInt_FromLong((int)pow(val1,val2));
+ }
+
PyTypeObject IntLike_Type = {
PyObject_HEAD_INIT(0)
/*ob_size*/ 0,
@@ -863,6 +878,7 @@
assert (a + b) == 3
assert (b + c) == 5
assert (d + a) == 5
+ assert pow(d,b) == 16
def test_tp_new_in_subclass_of_type(self):
module = self.import_module(name='foo3')
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit