mycli 2.29.6__tar.gz → 2.30.1__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.
Files changed (231) hide show
  1. {mycli-2.29.6 → mycli-2.30.1}/.github/workflows/ci.yml +5 -5
  2. {mycli-2.29.6 → mycli-2.30.1}/.github/workflows/publish.yml +5 -5
  3. {mycli-2.29.6/mycli.egg-info → mycli-2.30.1}/PKG-INFO +5 -5
  4. {mycli-2.29.6 → mycli-2.30.1}/changelog.md +37 -0
  5. mycli-2.30.1/doc/key_bindings.md +155 -0
  6. {mycli-2.29.6 → mycli-2.30.1}/doc/transforms.md +12 -11
  7. {mycli-2.29.6 → mycli-2.30.1}/docker/Dockerfile +2 -1
  8. mycli-2.30.1/docker/resources/dot_mycli_history.txt +26 -0
  9. {mycli-2.29.6 → mycli-2.30.1}/docker/resources/test_db-1.0.7.tar.gz +1 -1
  10. {mycli-2.29.6 → mycli-2.30.1}/mycli/cli_runner.py +30 -24
  11. {mycli-2.29.6 → mycli-2.30.1}/mycli/client.py +6 -9
  12. {mycli-2.29.6 → mycli-2.30.1}/mycli/config.py +18 -0
  13. {mycli-2.29.6 → mycli-2.30.1}/mycli/main.py +1 -2
  14. {mycli-2.29.6 → mycli-2.30.1}/mycli/main_modes/list_dsn.py +11 -8
  15. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/execution/sql_execute.py +1 -1
  16. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/special_commands/dsn_aliases.py +3 -38
  17. mycli-2.30.1/mycli/packages/utils/dsn_utils.py +37 -0
  18. {mycli-2.29.6 → mycli-2.30.1/mycli.egg-info}/PKG-INFO +5 -5
  19. {mycli-2.29.6 → mycli-2.30.1}/mycli.egg-info/SOURCES.txt +2 -0
  20. {mycli-2.29.6 → mycli-2.30.1}/mycli.egg-info/requires.txt +4 -4
  21. {mycli-2.29.6 → mycli-2.30.1}/mycli.egg-info/scm_file_list.json +2 -0
  22. mycli-2.30.1/mycli.egg-info/scm_version.json +8 -0
  23. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_cli_runner.py +8 -6
  24. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_client_query.py +20 -19
  25. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_dsn_aliases.py +8 -7
  26. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_main.py +36 -34
  27. mycli-2.30.1/mycli_test/pytests/test_main_modes_list_dsn.py +291 -0
  28. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_sql_execute.py +16 -0
  29. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_tabular_output.py +1 -1
  30. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/utils.py +3 -2
  31. {mycli-2.29.6 → mycli-2.30.1}/pyproject.toml +6 -7
  32. mycli-2.29.6/doc/key_bindings.md +0 -75
  33. mycli-2.29.6/mycli.egg-info/scm_version.json +0 -8
  34. mycli-2.29.6/mycli_test/pytests/test_main_modes_list_dsn.py +0 -112
  35. {mycli-2.29.6 → mycli-2.30.1}/.git-blame-ignore-revs +0 -0
  36. {mycli-2.29.6 → mycli-2.30.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  37. {mycli-2.29.6 → mycli-2.30.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  38. {mycli-2.29.6 → mycli-2.30.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  39. {mycli-2.29.6 → mycli-2.30.1}/.github/actions/lint/action.yml +0 -0
  40. {mycli-2.29.6 → mycli-2.30.1}/.github/actions/typecheck/action.yml +0 -0
  41. {mycli-2.29.6 → mycli-2.30.1}/.github/dependabot.yml +0 -0
  42. {mycli-2.29.6 → mycli-2.30.1}/.github/workflows/lint.yml +0 -0
  43. {mycli-2.29.6 → mycli-2.30.1}/.github/workflows/typecheck.yml +0 -0
  44. {mycli-2.29.6 → mycli-2.30.1}/.gitignore +0 -0
  45. {mycli-2.29.6 → mycli-2.30.1}/AGENTS.md +0 -0
  46. {mycli-2.29.6 → mycli-2.30.1}/AUTHORS.md +0 -0
  47. {mycli-2.29.6 → mycli-2.30.1}/CONTRIBUTING.md +0 -0
  48. {mycli-2.29.6 → mycli-2.30.1}/LICENSE.txt +0 -0
  49. {mycli-2.29.6 → mycli-2.30.1}/MANIFEST.in +0 -0
  50. {mycli-2.29.6 → mycli-2.30.1}/README.md +0 -0
  51. {mycli-2.29.6 → mycli-2.30.1}/SPONSORS.md +0 -0
  52. {mycli-2.29.6 → mycli-2.30.1}/doc/cookbook.md +0 -0
  53. {mycli-2.29.6 → mycli-2.30.1}/doc/known_bugs.md +0 -0
  54. {mycli-2.29.6 → mycli-2.30.1}/doc/llm.md +0 -0
  55. {mycli-2.29.6 → mycli-2.30.1}/doc/screenshots/main.gif +0 -0
  56. {mycli-2.29.6 → mycli-2.30.1}/doc/screenshots/polars_describe.png +0 -0
  57. {mycli-2.29.6 → mycli-2.30.1}/doc/screenshots/polars_group_by.png +0 -0
  58. {mycli-2.29.6 → mycli-2.30.1}/doc/screenshots/polars_histogram.png +0 -0
  59. {mycli-2.29.6 → mycli-2.30.1}/doc/screenshots/polars_pivot.png +0 -0
  60. {mycli-2.29.6 → mycli-2.30.1}/doc/screenshots/tables.png +0 -0
  61. {mycli-2.29.6 → mycli-2.30.1}/docker/resources/test_db_license.md +0 -0
  62. {mycli-2.29.6 → mycli-2.30.1}/mycli/AUTHORS.txt +0 -0
  63. {mycli-2.29.6 → mycli-2.30.1}/mycli/SPONSORS.txt +0 -0
  64. {mycli-2.29.6 → mycli-2.30.1}/mycli/TIPS.txt +0 -0
  65. {mycli-2.29.6 → mycli-2.30.1}/mycli/__init__.py +0 -0
  66. {mycli-2.29.6 → mycli-2.30.1}/mycli/app_state.py +0 -0
  67. {mycli-2.29.6 → mycli-2.30.1}/mycli/client_commands.py +0 -0
  68. {mycli-2.29.6 → mycli-2.30.1}/mycli/client_connection.py +0 -0
  69. {mycli-2.29.6 → mycli-2.30.1}/mycli/client_query.py +0 -0
  70. {mycli-2.29.6 → mycli-2.30.1}/mycli/compat.py +0 -0
  71. {mycli-2.29.6 → mycli-2.30.1}/mycli/constants.py +0 -0
  72. {mycli-2.29.6 → mycli-2.30.1}/mycli/main_modes/batch.py +0 -0
  73. {mycli-2.29.6 → mycli-2.30.1}/mycli/main_modes/checkup.py +0 -0
  74. {mycli-2.29.6 → mycli-2.30.1}/mycli/main_modes/completions.py +0 -0
  75. {mycli-2.29.6 → mycli-2.30.1}/mycli/main_modes/execute.py +0 -0
  76. {mycli-2.29.6 → mycli-2.30.1}/mycli/main_modes/repl.py +0 -0
  77. {mycli-2.29.6 → mycli-2.30.1}/mycli/myclirc +0 -0
  78. {mycli-2.29.6 → mycli-2.30.1}/mycli/output.py +0 -0
  79. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/__init__.py +0 -0
  80. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/completion/__init__.py +0 -0
  81. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/completion/completion_engine.py +0 -0
  82. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/completion/completion_refresher.py +0 -0
  83. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/completion/schema_prefetcher.py +0 -0
  84. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/completion/sql_completer.py +0 -0
  85. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/credentials/__init__.py +0 -0
  86. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/credentials/password_sources.py +0 -0
  87. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/dataframes/__init__.py +0 -0
  88. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/dataframes/completion.py +0 -0
  89. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/dataframes/transform.py +0 -0
  90. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/execution/__init__.py +0 -0
  91. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/execution/background_runner.py +0 -0
  92. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/integrations/__init__.py +0 -0
  93. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/integrations/boundary/__init__.py +0 -0
  94. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/integrations/boundary/boundary_tunnel.py +0 -0
  95. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/integrations/fzf/__init__.py +0 -0
  96. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/integrations/fzf/fzf.py +0 -0
  97. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/integrations/kubernetes/__init__.py +0 -0
  98. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/integrations/kubernetes/kubectl_tunnel.py +0 -0
  99. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/integrations/macos/__init__.py +0 -0
  100. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/integrations/macos/macos_keychain.py +0 -0
  101. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/integrations/openssh/__init__.py +0 -0
  102. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/integrations/openssh/ssh_tunnel.py +0 -0
  103. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/integrations/vault/__init__.py +0 -0
  104. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/integrations/vault/vault_credentials.py +0 -0
  105. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/prompt_toolkit/__init__.py +0 -0
  106. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/prompt_toolkit/fzf_history.py +0 -0
  107. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/prompt_toolkit/history.py +0 -0
  108. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/prompt_toolkit/key_bindings.py +0 -0
  109. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/prompt_toolkit/multiline.py +0 -0
  110. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/prompt_toolkit/style.py +0 -0
  111. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/prompt_toolkit/toolbar.py +0 -0
  112. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/prompt_toolkit/utils.py +0 -0
  113. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/pygments/__init__.py +0 -0
  114. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/pygments/mycli_lexer.py +0 -0
  115. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/redirection/__init__.py +0 -0
  116. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/redirection/hybrid_redirection.py +0 -0
  117. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/special_commands/__init__.py +0 -0
  118. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/special_commands/db_commands.py +0 -0
  119. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/special_commands/delimiter_command.py +0 -0
  120. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/special_commands/favorite_queries.py +0 -0
  121. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/special_commands/io_commands.py +0 -0
  122. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/special_commands/llm.py +0 -0
  123. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/special_commands/main.py +0 -0
  124. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/special_commands/source.py +0 -0
  125. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/special_commands/special_command_utils.py +0 -0
  126. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/sql_result/__init__.py +0 -0
  127. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/sql_result/sql_result.py +0 -0
  128. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/tabular_output/__init__.py +0 -0
  129. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/tabular_output/sql_format.py +0 -0
  130. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/utils/__init__.py +0 -0
  131. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/utils/batch_utils.py +0 -0
  132. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/utils/cli_utils.py +0 -0
  133. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/utils/interactive_utils.py +0 -0
  134. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/utils/key_binding_utils.py +0 -0
  135. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/utils/keyring_utils.py +0 -0
  136. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/utils/path_utils.py +0 -0
  137. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/utils/sql_utils.py +0 -0
  138. {mycli-2.29.6 → mycli-2.30.1}/mycli/packages/utils/string_utils.py +0 -0
  139. {mycli-2.29.6 → mycli-2.30.1}/mycli/resources/completions/bash/mycli +0 -0
  140. {mycli-2.29.6 → mycli-2.30.1}/mycli/resources/completions/fish/mycli.fish +0 -0
  141. {mycli-2.29.6 → mycli-2.30.1}/mycli/resources/completions/zsh/_mycli +0 -0
  142. {mycli-2.29.6 → mycli-2.30.1}/mycli/types.py +0 -0
  143. {mycli-2.29.6 → mycli-2.30.1}/mycli.egg-info/dependency_links.txt +0 -0
  144. {mycli-2.29.6 → mycli-2.30.1}/mycli.egg-info/entry_points.txt +0 -0
  145. {mycli-2.29.6 → mycli-2.30.1}/mycli.egg-info/top_level.txt +0 -0
  146. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/__init__.py +0 -0
  147. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/__init__.py +0 -0
  148. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/auto_vertical.feature +0 -0
  149. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/basic_commands.feature +0 -0
  150. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/connection.feature +0 -0
  151. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/crud_database.feature +0 -0
  152. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/crud_table.feature +0 -0
  153. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/db_utils.py +0 -0
  154. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/environment.py +0 -0
  155. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/fixture_data/help_commands.txt +0 -0
  156. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/fixture_utils.py +0 -0
  157. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/iocommands.feature +0 -0
  158. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/named_queries.feature +0 -0
  159. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/specials.feature +0 -0
  160. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/steps/__init__.py +0 -0
  161. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/steps/auto_vertical.py +0 -0
  162. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/steps/basic_commands.py +0 -0
  163. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/steps/connection.py +0 -0
  164. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/steps/crud_database.py +0 -0
  165. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/steps/crud_table.py +0 -0
  166. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/steps/iocommands.py +0 -0
  167. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/steps/named_queries.py +0 -0
  168. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/steps/specials.py +0 -0
  169. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/steps/utils.py +0 -0
  170. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/steps/wrappers.py +0 -0
  171. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/features/wrappager.py +0 -0
  172. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/myclirc +0 -0
  173. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/mylogin.cnf +0 -0
  174. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/conftest.py +0 -0
  175. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_app_state.py +0 -0
  176. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_background_runner.py +0 -0
  177. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_bash_completion.py +0 -0
  178. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_batch_utils.py +0 -0
  179. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_boundary_tunnel.py +0 -0
  180. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_checkup.py +0 -0
  181. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_cli_utils.py +0 -0
  182. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_clibuffer.py +0 -0
  183. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_client.py +0 -0
  184. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_client_commands.py +0 -0
  185. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_client_connection.py +0 -0
  186. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_completer_use_switch.py +0 -0
  187. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_completion_engine.py +0 -0
  188. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_completion_refresher.py +0 -0
  189. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_config.py +0 -0
  190. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_delimitercommand.py +0 -0
  191. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_favoritequeries.py +0 -0
  192. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_fish_completion.py +0 -0
  193. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_fzf.py +0 -0
  194. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_hybrid_redirection.py +0 -0
  195. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_interactive_utils.py +0 -0
  196. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_key_binding_utils.py +0 -0
  197. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_key_bindings.py +0 -0
  198. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_keyring_utils.py +0 -0
  199. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_kubectl_tunnel.py +0 -0
  200. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_macos_keychain.py +0 -0
  201. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_main_modes_batch.py +0 -0
  202. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_main_modes_execute.py +0 -0
  203. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_main_modes_repl.py +0 -0
  204. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_naive_completion.py +0 -0
  205. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_output.py +0 -0
  206. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_password_sources.py +0 -0
  207. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_path_utils.py +0 -0
  208. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_polars_completion.py +0 -0
  209. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_polars_transform.py +0 -0
  210. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_prompt_toolkit_fzf_history.py +0 -0
  211. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_prompt_toolkit_history.py +0 -0
  212. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_prompt_toolkit_style.py +0 -0
  213. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_prompt_toolkit_toolbar.py +0 -0
  214. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_prompt_toolkit_utils.py +0 -0
  215. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_schema_prefetcher.py +0 -0
  216. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_smart_completion_public_schema_only.py +0 -0
  217. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_special_commands_init.py +0 -0
  218. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_special_db_commands.py +0 -0
  219. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_special_io_commands.py +0 -0
  220. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_special_llm.py +0 -0
  221. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_special_main.py +0 -0
  222. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_special_source.py +0 -0
  223. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_special_utils.py +0 -0
  224. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_sql_utils.py +0 -0
  225. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_sqlcompleter.py +0 -0
  226. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_sqlresult.py +0 -0
  227. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_ssh_tunnel.py +0 -0
  228. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_string_utils.py +0 -0
  229. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_vault.py +0 -0
  230. {mycli-2.29.6 → mycli-2.30.1}/mycli_test/pytests/test_zsh_completion.py +0 -0
  231. {mycli-2.29.6 → mycli-2.30.1}/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@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
27
+ - uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
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@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
69
+ - uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
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@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
119
+ - uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
120
120
  with:
121
121
  version: 'latest'
122
122
 
@@ -148,7 +148,7 @@ jobs:
148
148
  runs-on: windows-latest
149
149
 
150
150
  steps:
151
- - uses: vampire/setup-wsl@d1da7f2c0322a5ee4f24975344f67fc0f5baf364 # v7.0.0
151
+ - uses: vampire/setup-wsl@4c48163d9f981914dd8caa0fc335fe19cca5bff4 # v7.2.0
152
152
  with:
153
153
  distribution: Ubuntu-24.04
154
154
  use-cache: 'true'
@@ -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@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
223
+ - uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
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@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
54
+ - uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
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@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
96
+ - uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
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@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
147
+ - uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
148
148
  with:
149
149
  version: 'latest'
150
150
 
@@ -177,7 +177,7 @@ jobs:
177
177
  needs: [typecheck]
178
178
 
179
179
  steps:
180
- - uses: vampire/setup-wsl@d1da7f2c0322a5ee4f24975344f67fc0f5baf364 # v7.0.0
180
+ - uses: vampire/setup-wsl@4c48163d9f981914dd8caa0fc335fe19cca5bff4 # v7.2.0
181
181
  with:
182
182
  distribution: Ubuntu-24.04
183
183
  use-cache: 'true'
@@ -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@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
251
+ - uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
252
252
  with:
253
253
  version: "latest"
254
254
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mycli
3
- Version: 2.29.6
3
+ Version: 2.30.1
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
@@ -38,10 +38,10 @@ Requires-Dist: sqlparse~=0.6.0
38
38
  Requires-Dist: sqlglot~=30.23.0
39
39
  Requires-Dist: sqlglotc~=30.23.0
40
40
  Requires-Dist: configobj~=5.0.9
41
- Requires-Dist: cli_helpers[styles]~=2.15.1
41
+ Requires-Dist: cli_helpers[styles]~=2.15.2
42
42
  Requires-Dist: wcwidth~=0.9.2
43
43
  Requires-Dist: pyperclip~=1.11.0
44
- Requires-Dist: pycryptodomex~=3.24.0
44
+ Requires-Dist: pycryptodomex~=3.24.1
45
45
  Requires-Dist: rapidfuzz~=3.14.6
46
46
  Requires-Dist: keyring~=25.7.0
47
47
  Requires-Dist: jinja2~=3.1.6
@@ -50,7 +50,7 @@ Requires-Dist: yaspin~=3.5.1
50
50
  Provides-Extra: llm
51
51
  Requires-Dist: llm~=0.36; extra == "llm"
52
52
  Requires-Dist: setuptools==84.*; extra == "llm"
53
- Requires-Dist: pip~=26.2.1; extra == "llm"
53
+ Requires-Dist: pip~=26.2.2; extra == "llm"
54
54
  Provides-Extra: dataframe
55
55
  Requires-Dist: polars~=2.0.0; extra == "dataframe"
56
56
  Requires-Dist: altair~=6.3.0; extra == "dataframe"
@@ -67,7 +67,7 @@ Requires-Dist: pytest-cov~=7.1.0; extra == "dev"
67
67
  Requires-Dist: pytest-random-order~=1.2.0; extra == "dev"
68
68
  Requires-Dist: tox~=4.64.9; extra == "dev"
69
69
  Requires-Dist: pdbpp~=0.12.1; extra == "dev"
70
- Requires-Dist: ruff~=0.16.5; extra == "dev"
70
+ Requires-Dist: ruff~=0.17.0; extra == "dev"
71
71
  Dynamic: license-file
72
72
 
73
73
  # mycli
@@ -1,3 +1,40 @@
1
+ v2.30.1 (2026/10/24)
2
+ ==============
3
+
4
+ Internal
5
+ --------
6
+ * Update `pycryptodomex` to v3.24.1.
7
+ * Update `pip` LLM dependency to v26.2.2.
8
+
9
+
10
+ v2.30.0 (2026/10/17)
11
+ ==============
12
+
13
+ Features
14
+ --------
15
+ * Populate history file in Docker with examples.
16
+ * Faster dynamic completions via faster `--list-dsn`.
17
+
18
+
19
+ Bug Fixes
20
+ --------
21
+ * Show the username in the Docker prompt.
22
+ * Show the username in the prompt if a default user was used.
23
+
24
+
25
+ Documentation
26
+ --------
27
+ * Dataframe transforms are no longer experimental.
28
+ * Update key bindings doc.
29
+
30
+
31
+ Internal
32
+ --------
33
+ * Update `cli_helpers` to v2.15.2, improving vertical output.
34
+ * Update `ruff` to v0.17.0.
35
+ * Complete moving `MyCli` to `client.py`.
36
+
37
+
1
38
  v2.29.6 (2026/10/15)
2
39
  ==============
3
40
 
@@ -0,0 +1,155 @@
1
+ # Key Bindings
2
+
3
+ There are two major editing modes available: Emacs mode and Vi mode. The mode
4
+ can be changed via the `key_bindings` property in the config file (`~/.myclirc`) or
5
+ toggled via the <kbd>F4</kbd> key.
6
+
7
+ Emacs mode is the default. In Emacs mode you can type <kbd>Control-a</kbd> to go
8
+ to the beginning of a line, <kbd>Control-e</kbd> to go to the end of a line,
9
+ with many more options for navigation, similar to the defaults of the [readline](https://tiswww.case.edu/php/chet/readline/rluserman.html)
10
+ library.
11
+
12
+ When Vi mode is enabled you can use vi-style navigation, along with modal
13
+ editing features offered by Vim in the REPL, including text objects.
14
+
15
+ Most key bindings are simply inherited from [prompt-toolkit](https://python-prompt-toolkit.readthedocs.io/en/master/index.html).
16
+
17
+ Mycli also adds some custom keybindings which are summarized here along with
18
+ completion navigation.
19
+
20
+ ## The Basics: Custom Bindings and Completion Navigation
21
+
22
+ ### <kbd>F1</kbd>
23
+
24
+ Open the web documentation index in a browser tab.
25
+
26
+ ### <kbd>F2</kbd>
27
+
28
+ Toggle smart completions.
29
+
30
+ ### <kbd>F3</kbd>
31
+
32
+ Toggle multi-line mode.
33
+
34
+ ### <kbd>F4</kbd>
35
+
36
+ Toggle Emacs/Vi editing modes.
37
+
38
+ ### <kbd>Tab</kbd>
39
+
40
+ Summon completions + always advance in candidates (configurable).
41
+
42
+ ### <kbd>Control-Space</kbd>
43
+
44
+ Summon completions or advance in candidates if present (configurable).
45
+
46
+ ### <kbd>Enter</kbd>
47
+
48
+ Choose a completion candidate.
49
+
50
+ ### <kbd>Esc</kbd>
51
+
52
+ Cancel the completions popup.
53
+
54
+ ### <kbd>Control-g</kbd>
55
+
56
+ Cancel the completions popup.
57
+
58
+ ### <kbd>Control-r</kbd>
59
+
60
+ Search the query history with [fzf](https://github.com/junegunn/fzf) if available, or use
61
+ [prompt-toolkit](https://python-prompt-toolkit.readthedocs.io/en/master/index.html)'s
62
+ `reverse-i-search` as a fallback (configurable).
63
+
64
+ ### <kbd>Alt-Enter</kbd>
65
+
66
+ Introduce a line break in multi-line mode, or dispatch the current query in
67
+ single-line mode.
68
+
69
+ The keyboard combination <kbd>Alt-Enter</kbd> usually sends the sequence
70
+ `ESC`,`Enter` on the wire, and it may also be possible to use the <kbd>ESC</kbd>,<kbd>Enter</kbd>
71
+ key sequence.
72
+
73
+ ### Arrow keys
74
+
75
+ Completion navigation (when popup is present).
76
+
77
+ ### Right-arrow
78
+
79
+ Accept full-line history suggestion (when suggestion is visible).
80
+
81
+ ### <kbd>Control-d</kbd>
82
+
83
+ Exit the REPL (configurable).
84
+
85
+ ## In Emacs Mode Only
86
+
87
+ A comma indicates a sequence of multiple keystrokes.
88
+
89
+ ### <kbd>Control-x</kbd>, <kbd>p</kbd>
90
+
91
+ Prettify and indent the current statement, usually into multiple lines.
92
+
93
+ Only works for buffers containing single SQL statements.
94
+
95
+ ### <kbd>Control-x</kbd>, <kbd>u</kbd>
96
+
97
+ Unprettify and dedent the current statement, usually into one line.
98
+
99
+ Only works for buffers containing single SQL statements.
100
+
101
+ ### <kbd>Control-o</kbd>, <kbd>d</kbd>
102
+
103
+ Insert the current literal date at the cursor, as defined by `NOW()` on the
104
+ server.
105
+
106
+ ### <kbd>Control-o</kbd>, <kbd>t</kbd>
107
+
108
+ Insert the current literal datetime at the cursor, as defined by `NOW()` on
109
+ the server.
110
+
111
+ ### <kbd>Control-o</kbd>, <kbd>Control-d</kbd>
112
+
113
+ Insert the _quoted_ current literal date at the cursor, as defined by `NOW()`
114
+ on the server.
115
+
116
+ ### <kbd>Control-o</kbd>, <kbd>Control-t</kbd>
117
+
118
+ Insert the _quoted_ current literal datetime at the cursor, as defined by
119
+ `NOW()` on the server.
120
+
121
+ ### <kbd>Control-o</kbd>, <kbd>u</kbd>
122
+
123
+ Insert the current literal Unix timestamp at the cursor, in seconds, as defined
124
+ by `time.time()` on the client.
125
+
126
+ ### <kbd>Control-o</kbd>, <kbd>Control-u</kbd>
127
+
128
+ Insert the current literal Unix timestamp at the cursor, in microseconds, as
129
+ defined by `time.time()` on the client.
130
+
131
+ ### <kbd>Alt-r</kbd>
132
+
133
+ Search query history with [fzf](https://github.com/junegunn/fzf) even if `~/.myclirc`
134
+ is configured not to use fuzzy search on the default key <kbd>Control-r</kbd>.
135
+
136
+ ## Advanced
137
+
138
+ Since <kbd>Alt</kbd> key combinations usually work by sending a series of characters
139
+ on the wire, there is sometimes an ambiguity with regard to which characters were
140
+ physically typed. A timeout heuristic is used to resolve this.
141
+
142
+ Advanced users, and those on slow connections, may want to consult the following
143
+ settings in `~/.myclirc` to adjust the timeout heuristic. The threshold is separate
144
+ for Emacs and Vi edit modes:
145
+
146
+ ```ini
147
+ [keys]
148
+ # How long to wait for an Escape key sequence in vi mode.
149
+ # 0.5 seconds is the prompt_toolkit default, but vi users may find that too long.
150
+ # Shorter values mean that "Escape" alone is recognized more quickly.
151
+ vi_ttimeoutlen = 0.1
152
+
153
+ # How long to wait for an Escape key sequence in Emacs mode.
154
+ emacs_ttimeoutlen = 0.5
155
+ ```
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## Installing
4
4
 
5
+ ### Homebrew
6
+
7
+ No additional steps needed; Homebrew already comes with dataframe support.
8
+
9
+ ### pip
10
+
5
11
  Install mycli with dataframe support using:
6
12
 
7
13
  ```bash
@@ -14,18 +20,13 @@ or install these libraries separately:
14
20
  * [`altair`](https://pypi.org/project/altair/)
15
21
  * [`vl-convert-python`](https://pypi.org/project/vl-convert-python/)
16
22
 
17
- ## BETA STATUS
18
-
19
- Dataframe transforms and plots are new and experimental. The interface and
20
- functionality may still change.
21
-
22
- Here are some known limitations:
23
-
24
- * composing multiple transform operations is not supported
25
- * results from `UNION`s may be unable to be transformed
23
+ ## Limitations
26
24
 
27
- And there are inherent limitations to the post-processing model: the entire
28
- SQL result must be transferred from the server and loaded into local memory.
25
+ * composing multiple transform operations is not supported, though there is no
26
+ limitation on the code within one operation
27
+ * results from `UNION`s may not be able to be transformed
28
+ * the post-processing model means that the entire SQL result must be transferred
29
+ from the server and loaded into local memory
29
30
 
30
31
  ## Transforming
31
32
 
@@ -13,6 +13,7 @@ RUN apt-get update -qq && \
13
13
  rm -rf /var/lib/{apt,dpkg,cache,log}/
14
14
 
15
15
  COPY . /app
16
+ COPY docker/resources/dot_mycli_history.txt /root/.mycli-history
16
17
 
17
18
  RUN service mariadb restart && \
18
19
  cd /app/docker/resources && \
@@ -24,4 +25,4 @@ RUN service mariadb restart && \
24
25
 
25
26
  RUN cd /app && pip install --root-user-action=ignore -e .[llm,dataframe]
26
27
 
27
- CMD ["sh", "-c", "service mariadb start && mycli --database employees"]
28
+ CMD ["sh", "-c", "service mariadb start && mycli --user root --database employees"]
@@ -0,0 +1,26 @@
1
+ # 2026-10-08 07:35:11.242332
2
+ +SELECT MAX(salary) AS current_salary FROM salaries GROUP BY emp_no .| df['current_salary'].plot.hist();
3
+
4
+ # 2026-10-09 07:35:11.242332
5
+ +SELECT * FROM salaries .| df.group_by('emp_no').len(name='num_raises').with_columns(pl.col('num_raises') - 1);
6
+
7
+ # 2026-10-10 07:35:11.242332
8
+ +SELECT * FROM salaries LIMIT 10000 .| df.describe();
9
+
10
+ # 2026-10-11 07:35:11.242332
11
+ +SELECT employees.first_name, employees.last_name, MAX(salary) AS current_salary FROM salaries JOIN employees ON salaries.emp_no = employees.emp_no GROUP BY salaries.emp_no;
12
+
13
+ # 2026-10-12 07:35:11.242332
14
+ +SELECT salaries.emp_no, MAX(salary) AS current_salary FROM salaries JOIN employees ON salaries.emp_no = employees.emp_no GROUP BY salaries.emp_no;
15
+
16
+ # 2026-10-13 07:35:11.242332
17
+ +DESCRIBE employees;
18
+
19
+ # 2026-10-14 07:35:11.242332
20
+ +SELECT emp_no, MAX(salary) AS current_salary FROM salaries GROUP BY emp_no;
21
+
22
+ # 2026-10-15 07:35:11.242332
23
+ +SELECT emp_no, salary FROM salaries LIMIT 1000;
24
+
25
+ # 2026-10-16 07:35:11.242332
26
+ +DESCRIBE salaries;
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
- name: mycli-2.29.6/docker/resources/test_db-1.0.7.tar.gz
2
+ name: mycli-2.30.1/docker/resources/test_db-1.0.7.tar.gz
3
3
  size: 35607473 bytes
4
4
  sha256: c44c140f352f35d47fdb65df60f52b779ef552822fad6c4efcfa7b134c3faf84
@@ -14,7 +14,7 @@ __lazy_modules__ = [
14
14
  'mycli.main_modes.list_dsn',
15
15
  'mycli.packages.credentials.password_sources',
16
16
  'mycli.packages.integrations.vault.vault_credentials',
17
- 'mycli.packages.special_commands.dsn_aliases',
17
+ 'mycli.packages.utils.dsn_utils',
18
18
  'mycli.packages.utils.cli_utils',
19
19
  ]
20
20
 
@@ -32,7 +32,7 @@ from mycli.main_modes.batch import main_batch_from_stdin, main_batch_with_progre
32
32
  from mycli.main_modes.checkup import main_checkup
33
33
  from mycli.main_modes.completions import main_completions
34
34
  from mycli.main_modes.execute import main_execute_from_cli
35
- from mycli.main_modes.list_dsn import main_list_dsn
35
+ from mycli.main_modes.list_dsn import load_list_dsn_config, main_list_dsn
36
36
  from mycli.packages.credentials.password_sources import PasswordCandidates
37
37
  from mycli.packages.integrations.vault.vault_credentials import (
38
38
  DEFAULT_VAULT_EXECUTABLE,
@@ -41,8 +41,8 @@ from mycli.packages.integrations.vault.vault_credentials import (
41
41
  VaultError,
42
42
  get_field_from_vault,
43
43
  )
44
- from mycli.packages.special_commands.dsn_aliases import INVALID_DSN_ALIAS_ERROR, is_valid_dsn_alias
45
44
  from mycli.packages.utils.cli_utils import is_valid_connection_scheme
45
+ from mycli.packages.utils.dsn_utils import INVALID_DSN_ALIAS_ERROR, is_valid_dsn_alias
46
46
 
47
47
  if TYPE_CHECKING:
48
48
  from mycli.main import CliArgs
@@ -122,7 +122,7 @@ def expand_dsn_alias_env_vars(
122
122
  )
123
123
 
124
124
 
125
- def run_from_cli_args(cli_args: 'CliArgs', client_factory: ClientFactory) -> None:
125
+ def run_from_cli_args(cli_args: 'CliArgs', client_factory: ClientFactory | None = None) -> None:
126
126
  from mycli import main as main_module
127
127
 
128
128
  if cli_args.completions:
@@ -131,6 +131,32 @@ def run_from_cli_args(cli_args: 'CliArgs', client_factory: ClientFactory) -> Non
131
131
 
132
132
  cli_verbosity = main_module.preprocess_cli_args(cli_args, is_valid_connection_scheme)
133
133
 
134
+ if not cli_args.checkup:
135
+ if cli_args.csv and cli_args.format not in [None, 'csv']:
136
+ click.secho("Conflicting --csv and --format arguments.", err=True, fg="red")
137
+ sys.exit(1)
138
+
139
+ if cli_args.table and cli_args.format not in [None, 'table']:
140
+ click.secho("Conflicting --table and --format arguments.", err=True, fg="red")
141
+ sys.exit(1)
142
+
143
+ if not cli_args.format:
144
+ cli_args.format = 'default'
145
+ if cli_args.csv:
146
+ cli_args.format = 'csv'
147
+ if cli_args.table:
148
+ cli_args.format = 'table'
149
+
150
+ if cli_args.list_dsn:
151
+ config = load_list_dsn_config(cli_args.myclirc)
152
+ verbosity = cli_verbosity or (-1 if config['main'].as_bool('less_chatty') else 0)
153
+ sys.exit(main_list_dsn(config, verbosity))
154
+
155
+ if client_factory is None:
156
+ import mycli.client as mycli_client
157
+
158
+ client_factory = mycli_client.MyCli
159
+
134
160
  mycli = client_factory(
135
161
  prompt=cli_args.prompt,
136
162
  toolbar_format=cli_args.toolbar,
@@ -147,26 +173,6 @@ def run_from_cli_args(cli_args: 'CliArgs', client_factory: ClientFactory) -> Non
147
173
  main_checkup(mycli)
148
174
  sys.exit(0)
149
175
 
150
- if cli_args.csv and cli_args.format not in [None, 'csv']:
151
- click.secho("Conflicting --csv and --format arguments.", err=True, fg="red")
152
- sys.exit(1)
153
-
154
- if cli_args.table and cli_args.format not in [None, 'table']:
155
- click.secho("Conflicting --table and --format arguments.", err=True, fg="red")
156
- sys.exit(1)
157
-
158
- if not cli_args.format:
159
- cli_args.format = 'default'
160
-
161
- if cli_args.csv:
162
- cli_args.format = 'csv'
163
-
164
- if cli_args.table:
165
- cli_args.format = 'table'
166
-
167
- if cli_args.list_dsn:
168
- sys.exit(main_list_dsn(mycli))
169
-
170
176
  dsn_uri = None
171
177
  dsn_password: str | None = None
172
178
  database: str | None = ''
@@ -24,10 +24,13 @@ from mycli.client_commands import ClientCommandsMixin, get_config_property_names
24
24
  from mycli.client_connection import ClientConnectionMixin
25
25
  from mycli.client_query import ClientQueryMixin
26
26
  from mycli.config import (
27
+ SYSTEM_CONFIG_FILES,
27
28
  get_mylogin_cnf_path,
29
+ get_xdg_config_file,
28
30
  open_mylogin_cnf,
29
31
  read_config_file,
30
32
  read_config_files,
33
+ resolve_user_config_path,
31
34
  write_default_config,
32
35
  )
33
36
  from mycli.constants import DEFAULT_PROMPT
@@ -61,10 +64,8 @@ class MyCli(AppStateMixin, OutputMixin, ClientCommandsMixin, ClientConnectionMix
61
64
 
62
65
  # check XDG_CONFIG_HOME exists and not an empty string
63
66
  xdg_config_home = os.environ.get("XDG_CONFIG_HOME", "~/.config")
64
- xdg_config_file = os.path.join(os.path.expanduser(xdg_config_home), "mycli", "myclirc")
65
- system_config_files: list[str | IO[str]] = [
66
- "/etc/myclirc",
67
- ]
67
+ xdg_config_file = get_xdg_config_file()
68
+ system_config_files: list[str | IO[str]] = SYSTEM_CONFIG_FILES
68
69
 
69
70
  def __init__(
70
71
  self,
@@ -92,11 +93,7 @@ class MyCli(AppStateMixin, OutputMixin, ClientCommandsMixin, ClientConnectionMix
92
93
  self.sandbox_mode: bool = False
93
94
  self.checkpoint: IO | None = None
94
95
 
95
- if myclirc is None:
96
- if os.path.exists(self.xdg_config_file):
97
- myclirc = self.xdg_config_file
98
- else:
99
- myclirc = '~/.myclirc'
96
+ myclirc = resolve_user_config_path(myclirc, xdg_config_file=self.xdg_config_file)
100
97
  self.myclirc_path = os.path.abspath(os.path.expanduser(myclirc))
101
98
 
102
99
  # Load config.
@@ -1,3 +1,5 @@
1
+ __lazy_modules__ = ['Cryptodome.Cipher']
2
+
1
3
  from copy import copy
2
4
  from importlib import resources
3
5
  from io import BytesIO, TextIOWrapper
@@ -12,6 +14,22 @@ from configobj import ConfigObj, ConfigObjError
12
14
  from Cryptodome.Cipher import AES
13
15
 
14
16
  logger = logging.getLogger(__name__)
17
+ SYSTEM_CONFIG_FILES: list[str | IO[str]] = ['/etc/myclirc']
18
+
19
+
20
+ def get_xdg_config_file() -> str:
21
+ return os.path.join(os.path.expanduser(os.environ.get('XDG_CONFIG_HOME', '~/.config')), 'mycli', 'myclirc')
22
+
23
+
24
+ def resolve_user_config_path(myclirc: str | None, *, xdg_config_file: str | None = None) -> str:
25
+ if myclirc is not None:
26
+ return myclirc
27
+ xdg_config_file = get_xdg_config_file() if xdg_config_file is None else xdg_config_file
28
+ return xdg_config_file if os.path.exists(xdg_config_file) else '~/.myclirc'
29
+
30
+
31
+ def read_user_config(myclirc: str | None) -> ConfigObj:
32
+ return read_config_files(SYSTEM_CONFIG_FILES + [resolve_user_config_path(myclirc)])
15
33
 
16
34
 
17
35
  class SQLValuePreservingConfigObj(ConfigObj):
@@ -23,7 +23,6 @@ import clickdc
23
23
 
24
24
  import mycli as mycli_package
25
25
  from mycli.cli_runner import run_from_cli_args
26
- from mycli.client import MyCli
27
26
  from mycli.constants import (
28
27
  DEFAULT_PROMPT,
29
28
  EMPTY_PASSWORD_FLAG_SENTINEL,
@@ -482,7 +481,7 @@ def click_entrypoint(
482
481
 
483
482
  """
484
483
 
485
- run_from_cli_args(cli_args, client_factory=MyCli)
484
+ run_from_cli_args(cli_args, client_factory=None)
486
485
 
487
486
 
488
487
  def main() -> int | None:
@@ -1,18 +1,21 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING
4
-
5
3
  import click
4
+ from configobj import ConfigObj
5
+
6
+ from mycli.config import read_user_config
7
+ from mycli.packages.utils.dsn_utils import is_valid_dsn_alias, merge_shared_dsns
6
8
 
7
- from mycli.packages.special_commands.dsn_aliases import is_valid_dsn_alias
8
9
 
9
- if TYPE_CHECKING:
10
- from mycli.client import MyCli
10
+ def load_list_dsn_config(myclirc: str | None) -> ConfigObj:
11
+ config = read_user_config(myclirc)
12
+ merge_shared_dsns(config, config['main'].get('shared_dsns_file'))
13
+ return config
11
14
 
12
15
 
13
- def main_list_dsn(mycli: 'MyCli') -> int:
16
+ def main_list_dsn(config: ConfigObj, verbosity: int) -> int:
14
17
  try:
15
- alias_dsn = mycli.config['alias_dsn']
18
+ alias_dsn = config['alias_dsn']
16
19
  except KeyError:
17
20
  click.secho('Invalid DSNs found in the config file. Please check the "[alias_dsn]" section in myclirc.', err=True, fg='red')
18
21
  return 1
@@ -22,7 +25,7 @@ def main_list_dsn(mycli: 'MyCli') -> int:
22
25
  for alias, value in alias_dsn.items():
23
26
  if not is_valid_dsn_alias(alias):
24
27
  continue
25
- if mycli.verbosity >= 1:
28
+ if verbosity >= 1:
26
29
  click.secho(f'{alias} : {value}')
27
30
  else:
28
31
  click.secho(alias)
@@ -320,7 +320,7 @@ class SQLExecute:
320
320
  # Update them after the connection is made to ensure that it was a
321
321
  # successful connection.
322
322
  self.dbname = db
323
- self.user = user
323
+ self.user = user or (conn.user.decode(conn.encoding) if isinstance(conn.user, bytes) else conn.user)
324
324
  self.password = password
325
325
  self.host = host
326
326
  self.port = port