mirror of https://github.com/python/cpython
gh-123446: Fix empty function names in `TypeError`s in `typeobject` (#123470)
This commit is contained in:
parent
32c7dbb2bc
commit
f8a736b8e1
|
@ -4021,6 +4021,20 @@ class ClassPropertiesAndMethods(unittest.TestCase):
|
||||||
y = x ** 2
|
y = x ** 2
|
||||||
self.assertIn('unsupported operand type(s) for **', str(cm.exception))
|
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):
|
def test_mutable_bases(self):
|
||||||
# Testing mutable bases...
|
# Testing mutable bases...
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix empty function name in :exc:`TypeError` when builtin magic methods are
|
||||||
|
used without the required args.
|
|
@ -8678,6 +8678,27 @@ check_num_args(PyObject *ob, int n)
|
||||||
return 0;
|
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__ */
|
/* Generic wrappers for overloadable 'operators' such as __getitem__ */
|
||||||
|
|
||||||
/* There's a wrapper *function* for each distinct function typedef used
|
/* There's a wrapper *function* for each distinct function typedef used
|
||||||
|
@ -8759,8 +8780,15 @@ wrap_ternaryfunc(PyObject *self, PyObject *args, void *wrapped)
|
||||||
|
|
||||||
/* Note: This wrapper only works for __pow__() */
|
/* 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;
|
return NULL;
|
||||||
|
}
|
||||||
|
other = PyTuple_GET_ITEM(args, 0);
|
||||||
|
if (size == 2) {
|
||||||
|
third = PyTuple_GET_ITEM(args, 1);
|
||||||
|
}
|
||||||
|
|
||||||
return (*func)(self, other, third);
|
return (*func)(self, other, third);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8771,10 +8799,17 @@ wrap_ternaryfunc_r(PyObject *self, PyObject *args, void *wrapped)
|
||||||
PyObject *other;
|
PyObject *other;
|
||||||
PyObject *third = Py_None;
|
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;
|
return NULL;
|
||||||
|
}
|
||||||
|
other = PyTuple_GET_ITEM(args, 0);
|
||||||
|
if (size == 2) {
|
||||||
|
third = PyTuple_GET_ITEM(args, 1);
|
||||||
|
}
|
||||||
|
|
||||||
return (*func)(other, self, third);
|
return (*func)(other, self, third);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8795,8 +8830,9 @@ wrap_indexargfunc(PyObject *self, PyObject *args, void *wrapped)
|
||||||
PyObject* o;
|
PyObject* o;
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "", 1, 1, &o))
|
if (!check_num_args(args, 1))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
o = PyTuple_GET_ITEM(args, 0);
|
||||||
i = PyNumber_AsSsize_t(o, PyExc_OverflowError);
|
i = PyNumber_AsSsize_t(o, PyExc_OverflowError);
|
||||||
if (i == -1 && PyErr_Occurred())
|
if (i == -1 && PyErr_Occurred())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -8852,7 +8888,7 @@ wrap_sq_setitem(PyObject *self, PyObject *args, void *wrapped)
|
||||||
int res;
|
int res;
|
||||||
PyObject *arg, *value;
|
PyObject *arg, *value;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "", 2, 2, &arg, &value))
|
if (!PyArg_UnpackTuple(args, "__setitem__", 2, 2, &arg, &value))
|
||||||
return NULL;
|
return NULL;
|
||||||
i = getindex(self, arg);
|
i = getindex(self, arg);
|
||||||
if (i == -1 && PyErr_Occurred())
|
if (i == -1 && PyErr_Occurred())
|
||||||
|
@ -8908,7 +8944,7 @@ wrap_objobjargproc(PyObject *self, PyObject *args, void *wrapped)
|
||||||
int res;
|
int res;
|
||||||
PyObject *key, *value;
|
PyObject *key, *value;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "", 2, 2, &key, &value))
|
if (!PyArg_UnpackTuple(args, "__setitem__", 2, 2, &key, &value))
|
||||||
return NULL;
|
return NULL;
|
||||||
res = (*func)(self, key, value);
|
res = (*func)(self, key, value);
|
||||||
if (res == -1 && PyErr_Occurred())
|
if (res == -1 && PyErr_Occurred())
|
||||||
|
@ -9005,7 +9041,7 @@ wrap_setattr(PyObject *self, PyObject *args, void *wrapped)
|
||||||
int res;
|
int res;
|
||||||
PyObject *name, *value;
|
PyObject *name, *value;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "", 2, 2, &name, &value))
|
if (!PyArg_UnpackTuple(args, "__setattr__", 2, 2, &name, &value))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!hackcheck(self, func, "__setattr__"))
|
if (!hackcheck(self, func, "__setattr__"))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -9115,7 +9151,7 @@ wrap_descr_get(PyObject *self, PyObject *args, void *wrapped)
|
||||||
PyObject *obj;
|
PyObject *obj;
|
||||||
PyObject *type = NULL;
|
PyObject *type = NULL;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "", 1, 2, &obj, &type))
|
if (!PyArg_UnpackTuple(args, "__get__", 1, 2, &obj, &type))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (obj == Py_None)
|
if (obj == Py_None)
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
|
@ -9136,7 +9172,7 @@ wrap_descr_set(PyObject *self, PyObject *args, void *wrapped)
|
||||||
PyObject *obj, *value;
|
PyObject *obj, *value;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "", 2, 2, &obj, &value))
|
if (!PyArg_UnpackTuple(args, "__set__", 2, 2, &obj, &value))
|
||||||
return NULL;
|
return NULL;
|
||||||
ret = (*func)(self, obj, value);
|
ret = (*func)(self, obj, value);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -9165,7 +9201,7 @@ wrap_buffer(PyObject *self, PyObject *args, void *wrapped)
|
||||||
{
|
{
|
||||||
PyObject *arg = NULL;
|
PyObject *arg = NULL;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "", 1, 1, &arg)) {
|
if (!PyArg_UnpackTuple(args, "__buffer__", 1, 1, &arg)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Py_ssize_t flags = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
|
Py_ssize_t flags = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
|
||||||
|
@ -9186,7 +9222,7 @@ static PyObject *
|
||||||
wrap_releasebuffer(PyObject *self, PyObject *args, void *wrapped)
|
wrap_releasebuffer(PyObject *self, PyObject *args, void *wrapped)
|
||||||
{
|
{
|
||||||
PyObject *arg = NULL;
|
PyObject *arg = NULL;
|
||||||
if (!PyArg_UnpackTuple(args, "", 1, 1, &arg)) {
|
if (!PyArg_UnpackTuple(args, "__release_buffer__", 1, 1, &arg)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!PyMemoryView_Check(arg)) {
|
if (!PyMemoryView_Check(arg)) {
|
||||||
|
|
Loading…
Reference in New Issue