diff --git a/beets/library.py b/beets/library.py index 33087de87..789b4c72f 100644 --- a/beets/library.py +++ b/beets/library.py @@ -397,7 +397,7 @@ class Item(LibModel): except (OSError, IOError) as exc: raise ReadError(read_path, exc) - for key in ITEM_KEYS_META: + for key in list(ITEM_KEYS_META) + MediaFile.custom_fields: value = getattr(f, key) if isinstance(value, (int, long)): # Filter values wider than 64 bits (in signed diff --git a/beets/mediafile.py b/beets/mediafile.py index 3f207ef20..7c47e54f2 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1276,6 +1276,8 @@ class MediaFile(object): 'channels', 'format']: yield property + custom_fields = [] + @classmethod def add_field(cls, name, descriptor): """Add a field to store custom tags. @@ -1293,6 +1295,7 @@ class MediaFile(object): if name in cls.__dict__: raise ValueError( u'property "{0}" already exists on MediaField'.format(name)) + cls.custom_fields.append(name) setattr(cls, name, descriptor) def update(self, dict, id3v23=False): diff --git a/test/test_mediafile.py b/test/test_mediafile.py index 5aa669bd5..4334f3c7e 100644 --- a/test/test_mediafile.py +++ b/test/test_mediafile.py @@ -272,6 +272,7 @@ class ExtendedFieldTestMixin(object): mediafile = MediaFile(mediafile.path) self.assertEqual(mediafile.initialkey, 'F#') delattr(MediaFile, 'initialkey') + MediaFile.custom_fields = [] def test_extended_attribute_from_item(self): MediaFile.add_field('initialkey', field_extension) @@ -284,6 +285,19 @@ class ExtendedFieldTestMixin(object): mediafile = MediaFile(mediafile.path) self.assertEqual(mediafile.initialkey, 'Gb') delattr(MediaFile, 'initialkey') + MediaFile.custom_fields = [] + + def test_flexible_attribute_from_file(self): + MediaFile.add_field('initialkey', field_extension) + + mediafile = self._mediafile_fixture('empty') + mediafile.update({'initialkey': 'F#'}) + + item = Item.from_path(mediafile.path) + self.assertEqual(item['initialkey'], 'F#') + + delattr(MediaFile, 'initialkey') + MediaFile.custom_fields = [] def test_invalid_descriptor(self): with self.assertRaises(ValueError) as cm: