Skip to content

Instantly share code, notes, and snippets.

@vestel
Created January 31, 2012 15:37
Show Gist options
  • Save vestel/1711115 to your computer and use it in GitHub Desktop.
Save vestel/1711115 to your computer and use it in GitHub Desktop.
Inheritance and MRO
from __future__ import generators
class A(object):
""" Normal class """
def su(self):
self.su_result = []
self.su_result.append("A:Start")
mro = list(self.__class__.__mro__)[:-1]
mro.reverse()
for i in mro:
try:
i._su(self)
except Exception:
self.su_result.append(i._exception(self))
break
self.su_result.append("A:End")
def _su(self):
pass
def td(self):
self.result = []
self.result.append("A:Start")
mro = list(self.__class__.__mro__)[:-1]
for i in mro:
try:
i._td(self)
except Exception:
self.result.append(i._exception(self))
self.result.append("A:End")
def _td(self):
pass
def _exception(self):
return "A:Exception"
class B(A):
""" Normal child class """
def _su(self):
self.su_result.append("B:Start")
def _td(self):
self.result.append("B:End")
def _exception(self):
return "B:Exception"
class BA(A):
""" Normal child class """
def _su(self):
self.su_result.append("B:Start")
def _td(self):
self.result.append("B:End")
class C(B):
""" Normal leaf class """
def _su(self):
self.su_result.append("C:Inside")
def _td(self):
self.result.append("C")
def _exception(self):
return "C:Exception"
class NE(BA):
""" Normal leaf class """
def _su(self):
raise Exception("SU")
def _td(self):
raise Exception("TD")
class D(A):
""" Defective child class """
def _su(self):
raise Exception("SU")
def _td(self):
raise Exception("TD")
def _exception(self):
return "D:Exception"
class E(B):
""" Errorious leaf class """
def _su(self):
raise Exception("SU")
def _td(self):
raise Exception("TD")
def _exception(self):
return "E:Exception"
class X(D):
""" Defective inheritant """
def _su(self):
self.su_result.append("X:Inside")
def _td(self):
self.result.append("X")
def _exception(self):
return "X:Exception"
class Z(D):
""" Totally broken """
def _su(self):
raise Exception("SU")
def _td(self):
raise Exception("TD")
def _exception(self):
return "Z:Exception"
import unittest
class TestEverything(unittest.TestCase):
def test_su_called(self):
a = A()
a.su()
self.assertEquals(a.su_result, ["A:Start","A:End"])
def test_td_called(self):
a = A()
a.td()
self.assertEquals(a.result, ["A:Start","A:End"])
def test_child_su_called(self):
b = B()
b.su()
self.assertEquals(b.su_result, ["A:Start","B:Start","A:End"])
def test_child_td_called(self):
b = B()
b.td()
self.assertEquals(b.result, ["A:Start","B:End","A:End"])
def test_exception_su_leaf(self):
e = E()
e.su()
self.assertEquals(e.su_result, ["A:Start","B:Start","E:Exception","A:End"])
def test_exception_td_leaf(self):
e = E()
e.td()
self.assertEquals(e.result, ["A:Start","E:Exception","B:End","A:End"])
def test_exception_su_defect(self):
d = D()
d.su()
self.assertEquals(d.su_result, ["A:Start","D:Exception","A:End"])
def test_exception_td_defect(self):
d = D()
d.td()
self.assertEquals(d.result, ["A:Start","D:Exception","A:End"])
def test_exception_su_passthro(self):
x = X()
x.su()
self.assertEquals(x.su_result, ["A:Start","D:Exception","A:End"])
def test_exception_td_passthro(self):
x = X()
x.td()
self.assertEquals(x.result, ["A:Start","X","D:Exception","A:End"])
def test_exception_su_total(self):
z = Z()
z.su()
self.assertEquals(z.su_result, ["A:Start","D:Exception","A:End"])
def test_exception_td_total(self):
z = Z()
z.td()
self.assertEquals(z.result, ["A:Start","Z:Exception","D:Exception","A:End"])
def test_grand_child_td_called(self):
c = C()
c.td()
self.assertEquals(c.result, ["A:Start","C","B:End","A:End"])
def test_grand_child_su_called(self):
c = C()
c.su()
self.assertEquals(c.su_result, ["A:Start","B:Start", "C:Inside","A:End"])
def test_grand_child_noex_su_called(self):
c = NE()
c.su()
self.assertEquals(c.su_result, ["A:Start","B:Start","A:Exception","A:End"])
def test_grand_child_noex_td_called(self):
c = NE()
c.td()
self.assertEquals(c.result, ["A:Start","A:Exception","B:End","A:End"])
if __name__ == '__main__':
import nose
nose.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment