diff --git a/beets/ui/commands/__init__.py b/beets/ui/commands/__init__.py index d88d397ec..e1d0389a3 100644 --- a/beets/ui/commands/__init__.py +++ b/beets/ui/commands/__init__.py @@ -39,7 +39,7 @@ def __getattr__(name: str): __name__, { "TerminalImportSession": "beets.ui.commands.import_.session", - "PromptChoice": "beets.ui.commands.import_.session", + "PromptChoice": "beets.util", }, name, ) diff --git a/beets/ui/commands/import_/session.py b/beets/ui/commands/import_/session.py index 27562664e..dcc80b793 100644 --- a/beets/ui/commands/import_/session.py +++ b/beets/ui/commands/import_/session.py @@ -1,10 +1,9 @@ from collections import Counter from itertools import chain -from typing import Any, NamedTuple from beets import autotag, config, importer, logging, plugins, ui from beets.autotag import Recommendation -from beets.util import displayable_path +from beets.util import PromptChoice, displayable_path from beets.util.units import human_bytes, human_seconds_short from .display import ( @@ -368,12 +367,6 @@ def _summary_judgment(rec): return action -class PromptChoice(NamedTuple): - short: str - long: str - callback: Any - - def choose_candidate( candidates, singleton, diff --git a/beets/util/__init__.py b/beets/util/__init__.py index 2d4bb8a65..517e076de 100644 --- a/beets/util/__init__.py +++ b/beets/util/__init__.py @@ -167,6 +167,12 @@ class MoveOperation(Enum): REFLINK_AUTO = 5 +class PromptChoice(NamedTuple): + short: str + long: str + callback: Any + + def normpath(path: PathLike) -> bytes: """Provide the canonical form of the path suitable for storing in the database. diff --git a/beetsplug/edit.py b/beetsplug/edit.py index 188afed1f..7ed465cfe 100644 --- a/beetsplug/edit.py +++ b/beetsplug/edit.py @@ -25,8 +25,8 @@ import yaml from beets import plugins, ui, util from beets.dbcore import types from beets.importer import Action -from beets.ui.commands.import_.session import PromptChoice from beets.ui.commands.utils import do_query +from beets.util import PromptChoice # These "safe" types can avoid the format/parse cycle that most fields go # through: they are safe to edit with native YAML types. diff --git a/beetsplug/mbsubmit.py b/beetsplug/mbsubmit.py index 93e88dc9e..f6d197256 100644 --- a/beetsplug/mbsubmit.py +++ b/beetsplug/mbsubmit.py @@ -26,8 +26,7 @@ import subprocess from beets import ui from beets.autotag import Recommendation from beets.plugins import BeetsPlugin -from beets.ui.commands import PromptChoice -from beets.util import displayable_path +from beets.util import PromptChoice, displayable_path from beetsplug.info import print_data diff --git a/beetsplug/play.py b/beetsplug/play.py index 8fb146213..0d96ee97f 100644 --- a/beetsplug/play.py +++ b/beetsplug/play.py @@ -21,8 +21,7 @@ from os.path import relpath from beets import config, ui, util from beets.plugins import BeetsPlugin from beets.ui import Subcommand -from beets.ui.commands import PromptChoice -from beets.util import get_temp_filename +from beets.util import PromptChoice, get_temp_filename # Indicate where arguments should be inserted into the command string. # If this is missing, they're placed at the end. diff --git a/docs/dev/plugins/other/prompts.rst b/docs/dev/plugins/other/prompts.rst index f734f0de3..29720b922 100644 --- a/docs/dev/plugins/other/prompts.rst +++ b/docs/dev/plugins/other/prompts.rst @@ -13,7 +13,7 @@ shall expose to the user: .. code-block:: python from beets.plugins import BeetsPlugin - from beets.ui.commands import PromptChoice + from beets.util import PromptChoice class ExamplePlugin(BeetsPlugin): diff --git a/test/test_plugins.py b/test/test_plugins.py index 4543b5ecc..6f7026718 100644 --- a/test/test_plugins.py +++ b/test/test_plugins.py @@ -41,7 +41,7 @@ from beets.test.helper import ( PluginTestCase, TerminalImportMixin, ) -from beets.util import displayable_path, syspath +from beets.util import PromptChoice, displayable_path, syspath class TestPluginRegistration(PluginTestCase): @@ -292,8 +292,8 @@ class PromptChoicesTest(TerminalImportMixin, PluginImportTestCase): def return_choices(self, session, task): return [ - ui.commands.PromptChoice("f", "Foo", None), - ui.commands.PromptChoice("r", "baR", None), + PromptChoice("f", "Foo", None), + PromptChoice("r", "baR", None), ] self.register_plugin(DummyPlugin) @@ -328,8 +328,8 @@ class PromptChoicesTest(TerminalImportMixin, PluginImportTestCase): def return_choices(self, session, task): return [ - ui.commands.PromptChoice("f", "Foo", None), - ui.commands.PromptChoice("r", "baR", None), + PromptChoice("f", "Foo", None), + PromptChoice("r", "baR", None), ] self.register_plugin(DummyPlugin) @@ -363,10 +363,10 @@ class PromptChoicesTest(TerminalImportMixin, PluginImportTestCase): def return_choices(self, session, task): return [ - ui.commands.PromptChoice("a", "A foo", None), # dupe - ui.commands.PromptChoice("z", "baZ", None), # ok - ui.commands.PromptChoice("z", "Zupe", None), # dupe - ui.commands.PromptChoice("z", "Zoo", None), + PromptChoice("a", "A foo", None), # dupe + PromptChoice("z", "baZ", None), # ok + PromptChoice("z", "Zupe", None), # dupe + PromptChoice("z", "Zoo", None), ] # dupe self.register_plugin(DummyPlugin) @@ -399,7 +399,7 @@ class PromptChoicesTest(TerminalImportMixin, PluginImportTestCase): ) def return_choices(self, session, task): - return [ui.commands.PromptChoice("f", "Foo", self.foo)] + return [PromptChoice("f", "Foo", self.foo)] def foo(self, session, task): pass @@ -441,7 +441,7 @@ class PromptChoicesTest(TerminalImportMixin, PluginImportTestCase): ) def return_choices(self, session, task): - return [ui.commands.PromptChoice("f", "Foo", self.foo)] + return [PromptChoice("f", "Foo", self.foo)] def foo(self, session, task): return Action.SKIP