From ca36df2d006feb11ec2c9fe095cd166d76d0cbd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0ar=C5=ABnas=20Nejus?= Date: Sat, 25 Apr 2026 17:57:45 +0100 Subject: [PATCH] Fix lambda closure bug in concurrent plugin method execution Replace inline lambda with named `materialize` helper to correctly pass plugin method and arguments to the thread executor, preventing all futures from calling the last plugin only. --- beets/metadata_plugins.py | 15 +++++++++------ docs/changelog.rst | 2 ++ test/test_metadata_plugins.py | 1 - 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/beets/metadata_plugins.py b/beets/metadata_plugins.py index e348b7a6d..bb9dbbf10 100644 --- a/beets/metadata_plugins.py +++ b/beets/metadata_plugins.py @@ -78,6 +78,12 @@ def _yield_from_plugins( ) -> Callable[..., Iterator[Ret]]: method_name = func.__name__ + def materialize( + plugin: MetadataSourcePlugin, method_name: str, *args, **kwargs + ) -> list[Ret]: + method = getattr(plugin, method_name) + return list(method(*args, **kwargs)) + @wraps(func) def wrapper(*args, **kwargs) -> Iterator[Ret]: # Run plugin methods concurrently for faster I/O-bound lookups. @@ -86,12 +92,9 @@ def _yield_from_plugins( executor.submit( # Evaluate iterator with list such that results are ready when # future.result() is called. - lambda *args, **kwargs: list( - getattr(plugin, method_name)( - *args, - **kwargs, - ) - ), + materialize, + plugin, + method_name, *args, **kwargs, ): plugin diff --git a/docs/changelog.rst b/docs/changelog.rst index 7150d7ba0..3eebfc084 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -59,6 +59,8 @@ Bug fixes - :doc:`plugins/discogs`: Prevent duplicate featured artists in track artist fields when the same artist is credited both in ``artists`` (for example with ``Feat.`` join text) and ``extraartists`` as ``Featuring``. :bug:`6166` +- :ref:`import-cmd` Metadata source plugin ID lookups now correctly call each + plugin's own lookup method when running in parallel. :bug:`6583` .. For plugin developers diff --git a/test/test_metadata_plugins.py b/test/test_metadata_plugins.py index e1b460c48..8f57ddbd9 100644 --- a/test/test_metadata_plugins.py +++ b/test/test_metadata_plugins.py @@ -128,7 +128,6 @@ class TestSearchApiMetadataSourcePlugin(PluginMixin): search_plugin._search_api("track", "query", {}) -@pytest.mark.xfail(reason="Currently only the last plugin is called") def test_albums_for_ids_calls_each_plugin_once(monkeypatch): start_workers = Event()