Skip to content

beet write: false positive for changes in fields with multiple values #5371

@celynw

Description

@celynw

Problem

It seems that for fields which allow multiple tags, the write command might incorrectly say there are changes to be made.

Backstory

I am using the albumtypes plugin to set the 'soundtrack' album type.

My relevant config looks like this:

albumtypes:
  types:
    - soundtrack: "OST"
    - ep: "EP"
    - single: "Single"
    - live: "Live"
    - compilation: "Anthology"
    - remix: "Remix"
  ignore_va: compilation
paths:
  default: $albumartist/$year - $album%aunique{}/%if{$multidisc,$paddisc-}$padtrack $title
  albumtype:soundtrack: Soundtracks/$album/%if{$multidisc,$paddisc-}$padtrack $title
  albumtypes:soundtrack: Soundtracks/$album/%if{$multidisc,$paddisc-}$padtrack $title
musicbrainz:

(I opened a related discussion, which was solved.)

Basically, if 'soundtrack' appears at all in MusicBrainz's albumtypes list, I'll set the main albumtype to soundtrack. This is because I prefer soundtrack to be the highest priority when something belongs to multiple types.

This does work; I checked the database manually, and the types are set correctly:

albumtype albumtypes
soundtrack album; soundtrack

I also checked the files themselves and found the data to also be correct.

RELEASETYPE     : album;soundtrack
MUSICBRAINZ_ALBUMTYPE: album;soundtrack

My issue is that when I run beet write, it tells me there are many changes to be made like:

albumtype: album -> soundtrack

This never clears; if I run the command again, it tries to do this again.

The issue seems to related to this part in mediafile:

    albumtypes = ListMediaField(
        MP3ListDescStorageStyle('MusicBrainz Album Type', split_v23=True),
        MP4ListStorageStyle('----:com.apple.iTunes:MusicBrainz Album Type'),
        ListStorageStyle('RELEASETYPE'),
        ListStorageStyle('MUSICBRAINZ_ALBUMTYPE'),
        ASFStorageStyle('MusicBrainz/Album Type'),
    )
    albumtype = albumtypes.single_field()

ListMediaField.single_field returns the first item in albumtypes.

This comes up in the write command, write_items(), where a 'clean_item` is created from the file on disk:

clean_item = library.Item.from_path(item.path)

It's a bit tricky, because both the file and the database are already correct, but because the write command thought there is a difference, it will attempt to write the corrections anyway.

  • Beets' database holds both multiple (albumtypes) and single fields (albumtype) for that entry, and the single field can be configured by the user to choose which one from the multiple field
  • Beets reads a field with multiple values and returns the first one to the write command
  • Beets writes (only) the multiple values tag to the file
    • I haven't investigated with other media file types - this one is an FLAC

If the above is always true, a workaround which works for me is to add

        if item.albumtype in clean_item.albumtypes:
            clean_item.albumtype = item.albumtype

before checking for the changes here:

changed = ui.show_model_changes(

I'm not sure if this is the most robust though.

Also, I guess it could apply to other 'multiple' fields too:

  • genres
  • catalognums
  • languages
  • mb_artistids
  • mb_albumartistids

Setup

  • OS: Ubuntu 22.04
  • Python version: 3.10.12
  • beets version: 2.0.0
  • Turning off plugins made problem go away (yes/no): N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions