changeset 30583:c6ce11f2ee50

py3: make a bytes version of getopt.getopt() getopt.getopt() deals with unicodes on Python 3 internally and if bytes arguments are passed, then it will return TypeError. So we have now pycompat.getoptb() which takes bytes arguments, convert them to unicode, call getopt.getopt() and then convert the returned value back to bytes and then return those value. All the instances of getopt.getopt() are replaced with pycompat.getoptb().
author Pulkit Goyal <7895pulkit@gmail.com>
date Tue, 06 Dec 2016 06:36:36 +0530
parents 6146d5acee69
children fbc3f73dc802
files mercurial/fancyopts.py mercurial/pycompat.py mercurial/statprof.py
diffstat 3 files changed, 30 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/fancyopts.py	Tue Dec 06 11:44:49 2016 +0000
+++ b/mercurial/fancyopts.py	Tue Dec 06 06:36:36 2016 +0530
@@ -7,10 +7,11 @@
 
 from __future__ import absolute_import
 
-import getopt
-
 from .i18n import _
-from . import error
+from . import (
+    error,
+    pycompat,
+)
 
 # Set of flags to not apply boolean negation logic on
 nevernegate = set([
@@ -34,13 +35,14 @@
         stopindex = args.index('--')
         extraargs = args[stopindex + 1:]
         args = args[:stopindex]
-    opts, parseargs = getopt.getopt(args, options, longoptions)
+    opts, parseargs = pycompat.getoptb(args, options, longoptions)
     args = []
     while parseargs:
         arg = parseargs.pop(0)
         if arg and arg[0] == '-' and len(arg) > 1:
             parseargs.insert(0, arg)
-            topts, newparseargs = getopt.getopt(parseargs, options, longoptions)
+            topts, newparseargs = pycompat.getoptb(parseargs,\
+                                            options, longoptions)
             opts = opts + topts
             parseargs = newparseargs
         else:
@@ -125,7 +127,7 @@
     if gnu:
         parse = gnugetopt
     else:
-        parse = getopt.getopt
+        parse = pycompat.getoptb
     opts, args = parse(args, shortlist, namelist)
 
     # transfer result to state
--- a/mercurial/pycompat.py	Tue Dec 06 11:44:49 2016 +0000
+++ b/mercurial/pycompat.py	Tue Dec 06 06:36:36 2016 +0530
@@ -10,6 +10,7 @@
 
 from __future__ import absolute_import
 
+import getopt
 import os
 import sys
 
@@ -87,6 +88,19 @@
     setattr = _wrapattrfunc(builtins.setattr)
     xrange = builtins.range
 
+    # getopt.getopt() on Python 3 deals with unicodes internally so we cannot
+    # pass bytes there. Passing unicodes will result in unicodes as return
+    # values which we need to convert again to bytes.
+    def getoptb(args, shortlist, namelist):
+        args = [a.decode('latin-1') for a in args]
+        shortlist = shortlist.decode('latin-1')
+        namelist = [a.decode('latin-1') for a in namelist]
+        opts, args = getopt.getopt(args, shortlist, namelist)
+        opts = [(a[0].encode('latin-1'), a[1].encode('latin-1'))
+                for a in opts]
+        args = [a.encode('latin-1') for a in args]
+        return opts, args
+
 else:
     def sysstr(s):
         return s
@@ -106,6 +120,9 @@
     def fsdecode(filename):
         return filename
 
+    def getoptb(args, shortlist, namelist):
+        return getopt.getopt(args, shortlist, namelist)
+
     osname = os.name
     ospathsep = os.pathsep
     ossep = os.sep
--- a/mercurial/statprof.py	Tue Dec 06 11:44:49 2016 +0000
+++ b/mercurial/statprof.py	Tue Dec 06 06:36:36 2016 +0530
@@ -116,6 +116,10 @@
 import threading
 import time
 
+from . import (
+    pycompat,
+)
+
 defaultdict = collections.defaultdict
 contextmanager = contextlib.contextmanager
 
@@ -771,7 +775,7 @@
 
     # process options
     try:
-        opts, args = getopt.getopt(sys.argv[optstart:], "hl:f:o:p:",
+        opts, args = pycompat.getoptb(sys.argv[optstart:], "hl:f:o:p:",
                                    ["help", "limit=", "file=", "output-file=", "script-path="])
     except getopt.error as msg:
         print(msg)