diff --git a/beets/dbcore/db.py b/beets/dbcore/db.py index 0f4dc1513..e92cba40c 100755 --- a/beets/dbcore/db.py +++ b/beets/dbcore/db.py @@ -290,10 +290,10 @@ class Model(object): if key in self._values_flex: # Flexible. del self._values_flex[key] self._dirty.add(key) # Mark for dropping on store. + elif key in self._fields: # Fixed + setattr(self, key, self._type(key).null) elif key in self._getters(): # Computed. raise KeyError(u'computed field {0} cannot be deleted'.format(key)) - elif key in self._fields: # Fixed. - raise KeyError(u'fixed field {0} cannot be deleted'.format(key)) else: raise KeyError(u'no such field {0}'.format(key)) diff --git a/beets/library.py b/beets/library.py index d0571ed3a..bbb6452fe 100644 --- a/beets/library.py +++ b/beets/library.py @@ -1506,9 +1506,16 @@ class DefaultTemplateFunctions(object): # Fast paths: no album, no item or library, or memoized value. if not self.item or not self.lib: return u'' - if self.item.album_id is None: + + if isinstance(self.item, Item): + album_id = self.item.album_id + elif isinstance(self.item, Album): + album_id = self.item.id + + if album_id is None: return u'' - memokey = ('aunique', keys, disam, self.item.album_id) + + memokey = ('aunique', keys, disam, album_id) memoval = self.lib._memotable.get(memokey) if memoval is not None: return memoval @@ -1528,7 +1535,7 @@ class DefaultTemplateFunctions(object): bracket_l = u'' bracket_r = u'' - album = self.lib.get_album(self.item) + album = self.lib.get_album(album_id) if not album: # Do nothing for singletons. self.lib._memotable[memokey] = u'' diff --git a/docs/changelog.rst b/docs/changelog.rst index 2d456ae88..7081a2ddb 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -42,6 +42,10 @@ New features: * The ``albumdisambig`` field no longer includes the MusicBrainz release group disambiguation comment. A new ``releasegroupdisambig`` field has been added. :bug:`3024` +* The :ref:`modify-cmd` command now allows resetting fixed attributes. For + example, ``beet modify -a artist:beatles artpath!`` resets ``artpath`` + attribute from matching albums back to the default value. + :bug:`2497` Changes: @@ -88,6 +92,9 @@ Fixes: :bug:`2504` :bug:`3029` * Avoid a crash when archive extraction fails during import. :bug:`3041` +* The ``%aunique`` template function now works correctly with the + ``-f/--format`` option. + :bug:`3043` .. _python-itunes: https://github.com/ocelma/python-itunes diff --git a/test/test_dbcore.py b/test/test_dbcore.py index d2d97d4b3..4c646802d 100644 --- a/test/test_dbcore.py +++ b/test/test_dbcore.py @@ -114,6 +114,19 @@ class AnotherTestModel(TestModel1): } +class TestModel5(TestModel1): + _fields = { + 'some_string_field': dbcore.types.STRING, + 'some_float_field': dbcore.types.FLOAT, + 'some_boolean_field': dbcore.types.BOOLEAN, + } + + +class TestDatabase5(dbcore.Database): + _models = (TestModel5,) + pass + + class TestDatabaseTwoModels(dbcore.Database): _models = (TestModel2, AnotherTestModel) pass @@ -266,9 +279,18 @@ class ModelTest(unittest.TestCase): del model['foo'] def test_delete_fixed_attribute(self): - model = TestModel1() - with self.assertRaises(KeyError): - del model['field_one'] + model = TestModel5() + model.some_string_field = 'foo' + model.some_float_field = 1.23 + model.some_boolean_field = True + + for field, type_ in model._fields.items(): + print("%s - %s" % (model[field], field)) + self.assertNotEqual(model[field], type_.null) + + for field, type_ in model._fields.items(): + del model[field] + self.assertEqual(model[field], type_.null) def test_null_value_normalization_by_type(self): model = TestModel1()