Decode sys.argv with surrogateescape for Python 3
authorZac Medico <zmedico@gentoo.org>
Thu, 20 Jun 2013 10:11:37 +0000 (03:11 -0700)
committerZac Medico <zmedico@gentoo.org>
Thu, 20 Jun 2013 10:11:37 +0000 (03:11 -0700)
With Python 3, the surrogateescape encoding error handler makes it
possible to access the original argv bytes, which can be useful
if their actual encoding does no match the filesystem encoding.

bin/portageq
bin/repoman
pym/_emerge/main.py
pym/portage/__init__.py

index 1ae1fe16e0aa61d24643056f18e9aa6037f83ad8..4be9f889069c0d84b209bf1d3f5e74e5feec04cd 100755 (executable)
@@ -1148,8 +1148,7 @@ else:
 
 def main(argv):
 
-       if argv and isinstance(argv[0], bytes):
-               argv = [portage._unicode_decode(x) for x in argv]
+       argv = portage._decode_argv(argv)
 
        nocolor = os.environ.get('NOCOLOR')
        if nocolor in ('yes', 'true'):
index c4a5a220ddf6b9cb802d5af29871434a81159d90..ff481d77638509f033b1e0eac26d00c7861ea547 100755 (executable)
@@ -156,8 +156,7 @@ def ParseArgs(argv, qahelp):
          (opts, args), just like a call to parser.parse_args()
        """
 
-       if argv and isinstance(argv[0], bytes):
-               argv = [portage._unicode_decode(x) for x in argv]
+       argv = portage._decode_argv(argv)
 
        modes = {
                'commit' : 'Run a scan then commit changes',
index b26ce306be7f4c81813430e1ea5e1e64e4e6fc07..fe9fb292448b281b2cc9054da1514951d2a7d07b 100644 (file)
@@ -981,10 +981,6 @@ def parse_opts(tmpcmdline, silent=False):
        if myaction is None and myoptions.deselect is True:
                myaction = 'deselect'
 
-       if myargs and isinstance(myargs[0], bytes):
-               for i in range(len(myargs)):
-                       myargs[i] = portage._unicode_decode(myargs[i])
-
        myfiles += myargs
 
        return myaction, myopts, myfiles
@@ -1014,6 +1010,8 @@ def emerge_main(args=None):
        if args is None:
                args = sys.argv[1:]
 
+       args = portage._decode_argv(args)
+
        # Disable color until we're sure that it should be enabled (after
        # EMERGE_DEFAULT_OPTS has been parsed).
        portage.output.havecolor = 0
index 7656c6ebefa4523bd4d3251db388c56690b278d4..d6da9f74473d8b9fb516f545d29dde034908f6cb 100644 (file)
@@ -174,6 +174,15 @@ _encodings = {
 }
 
 if sys.hexversion >= 0x3000000:
+
+       def _decode_argv(argv):
+               # With Python 3, the surrogateescape encoding error handler makes it
+               # possible to access the original argv bytes, which can be useful
+               # if their actual encoding does no match the filesystem encoding.
+               fs_encoding = sys.getfilesystemencoding()
+               return [_unicode_decode(x.encode(fs_encoding, 'surrogateescape'))
+                       for x in argv]
+
        def _unicode_encode(s, encoding=_encodings['content'], errors='backslashreplace'):
                if isinstance(s, str):
                        s = s.encode(encoding, errors)
@@ -186,6 +195,10 @@ if sys.hexversion >= 0x3000000:
 
        _native_string = _unicode_decode
 else:
+
+       def _decode_argv(argv):
+               return [_unicode_decode(x) for x in argv]
+
        def _unicode_encode(s, encoding=_encodings['content'], errors='backslashreplace'):
                if isinstance(s, unicode):
                        s = s.encode(encoding, errors)