diff --git a/Lib/test/test_lazy_import/__init__.py b/Lib/test/test_lazy_import/__init__.py index 899ecec1ba2afa4..c90f9fd8847bd98 100644 --- a/Lib/test/test_lazy_import/__init__.py +++ b/Lib/test/test_lazy_import/__init__.py @@ -277,6 +277,22 @@ 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()) { + /* Bubble up earlier unrelated 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 +171,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,