# HG changeset patch # User Pulkit Goyal <7895pulkit@gmail.com> # Date 2016-12-06 01:06:36 # Node ID c6ce11f2ee50bba7a219d77afd8254569d201ddc # Parent 6146d5acee69f6e52650a239b442b299eeac2675 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(). diff --git a/mercurial/fancyopts.py b/mercurial/fancyopts.py --- a/mercurial/fancyopts.py +++ b/mercurial/fancyopts.py @@ -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 @@ def gnugetopt(args, options, longoptions 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 @@ def fancyopts(args, options, state, gnu= if gnu: parse = gnugetopt else: - parse = getopt.getopt + parse = pycompat.getoptb opts, args = parse(args, shortlist, namelist) # transfer result to state diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py --- a/mercurial/pycompat.py +++ b/mercurial/pycompat.py @@ -10,6 +10,7 @@ This contains aliases to hide python ver from __future__ import absolute_import +import getopt import os import sys @@ -87,6 +88,19 @@ if ispy3: 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 @@ else: 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 diff --git a/mercurial/statprof.py b/mercurial/statprof.py --- a/mercurial/statprof.py +++ b/mercurial/statprof.py @@ -116,6 +116,10 @@ import tempfile import threading import time +from . import ( + pycompat, +) + defaultdict = collections.defaultdict contextmanager = contextlib.contextmanager @@ -771,7 +775,7 @@ def main(argv=None): # 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)