diff --git a/changelog.md b/changelog.md index 90e677bec..bcfcd895b 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,7 @@ Bug Fixes -------- * Read `/source` files and the `\e` editor file as UTF-8 instead of the locale encoding, so non-ASCII SQL no longer fails or is mis-decoded under non-UTF-8 locales. * Open the audit log and the `\T`/`\o` output files as UTF-8, so non-ASCII output no longer fails under non-UTF-8 locales. +* Bracket IPv6 hosts in the DSN shown and saved by `\dsn`, so a saved alias for `::1` can be used to connect again. * Support `DELIMITER` in batch input (`mycli < file.sql`, `--batch`), so dumps with triggers or routines restore. * Read `--batch` files and read and write `--checkpoint` files as UTF-8, fixing `--resume` and non-ASCII batch files on Windows. diff --git a/mycli/AUTHORS.txt b/mycli/AUTHORS.txt index 731d659bd..a2bc606b0 100644 --- a/mycli/AUTHORS.txt +++ b/mycli/AUTHORS.txt @@ -123,6 +123,7 @@ Contributors: * Wei-Lun Li * Shaurya Kesarwani * Alex Castillo + * Karim Masmoudi * Jay Hemnani * Alpenj diff --git a/mycli/packages/special_commands/special_command_utils.py b/mycli/packages/special_commands/special_command_utils.py index f729c097f..eb28eb243 100644 --- a/mycli/packages/special_commands/special_command_utils.py +++ b/mycli/packages/special_commands/special_command_utils.py @@ -167,6 +167,9 @@ def format_connection_dsn( if user_part := urlquote(user or ''): user_part = f'{user_part}@' host_part = host or 'localhost' + if ':' in host_part and not host_part.startswith('['): + # IPv6 literals must be bracketed so the port can be told apart + host_part = f'[{host_part}]' port_part = f':{port}' if port is not None else '' if db_part := urlquote(database or ''): db_part = f'/{db_part}' diff --git a/mycli_test/pytests/test_special_utils.py b/mycli_test/pytests/test_special_utils.py index 2ffb62729..b82e32ebb 100644 --- a/mycli_test/pytests/test_special_utils.py +++ b/mycli_test/pytests/test_special_utils.py @@ -5,6 +5,7 @@ import tempfile from types import SimpleNamespace from unittest.mock import MagicMock +from urllib.parse import urlparse import pymysql import pytest @@ -327,6 +328,21 @@ def test_format_connection_dsn_includes_ssh_jump() -> None: ) +def test_format_connection_dsn_brackets_ipv6_host() -> None: + dsn = format_connection_dsn( + user='alice', + host='::1', + port=3307, + database='prod', + socket=None, + character_set=None, + ) + assert dsn == 'mysql://alice@[::1]:3307/prod' + uri = urlparse(dsn) + assert uri.hostname == '::1' + assert uri.port == 3307 + + def test_format_connection_dsn_includes_encoded_kubectl_resource() -> None: assert ( format_connection_dsn(