parent
305a76486d
commit
bdd1fb983b
@ -45,6 +45,12 @@ v0.20.0 (UNRELEASED)
|
|||||||
|
|
||||||
- Hide empty collections from :func:`repr()` representations.
|
- Hide empty collections from :func:`repr()` representations.
|
||||||
|
|
||||||
|
- Field values are no longer stored on the model instance when the value
|
||||||
|
matches the default value for the field. This makes two models equal when
|
||||||
|
they have a field which in one case is implicitly set to the default value
|
||||||
|
and in the other case explicitly set to the default value, but with otherwise
|
||||||
|
equal fields. (Fixes: :issue:`837`)
|
||||||
|
|
||||||
|
|
||||||
v0.19.4 (2014-09-01)
|
v0.19.4 (2014-09-01)
|
||||||
====================
|
====================
|
||||||
|
|||||||
@ -18,6 +18,8 @@ class ImmutableObject(object):
|
|||||||
raise TypeError(
|
raise TypeError(
|
||||||
'__init__() got an unexpected keyword argument "%s"' %
|
'__init__() got an unexpected keyword argument "%s"' %
|
||||||
key)
|
key)
|
||||||
|
if value == getattr(self, key):
|
||||||
|
continue # Don't explicitly set default values
|
||||||
self.__dict__[key] = value
|
self.__dict__[key] = value
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
@ -72,13 +74,11 @@ class ImmutableObject(object):
|
|||||||
for key in self.__dict__.keys():
|
for key in self.__dict__.keys():
|
||||||
public_key = key.lstrip('_')
|
public_key = key.lstrip('_')
|
||||||
value = values.pop(public_key, self.__dict__[key])
|
value = values.pop(public_key, self.__dict__[key])
|
||||||
if value is not None:
|
data[public_key] = value
|
||||||
data[public_key] = value
|
|
||||||
for key in values.keys():
|
for key in values.keys():
|
||||||
if hasattr(self, key):
|
if hasattr(self, key):
|
||||||
value = values.pop(key)
|
value = values.pop(key)
|
||||||
if value is not None:
|
data[key] = value
|
||||||
data[key] = value
|
|
||||||
if values:
|
if values:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
'copy() got an unexpected keyword argument "%s"' % key)
|
'copy() got an unexpected keyword argument "%s"' % key)
|
||||||
|
|||||||
@ -171,8 +171,8 @@ class ArtistTest(unittest.TestCase):
|
|||||||
|
|
||||||
def test_serialize_falsy_values(self):
|
def test_serialize_falsy_values(self):
|
||||||
self.assertDictEqual(
|
self.assertDictEqual(
|
||||||
{'__model__': 'Artist', 'uri': '', 'name': None},
|
{'__model__': 'Artist', 'uri': '', 'name': ''},
|
||||||
Artist(uri='', name=None).serialize())
|
Artist(uri='', name='').serialize())
|
||||||
|
|
||||||
def test_to_json_and_back(self):
|
def test_to_json_and_back(self):
|
||||||
artist1 = Artist(uri='uri', name='name')
|
artist1 = Artist(uri='uri', name='name')
|
||||||
@ -735,6 +735,24 @@ class TrackTest(unittest.TestCase):
|
|||||||
self.assertNotEqual(track1, track2)
|
self.assertNotEqual(track1, track2)
|
||||||
self.assertNotEqual(hash(track1), hash(track2))
|
self.assertNotEqual(hash(track1), hash(track2))
|
||||||
|
|
||||||
|
def test_ignores_values_with_default_value_none(self):
|
||||||
|
track1 = Track(name='name1')
|
||||||
|
track2 = Track(name='name1', album=None)
|
||||||
|
self.assertEqual(track1, track2)
|
||||||
|
self.assertEqual(hash(track1), hash(track2))
|
||||||
|
|
||||||
|
def test_ignores_values_with_default_value_zero(self):
|
||||||
|
track1 = Track(name='name1')
|
||||||
|
track2 = Track(name='name1', track_no=0)
|
||||||
|
self.assertEqual(track1, track2)
|
||||||
|
self.assertEqual(hash(track1), hash(track2))
|
||||||
|
|
||||||
|
def test_copy_can_reset_to_default_value(self):
|
||||||
|
track1 = Track(name='name1')
|
||||||
|
track2 = Track(name='name1', album=Album()).copy(album=None)
|
||||||
|
self.assertEqual(track1, track2)
|
||||||
|
self.assertEqual(hash(track1), hash(track2))
|
||||||
|
|
||||||
|
|
||||||
class TlTrackTest(unittest.TestCase):
|
class TlTrackTest(unittest.TestCase):
|
||||||
def test_tlid(self):
|
def test_tlid(self):
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user