From 23e46315e3a957f2c9ca969535e9455780045ccc Mon Sep 17 00:00:00 2001 From: Henry Oberholtzer Date: Sat, 20 Sep 2025 01:52:53 +0200 Subject: [PATCH 01/10] Remove Discogs Disambiguation stripping from metadata_plugins --- beets/metadata_plugins.py | 2 -- docs/changelog.rst | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/beets/metadata_plugins.py b/beets/metadata_plugins.py index 6a75d0f79..0372790af 100644 --- a/beets/metadata_plugins.py +++ b/beets/metadata_plugins.py @@ -298,8 +298,6 @@ class MetadataSourcePlugin(BeetsPlugin, metaclass=abc.ABCMeta): if not artist_id: artist_id = artist[id_key] name = artist[name_key] - # Strip disambiguation number. - name = re.sub(r" \(\d+\)$", "", name) # Move articles to the front. name = re.sub(r"^(.*?), (a|an|the)$", r"\2 \1", name, flags=re.I) # Use a join keyword if requested and available. diff --git a/docs/changelog.rst b/docs/changelog.rst index 8a35569c9..4ff7b7088 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -22,7 +22,7 @@ Bug fixes: For packagers: Other changes: - +- :class:`beets.metadata_plugin.MetadataSourcePlugin`: Remove discogs specific disambiguation stripping - :doc:`plugins/index`: Clarify that musicbrainz must be mentioned if plugin list modified :bug:`6020` - :doc:`/faq`: Add check for musicbrainz plugin if auto-tagger can't find a From 24fbc566f61d86d1fb2e6c1fcde98630b82e7828 Mon Sep 17 00:00:00 2001 From: Henry Oberholtzer Date: Sat, 20 Sep 2025 01:58:56 +0200 Subject: [PATCH 02/10] initial changes, changelog adjusted, TODO: test for various artists and update docs --- beetsplug/discogs.py | 9 +++++++ docs/changelog.rst | 6 ++++- test/plugins/test_discogs.py | 49 ++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/beetsplug/discogs.py b/beetsplug/discogs.py index c1c782f3e..d8f1d6ba5 100644 --- a/beetsplug/discogs.py +++ b/beetsplug/discogs.py @@ -76,6 +76,8 @@ TRACK_INDEX_RE = re.compile( re.VERBOSE, ) +DISAMBIGUATION_RE = re.compile(r" \(\d+\)$") + class ReleaseFormat(TypedDict): name: str @@ -96,6 +98,7 @@ class DiscogsPlugin(MetadataSourcePlugin): "separator": ", ", "index_tracks": False, "append_style_genre": False, + "strip_disambiguation": True, } ) self.config["apikey"].redact = True @@ -373,6 +376,12 @@ class DiscogsPlugin(MetadataSourcePlugin): artist = config["va_name"].as_str() if catalogno == "none": catalogno = None + + # Remove Discogs specific artist disambiguation 'Artist (2)' or 'Label (3)' + if self.config["strip_disambiguation"]: + artist = DISAMBIGUATION_RE.sub("", artist) + if label is not None: + label = DISAMBIGUATION_RE.sub("", label) # Explicitly set the `media` for the tracks, since it is expected by # `autotag.apply_metadata`, and set `medium_total`. for track in tracks: diff --git a/docs/changelog.rst b/docs/changelog.rst index 4ff7b7088..0814686f8 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -18,17 +18,21 @@ Bug fixes: - :doc:`plugins/spotify` Removed old and undocumented config options `artist_field`, `album_field` and `track` that were causing issues with track matching. :bug:`5189` +- :doc:`plugins/discogs` Added config option `strip_disambiguation` to allow choice of removing discogs numeric disambiguation :bug:`5366` +- :doc:`plugins/discogs` Fixed inconsistency in stripping disambiguation from artists but not labels :bug:`5366` For packagers: Other changes: -- :class:`beets.metadata_plugin.MetadataSourcePlugin`: Remove discogs specific disambiguation stripping + - :doc:`plugins/index`: Clarify that musicbrainz must be mentioned if plugin list modified :bug:`6020` - :doc:`/faq`: Add check for musicbrainz plugin if auto-tagger can't find a match :bug:`6020` - :doc:`guides/tagger`: Section on no matching release found, related to possibly disabled musicbrainz plugin :bug:`6020` +- :class:`beets.metadata_plugin.MetadataSourcePlugin`: Remove discogs specific + disambiguation stripping 2.4.0 (September 13, 2025) -------------------------- diff --git a/test/plugins/test_discogs.py b/test/plugins/test_discogs.py index e3e51042c..c279ff128 100644 --- a/test/plugins/test_discogs.py +++ b/test/plugins/test_discogs.py @@ -374,6 +374,55 @@ class DGAlbumInfoTest(BeetsTestCase): assert d.genre == "GENRE1, GENRE2" assert d.style is None + def test_strip_disambiguation_label_artist(self): + """Test removing discogs disambiguation""" + data = { + "id": 123, + "uri": "https://www.discogs.com/release/123456-something", + "tracklist": [self._make_track("A", "1", "01:01")], + "artists": [{"name": "ARTIST NAME (2)", "id": 321, "join": ""}], + "title": "TITLE", + "labels": [ + { + "name": "LABEL NAME (5)", + "catno": "CATALOG NUMBER", + } + ], + } + release = Bag( + data=data, + title=data["title"], + artists=[Bag(data=d) for d in data["artists"]], + ) + d = DiscogsPlugin().get_album_info(release) + assert d.artist == "ARTIST NAME" + assert d.label == "LABEL NAME" + + def test_strip_disambiguation_off_label_artist(self): + """Test not removing discogs disambiguation""" + data = { + "id": 123, + "uri": "https://www.discogs.com/release/123456-something", + "tracklist": [self._make_track("A", "1", "01:01")], + "artists": [{"name": "ARTIST NAME (2)", "id": 321, "join": ""}], + "title": "TITLE", + "labels": [ + { + "name": "LABEL NAME (5)", + "catno": "CATALOG NUMBER", + } + ], + } + config["discogs"]["strip_disambiguation"] = False + release = Bag( + data=data, + title=data["title"], + artists=[Bag(data=d) for d in data["artists"]], + ) + d = DiscogsPlugin().get_album_info(release) + assert d.artist == "ARTIST NAME (2)" + assert d.label == "LABEL NAME (5)" + @pytest.mark.parametrize( "formats, expected_media, expected_albumtype", From dda265dc77a9765274a2f484047123a06761d6a2 Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 19 Sep 2025 20:46:07 -0700 Subject: [PATCH 03/10] Disambiguation fix implemented & tested --- beets/metadata_plugins.py | 7 ++-- beetsplug/discogs.py | 26 +++++++++------ docs/changelog.rst | 8 +++-- docs/plugins/discogs.rst | 3 ++ test/plugins/test_discogs.py | 63 ++++++++++++++++++++++++++++++++---- 5 files changed, 86 insertions(+), 21 deletions(-) diff --git a/beets/metadata_plugins.py b/beets/metadata_plugins.py index 0372790af..0b8d81c95 100644 --- a/beets/metadata_plugins.py +++ b/beets/metadata_plugins.py @@ -271,10 +271,9 @@ class MetadataSourcePlugin(BeetsPlugin, metaclass=abc.ABCMeta): """Returns an artist string (all artists) and an artist_id (the main artist) for a list of artist object dicts. - For each artist, this function moves articles (such as 'a', 'an', - and 'the') to the front and strips trailing disambiguation numbers. It - returns a tuple containing the comma-separated string of all - normalized artists and the ``id`` of the main/first artist. + For each artist, this function moves articles (such as 'a', 'an', and 'the') + to the front. It returns a tuple containing the comma-separated string + of all normalized artists and the ``id`` of the main/first artist. Alternatively a keyword can be used to combine artists together into a single string by passing the join_key argument. diff --git a/beetsplug/discogs.py b/beetsplug/discogs.py index d8f1d6ba5..0ffbb0e3e 100644 --- a/beetsplug/discogs.py +++ b/beetsplug/discogs.py @@ -76,7 +76,7 @@ TRACK_INDEX_RE = re.compile( re.VERBOSE, ) -DISAMBIGUATION_RE = re.compile(r" \(\d+\)$") +DISAMBIGUATION_RE = re.compile(r" \(\d+\)") class ReleaseFormat(TypedDict): @@ -365,23 +365,22 @@ class DiscogsPlugin(MetadataSourcePlugin): label = catalogno = labelid = None if result.data.get("labels"): - label = result.data["labels"][0].get("name") + label = self.strip_disambiguation( + result.data["labels"][0].get("name") + ) catalogno = result.data["labels"][0].get("catno") labelid = result.data["labels"][0].get("id") cover_art_url = self.select_cover_art(result) - # Additional cleanups (various artists name, catalog number, media). + # Additional cleanups + # (various artists name, catalog number, media, disambiguation). if va: artist = config["va_name"].as_str() + else: + artist = self.strip_disambiguation(artist) if catalogno == "none": catalogno = None - - # Remove Discogs specific artist disambiguation 'Artist (2)' or 'Label (3)' - if self.config["strip_disambiguation"]: - artist = DISAMBIGUATION_RE.sub("", artist) - if label is not None: - label = DISAMBIGUATION_RE.sub("", label) # Explicitly set the `media` for the tracks, since it is expected by # `autotag.apply_metadata`, and set `medium_total`. for track in tracks: @@ -631,6 +630,14 @@ class DiscogsPlugin(MetadataSourcePlugin): return tracklist + def strip_disambiguation(self, text) -> str: + """Removes discogs specific disambiguations from a string. + Turns 'Label Name (5)' to 'Label Name' or 'Artist (1) & Another Artist (2)' + to 'Artist & Another Artist'. Does nothing if strip_disambiguation is False.""" + if not self.config["strip_disambiguation"]: + return text + return DISAMBIGUATION_RE.sub("", text) + def get_track_info(self, track, index, divisions): """Returns a TrackInfo object for a discogs track.""" title = track["title"] @@ -643,6 +650,7 @@ class DiscogsPlugin(MetadataSourcePlugin): artist, artist_id = self.get_artist( track.get("artists", []), join_key="join" ) + artist = self.strip_disambiguation(artist) length = self.get_track_length(track["duration"]) return TrackInfo( title=title, diff --git a/docs/changelog.rst b/docs/changelog.rst index 0814686f8..ddafd975d 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -18,8 +18,12 @@ Bug fixes: - :doc:`plugins/spotify` Removed old and undocumented config options `artist_field`, `album_field` and `track` that were causing issues with track matching. :bug:`5189` -- :doc:`plugins/discogs` Added config option `strip_disambiguation` to allow choice of removing discogs numeric disambiguation :bug:`5366` -- :doc:`plugins/discogs` Fixed inconsistency in stripping disambiguation from artists but not labels :bug:`5366` +- :doc:`plugins/discogs` Added config option `strip_disambiguation` to allow + choice of removing discogs numeric disambiguation :bug:`5366` +- :doc:`plugins/discogs` Fixed inconsistency in stripping disambiguation from + artists but not labels. :bug:`5366` +- :doc:`plugins/discogs` Wrote test coverage for removing disambiguation. + :bug:`5366` For packagers: diff --git a/docs/plugins/discogs.rst b/docs/plugins/discogs.rst index 44c0c0e22..3dac558bd 100644 --- a/docs/plugins/discogs.rst +++ b/docs/plugins/discogs.rst @@ -109,6 +109,9 @@ Other configurations available under ``discogs:`` are: - **search_limit**: The maximum number of results to return from Discogs. This is useful if you want to limit the number of results returned to speed up searches. Default: ``5`` +- **strip_disambiguation**: Discogs uses strings like ``"(4)"`` to mark distinct + artists and labels with the same name. If you'd like to use the discogs + disambiguation in your tags, you can disable it. Default: ``True`` .. _discogs guidelines: https://support.discogs.com/hc/en-us/articles/360005055373-Database-Guidelines-12-Tracklisting#Index_Tracks_And_Headings diff --git a/test/plugins/test_discogs.py b/test/plugins/test_discogs.py index c279ff128..5fe73dcac 100644 --- a/test/plugins/test_discogs.py +++ b/test/plugins/test_discogs.py @@ -375,7 +375,7 @@ class DGAlbumInfoTest(BeetsTestCase): assert d.style is None def test_strip_disambiguation_label_artist(self): - """Test removing discogs disambiguation""" + """Test removing discogs disambiguation from artist and label""" data = { "id": 123, "uri": "https://www.discogs.com/release/123456-something", @@ -399,21 +399,21 @@ class DGAlbumInfoTest(BeetsTestCase): assert d.label == "LABEL NAME" def test_strip_disambiguation_off_label_artist(self): - """Test not removing discogs disambiguation""" + """Test not removing discogs disambiguation from artist and label""" + config["discogs"]["strip_disambiguation"] = False data = { "id": 123, "uri": "https://www.discogs.com/release/123456-something", - "tracklist": [self._make_track("A", "1", "01:01")], + "tracklist": [self._make_track("a", "1", "01:01")], "artists": [{"name": "ARTIST NAME (2)", "id": 321, "join": ""}], - "title": "TITLE", + "title": "title", "labels": [ { "name": "LABEL NAME (5)", - "catno": "CATALOG NUMBER", + "catno": "catalog number", } ], } - config["discogs"]["strip_disambiguation"] = False release = Bag( data=data, title=data["title"], @@ -423,6 +423,57 @@ class DGAlbumInfoTest(BeetsTestCase): assert d.artist == "ARTIST NAME (2)" assert d.label == "LABEL NAME (5)" + def test_strip_disambiguation_multiple_artists(self): + """Test removing disambiguation if there are multiple artists on the release""" + data = { + "id": 123, + "uri": "https://www.discogs.com/release/123456-something", + "tracklist": [self._make_track("a", "1", "01:01")], + "artists": [ + {"name": "ARTIST NAME (2)", "id": 321, "join": "&"}, + {"name": "OTHER ARTIST (5)", "id": 321, "join": ""}, + ], + "title": "title", + } + release = Bag( + data=data, + title=data["title"], + artists=[Bag(data=d) for d in data["artists"]], + ) + d = DiscogsPlugin().get_album_info(release) + assert d.artist == "ARTIST NAME & OTHER ARTIST" + + def test_strip_disambiguation_artist_tracks(self): + data = { + "id": 123, + "uri": "https://www.discogs.com/release/123456-something", + "tracklist": [ + { + "title": "track", + "position": "A", + "type_": "track", + "duration": "5:44", + "artists": [ + { + "name": "TEST ARTIST (5)", + "tracks": "", + "id": 11146, + } + ], + } + ], + "artists": [{"name": "OTHER ARTIST (5)", "id": 321, "join": ""}], + "title": "title", + } + release = Bag( + data=data, + title=data["title"], + artists=[Bag(data=d) for d in data["artists"]], + ) + d = DiscogsPlugin().get_album_info(release) + assert d.tracks[0].artist == "TEST ARTIST" + assert d.artist == "OTHER ARTIST" + @pytest.mark.parametrize( "formats, expected_media, expected_albumtype", From 8a21bacd1455d06d571fd1251cd4a0513067b0e8 Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 19 Sep 2025 21:00:37 -0700 Subject: [PATCH 04/10] Add type check --- beetsplug/discogs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beetsplug/discogs.py b/beetsplug/discogs.py index 0ffbb0e3e..f22ea2274 100644 --- a/beetsplug/discogs.py +++ b/beetsplug/discogs.py @@ -630,7 +630,7 @@ class DiscogsPlugin(MetadataSourcePlugin): return tracklist - def strip_disambiguation(self, text) -> str: + def strip_disambiguation(self, text: str) -> str: """Removes discogs specific disambiguations from a string. Turns 'Label Name (5)' to 'Label Name' or 'Artist (1) & Another Artist (2)' to 'Artist & Another Artist'. Does nothing if strip_disambiguation is False.""" From 3fd49a7de8948379278adf48b6231f66068a8d56 Mon Sep 17 00:00:00 2001 From: Sebastian Mohr Date: Mon, 15 Sep 2025 23:56:43 +0200 Subject: [PATCH 05/10] Moved arts.py file into beetsplug namespace as it is not used in core. --- {beets => beetsplug/_utils}/art.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {beets => beetsplug/_utils}/art.py (100%) diff --git a/beets/art.py b/beetsplug/_utils/art.py similarity index 100% rename from beets/art.py rename to beetsplug/_utils/art.py From 34114fe9155d1e8cf9b3cee72617429274bab949 Mon Sep 17 00:00:00 2001 From: Sebastian Mohr Date: Mon, 15 Sep 2025 23:57:15 +0200 Subject: [PATCH 06/10] New import location for art.py --- beetsplug/_utils/__init__.py | 0 beetsplug/convert.py | 3 ++- beetsplug/embedart.py | 3 ++- test/plugins/test_embedart.py | 3 ++- 4 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 beetsplug/_utils/__init__.py diff --git a/beetsplug/_utils/__init__.py b/beetsplug/_utils/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/beetsplug/convert.py b/beetsplug/convert.py index e9db3592e..102976dd7 100644 --- a/beetsplug/convert.py +++ b/beetsplug/convert.py @@ -25,12 +25,13 @@ from string import Template import mediafile from confuse import ConfigTypeError, Optional -from beets import art, config, plugins, ui, util +from beets import config, plugins, ui, util from beets.library import Item, parse_query_string from beets.plugins import BeetsPlugin from beets.util import par_map from beets.util.artresizer import ArtResizer from beets.util.m3u import M3UFile +from beetsplug._utils import art _fs_lock = threading.Lock() _temp_files = [] # Keep track of temporary transcoded files for deletion. diff --git a/beetsplug/embedart.py b/beetsplug/embedart.py index 1a59e4f9c..cbf40f570 100644 --- a/beetsplug/embedart.py +++ b/beetsplug/embedart.py @@ -20,11 +20,12 @@ from mimetypes import guess_extension import requests -from beets import art, config, ui +from beets import config, ui from beets.plugins import BeetsPlugin from beets.ui import print_ from beets.util import bytestring_path, displayable_path, normpath, syspath from beets.util.artresizer import ArtResizer +from beetsplug._utils import art def _confirm(objs, album): diff --git a/test/plugins/test_embedart.py b/test/plugins/test_embedart.py index 58d2a5f63..734183d3b 100644 --- a/test/plugins/test_embedart.py +++ b/test/plugins/test_embedart.py @@ -23,7 +23,7 @@ from unittest.mock import MagicMock, patch import pytest from mediafile import MediaFile -from beets import art, config, logging, ui +from beets import config, logging, ui from beets.test import _common from beets.test.helper import ( BeetsTestCase, @@ -33,6 +33,7 @@ from beets.test.helper import ( ) from beets.util import bytestring_path, displayable_path, syspath from beets.util.artresizer import ArtResizer +from beetsplug._utils import art from test.test_art_resize import DummyIMBackend From f4691c85e947aa34c389fe6b2613cd5e89eb1763 Mon Sep 17 00:00:00 2001 From: Sebastian Mohr Date: Tue, 16 Sep 2025 00:03:16 +0200 Subject: [PATCH 07/10] Added changelog and git blame ignore rev --- .git-blame-ignore-revs | 4 +++- docs/changelog.rst | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index fbe32b497..ed86e3f8c 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -70,4 +70,6 @@ d93ddf8dd43e4f9ed072a03829e287c78d2570a2 # Moved dev docs 07549ed896d9649562d40b75cd30702e6fa6e975 # Moved plugin docs Further Reading chapter -33f1a5d0bef8ca08be79ee7a0d02a018d502680d \ No newline at end of file +33f1a5d0bef8ca08be79ee7a0d02a018d502680d +# Moved art.py utility module from beets into beetsplug +a7b69e50108eebef8ce92c015f18a42f8bf7276f \ No newline at end of file diff --git a/docs/changelog.rst b/docs/changelog.rst index ddafd975d..94a90a1b5 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -35,6 +35,9 @@ Other changes: match :bug:`6020` - :doc:`guides/tagger`: Section on no matching release found, related to possibly disabled musicbrainz plugin :bug:`6020` +- Moved ``art.py`` utility module from ``beets`` into ``beetsplug`` namespace as it + is not used in the core beets codebase. It can now be found in + ``beetsplug._utils``. - :class:`beets.metadata_plugin.MetadataSourcePlugin`: Remove discogs specific disambiguation stripping From c991b14e7d913d719e0ab3580336b1e386bbfb69 Mon Sep 17 00:00:00 2001 From: Sebastian Mohr Date: Tue, 16 Sep 2025 00:18:04 +0200 Subject: [PATCH 08/10] fix test by changing patch --- .git-blame-ignore-revs | 2 +- docs/changelog.rst | 4 ++-- test/plugins/test_embedart.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index ed86e3f8c..2ee64a97d 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -72,4 +72,4 @@ d93ddf8dd43e4f9ed072a03829e287c78d2570a2 # Moved plugin docs Further Reading chapter 33f1a5d0bef8ca08be79ee7a0d02a018d502680d # Moved art.py utility module from beets into beetsplug -a7b69e50108eebef8ce92c015f18a42f8bf7276f \ No newline at end of file +28aee0fde463f1e18dfdba1994e2bdb80833722f \ No newline at end of file diff --git a/docs/changelog.rst b/docs/changelog.rst index 94a90a1b5..44449e811 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -35,8 +35,8 @@ Other changes: match :bug:`6020` - :doc:`guides/tagger`: Section on no matching release found, related to possibly disabled musicbrainz plugin :bug:`6020` -- Moved ``art.py`` utility module from ``beets`` into ``beetsplug`` namespace as it - is not used in the core beets codebase. It can now be found in +- Moved ``art.py`` utility module from ``beets`` into ``beetsplug`` namespace as + it is not used in the core beets codebase. It can now be found in ``beetsplug._utils``. - :class:`beets.metadata_plugin.MetadataSourcePlugin`: Remove discogs specific disambiguation stripping diff --git a/test/plugins/test_embedart.py b/test/plugins/test_embedart.py index 734183d3b..d40025374 100644 --- a/test/plugins/test_embedart.py +++ b/test/plugins/test_embedart.py @@ -284,7 +284,7 @@ class DummyArtResizer(ArtResizer): @patch("beets.util.artresizer.subprocess") -@patch("beets.art.extract") +@patch("beetsplug._utils.art.extract") class ArtSimilarityTest(unittest.TestCase): def setUp(self): self.item = _common.item() From 92579b30d833ba897cd22dd3b6e176fea83a4d27 Mon Sep 17 00:00:00 2001 From: Henry Date: Sun, 21 Sep 2025 09:25:30 -0700 Subject: [PATCH 09/10] Reformat docs --- docs/changelog.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 4e7b92840..5d7e3f803 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -37,9 +37,8 @@ Other changes: possibly disabled musicbrainz plugin :bug:`6020` - Moved ``art.py`` utility module from ``beets`` into ``beetsplug`` namespace as it is not used in the core beets codebase. It can now be found in - ``beetsplug._utils``. - - :class:`beets.metadata_plugin.MetadataSourcePlugin`: Remove discogs specific - disambiguation stripping + ``beetsplug._utils``. - :class:`beets.metadata_plugin.MetadataSourcePlugin`: + Remove discogs specific disambiguation stripping 2.4.0 (September 13, 2025) -------------------------- From 8e644157e87c970bca3140075b022d0ac3a377bb Mon Sep 17 00:00:00 2001 From: Henry Oberholtzer Date: Mon, 22 Sep 2025 19:47:50 +0200 Subject: [PATCH 10/10] Refactor tests, adjust changelog, move config option to new features. --- docs/changelog.rst | 11 ++--- test/plugins/test_discogs.py | 89 +++++++++++++----------------------- 2 files changed, 38 insertions(+), 62 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index b182a6cba..8a16399f9 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -11,6 +11,8 @@ New features: - :doc:`plugins/lastgenre`: Add a ``--pretend`` option to preview genre changes without storing or writing them. +- :doc:`plugins/discogs`: New config option `strip_disambiguation` to toggle + stripping discogs numeric disambiguation on artist and label fields. Bug fixes: @@ -21,12 +23,8 @@ Bug fixes: - :doc:`plugins/spotify` Removed old and undocumented config options `artist_field`, `album_field` and `track` that were causing issues with track matching. :bug:`5189` -- :doc:`plugins/discogs` Added config option `strip_disambiguation` to allow - choice of removing discogs numeric disambiguation :bug:`5366` - :doc:`plugins/discogs` Fixed inconsistency in stripping disambiguation from artists but not labels. :bug:`5366` -- :doc:`plugins/discogs` Wrote test coverage for removing disambiguation. - :bug:`5366` For packagers: @@ -40,8 +38,9 @@ Other changes: possibly disabled musicbrainz plugin :bug:`6020` - Moved ``art.py`` utility module from ``beets`` into ``beetsplug`` namespace as it is not used in the core beets codebase. It can now be found in - ``beetsplug._utils``. - :class:`beets.metadata_plugin.MetadataSourcePlugin`: - Remove discogs specific disambiguation stripping + ``beetsplug._utils``. +- :class:`beets.metadata_plugin.MetadataSourcePlugin`: Remove discogs specific + disambiguation stripping. 2.4.0 (September 13, 2025) -------------------------- diff --git a/test/plugins/test_discogs.py b/test/plugins/test_discogs.py index 5fe73dcac..92301380e 100644 --- a/test/plugins/test_discogs.py +++ b/test/plugins/test_discogs.py @@ -374,38 +374,26 @@ class DGAlbumInfoTest(BeetsTestCase): assert d.genre == "GENRE1, GENRE2" assert d.style is None - def test_strip_disambiguation_label_artist(self): - """Test removing discogs disambiguation from artist and label""" + def test_strip_disambiguation(self): + """Test removing disambiguation from all disambiguated fields.""" data = { "id": 123, "uri": "https://www.discogs.com/release/123456-something", - "tracklist": [self._make_track("A", "1", "01:01")], - "artists": [{"name": "ARTIST NAME (2)", "id": 321, "join": ""}], - "title": "TITLE", - "labels": [ + "tracklist": [ { - "name": "LABEL NAME (5)", - "catno": "CATALOG NUMBER", + "title": "track", + "position": "A", + "type_": "track", + "duration": "5:44", + "artists": [ + {"name": "TEST ARTIST (5)", "tracks": "", "id": 11146} + ], } ], - } - release = Bag( - data=data, - title=data["title"], - artists=[Bag(data=d) for d in data["artists"]], - ) - d = DiscogsPlugin().get_album_info(release) - assert d.artist == "ARTIST NAME" - assert d.label == "LABEL NAME" - - def test_strip_disambiguation_off_label_artist(self): - """Test not removing discogs disambiguation from artist and label""" - config["discogs"]["strip_disambiguation"] = False - data = { - "id": 123, - "uri": "https://www.discogs.com/release/123456-something", - "tracklist": [self._make_track("a", "1", "01:01")], - "artists": [{"name": "ARTIST NAME (2)", "id": 321, "join": ""}], + "artists": [ + {"name": "ARTIST NAME (2)", "id": 321, "join": "&"}, + {"name": "OTHER ARTIST (5)", "id": 321, "join": ""}, + ], "title": "title", "labels": [ { @@ -420,30 +408,13 @@ class DGAlbumInfoTest(BeetsTestCase): artists=[Bag(data=d) for d in data["artists"]], ) d = DiscogsPlugin().get_album_info(release) - assert d.artist == "ARTIST NAME (2)" - assert d.label == "LABEL NAME (5)" - - def test_strip_disambiguation_multiple_artists(self): - """Test removing disambiguation if there are multiple artists on the release""" - data = { - "id": 123, - "uri": "https://www.discogs.com/release/123456-something", - "tracklist": [self._make_track("a", "1", "01:01")], - "artists": [ - {"name": "ARTIST NAME (2)", "id": 321, "join": "&"}, - {"name": "OTHER ARTIST (5)", "id": 321, "join": ""}, - ], - "title": "title", - } - release = Bag( - data=data, - title=data["title"], - artists=[Bag(data=d) for d in data["artists"]], - ) - d = DiscogsPlugin().get_album_info(release) assert d.artist == "ARTIST NAME & OTHER ARTIST" + assert d.tracks[0].artist == "TEST ARTIST" + assert d.label == "LABEL NAME" - def test_strip_disambiguation_artist_tracks(self): + def test_strip_disambiguation_false(self): + """Test disabling disambiguation removal from all disambiguated fields.""" + config["discogs"]["strip_disambiguation"] = False data = { "id": 123, "uri": "https://www.discogs.com/release/123456-something", @@ -454,16 +425,21 @@ class DGAlbumInfoTest(BeetsTestCase): "type_": "track", "duration": "5:44", "artists": [ - { - "name": "TEST ARTIST (5)", - "tracks": "", - "id": 11146, - } + {"name": "TEST ARTIST (5)", "tracks": "", "id": 11146} ], } ], - "artists": [{"name": "OTHER ARTIST (5)", "id": 321, "join": ""}], + "artists": [ + {"name": "ARTIST NAME (2)", "id": 321, "join": "&"}, + {"name": "OTHER ARTIST (5)", "id": 321, "join": ""}, + ], "title": "title", + "labels": [ + { + "name": "LABEL NAME (5)", + "catno": "catalog number", + } + ], } release = Bag( data=data, @@ -471,8 +447,9 @@ class DGAlbumInfoTest(BeetsTestCase): artists=[Bag(data=d) for d in data["artists"]], ) d = DiscogsPlugin().get_album_info(release) - assert d.tracks[0].artist == "TEST ARTIST" - assert d.artist == "OTHER ARTIST" + assert d.artist == "ARTIST NAME (2) & OTHER ARTIST (5)" + assert d.tracks[0].artist == "TEST ARTIST (5)" + assert d.label == "LABEL NAME (5)" @pytest.mark.parametrize(