diff --git a/mopidy/models/immutable.py b/mopidy/models/immutable.py index 8e282c91..485480a9 100644 --- a/mopidy/models/immutable.py +++ b/mopidy/models/immutable.py @@ -15,7 +15,9 @@ class ImmutableObjectMeta(type): def __new__(cls, name, bases, attrs): fields = {} - for key, value in attrs.items(): + for base in bases: # Copy parent fields over to our state + fields.update(getattr(base, '_fields', {})) + for key, value in attrs.items(): # Add our own fields if isinstance(value, Field): fields[key] = '_' + key value._name = key diff --git a/tests/models/test_models.py b/tests/models/test_models.py index f0f5ff6c..be82d3b2 100644 --- a/tests/models/test_models.py +++ b/tests/models/test_models.py @@ -19,6 +19,7 @@ class InheritanceTest(unittest.TestCase): pass def test_sub_class_can_have_its_own_slots(self): + # Needed for things like SpotifyTrack in mopidy-spotify 1.x class Foo(Track): __slots__ = ('_foo',) @@ -26,6 +27,17 @@ class InheritanceTest(unittest.TestCase): f = Foo() f._foo = 123 + def test_sub_class_can_be_initialized(self): + # Fails with following error if fields are not handled across classes. + # TypeError: __init__() got an unexpected keyword argument "type" + # Essentially this is testing that sub-classes take parent _fields into + # account. + + class Foo(Ref): + pass + + Foo.directory() + class CachingTest(unittest.TestCase):