beetsplug: Error out on conflicts in template functions

Raises an exception if multiple plugins provide template functions for the same field.

Closes #5002, supersedes #5003.
This commit is contained in:
Maxr1998 2023-12-16 16:38:32 +01:00
parent adf4b9779a
commit e64ee0b0cd
No known key found for this signature in database
GPG key ID: ECECF0D4F4816C81
2 changed files with 27 additions and 4 deletions

View file

@ -444,14 +444,29 @@ def import_stages():
# New-style (lazy) plugin-provided fields.
def _check_conflicts_and_merge(plugin, plugin_funcs, funcs):
"""Check the provided template functions for conflicts and merge into funcs.
Raises a `PluginConflictException` if a plugin defines template functions
for fields that another plugin has already defined template functions for.
"""
if plugin_funcs:
if not plugin_funcs.keys().isdisjoint(funcs.keys()):
conflicted_fields = ", ".join(plugin_funcs.keys() & funcs.keys())
raise PluginConflictException(
f"Plugin {plugin.name} defines template functions for "
f"{conflicted_fields} that conflict with another plugin."
)
funcs.update(plugin_funcs)
def item_field_getters():
"""Get a dictionary mapping field names to unary functions that
compute the field's value.
"""
funcs = {}
for plugin in find_plugins():
if plugin.template_fields:
funcs.update(plugin.template_fields)
_check_conflicts_and_merge(plugin, plugin.template_fields, funcs)
return funcs
@ -459,8 +474,7 @@ def album_field_getters():
"""As above, for album fields."""
funcs = {}
for plugin in find_plugins():
if plugin.album_template_fields:
funcs.update(plugin.album_template_fields)
_check_conflicts_and_merge(plugin, plugin.album_template_fields, funcs)
return funcs

View file

@ -277,6 +277,15 @@ Bug fixes:
* Fix bug regarding displaying tracks that have been changed not being
displayed unless the detail configuration is enabled.
For plugin developers:
* beets now explicitly prevents multiple plugins to define replacement
functions for the same field. When previously defining `template_fields`
for the same field in two plugins, the last loaded plugin would silently
overwrite the function defined by the other plugin.
Now, beets will raise an exception when this happens.
:bug:`5002`
For packagers:
* As noted above, the minimum Python version is now 3.7.