y = x ** 2
self.assertIn('unsupported operand type(s) for **', str(cm.exception))
+ def test_pow_wrapper_error_messages(self):
+ self.assertRaisesRegex(TypeError,
+ 'expected 1 or 2 arguments, got 0',
+ int().__pow__)
+ self.assertRaisesRegex(TypeError,
+ 'expected 1 or 2 arguments, got 3',
+ int().__pow__, 1, 2, 3)
+ self.assertRaisesRegex(TypeError,
+ 'expected 1 or 2 arguments, got 0',
+ int().__rpow__)
+ self.assertRaisesRegex(TypeError,
+ 'expected 1 or 2 arguments, got 3',
+ int().__rpow__, 1, 2, 3)
+
def test_mutable_bases(self):
# Testing mutable bases...
return 0;
}
+static Py_ssize_t
+check_pow_args(PyObject *ob)
+{
+ // Returns the argument count on success or `-1` on error.
+ int min = 1;
+ int max = 2;
+ if (!PyTuple_CheckExact(ob)) {
+ PyErr_SetString(PyExc_SystemError,
+ "PyArg_UnpackTuple() argument list is not a tuple");
+ return -1;
+ }
+ Py_ssize_t size = PyTuple_GET_SIZE(ob);
+ if (size >= min && size <= max) {
+ return size;
+ }
+ PyErr_Format(
+ PyExc_TypeError,
+ "expected %d or %d arguments, got %zd", min, max, PyTuple_GET_SIZE(ob));
+ return -1;
+}
+
/* Generic wrappers for overloadable 'operators' such as __getitem__ */
/* There's a wrapper *function* for each distinct function typedef used
/* Note: This wrapper only works for __pow__() */
- if (!PyArg_UnpackTuple(args, "", 1, 2, &other, &third))
+ Py_ssize_t size = check_pow_args(args);
+ if (size == -1) {
return NULL;
+ }
+ other = PyTuple_GET_ITEM(args, 0);
+ if (size == 2) {
+ third = PyTuple_GET_ITEM(args, 1);
+ }
+
return (*func)(self, other, third);
}
PyObject *other;
PyObject *third = Py_None;
- /* Note: This wrapper only works for __pow__() */
+ /* Note: This wrapper only works for __rpow__() */
- if (!PyArg_UnpackTuple(args, "", 1, 2, &other, &third))
+ Py_ssize_t size = check_pow_args(args);
+ if (size == -1) {
return NULL;
+ }
+ other = PyTuple_GET_ITEM(args, 0);
+ if (size == 2) {
+ third = PyTuple_GET_ITEM(args, 1);
+ }
+
return (*func)(other, self, third);
}
PyObject* o;
Py_ssize_t i;
- if (!PyArg_UnpackTuple(args, "", 1, 1, &o))
+ if (!check_num_args(args, 1))
return NULL;
+ o = PyTuple_GET_ITEM(args, 0);
i = PyNumber_AsSsize_t(o, PyExc_OverflowError);
if (i == -1 && PyErr_Occurred())
return NULL;
int res;
PyObject *arg, *value;
- if (!PyArg_UnpackTuple(args, "", 2, 2, &arg, &value))
+ if (!PyArg_UnpackTuple(args, "__setitem__", 2, 2, &arg, &value))
return NULL;
i = getindex(self, arg);
if (i == -1 && PyErr_Occurred())
int res;
PyObject *key, *value;
- if (!PyArg_UnpackTuple(args, "", 2, 2, &key, &value))
+ if (!PyArg_UnpackTuple(args, "__setitem__", 2, 2, &key, &value))
return NULL;
res = (*func)(self, key, value);
if (res == -1 && PyErr_Occurred())
int res;
PyObject *name, *value;
- if (!PyArg_UnpackTuple(args, "", 2, 2, &name, &value))
+ if (!PyArg_UnpackTuple(args, "__setattr__", 2, 2, &name, &value))
return NULL;
if (!hackcheck(self, func, "__setattr__"))
return NULL;
PyObject *obj;
PyObject *type = NULL;
- if (!PyArg_UnpackTuple(args, "", 1, 2, &obj, &type))
+ if (!PyArg_UnpackTuple(args, "__get__", 1, 2, &obj, &type))
return NULL;
if (obj == Py_None)
obj = NULL;
PyObject *obj, *value;
int ret;
- if (!PyArg_UnpackTuple(args, "", 2, 2, &obj, &value))
+ if (!PyArg_UnpackTuple(args, "__set__", 2, 2, &obj, &value))
return NULL;
ret = (*func)(self, obj, value);
if (ret < 0)
{
PyObject *arg = NULL;
- if (!PyArg_UnpackTuple(args, "", 1, 1, &arg)) {
+ if (!PyArg_UnpackTuple(args, "__buffer__", 1, 1, &arg)) {
return NULL;
}
Py_ssize_t flags = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
wrap_releasebuffer(PyObject *self, PyObject *args, void *wrapped)
{
PyObject *arg = NULL;
- if (!PyArg_UnpackTuple(args, "", 1, 1, &arg)) {
+ if (!PyArg_UnpackTuple(args, "__release_buffer__", 1, 1, &arg)) {
return NULL;
}
if (!PyMemoryView_Check(arg)) {