mycli 2.30.2__tar.gz → 2.30.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mycli-2.30.2 → mycli-2.30.4}/.github/workflows/ci.yml +8 -8
- {mycli-2.30.2 → mycli-2.30.4}/.github/workflows/publish.yml +9 -9
- {mycli-2.30.2/mycli.egg-info → mycli-2.30.4}/PKG-INFO +14 -14
- {mycli-2.30.2 → mycli-2.30.4}/changelog.md +38 -1
- {mycli-2.30.2 → mycli-2.30.4}/docker/resources/test_db-1.0.7.tar.gz +1 -1
- {mycli-2.30.2 → mycli-2.30.4}/mycli/AUTHORS.txt +1 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/cli_runner.py +2 -2
- {mycli-2.30.2 → mycli-2.30.4}/mycli/client_connection.py +2 -3
- {mycli-2.30.2 → mycli-2.30.4}/mycli/constants.py +0 -4
- {mycli-2.30.2 → mycli-2.30.4}/mycli/main_modes/repl.py +2 -2
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/execution/sql_execute.py +4 -4
- {mycli-2.30.2 → mycli-2.30.4/mycli.egg-info}/PKG-INFO +14 -14
- {mycli-2.30.2 → mycli-2.30.4}/mycli.egg-info/SOURCES.txt +1 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli.egg-info/requires.txt +13 -13
- {mycli-2.30.2 → mycli-2.30.4}/mycli.egg-info/scm_file_list.json +1 -0
- mycli-2.30.4/mycli.egg-info/scm_version.json +8 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_cli_runner.py +40 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_client_connection.py +3 -2
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_main.py +2 -2
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_main_modes_repl.py +1 -1
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_special_io_commands.py +88 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_special_main.py +39 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_sql_execute.py +71 -1
- mycli-2.30.4/mycli_test/pytests/test_sql_format.py +97 -0
- {mycli-2.30.2 → mycli-2.30.4}/pyproject.toml +15 -14
- mycli-2.30.2/mycli.egg-info/scm_version.json +0 -8
- {mycli-2.30.2 → mycli-2.30.4}/.git-blame-ignore-revs +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/.github/actions/lint/action.yml +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/.github/actions/typecheck/action.yml +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/.github/dependabot.yml +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/.github/workflows/lint.yml +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/.github/workflows/typecheck.yml +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/.gitignore +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/AGENTS.md +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/AUTHORS.md +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/CONTRIBUTING.md +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/LICENSE.txt +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/MANIFEST.in +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/README.md +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/SPONSORS.md +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/doc/cookbook.md +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/doc/key_bindings.md +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/doc/known_bugs.md +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/doc/llm.md +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/doc/screenshots/main.gif +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/doc/screenshots/polars_describe.png +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/doc/screenshots/polars_group_by.png +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/doc/screenshots/polars_histogram.png +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/doc/screenshots/polars_pivot.png +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/doc/screenshots/tables.png +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/doc/transforms.md +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/docker/Dockerfile +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/docker/resources/dot_mycli_history.txt +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/docker/resources/test_db_license.md +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/SPONSORS.txt +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/TIPS.txt +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/app_state.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/client.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/client_commands.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/client_query.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/compat.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/config.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/main.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/main_modes/batch.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/main_modes/checkup.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/main_modes/completions.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/main_modes/execute.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/main_modes/list_dsn.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/myclirc +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/output.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/completion/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/completion/completion_engine.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/completion/completion_refresher.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/completion/schema_prefetcher.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/completion/sql_completer.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/credentials/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/credentials/password_sources.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/dataframes/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/dataframes/completion.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/dataframes/transform.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/execution/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/execution/background_runner.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/integrations/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/integrations/boundary/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/integrations/boundary/boundary_tunnel.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/integrations/fzf/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/integrations/fzf/fzf.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/integrations/kubernetes/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/integrations/kubernetes/kubectl_tunnel.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/integrations/macos/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/integrations/macos/macos_keychain.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/integrations/openssh/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/integrations/openssh/ssh_tunnel.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/integrations/vault/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/integrations/vault/vault_credentials.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/prompt_toolkit/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/prompt_toolkit/fzf_history.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/prompt_toolkit/history.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/prompt_toolkit/key_bindings.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/prompt_toolkit/multiline.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/prompt_toolkit/style.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/prompt_toolkit/toolbar.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/prompt_toolkit/utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/pygments/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/pygments/mycli_lexer.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/redirection/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/redirection/hybrid_redirection.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/special_commands/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/special_commands/db_commands.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/special_commands/delimiter_command.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/special_commands/dsn_aliases.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/special_commands/favorite_queries.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/special_commands/io_commands.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/special_commands/llm.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/special_commands/main.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/special_commands/source.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/special_commands/special_command_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/sql_result/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/sql_result/sql_result.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/tabular_output/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/tabular_output/sql_format.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/utils/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/utils/batch_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/utils/cli_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/utils/dsn_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/utils/interactive_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/utils/key_binding_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/utils/keyring_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/utils/path_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/utils/sql_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/packages/utils/string_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/resources/completions/bash/mycli +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/resources/completions/fish/mycli.fish +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/resources/completions/zsh/_mycli +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli/types.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli.egg-info/dependency_links.txt +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli.egg-info/entry_points.txt +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli.egg-info/top_level.txt +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/auto_vertical.feature +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/basic_commands.feature +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/connection.feature +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/crud_database.feature +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/crud_table.feature +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/db_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/environment.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/fixture_data/help_commands.txt +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/fixture_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/iocommands.feature +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/named_queries.feature +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/specials.feature +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/steps/__init__.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/steps/auto_vertical.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/steps/basic_commands.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/steps/connection.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/steps/crud_database.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/steps/crud_table.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/steps/iocommands.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/steps/named_queries.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/steps/specials.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/steps/utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/steps/wrappers.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/features/wrappager.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/myclirc +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/mylogin.cnf +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/conftest.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_app_state.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_background_runner.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_bash_completion.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_batch_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_boundary_tunnel.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_checkup.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_cli_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_clibuffer.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_client.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_client_commands.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_client_query.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_completer_use_switch.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_completion_engine.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_completion_refresher.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_config.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_delimitercommand.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_dsn_aliases.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_favoritequeries.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_fish_completion.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_fzf.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_hybrid_redirection.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_interactive_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_key_binding_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_key_bindings.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_keyring_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_kubectl_tunnel.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_macos_keychain.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_main_modes_batch.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_main_modes_execute.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_main_modes_list_dsn.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_naive_completion.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_output.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_password_sources.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_path_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_polars_completion.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_polars_transform.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_prompt_toolkit_fzf_history.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_prompt_toolkit_history.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_prompt_toolkit_style.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_prompt_toolkit_toolbar.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_prompt_toolkit_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_schema_prefetcher.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_smart_completion_public_schema_only.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_special_commands_init.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_special_db_commands.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_special_llm.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_special_source.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_special_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_sql_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_sqlcompleter.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_sqlresult.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_ssh_tunnel.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_string_utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_tabular_output.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_vault.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/pytests/test_zsh_completion.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/mycli_test/utils.py +0 -0
- {mycli-2.30.2 → mycli-2.30.4}/setup.cfg +0 -0
|
@@ -24,7 +24,7 @@ jobs:
|
|
|
24
24
|
steps:
|
|
25
25
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
26
26
|
|
|
27
|
-
- uses: astral-sh/setup-uv@
|
|
27
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
28
28
|
with:
|
|
29
29
|
version: "latest"
|
|
30
30
|
|
|
@@ -66,7 +66,7 @@ jobs:
|
|
|
66
66
|
steps:
|
|
67
67
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
68
68
|
|
|
69
|
-
- uses: astral-sh/setup-uv@
|
|
69
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
70
70
|
with:
|
|
71
71
|
version: "latest"
|
|
72
72
|
|
|
@@ -116,7 +116,7 @@ jobs:
|
|
|
116
116
|
steps:
|
|
117
117
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
118
118
|
|
|
119
|
-
- uses: astral-sh/setup-uv@
|
|
119
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
120
120
|
with:
|
|
121
121
|
version: 'latest'
|
|
122
122
|
|
|
@@ -130,7 +130,7 @@ jobs:
|
|
|
130
130
|
run: uv sync --extra dev,llm,dataframe -p ${{ matrix.python-version }}
|
|
131
131
|
|
|
132
132
|
- name: Set up MySQL
|
|
133
|
-
uses: shogo82148/actions-setup-mysql@
|
|
133
|
+
uses: shogo82148/actions-setup-mysql@13a38f2af408e58a0c80168fc620a63a15357339 # v1.56.2
|
|
134
134
|
with:
|
|
135
135
|
mysql-version: '9.7'
|
|
136
136
|
root-password: root
|
|
@@ -150,7 +150,7 @@ jobs:
|
|
|
150
150
|
steps:
|
|
151
151
|
- uses: vampire/setup-wsl@4c48163d9f981914dd8caa0fc335fe19cca5bff4 # v7.2.0
|
|
152
152
|
with:
|
|
153
|
-
distribution: Ubuntu-
|
|
153
|
+
distribution: Ubuntu-26.04
|
|
154
154
|
use-cache: 'true'
|
|
155
155
|
update: 'false'
|
|
156
156
|
additional-packages: |
|
|
@@ -166,9 +166,9 @@ jobs:
|
|
|
166
166
|
run: |
|
|
167
167
|
mkdir -p /root/mycli
|
|
168
168
|
|
|
169
|
-
- uses: ubuntu/wsl/.github/actions/wsl-checkout@
|
|
169
|
+
- uses: ubuntu/wsl/.github/actions/wsl-checkout@c1984d32aea99733825250f86df5f9f6d7e284c3
|
|
170
170
|
with:
|
|
171
|
-
distro: Ubuntu-
|
|
171
|
+
distro: Ubuntu-26.04
|
|
172
172
|
working-dir: /root/mycli
|
|
173
173
|
|
|
174
174
|
- name: Install uv
|
|
@@ -220,7 +220,7 @@ jobs:
|
|
|
220
220
|
steps:
|
|
221
221
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
222
222
|
|
|
223
|
-
- uses: astral-sh/setup-uv@
|
|
223
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
224
224
|
with:
|
|
225
225
|
version: "latest"
|
|
226
226
|
|
|
@@ -51,7 +51,7 @@ jobs:
|
|
|
51
51
|
|
|
52
52
|
steps:
|
|
53
53
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
54
|
-
- uses: astral-sh/setup-uv@
|
|
54
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
55
55
|
with:
|
|
56
56
|
version: "latest"
|
|
57
57
|
|
|
@@ -93,7 +93,7 @@ jobs:
|
|
|
93
93
|
steps:
|
|
94
94
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
95
95
|
|
|
96
|
-
- uses: astral-sh/setup-uv@
|
|
96
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
97
97
|
with:
|
|
98
98
|
version: "latest"
|
|
99
99
|
|
|
@@ -144,7 +144,7 @@ jobs:
|
|
|
144
144
|
steps:
|
|
145
145
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
146
146
|
|
|
147
|
-
- uses: astral-sh/setup-uv@
|
|
147
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
148
148
|
with:
|
|
149
149
|
version: 'latest'
|
|
150
150
|
|
|
@@ -158,7 +158,7 @@ jobs:
|
|
|
158
158
|
run: uv sync --extra dev,llm,dataframe --python ${{ matrix.python-version }}
|
|
159
159
|
|
|
160
160
|
- name: Set up MySQL
|
|
161
|
-
uses: shogo82148/actions-setup-mysql@
|
|
161
|
+
uses: shogo82148/actions-setup-mysql@13a38f2af408e58a0c80168fc620a63a15357339 # v1.56.2
|
|
162
162
|
with:
|
|
163
163
|
mysql-version: '9.7'
|
|
164
164
|
root-password: root
|
|
@@ -179,7 +179,7 @@ jobs:
|
|
|
179
179
|
steps:
|
|
180
180
|
- uses: vampire/setup-wsl@4c48163d9f981914dd8caa0fc335fe19cca5bff4 # v7.2.0
|
|
181
181
|
with:
|
|
182
|
-
distribution: Ubuntu-
|
|
182
|
+
distribution: Ubuntu-26.04
|
|
183
183
|
use-cache: 'true'
|
|
184
184
|
update: 'false'
|
|
185
185
|
additional-packages: |
|
|
@@ -195,9 +195,9 @@ jobs:
|
|
|
195
195
|
run: |
|
|
196
196
|
mkdir -p /root/mycli
|
|
197
197
|
|
|
198
|
-
- uses: ubuntu/wsl/.github/actions/wsl-checkout@
|
|
198
|
+
- uses: ubuntu/wsl/.github/actions/wsl-checkout@c1984d32aea99733825250f86df5f9f6d7e284c3
|
|
199
199
|
with:
|
|
200
|
-
distro: Ubuntu-
|
|
200
|
+
distro: Ubuntu-26.04
|
|
201
201
|
working-dir: /root/mycli
|
|
202
202
|
|
|
203
203
|
- name: Install uv
|
|
@@ -248,7 +248,7 @@ jobs:
|
|
|
248
248
|
|
|
249
249
|
steps:
|
|
250
250
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
251
|
-
- uses: astral-sh/setup-uv@
|
|
251
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
252
252
|
with:
|
|
253
253
|
version: "latest"
|
|
254
254
|
|
|
@@ -309,7 +309,7 @@ jobs:
|
|
|
309
309
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
310
310
|
|
|
311
311
|
- name: Log in to the Container registry
|
|
312
|
-
uses: docker/login-action@
|
|
312
|
+
uses: docker/login-action@8aa5831fb8d48d8f76594c7ddde61ae58019f550 # v4.8.0
|
|
313
313
|
with:
|
|
314
314
|
registry: ${{ env.REGISTRY }}
|
|
315
315
|
username: ${{ github.actor }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mycli
|
|
3
|
-
Version: 2.30.
|
|
3
|
+
Version: 2.30.4
|
|
4
4
|
Summary: Rich MySQL terminal client with autocompletion, syntax highlighting, and dataframes
|
|
5
5
|
Author: Mycli Core Team
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -33,13 +33,13 @@ Requires-Dist: clickdc~=0.1.1
|
|
|
33
33
|
Requires-Dist: cryptography~=50.0.2
|
|
34
34
|
Requires-Dist: Pygments~=2.21.0
|
|
35
35
|
Requires-Dist: prompt_toolkit~=3.0.53
|
|
36
|
-
Requires-Dist: PyMySQL~=1.2.
|
|
37
|
-
Requires-Dist: sqlparse~=0.6.
|
|
38
|
-
Requires-Dist: sqlglot~=30.
|
|
39
|
-
Requires-Dist: sqlglotc~=30.
|
|
36
|
+
Requires-Dist: PyMySQL~=1.2.4
|
|
37
|
+
Requires-Dist: sqlparse~=0.6.1
|
|
38
|
+
Requires-Dist: sqlglot~=30.25.0
|
|
39
|
+
Requires-Dist: sqlglotc~=30.25.0
|
|
40
40
|
Requires-Dist: configobj~=5.0.9
|
|
41
41
|
Requires-Dist: cli_helpers[styles]~=2.15.3
|
|
42
|
-
Requires-Dist: wcwidth~=0.9.
|
|
42
|
+
Requires-Dist: wcwidth~=0.9.4
|
|
43
43
|
Requires-Dist: pyperclip~=1.11.0
|
|
44
44
|
Requires-Dist: pycryptodomex~=3.24.1
|
|
45
45
|
Requires-Dist: rapidfuzz~=3.14.6
|
|
@@ -48,26 +48,26 @@ Requires-Dist: jinja2~=3.1.6
|
|
|
48
48
|
Requires-Dist: markupsafe~=3.0.4
|
|
49
49
|
Requires-Dist: yaspin~=3.5.1
|
|
50
50
|
Provides-Extra: llm
|
|
51
|
-
Requires-Dist: llm~=0.
|
|
51
|
+
Requires-Dist: llm~=0.37.1; extra == "llm"
|
|
52
52
|
Requires-Dist: setuptools==84.*; extra == "llm"
|
|
53
|
-
Requires-Dist: pip~=26.
|
|
53
|
+
Requires-Dist: pip~=26.3; extra == "llm"
|
|
54
54
|
Provides-Extra: dataframe
|
|
55
|
-
Requires-Dist: polars~=2.
|
|
55
|
+
Requires-Dist: polars~=2.1.0; extra == "dataframe"
|
|
56
56
|
Requires-Dist: altair~=6.3.0; extra == "dataframe"
|
|
57
57
|
Requires-Dist: vl-convert-python~=1.9.0; extra == "dataframe"
|
|
58
58
|
Provides-Extra: all
|
|
59
59
|
Requires-Dist: mycli[dataframe,llm]; extra == "all"
|
|
60
60
|
Provides-Extra: dev
|
|
61
61
|
Requires-Dist: behave~=1.3.3; extra == "dev"
|
|
62
|
-
Requires-Dist: coverage~=7.
|
|
63
|
-
Requires-Dist: mypy~=2.4.
|
|
62
|
+
Requires-Dist: coverage~=7.17.2; extra == "dev"
|
|
63
|
+
Requires-Dist: mypy~=2.4.1; extra == "dev"
|
|
64
64
|
Requires-Dist: pexpect~=4.9.0; extra == "dev"
|
|
65
|
-
Requires-Dist: pytest~=9.
|
|
65
|
+
Requires-Dist: pytest~=9.2.0; extra == "dev"
|
|
66
66
|
Requires-Dist: pytest-cov~=7.1.0; extra == "dev"
|
|
67
67
|
Requires-Dist: pytest-random-order~=1.2.0; extra == "dev"
|
|
68
|
-
Requires-Dist: tox~=4.
|
|
68
|
+
Requires-Dist: tox~=4.67.1; extra == "dev"
|
|
69
69
|
Requires-Dist: pdbpp~=0.12.1; extra == "dev"
|
|
70
|
-
Requires-Dist: ruff~=0.17.
|
|
70
|
+
Requires-Dist: ruff~=0.17.3; extra == "dev"
|
|
71
71
|
Dynamic: license-file
|
|
72
72
|
|
|
73
73
|
# mycli
|
|
@@ -1,9 +1,46 @@
|
|
|
1
|
+
v2.30.4 (2026/11/12)
|
|
2
|
+
==============
|
|
3
|
+
|
|
4
|
+
Bug Fixes
|
|
5
|
+
--------
|
|
6
|
+
* Decode percent-encoded database names in DSN URIs, including aliases with environment variable expansion enabled.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
Internal
|
|
10
|
+
--------
|
|
11
|
+
* Improve test coverage for `packages/special_commands/main.py`.
|
|
12
|
+
* Improve test coverage for `packages/special_commands/io_commands.py`.
|
|
13
|
+
* Improve test coverage for `packages/execution/sql_execute.py`.
|
|
14
|
+
* Improve test coverage for `packages/tabular_output/sql_format.py`.
|
|
15
|
+
* Update `pymysql` dependency to v1.2.4.
|
|
16
|
+
* Update `sqlparse` dependency to v0.6.1.
|
|
17
|
+
* Update `llm` dependency to v0.37.1.
|
|
18
|
+
* Update `pip` dependency to v26.3.
|
|
19
|
+
* Update `coverage` dev dependency to v7.17.2.
|
|
20
|
+
* Update `mypy` dev dependency to v2.4.1.
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
v2.30.3 (2026/11/05)
|
|
24
|
+
==============
|
|
25
|
+
|
|
26
|
+
Internal
|
|
27
|
+
--------
|
|
28
|
+
* Update `wcwidth` dependency to v0.9.4.
|
|
29
|
+
* Update `sqlglot` dependency to v30.25.0.
|
|
30
|
+
* Update `coverage` dev dependency to v7.17.0.
|
|
31
|
+
* Update `tox` dev dependency to v4.67.1.
|
|
32
|
+
* Update `ruff` dev dependency to v0.17.3.
|
|
33
|
+
* Update WSL Linux in CI to Ubuntu 26.04.
|
|
34
|
+
* Update `polars` dependency to v2.1.0.
|
|
35
|
+
* Update `pytest` dev dependency to v9.2.0.
|
|
36
|
+
|
|
37
|
+
|
|
1
38
|
v2.30.2 (2026/10/28)
|
|
2
39
|
==============
|
|
3
40
|
|
|
4
41
|
Bug Fixes
|
|
5
42
|
--------
|
|
6
|
-
* Read and write the
|
|
43
|
+
* Read and write the package `myclirc` as UTF-8, fixing a startup crash on non-UTF-8 locales such as Japanese Windows.
|
|
7
44
|
* Keep checking later statements for the destructive warning after a single-table `UPDATE ... WHERE`.
|
|
8
45
|
|
|
9
46
|
|
|
@@ -117,7 +117,7 @@ def expand_dsn_alias_env_vars(
|
|
|
117
117
|
expand_dsn_alias_env_var(unquote(password) if password is not None else None, alias_name),
|
|
118
118
|
expand_dsn_alias_env_var(host, alias_name),
|
|
119
119
|
port_number,
|
|
120
|
-
expand_dsn_alias_env_var(uri.path[1:], alias_name) or '',
|
|
120
|
+
expand_dsn_alias_env_var(unquote(uri.path[1:]), alias_name) or '',
|
|
121
121
|
params,
|
|
122
122
|
)
|
|
123
123
|
|
|
@@ -310,7 +310,7 @@ def run_from_cli_args(cli_args: 'CliArgs', client_factory: ClientFactory | None
|
|
|
310
310
|
dsn_password = unquote(uri.password) if uri.password is not None else None
|
|
311
311
|
dsn_host = uri.hostname
|
|
312
312
|
dsn_port = uri.port
|
|
313
|
-
dsn_database = uri.path[1:]
|
|
313
|
+
dsn_database = unquote(uri.path[1:])
|
|
314
314
|
dsn_params = parse_qs(uri.query, keep_blank_values=True) if uri.query else {}
|
|
315
315
|
|
|
316
316
|
if not database:
|
|
@@ -10,7 +10,7 @@ import click
|
|
|
10
10
|
import keyring
|
|
11
11
|
import pymysql
|
|
12
12
|
from pymysql.constants.CR import CR_SERVER_LOST
|
|
13
|
-
from pymysql.constants.ER import ACCESS_DENIED_ERROR, HANDSHAKE_ERROR
|
|
13
|
+
from pymysql.constants.ER import ACCESS_DENIED_ERROR, HANDSHAKE_ERROR, MUST_CHANGE_PASSWORD_LOGIN
|
|
14
14
|
|
|
15
15
|
from mycli.compat import WIN
|
|
16
16
|
from mycli.config import str_to_bool
|
|
@@ -19,7 +19,6 @@ from mycli.constants import (
|
|
|
19
19
|
DEFAULT_HOST,
|
|
20
20
|
DEFAULT_PORT,
|
|
21
21
|
EMPTY_PASSWORD_FLAG_SENTINEL,
|
|
22
|
-
ER_MUST_CHANGE_PASSWORD_LOGIN,
|
|
23
22
|
)
|
|
24
23
|
from mycli.packages.credentials.password_sources import PasswordCandidates
|
|
25
24
|
from mycli.packages.execution.sql_execute import SQLExecute
|
|
@@ -433,7 +432,7 @@ class ClientConnectionMixin:
|
|
|
433
432
|
keyring_retrieved_cleanly=keyring_retrieved_cleanly,
|
|
434
433
|
keyring_save_eligible=keyring_save_eligible,
|
|
435
434
|
)
|
|
436
|
-
elif e1.args[0] ==
|
|
435
|
+
elif e1.args[0] == MUST_CHANGE_PASSWORD_LOGIN:
|
|
437
436
|
self.echo(
|
|
438
437
|
"Your password has expired and the server rejected the connection.",
|
|
439
438
|
err=True,
|
|
@@ -38,10 +38,6 @@ TEST_DATABASE = 'mycli_test_db'
|
|
|
38
38
|
DEFAULT_WIDTH = 80
|
|
39
39
|
DEFAULT_HEIGHT = 25
|
|
40
40
|
|
|
41
|
-
# MySQL error codes not available in pymysql.constants.ER
|
|
42
|
-
ER_MUST_CHANGE_PASSWORD_LOGIN = 1862
|
|
43
|
-
ER_MUST_CHANGE_PASSWORD = 1820
|
|
44
|
-
|
|
45
41
|
EMPTY_PASSWORD_FLAG_SENTINEL = -1
|
|
46
42
|
DEFAULT_PROMPT = "\\t \\u@\\h:\\d> "
|
|
47
43
|
|
|
@@ -49,6 +49,7 @@ from pymysql.constants.CR import (
|
|
|
49
49
|
CR_SERVER_GONE_ERROR,
|
|
50
50
|
CR_SERVER_LOST,
|
|
51
51
|
)
|
|
52
|
+
from pymysql.constants.ER import MUST_CHANGE_PASSWORD
|
|
52
53
|
from pymysql.constants.SERVER_STATUS import SERVER_STATUS_IN_TRANS
|
|
53
54
|
from pymysql.cursors import Cursor
|
|
54
55
|
|
|
@@ -57,7 +58,6 @@ from mycli.compat import WIN
|
|
|
57
58
|
from mycli.constants import (
|
|
58
59
|
DEFAULT_HOST,
|
|
59
60
|
DEFAULT_WIDTH,
|
|
60
|
-
ER_MUST_CHANGE_PASSWORD,
|
|
61
61
|
HOME_URL,
|
|
62
62
|
ISSUES_URL,
|
|
63
63
|
QueryState,
|
|
@@ -1110,7 +1110,7 @@ def _one_iteration(
|
|
|
1110
1110
|
mycli.echo(str(exc), err=True, fg='red')
|
|
1111
1111
|
except pymysql.OperationalError as e1:
|
|
1112
1112
|
mycli.logger.debug('Exception: %r', e1)
|
|
1113
|
-
if e1.args[0] ==
|
|
1113
|
+
if e1.args[0] == MUST_CHANGE_PASSWORD:
|
|
1114
1114
|
mycli.sandbox_mode = True
|
|
1115
1115
|
mycli.echo(
|
|
1116
1116
|
"ERROR 1820: You must reset your password using ALTER USER or SET PASSWORD before executing this statement.",
|
|
@@ -12,10 +12,10 @@ import pymysql
|
|
|
12
12
|
from pymysql.connections import Connection
|
|
13
13
|
from pymysql.constants import FIELD_TYPE
|
|
14
14
|
from pymysql.constants.CR import CR_SSL_CONNECTION_ERROR
|
|
15
|
+
from pymysql.constants.ER import MUST_CHANGE_PASSWORD
|
|
15
16
|
from pymysql.converters import conversions, convert_date, convert_datetime, convert_time, decoders
|
|
16
17
|
from pymysql.cursors import Cursor, SSCursor
|
|
17
18
|
|
|
18
|
-
from mycli.constants import ER_MUST_CHANGE_PASSWORD
|
|
19
19
|
from mycli.packages.execution.background_runner import BackgroundRunner
|
|
20
20
|
from mycli.packages.special_commands import io_commands
|
|
21
21
|
from mycli.packages.special_commands.main import CommandNotFound, execute
|
|
@@ -296,9 +296,9 @@ class SQLExecute:
|
|
|
296
296
|
connect_kwargs['ssl_disabled'] = True
|
|
297
297
|
conn = pymysql.connect(**connect_kwargs) # type: ignore[misc]
|
|
298
298
|
except pymysql.OperationalError as e:
|
|
299
|
-
if e.args[0] ==
|
|
299
|
+
if e.args[0] == MUST_CHANGE_PASSWORD:
|
|
300
300
|
# Post-handshake queries (SET NAMES, SET AUTOCOMMIT, init_command)
|
|
301
|
-
# fail with
|
|
301
|
+
# fail with MUST_CHANGE_PASSWORD in sandbox mode.
|
|
302
302
|
# Reconnect with only the raw handshake.
|
|
303
303
|
connect_kwargs['defer_connect'] = True
|
|
304
304
|
connect_kwargs['autocommit'] = None
|
|
@@ -659,7 +659,7 @@ class SQLExecute:
|
|
|
659
659
|
"""Connect in sandbox mode, performing only the handshake.
|
|
660
660
|
|
|
661
661
|
pymysql's normal connect() runs post-handshake queries (SET NAMES,
|
|
662
|
-
SET AUTOCOMMIT, init_command) that all fail with
|
|
662
|
+
SET AUTOCOMMIT, init_command) that all fail with MUST_CHANGE_PASSWORD
|
|
663
663
|
in sandbox mode. This method performs the raw socket connection and
|
|
664
664
|
authentication handshake only.
|
|
665
665
|
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mycli
|
|
3
|
-
Version: 2.30.
|
|
3
|
+
Version: 2.30.4
|
|
4
4
|
Summary: Rich MySQL terminal client with autocompletion, syntax highlighting, and dataframes
|
|
5
5
|
Author: Mycli Core Team
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -33,13 +33,13 @@ Requires-Dist: clickdc~=0.1.1
|
|
|
33
33
|
Requires-Dist: cryptography~=50.0.2
|
|
34
34
|
Requires-Dist: Pygments~=2.21.0
|
|
35
35
|
Requires-Dist: prompt_toolkit~=3.0.53
|
|
36
|
-
Requires-Dist: PyMySQL~=1.2.
|
|
37
|
-
Requires-Dist: sqlparse~=0.6.
|
|
38
|
-
Requires-Dist: sqlglot~=30.
|
|
39
|
-
Requires-Dist: sqlglotc~=30.
|
|
36
|
+
Requires-Dist: PyMySQL~=1.2.4
|
|
37
|
+
Requires-Dist: sqlparse~=0.6.1
|
|
38
|
+
Requires-Dist: sqlglot~=30.25.0
|
|
39
|
+
Requires-Dist: sqlglotc~=30.25.0
|
|
40
40
|
Requires-Dist: configobj~=5.0.9
|
|
41
41
|
Requires-Dist: cli_helpers[styles]~=2.15.3
|
|
42
|
-
Requires-Dist: wcwidth~=0.9.
|
|
42
|
+
Requires-Dist: wcwidth~=0.9.4
|
|
43
43
|
Requires-Dist: pyperclip~=1.11.0
|
|
44
44
|
Requires-Dist: pycryptodomex~=3.24.1
|
|
45
45
|
Requires-Dist: rapidfuzz~=3.14.6
|
|
@@ -48,26 +48,26 @@ Requires-Dist: jinja2~=3.1.6
|
|
|
48
48
|
Requires-Dist: markupsafe~=3.0.4
|
|
49
49
|
Requires-Dist: yaspin~=3.5.1
|
|
50
50
|
Provides-Extra: llm
|
|
51
|
-
Requires-Dist: llm~=0.
|
|
51
|
+
Requires-Dist: llm~=0.37.1; extra == "llm"
|
|
52
52
|
Requires-Dist: setuptools==84.*; extra == "llm"
|
|
53
|
-
Requires-Dist: pip~=26.
|
|
53
|
+
Requires-Dist: pip~=26.3; extra == "llm"
|
|
54
54
|
Provides-Extra: dataframe
|
|
55
|
-
Requires-Dist: polars~=2.
|
|
55
|
+
Requires-Dist: polars~=2.1.0; extra == "dataframe"
|
|
56
56
|
Requires-Dist: altair~=6.3.0; extra == "dataframe"
|
|
57
57
|
Requires-Dist: vl-convert-python~=1.9.0; extra == "dataframe"
|
|
58
58
|
Provides-Extra: all
|
|
59
59
|
Requires-Dist: mycli[dataframe,llm]; extra == "all"
|
|
60
60
|
Provides-Extra: dev
|
|
61
61
|
Requires-Dist: behave~=1.3.3; extra == "dev"
|
|
62
|
-
Requires-Dist: coverage~=7.
|
|
63
|
-
Requires-Dist: mypy~=2.4.
|
|
62
|
+
Requires-Dist: coverage~=7.17.2; extra == "dev"
|
|
63
|
+
Requires-Dist: mypy~=2.4.1; extra == "dev"
|
|
64
64
|
Requires-Dist: pexpect~=4.9.0; extra == "dev"
|
|
65
|
-
Requires-Dist: pytest~=9.
|
|
65
|
+
Requires-Dist: pytest~=9.2.0; extra == "dev"
|
|
66
66
|
Requires-Dist: pytest-cov~=7.1.0; extra == "dev"
|
|
67
67
|
Requires-Dist: pytest-random-order~=1.2.0; extra == "dev"
|
|
68
|
-
Requires-Dist: tox~=4.
|
|
68
|
+
Requires-Dist: tox~=4.67.1; extra == "dev"
|
|
69
69
|
Requires-Dist: pdbpp~=0.12.1; extra == "dev"
|
|
70
|
-
Requires-Dist: ruff~=0.17.
|
|
70
|
+
Requires-Dist: ruff~=0.17.3; extra == "dev"
|
|
71
71
|
Dynamic: license-file
|
|
72
72
|
|
|
73
73
|
# mycli
|
|
@@ -216,6 +216,7 @@ mycli_test/pytests/test_special_main.py
|
|
|
216
216
|
mycli_test/pytests/test_special_source.py
|
|
217
217
|
mycli_test/pytests/test_special_utils.py
|
|
218
218
|
mycli_test/pytests/test_sql_execute.py
|
|
219
|
+
mycli_test/pytests/test_sql_format.py
|
|
219
220
|
mycli_test/pytests/test_sql_utils.py
|
|
220
221
|
mycli_test/pytests/test_sqlcompleter.py
|
|
221
222
|
mycli_test/pytests/test_sqlresult.py
|
|
@@ -3,13 +3,13 @@ clickdc~=0.1.1
|
|
|
3
3
|
cryptography~=50.0.2
|
|
4
4
|
Pygments~=2.21.0
|
|
5
5
|
prompt_toolkit~=3.0.53
|
|
6
|
-
PyMySQL~=1.2.
|
|
7
|
-
sqlparse~=0.6.
|
|
8
|
-
sqlglot~=30.
|
|
9
|
-
sqlglotc~=30.
|
|
6
|
+
PyMySQL~=1.2.4
|
|
7
|
+
sqlparse~=0.6.1
|
|
8
|
+
sqlglot~=30.25.0
|
|
9
|
+
sqlglotc~=30.25.0
|
|
10
10
|
configobj~=5.0.9
|
|
11
11
|
cli_helpers[styles]~=2.15.3
|
|
12
|
-
wcwidth~=0.9.
|
|
12
|
+
wcwidth~=0.9.4
|
|
13
13
|
pyperclip~=1.11.0
|
|
14
14
|
pycryptodomex~=3.24.1
|
|
15
15
|
rapidfuzz~=3.14.6
|
|
@@ -22,23 +22,23 @@ yaspin~=3.5.1
|
|
|
22
22
|
mycli[dataframe,llm]
|
|
23
23
|
|
|
24
24
|
[dataframe]
|
|
25
|
-
polars~=2.
|
|
25
|
+
polars~=2.1.0
|
|
26
26
|
altair~=6.3.0
|
|
27
27
|
vl-convert-python~=1.9.0
|
|
28
28
|
|
|
29
29
|
[dev]
|
|
30
30
|
behave~=1.3.3
|
|
31
|
-
coverage~=7.
|
|
32
|
-
mypy~=2.4.
|
|
31
|
+
coverage~=7.17.2
|
|
32
|
+
mypy~=2.4.1
|
|
33
33
|
pexpect~=4.9.0
|
|
34
|
-
pytest~=9.
|
|
34
|
+
pytest~=9.2.0
|
|
35
35
|
pytest-cov~=7.1.0
|
|
36
36
|
pytest-random-order~=1.2.0
|
|
37
|
-
tox~=4.
|
|
37
|
+
tox~=4.67.1
|
|
38
38
|
pdbpp~=0.12.1
|
|
39
|
-
ruff~=0.17.
|
|
39
|
+
ruff~=0.17.3
|
|
40
40
|
|
|
41
41
|
[llm]
|
|
42
|
-
llm~=0.
|
|
42
|
+
llm~=0.37.1
|
|
43
43
|
setuptools==84.*
|
|
44
|
-
pip~=26.
|
|
44
|
+
pip~=26.3
|
|
@@ -208,6 +208,7 @@
|
|
|
208
208
|
"mycli_test/pytests/test_special_source.py",
|
|
209
209
|
"mycli_test/pytests/test_special_utils.py",
|
|
210
210
|
"mycli_test/pytests/test_sql_execute.py",
|
|
211
|
+
"mycli_test/pytests/test_sql_format.py",
|
|
211
212
|
"mycli_test/pytests/test_sql_utils.py",
|
|
212
213
|
"mycli_test/pytests/test_sqlcompleter.py",
|
|
213
214
|
"mycli_test/pytests/test_sqlresult.py",
|
|
@@ -93,6 +93,46 @@ def test_expand_dsn_alias_env_var_returns_none() -> None:
|
|
|
93
93
|
assert cli_runner.expand_dsn_alias_env_var(None, 'prod') is None
|
|
94
94
|
|
|
95
95
|
|
|
96
|
+
@pytest.mark.parametrize('expand_env', (False, True))
|
|
97
|
+
@pytest.mark.parametrize(
|
|
98
|
+
('path', 'expected'),
|
|
99
|
+
(
|
|
100
|
+
('sales%20data', 'sales data'),
|
|
101
|
+
('caf%C3%A9', 'café'),
|
|
102
|
+
('rate%25', 'rate%'),
|
|
103
|
+
('rate%2520', 'rate%20'),
|
|
104
|
+
('sales+data', 'sales+data'),
|
|
105
|
+
),
|
|
106
|
+
)
|
|
107
|
+
def test_run_from_cli_args_decodes_dsn_database(monkeypatch: pytest.MonkeyPatch, expand_env: bool, path: str, expected: str) -> None:
|
|
108
|
+
cli_args = make_cli_args()
|
|
109
|
+
uri = f'mysql://user@host/{path}'
|
|
110
|
+
config = default_config()
|
|
111
|
+
cli_args.dsn = 'prod' if expand_env else uri
|
|
112
|
+
config['main']['expand_dsn_alias_env_vars'] = str(expand_env)
|
|
113
|
+
config['alias_dsn'] = {'prod': uri}
|
|
114
|
+
client = DummyMyCli(config=config)
|
|
115
|
+
|
|
116
|
+
run_with_client(monkeypatch, cli_args, client)
|
|
117
|
+
|
|
118
|
+
assert client.connect_calls[-1]['database'] == expected
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@pytest.mark.parametrize('path', ('${MYCLI_TEST_DSN_DATABASE}', '%24%7BMYCLI_TEST_DSN_DATABASE%7D'))
|
|
122
|
+
def test_run_from_cli_args_preserves_literal_database_env_value(monkeypatch: pytest.MonkeyPatch, path: str) -> None:
|
|
123
|
+
monkeypatch.setenv('MYCLI_TEST_DSN_DATABASE', 'sales%20data')
|
|
124
|
+
cli_args = make_cli_args()
|
|
125
|
+
cli_args.dsn = 'prod'
|
|
126
|
+
config = default_config()
|
|
127
|
+
config['main']['expand_dsn_alias_env_vars'] = 'true'
|
|
128
|
+
config['alias_dsn'] = {'prod': f'mysql://user@host/{path}'}
|
|
129
|
+
client = DummyMyCli(config=config)
|
|
130
|
+
|
|
131
|
+
run_with_client(monkeypatch, cli_args, client)
|
|
132
|
+
|
|
133
|
+
assert client.connect_calls[-1]['database'] == 'sales%20data'
|
|
134
|
+
|
|
135
|
+
|
|
96
136
|
def test_split_dsn_netloc_handles_user_without_password() -> None:
|
|
97
137
|
assert cli_runner.split_dsn_netloc('user@host:3306') == ('user', None, 'host', '3306')
|
|
98
138
|
|
|
@@ -8,11 +8,12 @@ from typing import Any, Literal, cast
|
|
|
8
8
|
|
|
9
9
|
from configobj import ConfigObj
|
|
10
10
|
import pymysql
|
|
11
|
+
from pymysql.constants.ER import MUST_CHANGE_PASSWORD_LOGIN
|
|
11
12
|
import pytest
|
|
12
13
|
|
|
13
14
|
from mycli import client_connection
|
|
14
15
|
from mycli.client_connection import ClientConnectionMixin
|
|
15
|
-
from mycli.constants import DEFAULT_CHARSET, EMPTY_PASSWORD_FLAG_SENTINEL
|
|
16
|
+
from mycli.constants import DEFAULT_CHARSET, EMPTY_PASSWORD_FLAG_SENTINEL
|
|
16
17
|
from mycli.packages.credentials.password_sources import KNOWN_PASSWORD_SOURCES, PasswordCandidates
|
|
17
18
|
|
|
18
19
|
|
|
@@ -1304,7 +1305,7 @@ def test_connect_exits_when_password_retry_still_has_no_password(monkeypatch: py
|
|
|
1304
1305
|
|
|
1305
1306
|
def test_connect_reports_expired_password_login_error() -> None:
|
|
1306
1307
|
client = DummyClient()
|
|
1307
|
-
FakeSQLExecute.effects = [op_error(
|
|
1308
|
+
FakeSQLExecute.effects = [op_error(MUST_CHANGE_PASSWORD_LOGIN, 'expired')]
|
|
1308
1309
|
|
|
1309
1310
|
with pytest.raises(SystemExit) as excinfo:
|
|
1310
1311
|
client.connect(host='db', port=3307)
|
|
@@ -25,6 +25,7 @@ from prompt_toolkit.formatted_text import (
|
|
|
25
25
|
to_plain_text,
|
|
26
26
|
)
|
|
27
27
|
import pymysql
|
|
28
|
+
from pymysql.constants.ER import MUST_CHANGE_PASSWORD_LOGIN
|
|
28
29
|
from pymysql.err import OperationalError
|
|
29
30
|
import pytest
|
|
30
31
|
|
|
@@ -40,7 +41,6 @@ from mycli.constants import (
|
|
|
40
41
|
DEFAULT_PORT,
|
|
41
42
|
DEFAULT_USER,
|
|
42
43
|
EMPTY_PASSWORD_FLAG_SENTINEL,
|
|
43
|
-
ER_MUST_CHANGE_PASSWORD_LOGIN,
|
|
44
44
|
TEST_DATABASE,
|
|
45
45
|
)
|
|
46
46
|
from mycli.main import (
|
|
@@ -2386,7 +2386,7 @@ def test_connect_reports_expired_password_login_error(monkeypatch: pytest.Monkey
|
|
|
2386
2386
|
|
|
2387
2387
|
class ExpiredPasswordSQLExecute(RecordingSQLExecute):
|
|
2388
2388
|
calls: list[dict[str, Any]] = []
|
|
2389
|
-
side_effects: list[Any] = [pymysql.OperationalError(
|
|
2389
|
+
side_effects: list[Any] = [pymysql.OperationalError(MUST_CHANGE_PASSWORD_LOGIN, 'must change password')]
|
|
2390
2390
|
|
|
2391
2391
|
monkeypatch.setattr(mycli.client_connection, 'SQLExecute', ExpiredPasswordSQLExecute)
|
|
2392
2392
|
|
|
@@ -2238,7 +2238,7 @@ def test_one_iteration_enters_sandbox_mode_on_must_change_password_error(monkeyp
|
|
|
2238
2238
|
connection_id = 0
|
|
2239
2239
|
|
|
2240
2240
|
def run(self, text: str) -> Iterator[SQLResult]:
|
|
2241
|
-
raise pymysql.OperationalError(repl_mode.
|
|
2241
|
+
raise pymysql.OperationalError(repl_mode.MUST_CHANGE_PASSWORD, 'must change password')
|
|
2242
2242
|
|
|
2243
2243
|
cli = make_repl_cli(FakeSQLExecute())
|
|
2244
2244
|
|