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.
This commit is contained in:
Šarūnas Nejus
2026-04-25 17:57:45 +01:00
parent 622d9a9039
commit ca36df2d00
3 changed files with 11 additions and 7 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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()