Skip to content

Commit 71bcb5a

Browse files
committed
do not override errors from descriptors on modules
1 parent 53e944c commit 71bcb5a

2 files changed

Lines changed: 17 additions & 10 deletions

File tree

Lib/test/test_module.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,14 @@ def test_module_finalization_at_shutdown(self):
227227
b"len = len",
228228
b"shutil.rmtree = rmtree"})
229229

230+
def test_descriptor_errors_propogate(self):
231+
class Descr:
232+
def __get__(self, o, t):
233+
raise RuntimeError
234+
class M(ModuleType):
235+
melon = Descr()
236+
self.assertRaises(RuntimeError, getattr, M("mymod"), "melon")
237+
230238
# frozen and namespace module reprs are tested in importlib.
231239

232240

Objects/moduleobject.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -412,24 +412,23 @@ module_repr(PyModuleObject *m)
412412
}
413413

414414
static PyObject*
415-
module_getattr(PyObject *m, PyObject *name)
415+
module_getattro(PyModuleObject *m, PyObject *name)
416416
{
417-
PyModuleObject *module;
418417
PyObject *attr, *mod_name;
419-
attr = PyObject_GenericGetAttr(m, name);
420-
if (attr != NULL)
418+
attr = PyObject_GenericGetAttr((PyObject *)m, name);
419+
if (attr || !PyErr_ExceptionMatches(PyExc_AttributeError))
421420
return attr;
422421
PyErr_Clear();
423-
module = (PyModuleObject*)m;
424-
if (module->md_dict != NULL) {
425-
mod_name = PyDict_GetItemString(module->md_dict, "__name__");
426-
if (mod_name != NULL) {
422+
if (m->md_dict) {
423+
mod_name = PyDict_GetItemString(m->md_dict, "__name__");
424+
if (mod_name) {
427425
PyErr_Format(PyExc_AttributeError,
428426
"module '%U' has no attribute '%U'", mod_name, name);
429427
return NULL;
430428
}
431-
else if (PyErr_Occurred())
429+
else if (PyErr_Occurred()) {
432430
PyErr_Clear();
431+
}
433432
}
434433
PyErr_Format(PyExc_AttributeError,
435434
"module has no attribute '%U'", name);
@@ -512,7 +511,7 @@ PyTypeObject PyModule_Type = {
512511
0, /* tp_hash */
513512
0, /* tp_call */
514513
0, /* tp_str */
515-
module_getattr, /* tp_getattro */
514+
(getattrofunc)module_getattro, /* tp_getattro */
516515
PyObject_GenericSetAttr, /* tp_setattro */
517516
0, /* tp_as_buffer */
518517
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |

0 commit comments

Comments
 (0)