From 1796719bb3cb97a9c310a255147514fd786ceb44 Mon Sep 17 00:00:00 2001 From: Ryan Rowe Date: Wed, 22 Jul 2020 14:32:58 -0700 Subject: [PATCH] src/class: fix init on dispatch of twice derived classes --- dynamic_dispatch/_class.py | 2 +- tests/test_class.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/dynamic_dispatch/_class.py b/dynamic_dispatch/_class.py index 697406c..ca2ee64 100644 --- a/dynamic_dispatch/_class.py +++ b/dynamic_dispatch/_class.py @@ -65,7 +65,7 @@ class Registered(wrap): def __init__(self, *args, **kwargs): # Certain scenarios can cause __init__ to be called twice. This prevents it. - if not self.__dispatch_init: + if self.__class__ == __class__ and not self.__dispatch_init: return self.__dispatch_init = False diff --git a/tests/test_class.py b/tests/test_class.py index 129d2ff..27512fc 100644 --- a/tests/test_class.py +++ b/tests/test_class.py @@ -541,3 +541,31 @@ def __init__(self, a): self.assertEqual(obj.abc_count, 1) self.assertEqual(obj.a, 5) self.assertEqual(obj.a_count, 1) + + def test_dispatch_twice_derived(self): + @dynamic_dispatch + class Foo(OneArgInit): + pass + + @Foo.dispatch(on='bar') + class Bar(Foo): + def __init__(self, abc, d): + super().__init__(abc) + self.d = d + self.d_count = getattr(self, 'b_count', 0) + 1 + + @Foo.dispatch(on='baz') + class Baz(Bar): + def __init__(self, abc, d, e): + super().__init__(abc, d) + self.e = e + self.e_count = getattr(self, 'e_count', 0) + 1 + + obj = Foo('baz', 'd', 'e') + self.assertIsInstance(obj, Baz) + self.assertEqual(obj.abc, 'baz') + self.assertEqual(obj.abc_count, 1) + self.assertEqual(obj.d, 'd') + self.assertEqual(obj.d_count, 1) + self.assertEqual(obj.e, 'e') + self.assertEqual(obj.e_count, 1)