4318383b091a — aurelien@trantor.local 12 years ago
[tests] diamond inheritance & next_method, ambiguous case
2 files changed, 35 insertions(+), 1 deletions(-)

M dispatch.py
M test/test_gf.py
M dispatch.py +1 -1
@@ 25,8 25,8 @@ class GF(object):
     def __call__(self, *args):
         sig = signature(*args)
         self._pos = 0
-        self._funcs = self.linearized_table(sig)
         if sig not in self._cache:
+            self._funcs = self.linearized_table(sig)
             func = self._funcs.pop()
             self._cache[sig] = func
         else:

          
M test/test_gf.py +34 -0
@@ 75,6 75,40 @@ class TestGF(unittest.TestCase):
         self.assertTrue(beats(p, r))
         self.assertFalse(beats(r, p))
 
+    def test_deep_diamond(self):
+        class A(object): pass
+        class B(A): pass
+        class X(object): pass
+        class Y(X): pass
+        @method(A,X)
+        def foo(x,y):
+            return ('AX',)
+        @method(A,Y)
+        def foo(x,y):
+            return foo.next_method(x, y) + ('AY',)
+        @method(B,X)
+        def foo(x,y):
+            return foo.next_method(x, y) + ('BX',)
+        @method(B,Y)
+        def foo(x,y):
+            return foo.next_method(x, y) + ('BY',)
+
+        b, y = B(), Y()
+        self.assertEquals(foo(b, y), ('AX', 'AY', 'BX', 'BY'))
+
+    def test_ambiguity(self):
+        class A(object): pass
+        class B(A): pass
+        class X(object): pass
+        class Y(X): pass
+        @method(A,Y)
+        def foo(a,y):
+            return a,y
+        @method(B,X)
+        def foo(b,x):
+            return b,x
+        b, y = B(), Y()
+        print foo(b, y)
 
 if __name__ == '__main__':
     unittest.main()