[pypy-commit] pypy py3.5: test and fix
arigo
pypy.commits at gmail.com
Sat Dec 3 03:47:49 EST 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r88839:5ff985c7735b
Date: 2016-12-03 09:47 +0100
http://bitbucket.org/pypy/pypy/changeset/5ff985c7735b/
Log: test and fix
diff --git a/pypy/objspace/std/test/test_typeobject.py b/pypy/objspace/std/test/test_typeobject.py
--- a/pypy/objspace/std/test/test_typeobject.py
+++ b/pypy/objspace/std/test/test_typeobject.py
@@ -270,6 +270,37 @@
assert 0, "exception not propagated"
"""
+ def test_mutable_bases_with_failing_mro_2(self): """
+ class E(Exception):
+ pass
+ class M(type):
+ def mro(cls):
+ if cls.__name__ == 'Sub' and A.__bases__ == (Base1,):
+ A.__bases__ = (Base2,)
+ raise E
+ return type.mro(cls)
+
+ class Base0:
+ pass
+ class Base1:
+ pass
+ class Base2:
+ pass
+ class A(Base0, metaclass=M):
+ pass
+ class Sub(A):
+ pass
+
+ try:
+ A.__bases__ = (Base1,)
+ except E:
+ assert A.__bases__ == (Base2,)
+ assert A.__mro__ == (A, Base2, object)
+ assert Sub.__mro__ == (Sub, A, Base2, object)
+ else:
+ assert 0
+ """
+
def test_mutable_bases_catch_mro_conflict(self):
class A(object):
pass
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -802,8 +802,9 @@
return space.newtuple(w_type.bases_w)
def mro_subclasses(space, w_type, temp):
- temp.append((w_type, w_type.mro_w))
+ old_mro_w = w_type.mro_w
compute_mro(w_type)
+ temp.append((w_type, old_mro_w, w_type.mro_w))
for w_sc in w_type.get_subclasses():
assert isinstance(w_sc, W_TypeObject)
mro_subclasses(space, w_sc, temp)
@@ -856,9 +857,11 @@
# try to recompute all MROs
mro_subclasses(space, w_type, temp)
except:
- for cls, old_mro in temp:
- cls.mro_w = old_mro
- w_type.bases_w = saved_bases_w
+ for cls, old_mro, new_mro in temp:
+ if cls.mro_w is new_mro: # don't revert if it changed again
+ cls.mro_w = old_mro
+ if w_type.bases_w is newbases_w: # don't revert if it changed again
+ w_type.bases_w = saved_bases_w
raise
if (w_type.version_tag() is not None and
not is_mro_purely_of_types(w_type.mro_w)):
More information about the pypy-commit
mailing list