mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 08:39:17 +01:00
Centralise warnings for maintainers into deprecate_for_maintainers
This commit is contained in:
parent
c79cad4ed1
commit
39288637b9
8 changed files with 62 additions and 55 deletions
|
|
@ -26,13 +26,9 @@ __author__ = "Adrian Sampson <adrian@radbox.org>"
|
||||||
def __getattr__(name: str):
|
def __getattr__(name: str):
|
||||||
"""Handle deprecated imports."""
|
"""Handle deprecated imports."""
|
||||||
return deprecate_imports(
|
return deprecate_imports(
|
||||||
old_module=__name__,
|
__name__,
|
||||||
new_module_by_name={
|
{"art": "beetsplug._utils", "vfs": "beetsplug._utils"},
|
||||||
"art": "beetsplug._utils",
|
name,
|
||||||
"vfs": "beetsplug._utils",
|
|
||||||
},
|
|
||||||
name=name,
|
|
||||||
version="3.0.0",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import warnings
|
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
|
@ -24,7 +23,7 @@ from beets import config, logging
|
||||||
|
|
||||||
# Parts of external interface.
|
# Parts of external interface.
|
||||||
from beets.util import unique_list
|
from beets.util import unique_list
|
||||||
from beets.util.deprecation import deprecate_imports
|
from beets.util.deprecation import deprecate_for_maintainers, deprecate_imports
|
||||||
|
|
||||||
from .hooks import AlbumInfo, AlbumMatch, TrackInfo, TrackMatch
|
from .hooks import AlbumInfo, AlbumMatch, TrackInfo, TrackMatch
|
||||||
from .match import Proposal, Recommendation, tag_album, tag_item
|
from .match import Proposal, Recommendation, tag_album, tag_item
|
||||||
|
|
@ -37,18 +36,13 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
def __getattr__(name: str):
|
def __getattr__(name: str):
|
||||||
if name == "current_metadata":
|
if name == "current_metadata":
|
||||||
warnings.warn(
|
deprecate_for_maintainers(
|
||||||
(
|
f"'beets.autotag.{name}'", "'beets.util.get_most_common_tags'"
|
||||||
f"'beets.autotag.{name}' is deprecated and will be removed in"
|
|
||||||
" 3.0.0. Use 'beets.util.get_most_common_tags' instead."
|
|
||||||
),
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
)
|
||||||
return import_module("beets.util").get_most_common_tags
|
return import_module("beets.util").get_most_common_tags
|
||||||
|
|
||||||
return deprecate_imports(
|
return deprecate_imports(
|
||||||
__name__, {"Distance": "beets.autotag.distance"}, name, "3.0.0"
|
__name__, {"Distance": "beets.autotag.distance"}, name
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ NEW_MODULE_BY_NAME = dict.fromkeys(
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name: str):
|
def __getattr__(name: str):
|
||||||
return deprecate_imports(__name__, NEW_MODULE_BY_NAME, name, "3.0.0")
|
return deprecate_imports(__name__, NEW_MODULE_BY_NAME, name)
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
|
|
||||||
|
|
@ -13,17 +13,11 @@
|
||||||
# included in all copies or substantial portions of the Software.
|
# included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
import mediafile
|
import mediafile
|
||||||
|
|
||||||
warnings.warn(
|
from .util.deprecation import deprecate_for_maintainers
|
||||||
"beets.mediafile is deprecated; use mediafile instead",
|
|
||||||
# Show the location of the `import mediafile` statement as the warning's
|
deprecate_for_maintainers("'beets.mediafile'", "'mediafile'", stacklevel=2)
|
||||||
# source, rather than this file, such that the offending module can be
|
|
||||||
# identified easily.
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Import everything from the mediafile module into this module.
|
# Import everything from the mediafile module into this module.
|
||||||
for key, value in mediafile.__dict__.items():
|
for key, value in mediafile.__dict__.items():
|
||||||
|
|
@ -31,4 +25,4 @@ for key, value in mediafile.__dict__.items():
|
||||||
globals()[key] = value
|
globals()[key] = value
|
||||||
|
|
||||||
# Cleanup namespace.
|
# Cleanup namespace.
|
||||||
del key, value, warnings, mediafile
|
del key, value, mediafile
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import abc
|
||||||
import inspect
|
import inspect
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from functools import cached_property, wraps
|
from functools import cached_property, wraps
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
|
@ -33,6 +32,7 @@ from typing_extensions import ParamSpec
|
||||||
import beets
|
import beets
|
||||||
from beets import logging
|
from beets import logging
|
||||||
from beets.util import unique_list
|
from beets.util import unique_list
|
||||||
|
from beets.util.deprecation import deprecate_for_maintainers
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from collections.abc import Callable, Iterable, Sequence
|
from collections.abc import Callable, Iterable, Sequence
|
||||||
|
|
@ -184,11 +184,12 @@ class BeetsPlugin(metaclass=abc.ABCMeta):
|
||||||
):
|
):
|
||||||
return
|
return
|
||||||
|
|
||||||
warnings.warn(
|
deprecate_for_maintainers(
|
||||||
f"{cls.__name__} is used as a legacy metadata source. "
|
(
|
||||||
"It should extend MetadataSourcePlugin instead of BeetsPlugin. "
|
f"'{cls.__name__}' is used as a legacy metadata source since it"
|
||||||
"Support for this will be removed in the v3.0.0 release!",
|
" inherits 'beets.plugins.BeetsPlugin'. Support for this"
|
||||||
DeprecationWarning,
|
),
|
||||||
|
"'beets.metadata_plugins.MetadataSourcePlugin'",
|
||||||
stacklevel=3,
|
stacklevel=3,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -265,7 +266,10 @@ class BeetsPlugin(metaclass=abc.ABCMeta):
|
||||||
if source.filename: # user config
|
if source.filename: # user config
|
||||||
self._log.warning(message)
|
self._log.warning(message)
|
||||||
else: # 3rd-party plugin config
|
else: # 3rd-party plugin config
|
||||||
warnings.warn(message, DeprecationWarning, stacklevel=0)
|
deprecate_for_maintainers(
|
||||||
|
"'source_weight' configuration option",
|
||||||
|
"'data_source_mismatch_penalty'",
|
||||||
|
)
|
||||||
|
|
||||||
def commands(self) -> Sequence[Subcommand]:
|
def commands(self) -> Sequence[Subcommand]:
|
||||||
"""Should return a list of beets.ui.Subcommand objects for
|
"""Should return a list of beets.ui.Subcommand objects for
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ import sqlite3
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
import traceback
|
import traceback
|
||||||
import warnings
|
|
||||||
from difflib import SequenceMatcher
|
from difflib import SequenceMatcher
|
||||||
from functools import cache
|
from functools import cache
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
@ -40,6 +39,7 @@ from beets import config, library, logging, plugins, util
|
||||||
from beets.dbcore import db
|
from beets.dbcore import db
|
||||||
from beets.dbcore import query as db_query
|
from beets.dbcore import query as db_query
|
||||||
from beets.util import as_string
|
from beets.util import as_string
|
||||||
|
from beets.util.deprecation import deprecate_for_maintainers
|
||||||
from beets.util.functemplate import template
|
from beets.util.functemplate import template
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
@ -114,11 +114,7 @@ def decargs(arglist):
|
||||||
.. deprecated:: 2.4.0
|
.. deprecated:: 2.4.0
|
||||||
This function will be removed in 3.0.0.
|
This function will be removed in 3.0.0.
|
||||||
"""
|
"""
|
||||||
warnings.warn(
|
deprecate_for_maintainers("'beets.ui.decargs'")
|
||||||
"decargs() is deprecated and will be removed in version 3.0.0.",
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
|
||||||
return arglist
|
return arglist
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
interface.
|
interface.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from beets.util import deprecate_imports
|
from beets.util.deprecation import deprecate_imports
|
||||||
|
|
||||||
from .completion import completion_cmd
|
from .completion import completion_cmd
|
||||||
from .config import config_cmd
|
from .config import config_cmd
|
||||||
|
|
@ -36,14 +36,12 @@ from .write import write_cmd
|
||||||
def __getattr__(name: str):
|
def __getattr__(name: str):
|
||||||
"""Handle deprecated imports."""
|
"""Handle deprecated imports."""
|
||||||
return deprecate_imports(
|
return deprecate_imports(
|
||||||
old_module=__name__,
|
__name__,
|
||||||
new_module_by_name={
|
{
|
||||||
"TerminalImportSession": "beets.ui.commands.import_.session",
|
"TerminalImportSession": "beets.ui.commands.import_.session",
|
||||||
"PromptChoice": "beets.ui.commands.import_.session",
|
"PromptChoice": "beets.ui.commands.import_.session",
|
||||||
# TODO: We might want to add more deprecated imports here
|
|
||||||
},
|
},
|
||||||
name=name,
|
name,
|
||||||
version="3.0.0",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,39 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from packaging.version import Version
|
||||||
|
|
||||||
|
import beets
|
||||||
|
|
||||||
|
|
||||||
|
def _format_message(old: str, new: str | None = None) -> str:
|
||||||
|
next_major = f"{Version(beets.__version__).major + 1}.0.0"
|
||||||
|
msg = f"{old} is deprecated and will be removed in version {next_major}."
|
||||||
|
if new:
|
||||||
|
msg += f" Use {new} instead."
|
||||||
|
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
|
def deprecate_for_maintainers(
|
||||||
|
old: str, new: str | None = None, stacklevel: int = 1
|
||||||
|
) -> None:
|
||||||
|
"""Issue a deprecation warning visible to maintainers during development.
|
||||||
|
|
||||||
|
Emits a DeprecationWarning that alerts developers about deprecated code
|
||||||
|
patterns. Unlike user-facing warnings, these are primarily for internal
|
||||||
|
code maintenance and appear during test runs or with warnings enabled.
|
||||||
|
"""
|
||||||
|
warnings.warn(
|
||||||
|
_format_message(old, new), DeprecationWarning, stacklevel=stacklevel + 1
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def deprecate_imports(
|
def deprecate_imports(
|
||||||
old_module: str, new_module_by_name: dict[str, str], name: str, version: str
|
old_module: str, new_module_by_name: dict[str, str], name: str
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""Handle deprecated module imports by redirecting to new locations.
|
"""Handle deprecated module imports by redirecting to new locations.
|
||||||
|
|
||||||
|
|
@ -14,13 +43,9 @@ def deprecate_imports(
|
||||||
existing code to continue working during transition periods.
|
existing code to continue working during transition periods.
|
||||||
"""
|
"""
|
||||||
if new_module := new_module_by_name.get(name):
|
if new_module := new_module_by_name.get(name):
|
||||||
warnings.warn(
|
deprecate_for_maintainers(
|
||||||
(
|
f"'{old_module}.{name}'", f"'{new_module}.{name}'", stacklevel=2
|
||||||
f"'{old_module}.{name}' is deprecated and will be removed"
|
|
||||||
f" in {version}. Use '{new_module}.{name}' instead."
|
|
||||||
),
|
|
||||||
DeprecationWarning,
|
|
||||||
stacklevel=2,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return getattr(import_module(new_module), name)
|
return getattr(import_module(new_module), name)
|
||||||
raise AttributeError(f"module '{old_module}' has no attribute '{name}'")
|
raise AttributeError(f"module '{old_module}' has no attribute '{name}'")
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue