]> granicus.if.org Git - python/commitdiff
#21169: fix getpass to use replace error handler on UnicodeEncodeError.
authorR David Murray <rdmurray@bitdance.com>
Mon, 14 Apr 2014 02:07:39 +0000 (22:07 -0400)
committerR David Murray <rdmurray@bitdance.com>
Mon, 14 Apr 2014 02:07:39 +0000 (22:07 -0400)
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.

Lib/getpass.py
Lib/test/test_getpass.py
Misc/NEWS

index 53c38b8897569140f8bd35e73b1e2677a47351a0..274036348832e156ec5843048a9f1984ee632466 100644 (file)
@@ -135,7 +135,12 @@ def _raw_input(prompt="", stream=None, input=None):
         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()
index 1731bd44a65098ac4c7f766b68131be25b13548f..3452e46213a76c4376252cdb083bf039e1a56a63 100644 (file)
@@ -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 @@ class GetpassRawinputTest(unittest.TestCase):
         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)
index cb20934634256f263636d09b056121fb69e1f922..74c5e50cdd7cc7364a538a0d23b1a75e5b6d10f4 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -27,6 +27,10 @@ Core and Builtins
 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.