diff --git a/beets/mediafile.py b/beets/mediafile.py index 7b1b79f72..c4712404a 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -306,18 +306,23 @@ class Packed(object): """Makes a packed list of values subscriptable. To access the packed output after making changes, use packed_thing.items. """ - def __init__(self, items, packstyle, none_val=0, out_type=int): + def __init__(self, items, packstyle, out_type=int): """Create a Packed object for subscripting the packed values in items. The items are packed using packstyle, which is a value - from the packing enum. none_val is returned from a request when - no suitable value is found in the items. Values are converted to - out_type before they are returned. + from the packing enum. Values are converted to out_type before + they are returned. """ self.items = items self.packstyle = packstyle - self.none_val = none_val self.out_type = out_type + if out_type is int: + self.none_val = 0 + elif out_type is float: + self.none_val = 0.0 + else: + self.none_val = None + def __getitem__(self, index): if not isinstance(index, int): raise TypeError('index must be an integer') @@ -352,6 +357,10 @@ class Packed(object): return _safe_cast(self.out_type, out) def __setitem__(self, index, value): + # Interpret null values. + if value is None: + value = self.none_val + if self.packstyle in (packing.SLASHED, packing.TUPLE, packing.SC): # SLASHED, TUPLE and SC are always two-item packings length = 2 diff --git a/docs/changelog.rst b/docs/changelog.rst index 858790d4d..086cc4b23 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -12,6 +12,7 @@ Changelog crashing. * Add "System Volume Information" (an internal directory found on some Windows filesystems) to the default ignore list. +* Fix a crash when ReplayGain values were set to null. * Fix a crash when iTunes Sound Check tags contained invalid data. * Fix an error when the configuration file (``config.yaml``) is completely empty. diff --git a/test/test_mediafile.py b/test/test_mediafile.py index 7050b0651..5c237c248 100644 --- a/test/test_mediafile.py +++ b/test/test_mediafile.py @@ -189,6 +189,7 @@ class ZeroLengthMediaFile(beets.mediafile.MediaFile): return 0.0 class MissingAudioDataTest(unittest.TestCase): def setUp(self): + super(MissingAudioDataTest, self).setUp() path = os.path.join(_common.RSRC, 'full.mp3') self.mf = ZeroLengthMediaFile(path) @@ -198,6 +199,7 @@ class MissingAudioDataTest(unittest.TestCase): class TypeTest(unittest.TestCase): def setUp(self): + super(TypeTest, self).setUp() path = os.path.join(_common.RSRC, 'full.mp3') self.mf = beets.mediafile.MediaFile(path) @@ -205,6 +207,22 @@ class TypeTest(unittest.TestCase): self.mf.year = '2009' self.assertEqual(self.mf.year, 2009) + def test_set_replaygain_gain_to_none(self): + self.mf.rg_track_gain = None + self.assertEqual(self.mf.rg_track_gain, 0.0) + + def test_set_replaygain_peak_to_none(self): + self.mf.rg_track_peak = None + self.assertEqual(self.mf.rg_track_peak, 0.0) + + def test_set_year_to_none(self): + self.mf.year = None + self.assertEqual(self.mf.year, 0) + + def test_set_track_to_none(self): + self.mf.track = None + self.assertEqual(self.mf.track, 0) + class SoundCheckTest(unittest.TestCase): def test_round_trip(self): data = beets.mediafile._sc_encode(1.0, 1.0)