Commit 65c40114 authored by Michael W. Hudson's avatar Michael W. Hudson

I don't know why staring at the email to python-checkins made me

see problems with my code that I didn't see before the checkin, but:

When a subtype .mro() fails, we need to reset the type whose __bases__
are being changed, too.  Fix + test.
parent 6368e5ee
...@@ -3566,11 +3566,13 @@ def test_mutable_bases_with_failing_mro(): ...@@ -3566,11 +3566,13 @@ def test_mutable_bases_with_failing_mro():
# check here that E's gets restored. # check here that E's gets restored.
E_mro_before = E.__mro__ E_mro_before = E.__mro__
D_mro_before = D.__mro__
try: try:
D.__bases__ = (C2,) D.__bases__ = (C2,)
except RuntimeError: except RuntimeError:
vereq(E.__mro__, E_mro_before) vereq(E.__mro__, E_mro_before)
vereq(D.__mro__, D_mro_before)
else: else:
raise TestFailed, "exception not propagated" raise TestFailed, "exception not propagated"
......
...@@ -242,17 +242,12 @@ type_set_bases(PyTypeObject *type, PyObject *value, void *context) ...@@ -242,17 +242,12 @@ type_set_bases(PyTypeObject *type, PyObject *value, void *context)
type->tp_base = new_base; type->tp_base = new_base;
if (mro_internal(type) < 0) { if (mro_internal(type) < 0) {
type->tp_bases = old_bases; goto bail;
type->tp_base = old_base;
type->tp_mro = old_mro;
Py_DECREF(value);
Py_DECREF(new_base);
return -1;
} }
temp = PyList_New(0); temp = PyList_New(0);
if (!temp)
goto bail;
r = mro_subclasses(type, temp); r = mro_subclasses(type, temp);
...@@ -267,7 +262,7 @@ type_set_bases(PyTypeObject *type, PyObject *value, void *context) ...@@ -267,7 +262,7 @@ type_set_bases(PyTypeObject *type, PyObject *value, void *context)
Py_INCREF(cls->tp_mro); Py_INCREF(cls->tp_mro);
} }
Py_DECREF(temp); Py_DECREF(temp);
return r; goto bail;
} }
Py_DECREF(temp); Py_DECREF(temp);
...@@ -303,6 +298,16 @@ type_set_bases(PyTypeObject *type, PyObject *value, void *context) ...@@ -303,6 +298,16 @@ type_set_bases(PyTypeObject *type, PyObject *value, void *context)
Py_DECREF(old_mro); Py_DECREF(old_mro);
return r; return r;
bail:
type->tp_bases = old_bases;
type->tp_base = old_base;
type->tp_mro = old_mro;
Py_DECREF(value);
Py_DECREF(new_base);
return -1;
} }
static PyObject * static PyObject *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment