Merge #6213 - Fix ftintitle plugin to prioritize explicit featuring tokens

This commit is contained in:
Henry Oberholtzer 2026-01-08 12:21:00 -08:00
commit c04fc95e59
3 changed files with 23 additions and 4 deletions

View file

@ -61,11 +61,23 @@ def split_on_feat(
artist, which is always a string, and the featuring artist, which
may be a string or None if none is present.
"""
# split on the first "feat".
regex = re.compile(
plugins.feat_tokens(for_artist, custom_words), re.IGNORECASE
# Try explicit featuring tokens first (ft, feat, featuring, etc.)
# to avoid splitting on generic separators like "&" when both are present
regex_explicit = re.compile(
plugins.feat_tokens(for_artist=False, custom_words=custom_words),
re.IGNORECASE,
)
parts = tuple(s.strip() for s in regex.split(artist, 1))
parts = tuple(s.strip() for s in regex_explicit.split(artist, 1))
if len(parts) == 2:
return parts
# Fall back to all tokens including generic separators if no explicit match
if for_artist:
regex = re.compile(
plugins.feat_tokens(for_artist, custom_words), re.IGNORECASE
)
parts = tuple(s.strip() for s in regex.split(artist, 1))
if len(parts) == 1:
return parts[0], None
else:

View file

@ -86,6 +86,9 @@ Bug fixes:
name (like "feat.", "+", or "&") prevent it. Using the albumartists list field
and fetching a genre for each artist separately improves the chance of
receiving valid results in that stage.
- :doc:`/plugins/ftintitle`: Fixed artist name splitting to prioritize explicit
featuring tokens (feat, ft, featuring) over generic separators (&, and),
preventing incorrect splits when both are present.
For plugin developers:

View file

@ -321,6 +321,10 @@ def test_find_feat_part(
("Alice and Bob", ("Alice", "Bob")),
("Alice With Bob", ("Alice", "Bob")),
("Alice defeat Bob", ("Alice defeat Bob", None)),
("Alice & Bob feat Charlie", ("Alice & Bob", "Charlie")),
("Alice & Bob ft. Charlie", ("Alice & Bob", "Charlie")),
("Alice & Bob featuring Charlie", ("Alice & Bob", "Charlie")),
("Alice and Bob feat Charlie", ("Alice and Bob", "Charlie")),
],
)
def test_split_on_feat(