From b17a92d2d434a5d7bab3af60e01200130a74301d Mon Sep 17 00:00:00 2001 From: Karim Masmoudi <125830216+Kernel-Hunter@users.noreply.github.com> Date: Fri, 13 Nov 2026 15:57:39 +0100 Subject: [PATCH 1/2] Bracket IPv6 hosts in formatted DSNs format_connection_dsn wrote mysql://alice@::1:3307/prod, which urlparse cannot read back (port ':1:3307'), so a \dsn save alias for an IPv6 connection failed when used. --- changelog.md | 1 + .../special_commands/special_command_utils.py | 3 +++ mycli_test/pytests/test_special_utils.py | 16 ++++++++++++++++ 3 files changed, 20 insertions(+) diff --git a/changelog.md b/changelog.md index 4e5608816..1631747fb 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,7 @@ Upcoming (TBD) Bug Fixes -------- * 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. v2.30.4 (2026/11/12) 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( From 8e0080b1cbd6c19b05b35d5deda7712254a25fd2 Mon Sep 17 00:00:00 2001 From: Karim Masmoudi <125830216+Kernel-Hunter@users.noreply.github.com> Date: Fri, 13 Nov 2026 15:58:04 +0100 Subject: [PATCH 2/2] Add Karim Masmoudi to AUTHORS --- mycli/AUTHORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/mycli/AUTHORS.txt b/mycli/AUTHORS.txt index 6f58f6195..fb2661183 100644 --- a/mycli/AUTHORS.txt +++ b/mycli/AUTHORS.txt @@ -123,6 +123,7 @@ Contributors: * Wei-Lun Li * Shaurya Kesarwani * Alex Castillo + * Karim Masmoudi Created by: