From 6c11e51f44221d050b5ccf7c0b23ba4d4a75393f Mon Sep 17 00:00:00 2001 From: Roland Walker Date: Sat, 18 Apr 2026 16:00:38 -0400 Subject: [PATCH] more control over verbosity levels * let --verbose be given multiple times, incrementing a counter * add --quiet option to reduce the verbosity level * let CLI arguments always override config-file defaults, in this case the main.less_chatty option, which is made equivalent to --quiet This initial implementation respects three verbosity levels: * -1 (quiet) * 0 (default) * 1 (verbose) and doesn't yet adopt new behaviors for verbosity levels 2 or 3. Special-command verbosity is recast to avoid confusion with application- setting verbosity. Motivation: enable debugging logs to the console with -vvv. --- changelog.md | 1 + mycli/main.py | 26 +++++++++++++--- mycli/main_modes/list_dsn.py | 6 ++-- mycli/main_modes/list_ssh_config.py | 2 +- mycli/main_modes/repl.py | 4 +-- mycli/myclirc | 3 +- mycli/packages/special/dbcommands.py | 6 ++-- mycli/packages/special/llm.py | 8 ++--- mycli/packages/special/main.py | 16 +++++----- test/myclirc | 3 +- test/pytests/test_main.py | 30 +++++++++++++++++++ test/pytests/test_main_modes_list_dsn.py | 16 +++++----- .../test_main_modes_list_ssh_config.py | 16 +++++++--- test/pytests/test_main_modes_repl.py | 12 ++++---- test/pytests/test_main_regression.py | 18 ----------- test/pytests/test_special_dbcommands.py | 4 +-- test/pytests/test_special_llm.py | 2 +- test/pytests/test_special_main.py | 14 ++++----- test/utils.py | 3 +- 19 files changed, 117 insertions(+), 73 deletions(-) diff --git a/changelog.md b/changelog.md index fecc97bf..b42ef7ad 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,7 @@ Upcoming (TBD) Features --------- * Remove undocumented `%mycli` Jupyter magic. +* Add `--quiet` option, and let `--verbose` be given multiple times. Bug Fixes diff --git a/mycli/main.py b/mycli/main.py index ae6ca3c5..3c3c064a 100755 --- a/mycli/main.py +++ b/mycli/main.py @@ -143,6 +143,7 @@ def __init__( warn: bool | None = None, myclirc: str = "~/.myclirc", show_warnings: bool | None = None, + cli_verbosity: int = 0, ) -> None: self.sqlexecute = sqlexecute self.logfile = logfile @@ -194,7 +195,9 @@ def __init__( self.main_formatter.mycli = self self.redirect_formatter.mycli = self self.syntax_style = c["main"]["syntax_style"] - self.less_chatty = c["main"].as_bool("less_chatty") + self.verbosity = -1 if c["main"].as_bool("less_chatty") else 0 + if cli_verbosity: + self.verbosity = cli_verbosity self.cli_style = c["colors"] self.ptoolkit_style = style_factory_ptoolkit(self.syntax_style, self.cli_style) self.helpers_style = style_factory_helpers(self.syntax_style, self.cli_style) @@ -1306,10 +1309,15 @@ class CliArgs: is_flag=True, help=("""Verify server's "Common Name" in its cert against hostname used when connecting. This option is disabled by default."""), ) - verbose: bool = clickdc.option( + verbose: int = clickdc.option( '-v', + count=True, + help='More verbose output and feedback. Can be given multiple times.', + ) + quiet: bool = clickdc.option( + '-q', is_flag=True, - help='Verbose output.', + help='Less verbose output and feedback.', ) dbname: str | None = clickdc.option( '-D', @@ -1514,6 +1522,15 @@ def get_password_from_file(password_file: str | None) -> str | None: if cli_args.password is None and os.environ.get("MYSQL_PWD") is not None: cli_args.password = os.environ.get("MYSQL_PWD") + cli_verbosity = 0 + if cli_args.verbose and cli_args.quiet: + click.secho('Error: --verbose and --quiet are incompatible.', err=True, fg='red') + sys.exit(1) + elif cli_args.verbose: + cli_verbosity = int(cli_args.verbose) + elif cli_args.quiet: + cli_verbosity = -1 + mycli = MyCli( prompt=cli_args.prompt, toolbar_format=cli_args.toolbar, @@ -1525,6 +1542,7 @@ def get_password_from_file(password_file: str | None) -> str | None: warn=cli_args.warn, myclirc=cli_args.myclirc, show_warnings=cli_args.show_warnings, + cli_verbosity=cli_verbosity, ) if cli_args.checkup: @@ -1576,7 +1594,7 @@ def get_password_from_file(password_file: str | None) -> str | None: ) if cli_args.list_dsn: - sys.exit(main_list_dsn(mycli, cli_args)) + sys.exit(main_list_dsn(mycli)) if cli_args.list_ssh_config: sys.exit(main_list_ssh_config(mycli, cli_args)) diff --git a/mycli/main_modes/list_dsn.py b/mycli/main_modes/list_dsn.py index 39ce4584..6a00a2c6 100644 --- a/mycli/main_modes/list_dsn.py +++ b/mycli/main_modes/list_dsn.py @@ -5,10 +5,10 @@ import click if TYPE_CHECKING: - from mycli.main import CliArgs, MyCli + from mycli.main import MyCli -def main_list_dsn(mycli: 'MyCli', cli_args: 'CliArgs') -> int: +def main_list_dsn(mycli: 'MyCli') -> int: try: alias_dsn = mycli.config['alias_dsn'] except KeyError: @@ -18,7 +18,7 @@ def main_list_dsn(mycli: 'MyCli', cli_args: 'CliArgs') -> int: click.secho(str(e), err=True, fg='red') return 1 for alias, value in alias_dsn.items(): - if cli_args.verbose: + if mycli.verbosity >= 1: click.secho(f'{alias} : {value}') else: click.secho(alias) diff --git a/mycli/main_modes/list_ssh_config.py b/mycli/main_modes/list_ssh_config.py index 8c27a011..4d3b8cfc 100644 --- a/mycli/main_modes/list_ssh_config.py +++ b/mycli/main_modes/list_ssh_config.py @@ -18,7 +18,7 @@ def main_list_ssh_config(mycli: 'MyCli', cli_args: 'CliArgs') -> int: click.secho('Error reading ssh config', err=True, fg="red") return 1 for host_entry in host_entries: - if cli_args.verbose: + if mycli.verbosity >= 1: host_config = ssh_config.lookup(host_entry) click.secho(f"{host_entry} : {host_config.get('hostname')}") else: diff --git a/mycli/main_modes/repl.py b/mycli/main_modes/repl.py index 72bc373b..da8f148a 100644 --- a/mycli/main_modes/repl.py +++ b/mycli/main_modes/repl.py @@ -133,7 +133,7 @@ def _show_startup_banner( mycli: 'MyCli', sqlexecute: SQLExecute, ) -> None: - if mycli.less_chatty: + if mycli.verbosity < 0: return if sqlexecute.server_info is not None: @@ -807,5 +807,5 @@ def main_repl(mycli: 'MyCli') -> None: state.iterations += 1 except EOFError: special.close_tee() - if not mycli.less_chatty: + if mycli.verbosity >= 0: mycli.echo('Goodbye!') diff --git a/mycli/myclirc b/mycli/myclirc index 16c6e472..192b8e38 100644 --- a/mycli/myclirc +++ b/mycli/myclirc @@ -163,7 +163,8 @@ multiplex_window_title = '' # as frequently as the database is changed. multiplex_pane_title = '' -# Skip intro info on startup and outro info on exit +# Skip intro info on startup and outro info on exit, and generally reduce +# feedback. This is equivalent to giving --quiet at the command line. less_chatty = False # Use alias from --login-path instead of host name in prompt diff --git a/mycli/packages/special/dbcommands.py b/mycli/packages/special/dbcommands.py index 06ca8b75..a2705053 100644 --- a/mycli/packages/special/dbcommands.py +++ b/mycli/packages/special/dbcommands.py @@ -19,7 +19,7 @@ def list_tables( cur: Cursor, arg: str | None = None, _arg_type: ArgType = ArgType.PARSED_QUERY, - verbose: bool = False, + command_verbosity: bool = False, ) -> list[SQLResult]: if arg: query = f'SHOW FIELDS FROM {arg}' @@ -33,10 +33,10 @@ def list_tables( return [SQLResult()] # Fetch results before potentially executing another query - results = list(cur.fetchall()) if verbose and arg else cur + results = list(cur.fetchall()) if command_verbosity and arg else cur postamble = '' - if verbose and arg: + if command_verbosity and arg: query = f'SHOW CREATE TABLE {arg}' logger.debug(query) cur.execute(query) diff --git a/mycli/packages/special/llm.py b/mycli/packages/special/llm.py index 7e761066..e7786092 100644 --- a/mycli/packages/special/llm.py +++ b/mycli/packages/special/llm.py @@ -32,7 +32,7 @@ LLM_CLI_IMPORTED = False from pymysql.cursors import Cursor -from mycli.packages.special.main import Verbosity, parse_special_command +from mycli.packages.special.main import CommandVerbosity, parse_special_command from mycli.packages.sqlresult import SQLResult log = logging.getLogger(__name__) @@ -224,7 +224,7 @@ def handle_llm( prompt_field_truncate: int, prompt_section_truncate: int, ) -> tuple[str, str | None, float]: - _, verbosity, arg = parse_special_command(text) + _, command_verbosity, arg = parse_special_command(text) if not LLM_IMPORTED: raise FinishIteration(results=[SQLResult(preamble=NEED_DEPENDENCIES)]) if arg.strip().lower() in ['', 'help', '?', r'\?']: @@ -262,7 +262,7 @@ def handle_llm( sql = match.group(1).strip() else: raise FinishIteration(results=[SQLResult(preamble=output)]) - return (output if verbosity == Verbosity.SUCCINCT else "", sql, end - start) + return (output if command_verbosity == CommandVerbosity.SUCCINCT else "", sql, end - start) else: run_external_cmd("llm", *args, restart_cli=restart) raise FinishIteration(results=None) @@ -277,7 +277,7 @@ def handle_llm( prompt_section_truncate=prompt_section_truncate, ) end = time() - if verbosity == Verbosity.SUCCINCT: + if command_verbosity == CommandVerbosity.SUCCINCT: context = "" return (context, sql, end - start) except Exception as e: diff --git a/mycli/packages/special/main.py b/mycli/packages/special/main.py index e0ee43e1..82f306f2 100644 --- a/mycli/packages/special/main.py +++ b/mycli/packages/special/main.py @@ -48,21 +48,21 @@ class CommandNotFound(Exception): pass -class Verbosity(Enum): +class CommandVerbosity(Enum): SUCCINCT = "succinct" NORMAL = "normal" VERBOSE = "verbose" -def parse_special_command(sql: str) -> tuple[str, Verbosity, str]: +def parse_special_command(sql: str) -> tuple[str, CommandVerbosity, str]: command, _, arg = sql.partition(" ") - verbosity = Verbosity.NORMAL + command_verbosity = CommandVerbosity.NORMAL if "+" in command: - verbosity = Verbosity.VERBOSE + command_verbosity = CommandVerbosity.VERBOSE elif "-" in command: - verbosity = Verbosity.SUCCINCT + command_verbosity = CommandVerbosity.SUCCINCT command = command.strip().strip("+-") - return (command, verbosity, arg.strip()) + return (command, command_verbosity, arg.strip()) def special_command( @@ -130,7 +130,7 @@ def execute(cur: Cursor, sql: str) -> list[SQLResult]: """Execute a special command and return the results. If the special command is not supported a CommandNotFound will be raised. """ - command, verbosity, arg = parse_special_command(sql) + command, command_verbosity, arg = parse_special_command(sql) if (command not in COMMANDS) and (command.lower() not in COMMANDS): raise CommandNotFound(f'Command not found: {command}') @@ -150,7 +150,7 @@ def execute(cur: Cursor, sql: str) -> list[SQLResult]: if special_cmd.arg_type == ArgType.NO_QUERY: return special_cmd.handler() elif special_cmd.arg_type == ArgType.PARSED_QUERY: - return special_cmd.handler(cur=cur, arg=arg, verbose=(verbosity == Verbosity.VERBOSE)) + return special_cmd.handler(cur=cur, arg=arg, command_verbosity=(command_verbosity == CommandVerbosity.VERBOSE)) elif special_cmd.arg_type == ArgType.RAW_QUERY: return special_cmd.handler(cur=cur, query=sql) diff --git a/test/myclirc b/test/myclirc index a38f1994..ece0db36 100644 --- a/test/myclirc +++ b/test/myclirc @@ -161,7 +161,8 @@ multiplex_window_title = '' # as frequently as the database is changed. multiplex_pane_title = '' -# Skip intro info on startup and outro info on exit +# Skip intro info on startup and outro info on exit, and generally reduce +# feedback. This is equivalent to giving --quiet at the command line. less_chatty = True # Use alias from --login-path instead of host name in prompt diff --git a/test/pytests/test_main.py b/test/pytests/test_main.py index 84019590..048a3d85 100644 --- a/test/pytests/test_main.py +++ b/test/pytests/test_main.py @@ -2126,6 +2126,36 @@ def test_execute_arg_warns_about_ignoring_stdin(monkeypatch): assert 'Ignoring STDIN' in result.output +def test_verbose_and_quiet_are_incompatible() -> None: + runner = CliRunner() + + result = runner.invoke(click_entrypoint, args=['--verbose', '--quiet']) + + assert result.exit_code == 1 + assert 'incompatible.' in result.output + + +def test_quiet_sets_negative_cli_verbosity(monkeypatch: pytest.MonkeyPatch) -> None: + dummy_class = make_dummy_mycli_class( + config={ + 'main': {'use_keyring': 'false', 'my_cnf_transition_done': 'true'}, + 'connection': {'default_keepalive_ticks': 0}, + 'alias_dsn': {}, + } + ) + monkeypatch.setattr(main, 'MyCli', dummy_class) + monkeypatch.setattr(main.sys, 'stdin', SimpleNamespace(isatty=lambda: True)) + + cli_args = main.CliArgs() + cli_args.quiet = True + + call_click_entrypoint_direct(cli_args) + + dummy = dummy_class.last_instance + assert dummy is not None + assert dummy.init_kwargs['cli_verbosity'] == -1 + + def test_execute_arg_supersedes_batch_file(monkeypatch): mycli_main, mycli_main_batch, MockMyCli = noninteractive_mock_mycli(monkeypatch) runner = CliRunner() diff --git a/test/pytests/test_main_modes_list_dsn.py b/test/pytests/test_main_modes_list_dsn.py index a622015a..359a4b93 100644 --- a/test/pytests/test_main_modes_list_dsn.py +++ b/test/pytests/test_main_modes_list_dsn.py @@ -8,7 +8,7 @@ @dataclass class DummyCliArgs: - verbose: bool = False + verbose: int = 0 class DummyConfig: @@ -25,10 +25,11 @@ def __getitem__(self, key: str) -> dict[str, str]: class DummyMyCli: def __init__(self, config: Any) -> None: self.config = config + self.verbosity = 0 -def main_list_dsn(mycli: DummyMyCli, cli_args: DummyCliArgs) -> int: - return list_dsn_mode.main_list_dsn(cast(Any, mycli), cast(Any, cli_args)) +def main_list_dsn(mycli: DummyMyCli) -> int: + return list_dsn_mode.main_list_dsn(cast(Any, mycli)) def test_main_list_dsn_lists_aliases_without_values(monkeypatch) -> None: @@ -41,7 +42,7 @@ def test_main_list_dsn_lists_aliases_without_values(monkeypatch) -> None: lambda message, err=None, fg=None: secho_calls.append((message, err, fg)), ) - result = main_list_dsn(mycli, DummyCliArgs(verbose=False)) + result = main_list_dsn(mycli) assert result == 0 assert secho_calls == [ @@ -53,6 +54,7 @@ def test_main_list_dsn_lists_aliases_without_values(monkeypatch) -> None: def test_main_list_dsn_lists_aliases_with_values_in_verbose_mode(monkeypatch) -> None: secho_calls: list[tuple[str, bool | None, str | None]] = [] mycli = DummyMyCli(DummyConfig({'prod': 'mysql://u:p@h/db'})) + mycli.verbosity = 1 monkeypatch.setattr( list_dsn_mode.click, @@ -60,7 +62,7 @@ def test_main_list_dsn_lists_aliases_with_values_in_verbose_mode(monkeypatch) -> lambda message, err=None, fg=None: secho_calls.append((message, err, fg)), ) - result = main_list_dsn(mycli, DummyCliArgs(verbose=True)) + result = main_list_dsn(mycli) assert result == 0 assert secho_calls == [('prod : mysql://u:p@h/db', None, None)] @@ -76,7 +78,7 @@ def test_main_list_dsn_reports_invalid_alias_section(monkeypatch) -> None: lambda message, err=None, fg=None: secho_calls.append((message, err, fg)), ) - result = main_list_dsn(mycli, DummyCliArgs()) + result = main_list_dsn(mycli) assert result == 1 assert secho_calls == [ @@ -98,7 +100,7 @@ def test_main_list_dsn_reports_other_config_errors(monkeypatch) -> None: lambda message, err=None, fg=None: secho_calls.append((message, err, fg)), ) - result = main_list_dsn(mycli, DummyCliArgs()) + result = main_list_dsn(mycli) assert result == 1 assert secho_calls == [('boom', True, 'red')] diff --git a/test/pytests/test_main_modes_list_ssh_config.py b/test/pytests/test_main_modes_list_ssh_config.py index 287ed1f2..9ff104a4 100644 --- a/test/pytests/test_main_modes_list_ssh_config.py +++ b/test/pytests/test_main_modes_list_ssh_config.py @@ -9,7 +9,13 @@ @dataclass class DummyCliArgs: ssh_config_path: str = 'ssh_config' - verbose: bool = False + verbose: int = 0 + + +class DummyMyCli: + def __init__(self, config: Any) -> None: + self.config = config + self.verbosity = 0 class DummySSHConfig: @@ -27,7 +33,9 @@ def lookup(self, hostname: str) -> dict[str, str]: def main_list_ssh_config(cli_args: DummyCliArgs) -> int: - return list_ssh_config_mode.main_list_ssh_config(cast(Any, object()), cast(Any, cli_args)) + mycli = DummyMyCli(config={}) + mycli.verbosity = cli_args.verbose + return list_ssh_config_mode.main_list_ssh_config(cast(Any, mycli), cast(Any, cli_args)) def test_main_list_ssh_config_lists_hostnames(monkeypatch) -> None: @@ -41,7 +49,7 @@ def test_main_list_ssh_config_lists_hostnames(monkeypatch) -> None: lambda message, err=None, fg=None: secho_calls.append((message, err, fg)), ) - result = main_list_ssh_config(DummyCliArgs(verbose=False)) + result = main_list_ssh_config(DummyCliArgs(verbose=0)) assert result == 0 assert secho_calls == [ @@ -64,7 +72,7 @@ def test_main_list_ssh_config_lists_verbose_host_details(monkeypatch) -> None: lambda message, err=None, fg=None: secho_calls.append((message, err, fg)), ) - result = main_list_ssh_config(DummyCliArgs(verbose=True)) + result = main_list_ssh_config(DummyCliArgs(verbose=1)) assert result == 0 assert secho_calls == [('prod : db.example.com', None, None)] diff --git a/test/pytests/test_main_modes_repl.py b/test/pytests/test_main_modes_repl.py index c4083844..81f470a4 100644 --- a/test/pytests/test_main_modes_repl.py +++ b/test/pytests/test_main_modes_repl.py @@ -145,7 +145,7 @@ def make_repl_cli(sqlexecute: Any | None = None) -> Any: cli.prompt_format = cli.default_prompt cli.multiline_continuation_char = '>' cli.toolbar_format = 'default' - cli.less_chatty = True + cli.verbosity = -1 cli.keepalive_ticks = None cli._keepalive_counter = 0 cli.auto_vertical_output = False @@ -324,11 +324,11 @@ def test_repl_show_startup_banner_and_prompt_helpers(monkeypatch: pytest.MonkeyP monkeypatch.setattr(repl_mode, '_sponsors_picker', lambda: 'Carol') monkeypatch.setattr(repl_mode, '_tips_picker', lambda: 'Tip') - cli.less_chatty = False + cli.verbosity = 0 repl_mode._show_startup_banner(cli, cli.sqlexecute) monkeypatch.setattr(repl_mode.random, 'random', lambda: 0.6) repl_mode._show_startup_banner(cli, cli.sqlexecute) - cli.less_chatty = True + cli.verbosity = -1 repl_mode._show_startup_banner(cli, cli.sqlexecute) assert any('Thanks to the contributor' in line for line in printed) assert any('Tip — Tip' in line for line in printed) @@ -361,7 +361,7 @@ def test_repl_show_startup_banner_and_prompt_helpers(monkeypatch: pytest.MonkeyP def test_repl_show_startup_banner_thanks_sponsor(monkeypatch: pytest.MonkeyPatch) -> None: cli = make_repl_cli(SimpleNamespace(server_info='Server')) - cli.less_chatty = False + cli.verbosity = 0 printed: list[str] = [] monkeypatch.setattr(builtins, 'print', lambda *args, **kwargs: printed.append(' '.join(str(x) for x in args))) monkeypatch.setattr(repl_mode.random, 'random', lambda: 0.25) @@ -1170,7 +1170,7 @@ def run(self, text: str) -> Iterator[SQLResult]: def test_main_repl_covers_setup_loop_and_goodbye(monkeypatch: pytest.MonkeyPatch) -> None: cli = make_repl_cli(SimpleNamespace()) - cli.less_chatty = False + cli.verbosity = 0 cli.smart_completion = True loop_iterations: list[int] = [] monkeypatch.setattr(repl_mode, '_create_history', lambda mycli: 'history') @@ -1204,7 +1204,7 @@ def fake_one_iteration(mycli: Any, state: repl_mode.ReplState) -> None: def test_main_repl_covers_no_refresh_and_quiet_exit(monkeypatch: pytest.MonkeyPatch) -> None: cli = make_repl_cli(SimpleNamespace()) - cli.less_chatty = True + cli.verbosity = -1 cli.smart_completion = False monkeypatch.setattr(repl_mode, '_create_history', lambda mycli: 'history') monkeypatch.setattr(repl_mode, 'mycli_bindings', lambda mycli: 'bindings') diff --git a/test/pytests/test_main_regression.py b/test/pytests/test_main_regression.py index f4dfc62c..5bc348ac 100644 --- a/test/pytests/test_main_regression.py +++ b/test/pytests/test_main_regression.py @@ -1321,24 +1321,6 @@ def test_click_entrypoint_callback_covers_database_dsn_and_verbose_lists(monkeyp monkeypatch.setattr(main.sys, 'stdin', SimpleNamespace(isatty=lambda: True)) monkeypatch.setattr(main.sys.stderr, 'isatty', lambda: False) - dummy_class = make_dummy_mycli_class( - config={ - 'main': {'use_keyring': 'false', 'my_cnf_transition_done': 'true'}, - 'connection': {'default_keepalive_ticks': 0}, - 'alias_dsn': {'prod': 'mysql://u:p@h/db'}, - } - ) - monkeypatch.setattr(main, 'MyCli', dummy_class) - - cli_args = main.CliArgs() - cli_args.list_dsn = True - cli_args.verbose = True - with pytest.raises(SystemExit): - call_click_entrypoint_direct(cli_args) - assert 'prod : mysql://u:p@h/db' in click_lines - - click_lines.clear() - dummy_class = make_dummy_mycli_class( config={ 'main': {'use_keyring': 'false', 'my_cnf_transition_done': 'true'}, diff --git a/test/pytests/test_special_dbcommands.py b/test/pytests/test_special_dbcommands.py index 0fe372ec..e2e0d7f4 100644 --- a/test/pytests/test_special_dbcommands.py +++ b/test/pytests/test_special_dbcommands.py @@ -102,8 +102,8 @@ def fetchone_side_effect(): cur.fetchall.side_effect = fetchall_side_effect cur.fetchone.side_effect = fetchone_side_effect - # Call list_tables with verbose=True (simulating \dt+ table_name) - results = list_tables(cur, arg='test_table', verbose=True) + # Call list_tables with command_verbosity=True (simulating \dt+ table_name) + results = list_tables(cur, arg='test_table', command_verbosity=True) assert len(results) == 1 result = results[0] diff --git a/test/pytests/test_special_llm.py b/test/pytests/test_special_llm.py index 39401896..9ca28150 100644 --- a/test/pytests/test_special_llm.py +++ b/test/pytests/test_special_llm.py @@ -275,7 +275,7 @@ def test_llm_command_with_c_flag_and_fenced_sql(mock_run_cmd, mock_llm, executor mock_run_cmd.return_value = (0, fenced) test_text = r"\llm -c 'Rewrite SQL'" result, sql, duration = handle_llm(test_text, executor, 'mysql', 0, 0) - # Without verbose, result is empty, sql extracted + # Without verbosity, result is empty, sql extracted assert sql == sql_text assert result == "" assert isinstance(duration, float) diff --git a/test/pytests/test_special_main.py b/test/pytests/test_special_main.py index 204a1b28..bd6ed9a4 100644 --- a/test/pytests/test_special_main.py +++ b/test/pytests/test_special_main.py @@ -55,13 +55,13 @@ def load_isolated_special_main(module_name: str) -> ModuleType: @pytest.mark.parametrize( ('sql', 'expected'), [ - ('help select', ('help', special_main.Verbosity.NORMAL, 'select')), - (r'\llm+ prompt', (r'\llm', special_main.Verbosity.VERBOSE, 'prompt')), - (r'\llm- prompt', (r'\llm', special_main.Verbosity.SUCCINCT, 'prompt')), - ('help spaced ', ('help', special_main.Verbosity.NORMAL, 'spaced')), + ('help select', ('help', special_main.CommandVerbosity.NORMAL, 'select')), + (r'\llm+ prompt', (r'\llm', special_main.CommandVerbosity.VERBOSE, 'prompt')), + (r'\llm- prompt', (r'\llm', special_main.CommandVerbosity.SUCCINCT, 'prompt')), + ('help spaced ', ('help', special_main.CommandVerbosity.NORMAL, 'spaced')), ], ) -def test_parse_special_command(sql: str, expected: tuple[str, special_main.Verbosity, str]) -> None: +def test_parse_special_command(sql: str, expected: tuple[str, special_main.CommandVerbosity, str]) -> None: assert special_main.parse_special_command(sql) == expected @@ -182,8 +182,8 @@ def handler() -> list[SQLResult]: def test_execute_dispatches_parsed_query_command(restore_commands: None) -> None: calls: list[tuple[object, str, bool]] = [] - def handler(*, cur: object, arg: str, verbose: bool) -> list[SQLResult]: - calls.append((cur, arg, verbose)) + def handler(*, cur: object, arg: str, command_verbosity: bool) -> list[SQLResult]: + calls.append((cur, arg, command_verbosity)) return [SQLResult(status='parsed')] special_main.COMMANDS.clear() diff --git a/test/utils.py b/test/utils.py index 1d01ac33..db3d4bf3 100644 --- a/test/utils.py +++ b/test/utils.py @@ -147,7 +147,7 @@ def make_bare_mycli() -> Any: cli.destructive_keywords = ['drop'] cli.keepalive_ticks = None cli._keepalive_counter = 0 - cli.less_chatty = True + cli.verbosity = -1 cli.smart_completion = False cli.key_bindings = 'emacs' cli.auto_vertical_output = False @@ -203,6 +203,7 @@ def __init__(self, **kwargs: Any) -> None: self.run_query_calls: list[tuple[str, Any, bool]] = [] self.run_cli_called = False self.close_called = False + self.verbosity = 0 def connect(self, **kwargs: Any) -> None: self.connect_calls.append(dict(kwargs))