Skip to content

Commit

Permalink
beetsplug: Error out on conflicts in template functions
Browse files Browse the repository at this point in the history
Raises an exception if multiple plugins provide template functions for the same field.

Closes beetbox#5002, supersedes beetbox#5003.
  • Loading branch information
Maxr1998 committed Dec 16, 2023
1 parent adf4b97 commit e64ee0b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 4 deletions.
22 changes: 18 additions & 4 deletions beets/plugins.py
Expand Up @@ -444,23 +444,37 @@ 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


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


Expand Down
9 changes: 9 additions & 0 deletions docs/changelog.rst
Expand Up @@ -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.
Expand Down

0 comments on commit e64ee0b

Please sign in to comment.