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().
--- 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)