diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index e7da6630c1f423..9e91d9664ef8a9 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -855,6 +855,19 @@ def test_memory_leak_gh_140939(self): b = self.type2test(b'%*b') b % (_testcapi.PY_SSIZE_T_MAX, b'abc') + def test_mod_bytes_lookup_error(self): + # An error raised while looking up __bytes__ propagates. + class BadBytes: + @property + def __bytes__(self): + raise ZeroDivisionError + def __buffer__(self, flags): + return memoryview(b'abc') + + b = self.type2test(b'%b') + with self.assertRaises(ZeroDivisionError): + b % BadBytes() + def test_imod(self): b = self.type2test(b'hello, %b!') orig = b diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index d776a311ead2e9..36a0003079c1e9 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -162,6 +162,17 @@ def __getattr__(self, x): self.assertIn('MyConfig', repr(obj_weakref)) self.assertIn('MyConfig', str(obj_weakref)) + def test_repr_name_lookup_error(self): + # An error raised while looking up __name__ propagates. + class BadName: + @property + def __name__(self): + raise ZeroDivisionError + + obj = BadName() + with self.assertRaises(ZeroDivisionError): + repr(weakref.ref(obj)) + def test_basic_callback(self): self.check_basic_callback(C) self.check_basic_callback(create_function) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-10-14-11-40-06.gh-issue-159430.OWpyPm.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-14-11-40-06.gh-issue-159430.OWpyPm.rst new file mode 100644 index 00000000000000..fb4a6d6da4568a --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-14-11-40-06.gh-issue-159430.OWpyPm.rst @@ -0,0 +1,2 @@ +Report the correct exception if looking up :meth:`~object.__bytes__` raises +an exception while performing %-formatting of :class:`bytes`. diff --git a/Misc/NEWS.d/next/Library/2026-10-14-11-41-00.gh-issue-159430.ZEW-mx.rst b/Misc/NEWS.d/next/Library/2026-10-14-11-41-00.gh-issue-159430.ZEW-mx.rst new file mode 100644 index 00000000000000..5b9041891431c0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-14-11-41-00.gh-issue-159430.ZEW-mx.rst @@ -0,0 +1,2 @@ +Report the correct exception if looking up ``__name__`` raises an exception +when calling :func:`repr` on a :class:`weakref.ref`. diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 287d1e436fa641..9ee378292cc55e 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -577,6 +577,9 @@ format_obj(PyObject *v, const char **pbuf, Py_ssize_t *plen) *plen = PyBytes_GET_SIZE(result); return result; } + else if (PyErr_Occurred()) { + return NULL; + } /* does it support buffer protocol? */ if (PyObject_CheckBuffer(v)) { /* maybe we can avoid making a copy of the buffer object here? */ diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index d3d5723fbe32e7..6e43861d163096 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -221,6 +221,10 @@ weakref_repr(PyObject *self) } PyObject *name = _PyObject_LookupSpecial(obj, &_Py_ID(__name__)); + if (name == NULL && PyErr_Occurred()) { + Py_DECREF(obj); + return NULL; + } PyObject *repr; if (name == NULL || !PyUnicode_Check(name)) { repr = PyUnicode_FromFormat(