diff --git a/AGENTS.md b/AGENTS.md index 3920084d..51766e29 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -31,9 +31,9 @@ A command line client for MySQL with auto-completion and syntax highlighting. ├── mycli/packages/completion_engine.py # implementation of completion suggestions ├── mycli/packages/filepaths.py # utilities for files, including completion suggestions ├── mycli/packages/hybrid_redirection.py # implementation of shell-style redirects +├── mycli/packages/interactive_utils.py # utilities for confirming on destructive statements ├── mycli/packages/paramiko_stub/ # stub in case the Paramiko library is not installed ├── mycli/packages/sql_utils.py # utilities for parsing SQL statements -├── mycli/packages/prompt_utils.py # utilities for confirming on destructive statements ├── mycli/packages/ptoolkit/ # extends prompt_toolkit ├── mycli/packages/shortcuts.py # utilities for keyboard shortcuts ├── mycli/packages/special/ # implementation of mycli special commands diff --git a/changelog.md b/changelog.md index 8aea6f5a..f8bcafe4 100644 --- a/changelog.md +++ b/changelog.md @@ -47,6 +47,7 @@ Internal * Move SQL utilities to a new `sql_utils.py`. * Move CLI utilities to a new `cli_utils.py`. * Move keybinding utilities to a new `key_binding_utils.py`. +* Move interactive utilities to `interactive_utils.py`. * Modernize orthography of prompt_toolkit filters. diff --git a/mycli/main.py b/mycli/main.py index bbc2fb55..57ec4068 100755 --- a/mycli/main.py +++ b/mycli/main.py @@ -75,7 +75,7 @@ from mycli.packages import special from mycli.packages.cli_utils import filtered_sys_argv, is_valid_connection_scheme from mycli.packages.filepaths import dir_path_exists, guess_socket_location -from mycli.packages.prompt_utils import confirm_destructive_query +from mycli.packages.interactive_utils import confirm_destructive_query from mycli.packages.special.favoritequeries import FavoriteQueries from mycli.packages.special.main import ArgType from mycli.packages.sqlresult import SQLResult diff --git a/mycli/main_modes/batch.py b/mycli/main_modes/batch.py index d72b991f..ba23e839 100644 --- a/mycli/main_modes/batch.py +++ b/mycli/main_modes/batch.py @@ -12,7 +12,7 @@ import pymysql from mycli.packages.batch_utils import statements_from_filehandle -from mycli.packages.prompt_utils import confirm_destructive_query +from mycli.packages.interactive_utils import confirm_destructive_query from mycli.packages.sql_utils import is_destructive if TYPE_CHECKING: diff --git a/mycli/main_modes/repl.py b/mycli/main_modes/repl.py index c646f116..2bd6b0a2 100644 --- a/mycli/main_modes/repl.py +++ b/mycli/main_modes/repl.py @@ -47,11 +47,11 @@ from mycli.packages import special from mycli.packages.filepaths import dir_path_exists from mycli.packages.hybrid_redirection import get_redirect_components, is_redirect_command +from mycli.packages.interactive_utils import confirm, confirm_destructive_query from mycli.packages.key_binding_utils import ( handle_clip_command, handle_editor_command, ) -from mycli.packages.prompt_utils import confirm, confirm_destructive_query from mycli.packages.ptoolkit.history import FileHistoryWithTimestamp from mycli.packages.special.utils import format_uptime, get_ssl_version, get_uptime, get_warning_count from mycli.packages.sql_utils import ( diff --git a/mycli/packages/prompt_utils.py b/mycli/packages/interactive_utils.py similarity index 100% rename from mycli/packages/prompt_utils.py rename to mycli/packages/interactive_utils.py diff --git a/mycli/packages/special/iocommands.py b/mycli/packages/special/iocommands.py index a501aa8c..3c06eb44 100644 --- a/mycli/packages/special/iocommands.py +++ b/mycli/packages/special/iocommands.py @@ -17,7 +17,7 @@ import sqlparse from mycli.compat import WIN -from mycli.packages.prompt_utils import confirm_destructive_query +from mycli.packages.interactive_utils import confirm_destructive_query from mycli.packages.special.delimitercommand import DelimiterCommand from mycli.packages.special.favoritequeries import FavoriteQueries from mycli.packages.special.main import COMMANDS as SPECIAL_COMMANDS diff --git a/test/pytests/test_prompt_utils.py b/test/pytests/test_interactive_utils.py similarity index 69% rename from test/pytests/test_prompt_utils.py rename to test/pytests/test_interactive_utils.py index 745ff449..66182c93 100644 --- a/test/pytests/test_prompt_utils.py +++ b/test/pytests/test_interactive_utils.py @@ -3,11 +3,11 @@ import click import pytest -from mycli.packages import prompt_utils +from mycli.packages import interactive_utils def test_confirm_bool_param_type_converts_bool_and_strings() -> None: - boolean_type = prompt_utils.ConfirmBoolParamType() + boolean_type = interactive_utils.ConfirmBoolParamType() assert boolean_type.convert(True, None, None) is True assert boolean_type.convert(False, None, None) is False @@ -19,7 +19,7 @@ def test_confirm_bool_param_type_converts_bool_and_strings() -> None: def test_confirm_bool_param_type_rejects_invalid_string() -> None: - boolean_type = prompt_utils.ConfirmBoolParamType() + boolean_type = interactive_utils.ConfirmBoolParamType() with pytest.raises(click.BadParameter, match='maybe is not a valid boolean'): boolean_type.convert('maybe', None, None) @@ -38,13 +38,13 @@ def fake_is_destructive(keywords: list[str], query: str) -> bool: destructive_calls.append((keywords, query)) return False - monkeypatch.setattr(prompt_utils, 'is_destructive', fake_is_destructive) - monkeypatch.setattr(prompt_utils, 'prompt', fake_prompt) - monkeypatch.setattr(prompt_utils.sys, 'stdin', SimpleNamespace(isatty=lambda: True)) + monkeypatch.setattr(interactive_utils, 'is_destructive', fake_is_destructive) + monkeypatch.setattr(interactive_utils, 'prompt', fake_prompt) + monkeypatch.setattr(interactive_utils.sys, 'stdin', SimpleNamespace(isatty=lambda: True)) keywords = ['drop'] query = 'select 1;' - assert prompt_utils.confirm_destructive_query(keywords, query) is None + assert interactive_utils.confirm_destructive_query(keywords, query) is None assert destructive_calls == [(keywords, query)] assert prompt_called is False @@ -57,13 +57,13 @@ def fake_prompt(*args: object, **kwargs: object) -> bool: prompt_called = True return True - monkeypatch.setattr(prompt_utils, 'is_destructive', lambda keywords, query: True) - monkeypatch.setattr(prompt_utils, 'prompt', fake_prompt) - monkeypatch.setattr(prompt_utils.sys, 'stdin', SimpleNamespace(isatty=lambda: False)) + monkeypatch.setattr(interactive_utils, 'is_destructive', lambda keywords, query: True) + monkeypatch.setattr(interactive_utils, 'prompt', fake_prompt) + monkeypatch.setattr(interactive_utils.sys, 'stdin', SimpleNamespace(isatty=lambda: False)) keywords = ['drop'] sql = 'drop database foo;' - assert prompt_utils.confirm_destructive_query(keywords, sql) is None + assert interactive_utils.confirm_destructive_query(keywords, sql) is None assert prompt_called is False @@ -79,20 +79,20 @@ def fake_is_destructive(keywords: list[str], query: str) -> bool: destructive_calls.append((keywords, query)) return True - monkeypatch.setattr(prompt_utils, 'is_destructive', fake_is_destructive) - monkeypatch.setattr(prompt_utils, 'prompt', fake_prompt) - monkeypatch.setattr(prompt_utils.sys, 'stdin', SimpleNamespace(isatty=lambda: True)) + monkeypatch.setattr(interactive_utils, 'is_destructive', fake_is_destructive) + monkeypatch.setattr(interactive_utils, 'prompt', fake_prompt) + monkeypatch.setattr(interactive_utils.sys, 'stdin', SimpleNamespace(isatty=lambda: True)) keywords = ['drop'] query = 'drop database foo;' - result = prompt_utils.confirm_destructive_query(keywords, query) + result = interactive_utils.confirm_destructive_query(keywords, query) assert result is True assert destructive_calls == [(keywords, query)] assert prompt_calls == [ ( ("You're about to run a destructive command.\nDo you want to proceed? (y/n)",), - {'type': prompt_utils.BOOLEAN_TYPE}, + {'type': interactive_utils.BOOLEAN_TYPE}, ) ] @@ -109,18 +109,18 @@ def fake_is_destructive(keywords: list[str], query: str) -> bool: destructive_calls.append((keywords, query)) return True - monkeypatch.setattr(prompt_utils, 'is_destructive', fake_is_destructive) - monkeypatch.setattr(prompt_utils, 'prompt', fake_prompt) - monkeypatch.setattr(prompt_utils.sys, 'stdin', SimpleNamespace(isatty=lambda: True)) + monkeypatch.setattr(interactive_utils, 'is_destructive', fake_is_destructive) + monkeypatch.setattr(interactive_utils, 'prompt', fake_prompt) + monkeypatch.setattr(interactive_utils.sys, 'stdin', SimpleNamespace(isatty=lambda: True)) keywords = ['drop'] query = 'drop database foo;' - assert prompt_utils.confirm_destructive_query(keywords, query) is False + assert interactive_utils.confirm_destructive_query(keywords, query) is False assert destructive_calls == [(keywords, query)] assert prompt_calls == [ ( ("You're about to run a destructive command.\nDo you want to proceed? (y/n)",), - {'type': prompt_utils.BOOLEAN_TYPE}, + {'type': interactive_utils.BOOLEAN_TYPE}, ) ] @@ -131,7 +131,7 @@ def fake_confirm(*args: object, **kwargs: object) -> bool: monkeypatch.setattr(click, 'confirm', fake_confirm) - assert prompt_utils.confirm('continue?') is False + assert interactive_utils.confirm('continue?') is False def test_confirm_delegates_to_click_confirm(monkeypatch: pytest.MonkeyPatch) -> None: @@ -143,7 +143,7 @@ def fake_confirm(*args: object, **kwargs: object) -> bool: monkeypatch.setattr(click, 'confirm', fake_confirm) - assert prompt_utils.confirm('continue?', default=True) is True + assert interactive_utils.confirm('continue?', default=True) is True assert calls == [(('continue?',), {'default': True})] @@ -153,7 +153,7 @@ def fake_prompt(*args: object, **kwargs: object) -> bool: monkeypatch.setattr(click, 'prompt', fake_prompt) - assert prompt_utils.prompt('continue?') is False + assert interactive_utils.prompt('continue?') is False def test_prompt_delegates_to_click_prompt(monkeypatch: pytest.MonkeyPatch) -> None: @@ -165,5 +165,5 @@ def fake_prompt(*args: object, **kwargs: object) -> bool: monkeypatch.setattr(click, 'prompt', fake_prompt) - assert prompt_utils.prompt('continue?', type=prompt_utils.BOOLEAN_TYPE) is True - assert calls == [(('continue?',), {'type': prompt_utils.BOOLEAN_TYPE})] + assert interactive_utils.prompt('continue?', type=interactive_utils.BOOLEAN_TYPE) is True + assert calls == [(('continue?',), {'type': interactive_utils.BOOLEAN_TYPE})]