[PATCH v3] pwclient: Fix silent crash on python 2

Robin Jarry robin.jarry at 6wind.com
Wed May 3 00:51:51 AEST 2017


Replacing sys.stdout and sys.stderr can cause obscure crashes when
trying to write non unicode data. The interpreter is terminated with
SIGINT without any specific error writen on the console.

  rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f964820e8d0},
  {0x559f50, [], SA_RESTORER, 0x7f964820e8d0}, 8) = 0

This happens easily when there is an untrapped exception which should
lead to printing a traceback on stderr.

The only way to prevent UnicodeEncodeErrors is to make sure that one of
the locale-related environment variables (LC_ALL, LANG, LANGUAGE, etc.)
is set. Python will use the correct encoding accordingly.

Add a note about this on `pwclient --help`. Also, display a help message
when an encoding error occurs.

Fixes: 046419a3bf8f ("pwclient: Fix encoding problems")
Signed-off-by: Robin Jarry <robin.jarry at 6wind.com>
---

v3: Removed all hacks and added explicit error messages to avoid these encoding
errors completely.

Examples:

  $ cat ~/.pwclientrc
  [options]
  default = dpdk
  [dpdk]
  url= http://dpdk.org/dev/patchwork/xmlrpc/

  $ LANG= LC_ALL= PAGER= LANGUAGE= ./patchwork/bin/pwclient view 17892
  Traceback (most recent call last):
    File "./patchwork/bin/pwclient", line 823, in <module>
      main()
    File "./patchwork/bin/pwclient", line 768, in main
      print(s)
  UnicodeEncodeError: 'ascii' codec can't encode character u'\u0142' in position
  468: ordinal not in range(128)

  Try exporting the LANG or LC_ALL env vars. See pwclient --help for more details.

  $ ./patchwork/bin/pwclient --help
  usage: pwclient [-h]
                  {apply,git-am,get,info,projects,check-list,check-info,check-create,states,view,update,list,search}
                  ...

  Important: to avoid unicode encode/decode errors, you should export the LANG
  or LC_ALL environment variables according to the configured locales on your
  system. If these variables are already set, make sure that they point on valid
  and installed locales.
  [...]

 patchwork/bin/pwclient | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/patchwork/bin/pwclient b/patchwork/bin/pwclient
index ed0351bf5288..037099dbc8ba 100755
--- a/patchwork/bin/pwclient
+++ b/patchwork/bin/pwclient
@@ -41,16 +41,7 @@ except ImportError:
 import shutil
 import re
 import io
-import locale
 
-if sys.version_info.major == 2:
-    # hack to make writing unicode to standard output/error work on Python 2
-    OUT_ENCODING = (sys.stdout.encoding or locale.getpreferredencoding() or
-                    os.getenv('PYTHONIOENCODING', 'utf-8'))
-    sys.stdout = io.open(sys.stdout.fileno(), mode='w',
-                         encoding=OUT_ENCODING, errors='replace')
-    sys.stderr = io.open(sys.stderr.fileno(), mode='w',
-                         encoding=OUT_ENCODING, errors='replace')
 
 # Default Patchwork remote XML-RPC server URL
 # This script will check the PW_XMLRPC_URL environment variable
@@ -461,6 +452,12 @@ def main():
 
     action_parser = argparse.ArgumentParser(
         prog='pwclient',
+        description='''
+        Important: to avoid unicode encode/decode errors, you should export the
+        LANG or LC_ALL environment variables according to the configured locales
+        on your system. If these variables are already set, make sure that they
+        point on valid and installed locales.
+        ''',
         epilog='Use \'pwclient <command> --help\' for more info',
     )
 
@@ -822,4 +819,12 @@ def main():
 
 
 if __name__ == "__main__":
-    main()
+    try:
+        main()
+    except (UnicodeEncodeError, UnicodeDecodeError) as e:
+        import traceback
+        traceback.print_exc()
+        sys.stderr.write('''
+Try exporting the LANG or LC_ALL env vars. See pwclient --help for more details.
+''')
+        sys.exit(1)
-- 
2.11.0.193.g1d1bdafd6426



More information about the Patchwork mailing list