Skip to content

Commit cdeeaa7

Browse files
rjarrystephenfin
authored andcommitted
pwclient: Fix encoding problems
All data returned by the xmlrpc object is unicode decoded with 'utf-8' (on python 3, unicode == str). Add from __future__ import unicode_literals to make sure that everything is unicode and avoid surprises. On python 2, printing unicode to stdout causes it to be encoded to str (byte string) with the 'ascii' codec: >>> print some_unicode_string ... UnicodeEncodeError: 'ascii' codec can't encode character u'\u0142' in position 468: ordinal not in range(128) Work around ths by avoiding any explicit call to unicode() and by replacing sys.stdout and sys.stderr by unicode-aware file objects (as returned by io.open()). Guess the encoding of stdout and stderr by looking at (in that order): sys.stdout.encoding, locale.getpreferredencoding(), the PYTHONIOENCODING environment variable. If no encoding is defined, assume 'utf-8' as output encoding. Conflicts: patchwork/bin/pwclient Tested-by: Thomas Monjalon <[email protected]> Reviewed-by: Stephen Finucane <[email protected]> (cherry picked from commit 046419a)
1 parent cfe8b7b commit cdeeaa7

File tree

1 file changed

+19
-15
lines changed

1 file changed

+19
-15
lines changed

patchwork/bin/pwclient

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2222

2323
from __future__ import print_function
24+
from __future__ import unicode_literals
2425

2526
import os
2627
import sys
@@ -40,13 +41,17 @@ except ImportError:
4041
import configparser as ConfigParser
4142
import shutil
4243
import re
43-
44-
# Add a shim for Python 2's unicode() helper.
45-
try:
46-
unicode
47-
except NameError:
48-
# Python 3 does everything by unicode now.
49-
unicode = str
44+
import io
45+
import locale
46+
47+
if sys.version_info.major == 2:
48+
# hack to make writing unicode to standard output/error work on Python 2
49+
OUT_ENCODING = sys.stdout.encoding or locale.getpreferredencoding() or \
50+
os.getenv('PYTHONIOENCODING', 'utf-8')
51+
sys.stdout = io.open(sys.stdout.fileno(), mode='w',
52+
encoding=OUT_ENCODING, errors='replace')
53+
sys.stderr = io.open(sys.stderr.fileno(), mode='w',
54+
encoding=OUT_ENCODING, errors='replace')
5055

5156
# Default Patchwork remote XML-RPC server URL
5257
# This script will check the PW_XMLRPC_URL environment variable
@@ -214,8 +219,7 @@ def action_list(rpc, filter, submitter_str, delegate_str, format_str=None):
214219
for id in ids:
215220
person = rpc.person_get(id)
216221
print('Patches submitted by %s <%s>:' %
217-
(unicode(person['name']).encode('utf-8'),
218-
unicode(person['email']).encode('utf-8')))
222+
(person['name'], person['email']))
219223
f = filter
220224
f.add("submitter_id", id)
221225
patches = rpc.patch_list(f.d)
@@ -269,7 +273,7 @@ def action_check_info(rpc, check_id):
269273
print(s)
270274
print('-' * len(s))
271275
for key, value in sorted(check.items()):
272-
print("- %- 14s: %s" % (key, unicode(value)))
276+
print("- %- 14s: %s" % (key, value))
273277

274278

275279
def action_check_create(rpc, patch_id, context, state, url, description):
@@ -293,7 +297,7 @@ def action_info(rpc, patch_id):
293297
print(s)
294298
print('-' * len(s))
295299
for key, value in sorted(patch.items()):
296-
print("- %- 14s: %s" % (key, unicode(value)))
300+
print("- %- 14s: %s" % (key, value))
297301

298302

299303
def action_get(rpc, patch_id):
@@ -311,7 +315,7 @@ def action_get(rpc, patch_id):
311315
i += 1
312316

313317
try:
314-
f = open(fname, "w")
318+
f = io.open(fname, "w", encoding="utf-8")
315319
except:
316320
sys.stderr.write("Unable to open %s for writing\n" % fname)
317321
sys.exit(1)
@@ -343,7 +347,7 @@ def action_apply(rpc, patch_id, apply_cmd=None):
343347
s = rpc.patch_get_mbox(patch_id)
344348
if len(s) > 0:
345349
proc = subprocess.Popen(apply_cmd, stdin=subprocess.PIPE)
346-
proc.communicate(unicode(s).encode('utf-8'))
350+
proc.communicate(s.encode('utf-8'))
347351
return proc.returncode
348352
else:
349353
sys.stderr.write("Error: No patch content found\n")
@@ -757,15 +761,15 @@ def main():
757761
for patch_id in non_empty(h, patch_ids):
758762
s = rpc.patch_get_mbox(patch_id)
759763
if len(s) > 0:
760-
i.append(unicode(s))
764+
i.append(s)
761765
if len(i) > 0:
762766
pager.communicate(input="\n".join(i).encode("utf-8"))
763767
pager.stdin.close()
764768
else:
765769
for patch_id in non_empty(h, patch_ids):
766770
s = rpc.patch_get_mbox(patch_id)
767771
if len(s) > 0:
768-
print(unicode(s))
772+
print(s)
769773

770774
elif action == 'info':
771775
for patch_id in non_empty(h, patch_ids):

0 commit comments

Comments
 (0)