From e85e79b7fd6c7942936d356ddd72b9c62e281b07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20S=C5=82awecki?= Date: Sun, 16 Aug 2026 15:25:03 +0200 Subject: [PATCH] gh-154196: Improve `AttributeError` messages from unresolved lazy imports (GH-154688) (cherry picked from commit 125ca2699228379c9be80ad8a9d5c3631fcac44f) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartosz Sławecki --- Lib/test/test_lazy_import/__init__.py | 17 +++++++++++++ ...-07-25-12-43-42.gh-issue-154196.0rAdob.rst | 2 ++ Objects/lazyimportobject.c | 24 +++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-07-25-12-43-42.gh-issue-154196.0rAdob.rst diff --git a/Lib/test/test_lazy_import/__init__.py b/Lib/test/test_lazy_import/__init__.py index 0a53d2559c91f01..e716c6b749202e8 100644 --- a/Lib/test/test_lazy_import/__init__.py +++ b/Lib/test/test_lazy_import/__init__.py @@ -285,6 +285,23 @@ def test_lazy_import_type_attributes_accessible(self): proc = assert_python_ok("-c", code) self.assertIn(b"tp_free(op); } +/* Specialize the error message for failed attribute lookups. */ +static PyObject * +lazy_import_getattro(PyObject *op, PyObject *name) +{ + PyObject *value = _PyObject_GenericGetAttrWithDict(op, name, NULL, /* suppress */1); + if (value == NULL) { + if (PyErr_Occurred()) { + // pass up non-AttributeError exception + return NULL; + } + PyObject *lz_name = _PyLazyImport_GetName(op); + if (lz_name == NULL) { + return NULL; + } + PyErr_Format(PyExc_AttributeError, + "cannot access attribute %R on unresolved lazy import %R", + name, lz_name); + Py_DECREF(lz_name); + return NULL; + } + return value; +} + static PyObject * lazy_import_name(PyLazyImportObject *m) { @@ -149,6 +172,7 @@ PyTypeObject PyLazyImport_Type = { .tp_repr = lazy_import_repr, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_doc = lazy_import_doc, + .tp_getattro = lazy_import_getattro, .tp_traverse = lazy_import_traverse, .tp_clear = lazy_import_clear, .tp_methods = lazy_import_methods,