From b08570c90eb9fa2e2ee4429909b14240b7a427d4 Mon Sep 17 00:00:00 2001 From: Malcolm Smith Date: Fri, 25 Oct 2024 01:35:41 +0100 Subject: [PATCH] gh-125942: Android: set stdout to `errors="backslashreplace"` (#125943) Android stdout/err streams now use `backslashreplace` encoding to ensure readability of the Android log. --- Lib/_android_support.py | 11 +++++++---- Lib/test/test_android.py | 5 +---- .../2024-10-24-22-43-03.gh-issue-125942.3UQht1.rst | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-10-24-22-43-03.gh-issue-125942.3UQht1.rst diff --git a/Lib/_android_support.py b/Lib/_android_support.py index 353b34fa36a..7572745c851 100644 --- a/Lib/_android_support.py +++ b/Lib/_android_support.py @@ -31,16 +31,19 @@ def init_streams(android_log_write, stdout_prio, stderr_prio): logcat = Logcat(android_log_write) sys.stdout = TextLogStream( - stdout_prio, "python.stdout", sys.stdout.fileno(), - errors=sys.stdout.errors) + stdout_prio, "python.stdout", sys.stdout.fileno()) sys.stderr = TextLogStream( - stderr_prio, "python.stderr", sys.stderr.fileno(), - errors=sys.stderr.errors) + stderr_prio, "python.stderr", sys.stderr.fileno()) class TextLogStream(io.TextIOWrapper): def __init__(self, prio, tag, fileno=None, **kwargs): + # The default is surrogateescape for stdout and backslashreplace for + # stderr, but in the context of an Android log, readability is more + # important than reversibility. kwargs.setdefault("encoding", "UTF-8") + kwargs.setdefault("errors", "backslashreplace") + super().__init__(BinaryLogStream(prio, tag, fileno), **kwargs) self._lock = RLock() self._pending_bytes = [] diff --git a/Lib/test/test_android.py b/Lib/test/test_android.py index 2ef9f10fdcc..076190f7572 100644 --- a/Lib/test/test_android.py +++ b/Lib/test/test_android.py @@ -123,13 +123,10 @@ def test_str(self): self.assertIs(stream.readable(), False) self.assertEqual(stream.fileno(), fileno) self.assertEqual("UTF-8", stream.encoding) + self.assertEqual("backslashreplace", stream.errors) self.assertIs(stream.line_buffering, True) self.assertIs(stream.write_through, False) - # stderr is backslashreplace by default; stdout is configured - # that way by libregrtest.main. - self.assertEqual("backslashreplace", stream.errors) - def write(s, lines=None, *, write_len=None): if write_len is None: write_len = len(s) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-10-24-22-43-03.gh-issue-125942.3UQht1.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-24-22-43-03.gh-issue-125942.3UQht1.rst new file mode 100644 index 00000000000..d1b1ecd2a72 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-10-24-22-43-03.gh-issue-125942.3UQht1.rst @@ -0,0 +1,2 @@ +On Android, the ``errors`` setting of :any:`sys.stdout` was changed from +``surrogateescape`` to ``backslashreplace``.