From a04d1cf06779ce94293a4c19a5c707b817fd0df2 Mon Sep 17 00:00:00 2001 From: Roland Walker Date: Sat, 21 Feb 2026 11:36:53 -0500 Subject: [PATCH] accept on/off values for --use-keyring Accept on/off values for --use-keyring, keeping true/false, as well as treating "reset" as special. The motivation is uniformity in the interface. The only loss is that click does not display the value choices in the helpdoc, but they are already listed in the description. Here we also change the description to suggest on/off, while continuing to silently accept true/false. The reason for the change is that --ssl-mode came first, and --ssl-mode takes on/off. --- changelog.md | 1 + mycli/main.py | 10 +++++--- test/test_main.py | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index 188adc7f..2b2d34fb 100644 --- a/changelog.md +++ b/changelog.md @@ -10,6 +10,7 @@ Features * Let `help ` list similar keywords when not found. * Optionally highlight fuzzy search previews. * Make `\edit` synonymous with the `\e` command. +* More liberally accept `on`/`off` values for `true`/`false`, and vice versa. Bug Fixes diff --git a/mycli/main.py b/mycli/main.py index 52110157..70ad54bf 100755 --- a/mycli/main.py +++ b/mycli/main.py @@ -1786,9 +1786,9 @@ def get_last_query(self) -> str | None: @click.option( '--use-keyring', 'use_keyring_cli_opt', - type=click.Choice(['true', 'false', 'reset']), + type=str, default=None, - help='Store and retrieve passwords from the system keyring: true/false/reset.', + help='Store and retrieve passwords from the system keyring: on/off/reset.', ) @click.option( '--keepalive-ticks', @@ -2158,7 +2158,11 @@ def get_password_from_file(password_file: str | None) -> str | None: use_keyring = str_to_bool(mycli.config['main'].get('use_keyring', 'False')) reset_keyring = False else: - use_keyring = str_to_bool(use_keyring_cli_opt) + try: + use_keyring = str_to_bool(use_keyring_cli_opt) + except ValueError: + click.secho('Unknown value for --use_keyring', err=True, fg='red') + sys.exit(1) reset_keyring = False # todo: removeme after a period of transition diff --git a/test/test_main.py b/test/test_main.py index fc8b3a9b..c727e6f4 100644 --- a/test/test_main.py +++ b/test/test_main.py @@ -1015,6 +1015,65 @@ def run_query(self, query, new_line=True): assert MockMyCli.connect_args['character_set'] == 'utf8mb3' +def test_keyring_arg(monkeypatch): + # Setup classes to mock mycli.main.MyCli + class Formatter: + format_name = None + + class Logger: + def debug(self, *args, **args_dict): + pass + + def warning(self, *args, **args_dict): + pass + + class MockMyCli: + config = { + 'main': {}, + 'alias_dsn': {}, + "connection": { + "default_keepalive_ticks": 0, + }, + } + + def __init__(self, **args): + self.logger = Logger() + self.destructive_warning = False + self.main_formatter = Formatter() + self.redirect_formatter = Formatter() + self.ssl_mode = 'auto' + self.my_cnf = {'client': {}, 'mysqld': {}} + self.default_keepalive_ticks = 0 + + def connect(self, **args): + MockMyCli.connect_args = args + + def run_query(self, query, new_line=True): + pass + + import mycli.main + + monkeypatch.setattr(mycli.main, 'MyCli', MockMyCli) + runner = CliRunner() + + result = runner.invoke(mycli.main.cli, args=['--use-keyring', 'True']) + assert result.exit_code == 0, result.output + ' ' + str(result.exception) + assert MockMyCli.connect_args['use_keyring'] is True + + result = runner.invoke(mycli.main.cli, args=['--use-keyring', 'on']) + assert result.exit_code == 0, result.output + ' ' + str(result.exception) + assert MockMyCli.connect_args['use_keyring'] is True + + result = runner.invoke(mycli.main.cli, args=['--use-keyring', 'off']) + assert result.exit_code == 0, result.output + ' ' + str(result.exception) + assert MockMyCli.connect_args['use_keyring'] is False + + result = runner.invoke(mycli.main.cli, args=['--use-keyring', 'Reset']) + assert result.exit_code == 0, result.output + ' ' + str(result.exception) + assert MockMyCli.connect_args['use_keyring'] is True + assert MockMyCli.connect_args['reset_keyring'] is True + + def test_ssh_config(monkeypatch): # Setup classes to mock mycli.main.MyCli class Formatter: