diff --git a/mopidy/models.py b/mopidy/models.py index 4b268474..477b87a7 100644 --- a/mopidy/models.py +++ b/mopidy/models.py @@ -1,6 +1,7 @@ from __future__ import absolute_import, unicode_literals import copy +import inspect import json import weakref @@ -145,11 +146,12 @@ class ImmutableObjectMeta(type): value._name = key attrs['_fields'] = fields - attrs['__slots__'] = fields.values() attrs['_instances'] = weakref.WeakValueDictionary() + attrs['__slots__'] = fields.values() - for base in bases: - if '__weakref__' in getattr(base, '__slots__', []): + anncestors = [b for base in bases for b in inspect.getmro(base)] + for anncestor in anncestors: + if '__weakref__' in getattr(anncestor, '__slots__', []): break else: attrs['__slots__'].append('__weakref__') diff --git a/tests/models/test_models.py b/tests/models/test_models.py index 0407056c..27d02382 100644 --- a/tests/models/test_models.py +++ b/tests/models/test_models.py @@ -8,6 +8,17 @@ from mopidy.models import ( TlTrack, Track, model_json_decoder) +class InheritanecTest(unittest.TestCase): + + def test_weakref_and_slots_play_nice_in_subclass(self): + # Check that the following does not happen: + # TypeError: Error when calling the metaclass bases + # __weakref__ slot disallowed: either we already got one... + + class Foo(Track): + pass + + class CachingTest(unittest.TestCase): def test_same_instance(self):