Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Doc/using/mac.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Current installers provide a
`universal2 binary <https://en.wikipedia.org/wiki/Universal_binary>`_ build
of Python which runs natively on all Macs (Apple Silicon and Intel) that are
supported by a wide range of macOS versions,
currently typically from at least **macOS 10.13 High Sierra** on.
currently typically from at least **macOS 10.15 Catalina** on.

The downloaded file is a standard macOS installer package file (``.pkg``).
File integrity information (checksum, size, sigstore signature, etc) for each file is included
Expand Down
8 changes: 4 additions & 4 deletions Lib/test/test_coroutines.py
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,7 @@ async def foo():
return (await Awaitable())

with self.assertRaisesRegex(
TypeError, "__await__.*returned non-iterator of type"):
TypeError, "__await__.*must return an iterator, not"):

run_async(foo())

Expand Down Expand Up @@ -1106,7 +1106,7 @@ async def foo():
return await Awaitable()

with self.assertRaisesRegex(
TypeError, r"__await__\(\) returned a coroutine"):
TypeError, r"__await__\(\) must return an iterator, not coroutine"):
run_async(foo())

c.close()
Expand All @@ -1120,7 +1120,7 @@ async def foo():
return await Awaitable()

with self.assertRaisesRegex(
TypeError, "__await__.*returned non-iterator of type"):
TypeError, "__await__.*must return an iterator, not"):

run_async(foo())

Expand Down Expand Up @@ -2490,7 +2490,7 @@ async def foo():
return (await future)

with self.assertRaisesRegex(
TypeError, "__await__.*returned non-iterator of type 'int'"):
TypeError, "__await__.*must return an iterator, not int"):
self.assertEqual(foo().send(None), 1)


Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_type_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ def check_annotations(self, f):
print(f.__annotations__)

f.__annotate__ = lambda x: 42
with self.assertRaisesRegex(TypeError, r"__annotate__ returned non-dict of type 'int'"):
with self.assertRaisesRegex(TypeError, r"__annotate__\(\) must return a dict, not int"):
print(f.__annotations__)

f.__annotate__ = lambda x: {"x": x}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Mark ``_PyOptimizer_Optimize`` as :c:macro:`Py_NO_INLINE` to
prevent stack overflow crashes on macOS.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Enhance wrong type error messages and make them more consistent. Patch by
Semyon Moroz.
50 changes: 24 additions & 26 deletions Objects/abstract.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,9 @@ PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
return defaultvalue;
}
if (!PyLong_Check(result)) {
PyErr_Format(PyExc_TypeError, "__length_hint__ must be an integer, not %.100s",
Py_TYPE(result)->tp_name);
PyErr_Format(PyExc_TypeError,
"%T.__length_hint__() must return an int, not %T",
o, result);
Py_DECREF(result);
return -1;
}
Expand All @@ -143,7 +144,8 @@ PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
return -1;
}
if (res < 0) {
PyErr_Format(PyExc_ValueError, "__length_hint__() should return >= 0");
PyErr_Format(PyExc_ValueError,
"%T.__length_hint__() must return a non-negative int", o);
return -1;
}
return res;
Expand Down Expand Up @@ -887,8 +889,8 @@ PyObject_Format(PyObject *obj, PyObject *format_spec)

if (result && !PyUnicode_Check(result)) {
PyErr_Format(PyExc_TypeError,
"__format__ must return a str, not %.200s",
Py_TYPE(result)->tp_name);
"%T.__format__() must return a str, not %T",
obj, result);
Py_SETREF(result, NULL);
goto done;
}
Expand Down Expand Up @@ -1421,17 +1423,17 @@ _PyNumber_Index(PyObject *item)

if (!PyLong_Check(result)) {
PyErr_Format(PyExc_TypeError,
"__index__ returned non-int (type %.200s)",
Py_TYPE(result)->tp_name);
"%T.__index__() must return an int, not %T",
item, result);
Py_DECREF(result);
return NULL;
}
/* Issue #17576: warn if 'result' not of exact type int. */
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
"__index__ returned non-int (type %.200s). "
"%T.__index__() must return an int, not %T. "
"The ability to return an instance of a strict subclass of int "
"is deprecated, and may be removed in a future version of Python.",
Py_TYPE(result)->tp_name)) {
item, result)) {
Py_DECREF(result);
return NULL;
}
Expand Down Expand Up @@ -1531,17 +1533,17 @@ PyNumber_Long(PyObject *o)

if (!PyLong_Check(result)) {
PyErr_Format(PyExc_TypeError,
"__int__ returned non-int (type %.200s)",
Py_TYPE(result)->tp_name);
"%T.__int__() must return an int, not %T",
o, result);
Py_DECREF(result);
return NULL;
}
/* Issue #17576: warn if 'result' not of exact type int. */
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
"__int__ returned non-int (type %.200s). "
"%T.__int__() must return an int, not %T. "
"The ability to return an instance of a strict subclass of int "
"is deprecated, and may be removed in a future version of Python.",
Py_TYPE(result)->tp_name)) {
o, result)) {
Py_DECREF(result);
return NULL;
}
Expand Down Expand Up @@ -1609,17 +1611,16 @@ PyNumber_Float(PyObject *o)

