mirror of
https://github.com/beetbox/beets.git
synced 2026-01-18 06:05:06 +01:00
Legacy plugin copy not copying properties. (#6101)
The recently introduces `data_source_mismatch_penalty` property in the MetadataPlugin class was not copied in the backwards compatibility layer. This PR introduces a fixes this such that `cached_properties` are copied to legacy metadata plugins. This also includes a test for the expected behavior. See also [beetcamp issue](https://github.com/snejus/beetcamp/issues/85#issuecomment-3399273892).
This commit is contained in:
commit
af022683fe
4 changed files with 47 additions and 7 deletions
|
|
@ -22,7 +22,7 @@ import re
|
|||
import sys
|
||||
import warnings
|
||||
from collections import defaultdict
|
||||
from functools import wraps
|
||||
from functools import cached_property, wraps
|
||||
from importlib import import_module
|
||||
from pathlib import Path
|
||||
from types import GenericAlias
|
||||
|
|
@ -192,12 +192,23 @@ class BeetsPlugin(metaclass=abc.ABCMeta):
|
|||
stacklevel=3,
|
||||
)
|
||||
|
||||
method: property | cached_property[Any] | Callable[..., Any]
|
||||
for name, method in inspect.getmembers(
|
||||
MetadataSourcePlugin,
|
||||
predicate=lambda f: (
|
||||
inspect.isfunction(f)
|
||||
and f.__name__ not in MetadataSourcePlugin.__abstractmethods__
|
||||
and not hasattr(cls, f.__name__)
|
||||
predicate=lambda f: ( # type: ignore[arg-type]
|
||||
(
|
||||
isinstance(f, (property, cached_property))
|
||||
and not hasattr(
|
||||
BeetsPlugin,
|
||||
getattr(f, "attrname", None) or f.fget.__name__, # type: ignore[union-attr]
|
||||
)
|
||||
)
|
||||
or (
|
||||
inspect.isfunction(f)
|
||||
and f.__name__
|
||||
and not getattr(f, "__isabstractmethod__", False)
|
||||
and not hasattr(BeetsPlugin, f.__name__)
|
||||
)
|
||||
),
|
||||
):
|
||||
setattr(cls, name, method)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ For packagers:
|
|||
|
||||
- Fixed dynamic versioning install not disabled for source distribution builds.
|
||||
:bug:`6089`
|
||||
- Fixed issue with legacy metadata plugins not copying properties from the base
|
||||
class.
|
||||
|
||||
Other changes:
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from beets.autotag.distance import (
|
|||
)
|
||||
from beets.library import Item
|
||||
from beets.metadata_plugins import MetadataSourcePlugin, get_penalty
|
||||
from beets.plugins import BeetsPlugin
|
||||
from beets.test.helper import ConfigMixin
|
||||
|
||||
_p = pytest.param
|
||||
|
|
@ -310,8 +311,13 @@ class TestDataSourceDistance:
|
|||
def candidates(self, *args, **kwargs): ...
|
||||
def item_candidates(self, *args, **kwargs): ...
|
||||
|
||||
class OriginalPlugin(TestMetadataSourcePlugin):
|
||||
pass
|
||||
# We use BeetsPlugin here to check if our compatibility layer
|
||||
# for pre 2.4.0 MetadataPlugins is working as expected
|
||||
# TODO: Replace BeetsPlugin with TestMetadataSourcePlugin in v3.0.0
|
||||
with pytest.deprecated_call():
|
||||
|
||||
class OriginalPlugin(BeetsPlugin):
|
||||
data_source = "Original"
|
||||
|
||||
class OtherPlugin(TestMetadataSourcePlugin):
|
||||
@property
|
||||
|
|
@ -332,6 +338,7 @@ class TestDataSourceDistance:
|
|||
[
|
||||
_p("Original", "Original", 0.5, 1.0, True, MATCH, id="match"),
|
||||
_p("Original", "Other", 0.5, 1.0, True, MISMATCH, id="mismatch"),
|
||||
_p("Other", "Original", 0.5, 1.0, True, MISMATCH, id="mismatch"),
|
||||
_p("Original", "unknown", 0.5, 1.0, True, MISMATCH, id="mismatch-unknown"), # noqa: E501
|
||||
_p("Original", None, 0.5, 1.0, True, MISMATCH, id="mismatch-no-info"), # noqa: E501
|
||||
_p(None, "Other", 0.5, 1.0, True, MISMATCH, id="mismatch-no-original-multiple-sources"), # noqa: E501
|
||||
|
|
|
|||
|
|
@ -523,3 +523,23 @@ class TestImportPlugin(PluginMixin):
|
|||
assert "PluginImportError" not in caplog.text, (
|
||||
f"Plugin '{plugin_name}' has issues during import."
|
||||
)
|
||||
|
||||
|
||||
class TestDeprecationCopy:
|
||||
# TODO: remove this test in Beets 3.0.0
|
||||
def test_legacy_metadata_plugin_deprecation(self):
|
||||
"""Test that a MetadataSourcePlugin with 'legacy' data_source
|
||||
raises a deprecation warning and all function and properties are
|
||||
copied from the base class.
|
||||
"""
|
||||
with pytest.warns(DeprecationWarning, match="LegacyMetadataPlugin"):
|
||||
|
||||
class LegacyMetadataPlugin(plugins.BeetsPlugin):
|
||||
data_source = "legacy"
|
||||
|
||||
# Assert all methods are present
|
||||
assert hasattr(LegacyMetadataPlugin, "albums_for_ids")
|
||||
assert hasattr(LegacyMetadataPlugin, "tracks_for_ids")
|
||||
assert hasattr(LegacyMetadataPlugin, "data_source_mismatch_penalty")
|
||||
assert hasattr(LegacyMetadataPlugin, "_extract_id")
|
||||
assert hasattr(LegacyMetadataPlugin, "get_artist")
|
||||
|
|
|
|||
Loading…
Reference in a new issue