| 2498 | self.assertEqual(fun(aa), 'fun A') |
| 2499 | |
| 2500 | def test_mro_conflicts(self): |
| 2501 | c = collections.abc |
| 2502 | @functools.singledispatch |
| 2503 | def g(arg): |
| 2504 | return "base" |
| 2505 | class O(c.Sized): |
| 2506 | def __len__(self): |
| 2507 | return 0 |
| 2508 | o = O() |
| 2509 | self.assertEqual(g(o), "base") |
| 2510 | g.register(c.Iterable, lambda arg: "iterable") |
| 2511 | g.register(c.Container, lambda arg: "container") |
| 2512 | g.register(c.Sized, lambda arg: "sized") |
| 2513 | g.register(c.Set, lambda arg: "set") |
| 2514 | self.assertEqual(g(o), "sized") |
| 2515 | c.Iterable.register(O) |
| 2516 | self.assertEqual(g(o), "sized") # because it's explicitly in __mro__ |
| 2517 | c.Container.register(O) |
| 2518 | self.assertEqual(g(o), "sized") # see above: Sized is in __mro__ |
| 2519 | c.Set.register(O) |
| 2520 | self.assertEqual(g(o), "set") # because c.Set is a subclass of |
| 2521 | # c.Sized and c.Container |
| 2522 | class P: |
| 2523 | pass |
| 2524 | p = P() |
| 2525 | self.assertEqual(g(p), "base") |
| 2526 | c.Iterable.register(P) |
| 2527 | self.assertEqual(g(p), "iterable") |
| 2528 | c.Container.register(P) |
| 2529 | with self.assertRaises(RuntimeError) as re_one: |
| 2530 | g(p) |
| 2531 | self.assertIn( |
| 2532 | str(re_one.exception), |
| 2533 | (("Ambiguous dispatch: <class 'collections.abc.Container'> " |
| 2534 | "or <class 'collections.abc.Iterable'>"), |
| 2535 | ("Ambiguous dispatch: <class 'collections.abc.Iterable'> " |
| 2536 | "or <class 'collections.abc.Container'>")), |
| 2537 | ) |
| 2538 | class Q(c.Sized): |
| 2539 | def __len__(self): |
| 2540 | return 0 |
| 2541 | q = Q() |
| 2542 | self.assertEqual(g(q), "sized") |
| 2543 | c.Iterable.register(Q) |
| 2544 | self.assertEqual(g(q), "sized") # because it's explicitly in __mro__ |
| 2545 | c.Set.register(Q) |
| 2546 | self.assertEqual(g(q), "set") # because c.Set is a subclass of |
| 2547 | # c.Sized and c.Iterable |
| 2548 | @functools.singledispatch |
| 2549 | def h(arg): |
| 2550 | return "base" |
| 2551 | @h.register(c.Sized) |
| 2552 | def _(arg): |
| 2553 | return "sized" |
| 2554 | @h.register(c.Container) |
| 2555 | def _(arg): |
| 2556 | return "container" |
| 2557 | # Even though Sized and Container are explicit bases of MutableMapping, |