if (!PyFloat_Check(res)) {
PyErr_Format(PyExc_TypeError,
"%.50s.__float__ returned non-float (type %.50s)",
Py_TYPE(o)->tp_name, Py_TYPE(res)->tp_name);
"%T.__float__() must return a float, not %T", o, res);
Py_DECREF(res);
return NULL;
}
/* Issue #26983: warn if 'res' not of exact type float. */
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
"%.50s.__float__ returned non-float (type %.50s). "
"%T.__float__() must return a float, not %T. "
"The ability to return an instance of a strict subclass of float "
"is deprecated, and may be removed in a future version of Python.",
Py_TYPE(o)->tp_name, Py_TYPE(res)->tp_name)) {
o, res)) {
Py_DECREF(res);
return NULL;
}
Expand Down Expand Up @@ -2435,10 +2436,8 @@ method_output_as_list(PyObject *o, PyObject *meth)
PyThreadState *tstate = _PyThreadState_GET();
if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError)) {
_PyErr_Format(tstate, PyExc_TypeError,
"%.200s.%U() returned a non-iterable (type %.200s)",
Py_TYPE(o)->tp_name,
meth,
Py_TYPE(meth_output)->tp_name);
"%T.%U() must return an iterable, not %T",
o, meth, meth_output);
}
Py_DECREF(meth_output);
return NULL;
Expand Down Expand Up @@ -2818,9 +2817,8 @@ PyObject_GetIter(PyObject *o)
PyObject *res = (*f)(o);
if (res != NULL && !PyIter_Check(res)) {
PyErr_Format(PyExc_TypeError,
"iter() returned non-iterator "
"of type '%.100s'",
Py_TYPE(res)->tp_name);
"%T.__iter__() must return an iterator, not %T",
o, res);
Py_SETREF(res, NULL);
}
return res;
Expand All @@ -2839,8 +2837,8 @@ PyObject_GetAIter(PyObject *o) {
PyObject *it = (*f)(o);
if (it != NULL && !PyAIter_Check(it)) {
PyErr_Format(PyExc_TypeError,
"aiter() returned not an async iterator of type '%.100s'",
Py_TYPE(it)->tp_name);
"%T.__aiter__() must return an async iterator, not %T",
o, it);
Py_SETREF(it, NULL);
}
return it;
Expand Down
8 changes: 4 additions & 4 deletions Objects/bytesobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -566,8 +566,8 @@ format_obj(PyObject *v, const char **pbuf, Py_ssize_t *plen)
return NULL;
if (!PyBytes_Check(result)) {
PyErr_Format(PyExc_TypeError,
"__bytes__ returned non-bytes (type %.200s)",
Py_TYPE(result)->tp_name);
"%T.__bytes__() must return a bytes, not %T",
v, result);
Py_DECREF(result);
return NULL;
}
Expand Down Expand Up @@ -2793,8 +2793,8 @@ bytes_new_impl(PyTypeObject *type, PyObject *x, const char *encoding,
return NULL;
if (!PyBytes_Check(bytes)) {
PyErr_Format(PyExc_TypeError,
"__bytes__ returned non-bytes (type %.200s)",
Py_TYPE(bytes)->tp_name);
"%T.__bytes__() must return a bytes, not %T",
x, bytes);
Py_DECREF(bytes);
return NULL;
}
Expand Down
8 changes: 4 additions & 4 deletions Objects/complexobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -515,17 +515,17 @@ try_complex_special_method(PyObject *op)
}
if (!PyComplex_Check(res)) {
PyErr_Format(PyExc_TypeError,
"__complex__ returned non-complex (type %.200s)",
Py_TYPE(res)->tp_name);
"%T.__complex__() must return a complex, not %T",
op, res);
Py_DECREF(res);
return NULL;
}
/* Issue #29894: warn if 'res' not of exact type complex. */
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
"__complex__ returned non-complex (type %.200s). "
"%T.__complex__() must return a complex, not %T. "
"The ability to return an instance of a strict subclass of complex "
"is deprecated, and may be removed in a future version of Python.",
Py_TYPE(res)->tp_name)) {
op, res)) {
Py_DECREF(res);
return NULL;
}
Expand Down
8 changes: 4 additions & 4 deletions Objects/fileobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ PyFile_GetLine(PyObject *f, int n)
}
if (result != NULL && !PyBytes_Check(result) &&
!PyUnicode_Check(result)) {
PyErr_Format(PyExc_TypeError,
"%T.readline() must return a str, not %T", f, result);
Py_SETREF(result, NULL);
PyErr_SetString(PyExc_TypeError,
"object.readline() returned non-string");
}

