Merge pull request #1125 from adamcik/feature/model-tweaks
More model tweaks
This commit is contained in:
commit
c1ab352ba1
@ -1,6 +1,8 @@
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import copy
|
||||
import inspect
|
||||
import itertools
|
||||
import json
|
||||
import weakref
|
||||
|
||||
@ -145,11 +147,11 @@ class ImmutableObjectMeta(type):
|
||||
value._name = key
|
||||
|
||||
attrs['_fields'] = fields
|
||||
attrs['__slots__'] = fields.values()
|
||||
attrs['_instances'] = weakref.WeakValueDictionary()
|
||||
attrs['__slots__'] = ['_hash'] + fields.values()
|
||||
|
||||
for base in bases:
|
||||
if '__weakref__' in getattr(base, '__slots__', []):
|
||||
for ancestor in [b for base in bases for b in inspect.getmro(base)]:
|
||||
if '__weakref__' in getattr(ancestor, '__slots__', []):
|
||||
break
|
||||
else:
|
||||
attrs['__slots__'].append('__weakref__')
|
||||
@ -215,15 +217,18 @@ class ImmutableObject(object):
|
||||
}
|
||||
|
||||
def __hash__(self):
|
||||
hash_sum = 0
|
||||
for key, value in self._items():
|
||||
hash_sum += hash(key) + hash(value)
|
||||
return hash_sum
|
||||
if not hasattr(self, '_hash'):
|
||||
hash_sum = 0
|
||||
for key, value in self._items():
|
||||
hash_sum += hash(key) + hash(value)
|
||||
super(ImmutableObject, self).__setattr__('_hash', hash_sum)
|
||||
return self._hash
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, self.__class__):
|
||||
return False
|
||||
return dict(self._items()) == dict(other._items())
|
||||
return all(a == b for a, b in itertools.izip_longest(
|
||||
self._items(), other._items(), fillvalue=object()))
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
@ -263,6 +268,7 @@ class ImmutableObject(object):
|
||||
raise TypeError(
|
||||
'copy() got an unexpected keyword argument "%s"' % key)
|
||||
super(ImmutableObject, other).__setattr__(key, value)
|
||||
super(ImmutableObject, other).__delattr__('_hash')
|
||||
return self._instances.setdefault(weakref.ref(other), other)
|
||||
|
||||
def serialize(self):
|
||||
|
||||
@ -8,6 +8,17 @@ from mopidy.models import (
|
||||
TlTrack, Track, model_json_decoder)
|
||||
|
||||
|
||||
class InheritanceTest(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):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user