beets/beetsplug
Arne Beer 4d7b9cb14b fix(lastgenre): Canonicalize keep_existing fallback
Fixes a bug where existing tags were set to None, if they weren't whitelisted, but an whitelisted canonicalized parent existed up the tree.

In all other cases, the original genres are canonicalized and considered for the final genre, except in the keep_existing logic branch.
This PR fixes the issue and results in the expected behavior for this combination of options.

For the bug to trigger several conditions had to be met:

- Canonicalization is enabled and a whitelist is specified.
- `force` and `keep_existing` are set. Meaning, that Lastfm is queried for a genre, but the existing genres are still left around when none are found online.
- A release with a non-whitelisted genre exists, but that genre has a whitelisted genre parent up the tree.
- That very release has no genre on lastfm.

This is rather convoluted, but stay with me :D
What would happen is the following:

- `keep_genres` is set to the existing genres, as `force` and `keep_existing` is set.
- Genres for `track`/`album`/`artist` aren't found for this release, as they don't exist in lastfm.
- Then the `keep_existing` logic is entered.
  - The old logic only checks if the existing genres have an **exact** match for the whitelist. In contrast to all other code branches, we don't do the `_try_resolve_stage` in case there's no direct match, resulting in no match.
- We continue to the fallback logic, which returns the fallback (`None` in my case)

