From b7962be711d7cb0b52be53b5fa3a3192dfdc383e Mon Sep 17 00:00:00 2001 From: davfsa Date: Fri, 1 Apr 2022 16:35:25 +0200 Subject: [PATCH 1/3] Fix unicode decode error caused by `latin-1` encoding when sending the banner --- changes/idk.bugfix.md | 1 + hikari/internal/ux.py | 7 +++---- tests/hikari/internal/test_ux.py | 16 ++++++++++------ 3 files changed, 14 insertions(+), 10 deletions(-) create mode 100644 changes/idk.bugfix.md diff --git a/changes/idk.bugfix.md b/changes/idk.bugfix.md new file mode 100644 index 0000000000..04734d5e51 --- /dev/null +++ b/changes/idk.bugfix.md @@ -0,0 +1 @@ +Fix unicode decode error caused by `latin-1` encoding when sending the banner. diff --git a/hikari/internal/ux.py b/hikari/internal/ux.py index 04217fc9d8..55c3828d8d 100644 --- a/hikari/internal/ux.py +++ b/hikari/internal/ux.py @@ -223,10 +223,9 @@ def print_banner( for code in colorlog.escape_codes.escape_codes: args[code] = "" - sys.stdout.write(string.Template(raw_banner).safe_substitute(args)) - # Give the stream some time to flush - sys.stdout.flush() - time.sleep(0.125) + # 1 maps to stdout + with open(1, "w", encoding="utf-8") as stdout: + stdout.write(string.Template(raw_banner).safe_substitute(args)) def supports_color(allow_color: bool, force_color: bool) -> bool: diff --git a/tests/hikari/internal/test_ux.py b/tests/hikari/internal/test_ux.py index d5c6b96fc0..ff544396f1 100644 --- a/tests/hikari/internal/test_ux.py +++ b/tests/hikari/internal/test_ux.py @@ -19,6 +19,7 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import builtins import contextlib import importlib import logging @@ -180,7 +181,7 @@ def test_when_supports_color(self, mock_args): supports_color = stack.enter_context(mock.patch.object(ux, "supports_color", return_value=True)) read_text = stack.enter_context(mock.patch.object(importlib.resources, "read_text")) template = stack.enter_context(mock.patch.object(string, "Template")) - write = stack.enter_context(mock.patch.object(sys.stdout, "write")) + builtins_open = stack.enter_context(mock.patch.object(builtins, "open")) abspath = stack.enter_context(mock.patch.object(os.path, "abspath", return_value="some path")) dirname = stack.enter_context(mock.patch.object(os.path, "dirname")) @@ -207,7 +208,8 @@ def test_when_supports_color(self, mock_args): template.assert_called_once_with(read_text()) template().safe_substitute.assert_called_once_with(args) - write.assert_called_once_with(template().safe_substitute()) + builtins_open.assert_called_once_with(1, "w", encoding="utf-8") + builtins_open.return_value.__enter__.return_value.write.assert_called_once_with(template().safe_substitute()) dirname.assert_called_once_with("~/hikari") abspath.assert_called_once_with(dirname()) supports_color.assert_called_once_with(True, False) @@ -221,9 +223,9 @@ def test_when_doesnt_supports_color(self, mock_args): supports_color = stack.enter_context(mock.patch.object(ux, "supports_color", return_value=False)) read_text = stack.enter_context(mock.patch.object(importlib.resources, "read_text")) template = stack.enter_context(mock.patch.object(string, "Template")) - write = stack.enter_context(mock.patch.object(sys.stdout, "write")) abspath = stack.enter_context(mock.patch.object(os.path, "abspath", return_value="some path")) dirname = stack.enter_context(mock.patch.object(os.path, "dirname")) + builtins_open = stack.enter_context(mock.patch.object(builtins, "open")) with stack: ux.print_banner("hikari", True, False) @@ -248,10 +250,11 @@ def test_when_doesnt_supports_color(self, mock_args): template.assert_called_once_with(read_text()) template().safe_substitute.assert_called_once_with(args) - write.assert_called_once_with(template().safe_substitute()) dirname.assert_called_once_with("~/hikari") abspath.assert_called_once_with(dirname()) supports_color.assert_called_once_with(True, False) + builtins_open.assert_called_once_with(1, "w", encoding="utf-8") + builtins_open.return_value.__enter__.return_value.write.assert_called_once_with(template().safe_substitute()) def test_use_extra_args(self, mock_args): stack = contextlib.ExitStack() @@ -259,7 +262,7 @@ def test_use_extra_args(self, mock_args): stack.enter_context(mock.patch.object(time, "sleep")) read_text = stack.enter_context(mock.patch.object(importlib.resources, "read_text")) template = stack.enter_context(mock.patch.object(string, "Template")) - write = stack.enter_context(mock.patch.object(sys.stdout, "write")) + builtins_open = stack.enter_context(mock.patch.object(builtins, "open")) stack.enter_context(mock.patch.object(os.path, "abspath", return_value="some path")) extra_args = { @@ -289,7 +292,8 @@ def test_use_extra_args(self, mock_args): template.assert_called_once_with(read_text()) template().safe_substitute.assert_called_once_with(args) - write.assert_called_once_with(template().safe_substitute()) + builtins_open.assert_called_once_with(1, "w", encoding="utf-8") + builtins_open.return_value.__enter__.return_value.write.assert_called_once_with(template().safe_substitute()) def test_overwrite_args_raises_error(self, mock_args): stack = contextlib.ExitStack() From ce9a043a0896b7eae351e4a9b67c0d8c88033b2e Mon Sep 17 00:00:00 2001 From: davfsa Date: Fri, 1 Apr 2022 19:28:23 +0200 Subject: [PATCH 2/3] Rename changelog fragment --- changes/{idk.bugfix.md => 1120.bugfix.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changes/{idk.bugfix.md => 1120.bugfix.md} (100%) diff --git a/changes/idk.bugfix.md b/changes/1120.bugfix.md similarity index 100% rename from changes/idk.bugfix.md rename to changes/1120.bugfix.md From cd84394bf51c956a052e2f40231e6ed04e684e71 Mon Sep 17 00:00:00 2001 From: davfsa Date: Fri, 1 Apr 2022 19:44:19 +0200 Subject: [PATCH 3/3] Remove unnecessary import --- hikari/internal/ux.py | 1 - 1 file changed, 1 deletion(-) diff --git a/hikari/internal/ux.py b/hikari/internal/ux.py index 55c3828d8d..e4604a5c23 100644 --- a/hikari/internal/ux.py +++ b/hikari/internal/ux.py @@ -33,7 +33,6 @@ import re import string import sys -import time import typing import warnings