[Python-checkins] cpython (3.4): #21169: fix getpass to use replace error handler on UnicodeEncodeError.

r.david.murray python-checkins at python.org
Mon Apr 14 04:09:46 CEST 2014


http://hg.python.org/cpython/rev/f430fdd1628e
changeset:   90232:f430fdd1628e
branch:      3.4
parent:      90229:e8c184d8407d
user:        R David Murray <rdmurray at bitdance.com>
date:        Sun Apr 13 22:07:39 2014 -0400
summary:
  #21169: fix getpass to use replace error handler on UnicodeEncodeError.

If the input stream encoding couldn't encode one or more of the
non-ascii characters in the prompt, it would fail, throwing a
UnicodeEncodeError.  Now if that happens we re-encoding using the
'replace' error handler.

Patch by Kushal Das.

files:
  Lib/getpass.py           |   7 ++++++-
  Lib/test/test_getpass.py |  10 +++++++++-
  Misc/NEWS                |   4 ++++
  3 files changed, 19 insertions(+), 2 deletions(-)


diff --git a/Lib/getpass.py b/Lib/getpass.py
--- a/Lib/getpass.py
+++ b/Lib/getpass.py
@@ -135,7 +135,12 @@
         input = sys.stdin
     prompt = str(prompt)
     if prompt:
-        stream.write(prompt)
+        try:
+            stream.write(prompt)
+        except UnicodeEncodeError:
+            prompt = prompt.encode(stream.encoding, 'replace')
+            prompt = prompt.decode(stream.encoding)
+            stream.write(prompt)
         stream.flush()
     # NOTE: The Python C API calls flockfile() (and unlock) during readline.
     line = input.readline()
diff --git a/Lib/test/test_getpass.py b/Lib/test/test_getpass.py
--- a/Lib/test/test_getpass.py
+++ b/Lib/test/test_getpass.py
@@ -1,7 +1,7 @@
 import getpass
 import os
 import unittest
-from io import BytesIO, StringIO
+from io import BytesIO, StringIO, TextIOWrapper
 from unittest import mock
 from test import support
 
@@ -69,6 +69,14 @@
         getpass._raw_input(stream=StringIO())
         mock_input.readline.assert_called_once_with()
 
+    @mock.patch('sys.stdin')
+    def test_uses_stdin_as_different_locale(self, mock_input):
+        stream = TextIOWrapper(BytesIO(), encoding="ascii")
+        mock_input.readline.return_value = "Hasło: "
+        getpass._raw_input(prompt="Hasło: ",stream=stream)
+        mock_input.readline.assert_called_once_with()
+
+
     def test_raises_on_empty_input(self):
         input = StringIO('')
         self.assertRaises(EOFError, getpass._raw_input, input=input)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -27,6 +27,10 @@
 Library
 -------
 
+- Issue #21169: getpass now handles non-ascii characters that the
+  input stream encoding cannot encode by re-encoding using the
+  replace error handler.
+
 - Issue #21171: Fixed undocumented filter API of the rot13 codec.
   Patch by Berker Peksag.
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list