This patch results in one last try to resolve the existing genres when `keep_existing` is set, which includes canonicalization (if enabled).
2026-01-31 13:22:56 +01:00
..
_utils Retries with 1, 2, 4, 8, 16, 32s backoff 2026-01-30 00:46:13 +00:00
bpd Address RUF012 2026-01-13 20:55:40 +00:00
discogs Adjust type annotation, rebase. 2026-01-19 12:46:22 -08:00
lastgenre fix(lastgenre): Canonicalize keep_existing fallback 2026-01-31 13:22:56 +01:00
metasync Address RUF012 2026-01-13 20:55:40 +00:00
web Web plugin: add type hint for g.lib 2025-11-15 21:02:43 +01:00
_typing.py Resurrect translation functionality 2025-02-20 03:47:04 +00:00
absubmit.py Do not use backslashes to deal with long strings 2025-08-30 23:10:20 +01:00
acousticbrainz.py Address RUF012 2026-01-13 20:55:40 +00:00
advancedrewrite.py refactor: convert _types from class attributes to cached properties 2025-07-16 14:45:25 +01:00
albumtypes.py Configure future-annotations 2026-01-13 20:55:40 +00:00
aura.py Configure future-annotations 2026-01-13 20:55:40 +00:00
autobpm.py Fix plugin types 2025-07-16 14:06:34 +01:00
badfiles.py Delegate attribute access to logging 2025-08-30 23:10:21 +01:00
bareasc.py Do not assign args to query 2025-07-08 11:37:34 +01:00
beatport.py pyupgrade Python 3.10 2025-11-08 12:09:52 +00:00
bench.py Move vfs.py to beetsplug._utils package to avoid polluting core namespace (#6017) 2025-10-01 12:28:18 +02:00
bpm.py Do not use explicit indices for logging args when not needed 2025-08-30 23:10:21 +01:00
bpsync.py Enable RUF rules 2026-01-13 20:55:40 +00:00
bucket.py Replace string concatenation (' + ') 2025-08-30 23:10:15 +01:00
chroma.py Configure future-annotations 2026-01-13 20:55:40 +00:00
convert.py Update convert.py 2026-01-15 15:46:01 +00:00
deezer.py Address RUF012 2026-01-13 20:55:40 +00:00
duplicates.py Delegate attribute access to logging 2025-08-30 23:10:21 +01:00
edit.py Fix verbose comments and add e,c test 2025-12-09 12:14:03 -05:00
embedart.py Clear art on import 2025-11-10 22:38:37 +01:00
embyupdate.py Replace logging f-strings with arguments 2025-08-30 23:10:21 +01:00
export.py Enable RUF rules 2026-01-13 20:55:40 +00:00
fetchart.py Address RUF012 2026-01-13 20:55:40 +00:00
filefilter.py Reformat the codebase 2024-09-21 11:57:48 +01:00
fish.py fish: complete files in more places 2026-01-20 13:07:03 -08:00
freedesktop.py Reformat the codebase 2024-09-21 11:57:48 +01:00
fromfilename.py Enable RUF rules 2026-01-13 20:55:40 +00:00
ftintitle.py ftintitle: fix changelog conflict 2026-01-08 12:20:25 -08:00
fuzzy.py Reformat the codebase 2024-09-21 11:57:48 +01:00
hook.py Delegate attribute access to logging 2025-08-30 23:10:21 +01:00
ihate.py Do not use explicit indices for logging args when not needed 2025-08-30 23:10:21 +01:00
importadded.py Delegate attribute access to logging 2025-08-30 23:10:21 +01:00
importfeeds.py Do not use explicit indices for logging args when not needed 2025-08-30 23:10:21 +01:00
importsource.py importsource: fix potential prevent_suggest_removal crash 2025-12-21 13:07:02 +01:00
info.py Do not use explicit indices for logging args when not needed 2025-08-30 23:10:21 +01:00
inline.py Fix recursion in inline plugin when item_fields shadow DB fields (#6115) 2025-11-20 15:57:22 -05:00
ipfs.py Delegate attribute access to logging 2025-08-30 23:10:21 +01:00
keyfinder.py Enable RUF rules 2026-01-13 20:55:40 +00:00
kodiupdate.py Do not use explicit indices for logging args when not needed 2025-08-30 23:10:21 +01:00
lastimport.py Delegate attribute access to logging 2025-08-30 23:10:21 +01:00
limit.py Do not assign args to query 2025-07-08 11:37:34 +01:00
listenbrainz.py Type MusicBrainzAPI properly 2026-01-06 09:54:02 +00:00
loadext.py Use only plugins/disabled_plugins config in plugin loading 2025-08-09 15:11:58 +01:00
lyrics.py Address RUF012 2026-01-13 20:55:40 +00:00
mbcollection.py Type MusicBrainzAPI properly 2026-01-06 09:54:02 +00:00
mbpseudo.py Configure future-annotations 2026-01-13 20:55:40 +00:00
mbsubmit.py Enable RUF rules 2026-01-13 20:55:40 +00:00
mbsync.py Enable RUF rules 2026-01-13 20:55:40 +00:00
missing.py Address RUF012 2026-01-13 20:55:40 +00:00
mpdstats.py Address RUF012 2026-01-13 20:55:40 +00:00
mpdupdate.py Delegate attribute access to logging 2025-08-30 23:10:21 +01:00
musicbrainz.py Gracefully handle 404s when importing from MusicBrainz. 2026-01-22 12:20:04 +00:00
parentwork.py Migrate parentwork to use MusicBrainzAPI 2026-01-06 00:27:36 +00:00
permissions.py Apply formatting 2024-03-01 15:21:25 +10:00
play.py Move PromptChoice to beets.util module 2025-12-02 01:51:14 +00:00
playlist.py Address RUF012 2026-01-13 20:55:40 +00:00
plexupdate.py Replace string concatenation (' + ') 2025-08-30 23:10:15 +01:00
random.py Fix grouping for list fields and stabilize equal-chance order 2026-01-30 00:30:46 +00:00
replace.py Configure future-annotations 2026-01-13 20:55:40 +00:00
replaygain.py refactor: simplify CommandBackend and improve documentation 2026-01-18 10:52:41 +01:00
rewrite.py Do not use explicit indices for logging args when not needed 2025-08-30 23:10:21 +01:00
scrub.py Delegate attribute access to logging 2025-08-30 23:10:21 +01:00
smartplaylist.py Configure future-annotations 2026-01-13 20:55:40 +00:00
sonosupdate.py Apply formatting tools to all files 2023-10-22 09:53:18 +10:00
spotify.py Address RUF012 2026-01-13 20:55:40 +00:00
subsonicplaylist.py Replace string concatenation (' + ') 2025-08-30 23:10:15 +01:00
subsonicupdate.py Delegate attribute access to logging 2025-08-30 23:10:21 +01:00
substitute.py Apply substitute rules in sequence 2024-10-16 16:36:36 +02:00
the.py Address RUF012 2026-01-13 20:55:40 +00:00
thumbnails.py Delegate attribute access to logging 2025-08-30 23:10:21 +01:00
titlecase.py Configure future-annotations 2026-01-13 20:55:40 +00:00
types.py Replace format calls with f-strings 2025-08-30 18:42:26 +01:00
unimported.py Replace string concatenation (' + ') 2025-08-30 23:10:15 +01:00
zero.py Remove tests. Update docs. Remove unnecessary return 2025-10-14 03:17:34 +01:00