if (n < 0 && result != NULL && PyBytes_Check(result)) {
Expand Down Expand Up @@ -193,8 +193,8 @@ PyObject_AsFileDescriptor(PyObject *o)
Py_DECREF(fno);
}
else {
PyErr_SetString(PyExc_TypeError,
"fileno() returned a non-integer");
PyErr_Format(PyExc_TypeError,
"%T.fileno() must return an int, not %T", o, fno);
Py_DECREF(fno);
return -1;
}
Expand Down
8 changes: 4 additions & 4 deletions Objects/floatobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,16 +288,16 @@ PyFloat_AsDouble(PyObject *op)
if (!PyFloat_CheckExact(res)) {
if (!PyFloat_Check(res)) {
PyErr_Format(PyExc_TypeError,
"%.50s.__float__ returned non-float (type %.50s)",
Py_TYPE(op)->tp_name, Py_TYPE(res)->tp_name);
"%T.__float__() must return a float, not %T",
op, res);
Py_DECREF(res);
return -1;
}
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
"%.50s.__float__ returned non-float (type %.50s). "
"%T.__float__() must return a float, not %T. "
"The ability to return an instance of a strict subclass of float "
"is deprecated, and may be removed in a future version of Python.",
Py_TYPE(op)->tp_name, Py_TYPE(res)->tp_name)) {
op, res)) {
Py_DECREF(res);
return -1;
}
Expand Down
5 changes: 3 additions & 2 deletions Objects/funcobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,8 +560,9 @@ func_get_annotation_dict(PyFunctionObject *op)
return NULL;
}
if (!PyDict_Check(ann_dict)) {
PyErr_Format(PyExc_TypeError, "__annotate__ returned non-dict of type '%.100s'",
Py_TYPE(ann_dict)->tp_name);
PyErr_Format(PyExc_TypeError,
"__annotate__() must return a dict, not %T",
ann_dict);
Py_DECREF(ann_dict);
return NULL;
}
Expand Down
10 changes: 5 additions & 5 deletions Objects/genobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1092,14 +1092,14 @@ _PyCoro_GetAwaitableIter(PyObject *o)
if (PyCoro_CheckExact(res) || gen_is_coroutine(res)) {
/* __await__ must return an *iterator*, not
a coroutine or another awaitable (see PEP 492) */
PyErr_SetString(PyExc_TypeError,
"__await__() returned a coroutine");
PyErr_Format(PyExc_TypeError,
"%T.__await__() must return an iterator, "
"not coroutine", o);
Py_CLEAR(res);
} else if (!PyIter_Check(res)) {
PyErr_Format(PyExc_TypeError,
"__await__() returned non-iterator "
"of type '%.100s'",
Py_TYPE(res)->tp_name);
"%T.__await__() must return an iterator, "
"not %T", o, res);
Py_CLEAR(res);
}
}
Expand Down
5 changes: 3 additions & 2 deletions Objects/iterobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,9 @@ anextawaitable_getiter(anextawaitableobject *obj)
}
Py_SETREF(awaitable, new_awaitable);
if (!PyIter_Check(awaitable)) {
PyErr_SetString(PyExc_TypeError,
"__await__ returned a non-iterable");
PyErr_Format(PyExc_TypeError,
"%T.__await__() must return an iterable, not %T",
obj, awaitable);
Py_DECREF(awaitable);
return NULL;
}
Expand Down
5 changes: 3 additions & 2 deletions Objects/moduleobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1329,8 +1329,9 @@ module_get_annotations(PyObject *self, void *Py_UNUSED(ignored))
return NULL;
}
if (!PyDict_Check(annotations)) {
PyErr_Format(PyExc_TypeError, "__annotate__ returned non-dict of type '%.100s'",
Py_TYPE(annotations)->tp_name);
PyErr_Format(PyExc_TypeError,
"__annotate__() must return a dict, not %T",
annotations);
Py_DECREF(annotate);
Py_DECREF(annotations);
Py_DECREF(dict);
Expand Down
10 changes: 4 additions & 6 deletions Objects/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -784,8 +784,7 @@ PyObject_Repr(PyObject *v)
}
if (!PyUnicode_Check(res)) {
_PyErr_Format(tstate, PyExc_TypeError,
"__repr__ returned non-string (type %.200s)",
Py_TYPE(res)->tp_name);
"%T.__repr__() must return a str, not %T", v, res);
Py_DECREF(res);
return NULL;
}
Expand Down Expand Up @@ -827,8 +826,7 @@ PyObject_Str(PyObject *v)
}
if (!PyUnicode_Check(res)) {
_PyErr_Format(tstate, PyExc_TypeError,
"__str__ returned non-string (type %.200s)",
Py_TYPE(res)->tp_name);
"%T.__str__() must return a str, not %T", v, res);
Py_DECREF(res);
return NULL;
}
Expand Down Expand Up @@ -883,8 +881,8 @@ PyObject_Bytes(PyObject *v)
return NULL;
if (!PyBytes_Check(result)) {
PyErr_Format(PyExc_TypeError,
"__bytes__ returned non-bytes (type %.200s)",
Py_TYPE(result)->tp_name);
"%T.__bytes__() must return a bytes, not %T",
v, result);
Py_DECREF(result);
return NULL;
}
Expand Down
Loading
Loading