From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Wed, 30 Apr 2025 05:18:06 +0000 (-0700) Subject: gh-116436: Improve error message when TypeError occurs during dict update (#116443) X-Git-Tag: v3.14.0b1~179 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7e8b153fef71e464246827bf563923e2991290c6;p=thirdparty%2FPython%2Fcpython.git gh-116436: Improve error message when TypeError occurs during dict update (#116443) --- diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 9485ef2889f7..3104cbc66cb1 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -266,6 +266,31 @@ class DictTest(unittest.TestCase): self.assertRaises(ValueError, {}.update, [(1, 2, 3)]) + def test_update_type_error(self): + with self.assertRaises(TypeError) as cm: + {}.update([object() for _ in range(3)]) + + self.assertEqual(str(cm.exception), "object is not iterable") + self.assertEqual( + cm.exception.__notes__, + ['Cannot convert dictionary update sequence element #0 to a sequence'], + ) + + def badgen(): + yield "key" + raise TypeError("oops") + yield "value" + + with self.assertRaises(TypeError) as cm: + dict([badgen() for _ in range(3)]) + + self.assertEqual(str(cm.exception), "oops") + self.assertEqual( + cm.exception.__notes__, + ['Cannot convert dictionary update sequence element #0 to a sequence'], + ) + + def test_fromkeys(self): self.assertEqual(dict.fromkeys('abc'), {'a':None, 'b':None, 'c':None}) d = {} diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-03-06-22-33-33.gh-issue-116436.y8Thkt.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-03-06-22-33-33.gh-issue-116436.y8Thkt.rst new file mode 100644 index 000000000000..f9c3ab1f0a5a --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-03-06-22-33-33.gh-issue-116436.y8Thkt.rst @@ -0,0 +1 @@ +Improve error message when :exc:`TypeError` occurs during :meth:`dict.update` diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 4fdfd63cd4f7..b6f623b8ce9d 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -3730,13 +3730,14 @@ merge_from_seq2_lock_held(PyObject *d, PyObject *seq2, int override) } /* Convert item to sequence, and verify length 2. */ - fast = PySequence_Fast(item, ""); + fast = PySequence_Fast(item, "object is not iterable"); if (fast == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) - PyErr_Format(PyExc_TypeError, - "cannot convert dictionary update " + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + _PyErr_FormatNote( + "Cannot convert dictionary update " "sequence element #%zd to a sequence", i); + } goto Fail; } n = PySequence_Fast_GET_SIZE(fast);