| 2536 | self.assertEqual(fun(aa), 'fun A') |
| 2537 | |
| 2538 | def test_mro_conflicts(self): |
| 2539 | c = collections.abc |
| 2540 | @functools.singledispatch |
| 2541 | def g(arg): |
| 2542 | return "base" |
| 2543 | class O(c.Sized): |
| 2544 | def __len__(self): |
| 2545 | return 0 |
| 2546 | o = O() |
| 2547 | self.assertEqual(g(o), "base") |
| 2548 | g.register(c.Iterable, lambda arg: "iterable") |
| 2549 | g.register(c.Container, lambda arg: "container") |
| 2550 | g.register(c.Sized, lambda arg: "sized") |
| 2551 | g.register(c.Set, lambda arg: "set") |
| 2552 | self.assertEqual(g(o), "sized") |
| 2553 | c.Iterable.register(O) |
| 2554 | self.assertEqual(g(o), "sized") # because it's explicitly in __mro__ |
| 2555 | c.Container.register(O) |
| 2556 | self.assertEqual(g(o), "sized") # see above: Sized is in __mro__ |
| 2557 | c.Set.register(O) |
| 2558 | self.assertEqual(g(o), "set") # because c.Set is a subclass of |
| 2559 | # c.Sized and c.Container |
| 2560 | class P: |
| 2561 | pass |
| 2562 | p = P() |
| 2563 | self.assertEqual(g(p), "base") |
| 2564 | c.Iterable.register(P) |
| 2565 | self.assertEqual(g(p), "iterable") |
| 2566 | c.Container.register(P) |
| 2567 | with self.assertRaises(RuntimeError) as re_one: |
| 2568 | g(p) |
| 2569 | self.assertIn( |
| 2570 | str(re_one.exception), |
| 2571 | (("Ambiguous dispatch: <class 'collections.abc.Container'> " |
| 2572 | "or <class 'collections.abc.Iterable'>"), |
| 2573 | ("Ambiguous dispatch: <class 'collections.abc.Iterable'> " |
| 2574 | "or <class 'collections.abc.Container'>")), |
| 2575 | ) |
| 2576 | class Q(c.Sized): |
| 2577 | def __len__(self): |
| 2578 | return 0 |
| 2579 | q = Q() |
| 2580 | self.assertEqual(g(q), "sized") |
| 2581 | c.Iterable.register(Q) |
| 2582 | self.assertEqual(g(q), "sized") # because it's explicitly in __mro__ |
| 2583 | c.Set.register(Q) |
| 2584 | self.assertEqual(g(q), "set") # because c.Set is a subclass of |
| 2585 | # c.Sized and c.Iterable |
| 2586 | @functools.singledispatch |
| 2587 | def h(arg): |
| 2588 | return "base" |
| 2589 | @h.register(c.Sized) |
| 2590 | def _(arg): |
| 2591 | return "sized" |
| 2592 | @h.register(c.Container) |
| 2593 | def _(arg): |
| 2594 | return "container" |
| 2595 | # Even though Sized and Container are explicit bases of MutableMapping, |