Skip to content

Commit 23e018a

Browse files
committed
only accept AttributeError as indicating no __prepare__ attribute on a metaclass, allowing lookup errors to propogate
1 parent 8de42e2 commit 23e018a

3 files changed

Lines changed: 26 additions & 2 deletions

File tree

Lib/test/test_metaclass.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,20 @@
230230
42
231231
>>>
232232
233+
Test failures in looking up the __prepare__ method work.
234+
>>> class ObscureException(Exception):
235+
... pass
236+
>>> class FailDescr:
237+
... def __get__(self, instance, owner):
238+
... raise ObscureException
239+
>>> class Meta(type):
240+
... __prepare__ = FailDescr()
241+
>>> class X(metaclass=Meta):
242+
... pass
243+
Traceback (most recent call last):
244+
[...]
245+
test.test_metaclass.ObscureException
246+
233247
"""
234248

235249
__test__ = {'doctests' : doctests}

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ What's New in Python 3.2 Alpha 1?
1212
Core and Builtins
1313
-----------------
1414

15+
- Handle errors from looking up __prepare__ correctly.
16+
1517
- Issue #5939: Add additional runtime checking to ensure a valid capsule
1618
in Modules/_ctypes/callproc.c.
1719

Python/bltinmodule.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,16 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
108108
}
109109
prep = PyObject_GetAttrString(meta, "__prepare__");
110110
if (prep == NULL) {
111-
PyErr_Clear();
112-
ns = PyDict_New();
111+
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
112+
PyErr_Clear();
113+
ns = PyDict_New();
114+
}
115+
else {
116+
Py_DECREF(meta);
117+
Py_XDECREF(mkw);
118+
Py_DECREF(bases);
119+
return NULL;
120+
}
113121
}
114122
else {
115123
PyObject *pargs = PyTuple_Pack(2, name, bases);

0 commit comments

Comments
 (0)