diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 96190a7f5821709..05faad4532b867c 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -898,6 +898,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 ce93481e2735f78..bf9f17ce591a621 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 000000000000000..fb4a6d6da4568a6 --- /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 000000000000000..5b9041891431c0f --- /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 1917055d25198f1..bfd54176e5f662c 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -652,6 +652,9 @@ format_obj(PyObject *v, Py_ssize_t argidx, PyObject *key, *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 daeba5368b21660..db95bb926d5f733 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(