import unittest import pyfmi.testcase import operator from itertools import * points = 5 BFS = 1 DFS = 2 class Resolver(object): def __init__(self, cls, method=BFS): self._cls = cls if method==DFS: self._walk = self._dfs else: self._walk = self._bfs def __getattribute__(self, name): if name.startswith('_'): return object.__getattribute__(self, name) return self._walk(self._cls, name) def _bfs(self, cls, attr): queue = [cls] while queue: popped = queue.pop(0) if attr in popped.__dict__: return Struct(cls=popped, value=getattr(popped, attr)) for base in popped.__bases__: queue.append(base) return None def _dfs(self, cls, attr): if attr in cls.__dict__: return Struct(cls=cls, value=getattr(cls, attr)) for base in cls.__bases__: res = self._dfs(base, attr) if res: return res return None class Struct: def __init__(self, **kwargs): for key in kwargs: setattr(self, key, kwargs[key]) class ValueResolver(Resolver): def __init__(self, cls, method=BFS): Resolver.__init__(self, cls, method) def __getattribute__(self, name): if name.startswith('_'): return object.__getattribute__(self, name) res = Resolver.__getattribute__(self, name) if res == None: raise AttributeError("Class %s hasn't got an attribute named %s!" % \ (self._cls.__name__, name)) return res.value class ProblemTests(pyfmi.testcase.SpeakingTestCase): def testCurrent(self): class X: pass rd = self.user.Resolver(X, self.user.DFS) rb = self.user.Resolver(X, self.user.BFS) X.baba = 6 self.assertEqual(rd.baba.value, 6) self.assertEqual(rd.baba.cls, X) self.assertEqual(rb.baba.value, 6) self.assertEqual(rb.baba.cls, X) def testNone(self): class X: pass X.bab = 5 rb = self.user.Resolver(X, self.user.BFS) rd = self.user.Resolver(X, self.user.DFS) v = self.user.ValueResolver(X) self.assertEqual(rd.baba, None) self.assertEqual(rb.baba, None) self.assertRaises(AttributeError, operator.attrgetter('baba'), v) def testVersus(self): class D: pass class C: pass class B(D): pass class A(B, C): pass C.baba = D.baba = 1 rb = self.user.Resolver(A, self.user.BFS) rd = self.user.Resolver(A, self.user.DFS) v = self.user.ValueResolver(A) self.assertEqual(rb.baba.cls, C) self.assertEqual(rd.baba.cls, D) self.assertEqual(v.baba, 1) def testClsAttr(self): class X: pass X.cls = 5 r = self.user.Resolver(X) v = self.user.ValueResolver(X) self.assertEqual(r.cls.value, 5) self.assertEqual(v.cls, 5) def testNotSoComplex(self): class A(object): pass class B: pass class C(B): pass class D(C): pass class E(B): pass class F(D, A, E): pass A.x = 11 B.x = 12 E.x = 13 rfb = self.user.Resolver(F, self.user.BFS) rfd = self.user.Resolver(F, self.user.DFS) self.assertEqual(rfb.x.value, 11) self.assertEqual(rfd.x.value, 12) if __name__ == "__main__": ProblemTests.user_filename = "test.py"; unittest.main()