mercurial/pycompat.py
changeset 32882 f57f1f37290d
parent 32878 f22f39d56bb5
child 32883 6e38b4212661
equal deleted inserted replaced
32881:9e3733d93f64 32882:f57f1f37290d
    41     import io
    41     import io
    42     import struct
    42     import struct
    43 
    43 
    44     fsencode = os.fsencode
    44     fsencode = os.fsencode
    45     fsdecode = os.fsdecode
    45     fsdecode = os.fsdecode
    46     # A bytes version of os.name.
       
    47     oslinesep = os.linesep.encode('ascii')
    46     oslinesep = os.linesep.encode('ascii')
    48     osname = os.name.encode('ascii')
    47     osname = os.name.encode('ascii')
    49     ospathsep = os.pathsep.encode('ascii')
    48     ospathsep = os.pathsep.encode('ascii')
    50     ossep = os.sep.encode('ascii')
    49     ossep = os.sep.encode('ascii')
    51     osaltsep = os.altsep
    50     osaltsep = os.altsep
   208     unicode = str
   207     unicode = str
   209 
   208 
   210     def open(name, mode='r', buffering=-1):
   209     def open(name, mode='r', buffering=-1):
   211         return builtins.open(name, sysstr(mode), buffering)
   210         return builtins.open(name, sysstr(mode), buffering)
   212 
   211 
   213     # getopt.getopt() on Python 3 deals with unicodes internally so we cannot
       
   214     # pass bytes there. Passing unicodes will result in unicodes as return
       
   215     # values which we need to convert again to bytes.
       
   216     def getoptb(args, shortlist, namelist):
   212     def getoptb(args, shortlist, namelist):
       
   213         """
       
   214         Takes bytes arguments, converts them to unicode, pass them to
       
   215         getopt.getopt(), convert the returned values back to bytes and then
       
   216         return them for Python 3 compatibility as getopt.getopt() don't accepts
       
   217         bytes on Python 3.
       
   218         """
   217         args = [a.decode('latin-1') for a in args]
   219         args = [a.decode('latin-1') for a in args]
   218         shortlist = shortlist.decode('latin-1')
   220         shortlist = shortlist.decode('latin-1')
   219         namelist = [a.decode('latin-1') for a in namelist]
   221         namelist = [a.decode('latin-1') for a in namelist]
   220         opts, args = getopt.getopt(args, shortlist, namelist)
   222         opts, args = getopt.getopt(args, shortlist, namelist)
   221         opts = [(a[0].encode('latin-1'), a[1].encode('latin-1'))
   223         opts = [(a[0].encode('latin-1'), a[1].encode('latin-1'))
   222                 for a in opts]
   224                 for a in opts]
   223         args = [a.encode('latin-1') for a in args]
   225         args = [a.encode('latin-1') for a in args]
   224         return opts, args
   226         return opts, args
   225 
   227 
   226     # keys of keyword arguments in Python need to be strings which are unicodes
       
   227     # Python 3. This function takes keyword arguments, convert the keys to str.
       
   228     def strkwargs(dic):
   228     def strkwargs(dic):
       
   229         """
       
   230         Converts the keys of a python dictonary to str i.e. unicodes so that
       
   231         they can be passed as keyword arguments as dictonaries with bytes keys
       
   232         can't be passed as keyword arguments to functions on Python 3.
       
   233         """
   229         dic = dict((k.decode('latin-1'), v) for k, v in dic.iteritems())
   234         dic = dict((k.decode('latin-1'), v) for k, v in dic.iteritems())
   230         return dic
   235         return dic
   231 
   236 
   232     # keys of keyword arguments need to be unicode while passing into
       
   233     # a function. This function helps us to convert those keys back to bytes
       
   234     # again as we need to deal with bytes.
       
   235     def byteskwargs(dic):
   237     def byteskwargs(dic):
       
   238         """
       
   239         Converts keys of python dictonaries to bytes as they were converted to
       
   240         str to pass that dictonary as a keyword argument on Python 3.
       
   241         """
   236         dic = dict((k.encode('latin-1'), v) for k, v in dic.iteritems())
   242         dic = dict((k.encode('latin-1'), v) for k, v in dic.iteritems())
   237         return dic
   243         return dic
   238 
   244 
   239     # shlex.split() accepts unicodes on Python 3. This function takes bytes
       
   240     # argument, convert it into unicodes, pass into shlex.split(), convert the
       
   241     # returned value to bytes and return that.
       
   242     # TODO: handle shlex.shlex().
   245     # TODO: handle shlex.shlex().
   243     def shlexsplit(s):
   246     def shlexsplit(s):
       
   247         """
       
   248         Takes bytes argument, convert it to str i.e. unicodes, pass that into
       
   249         shlex.split(), convert the returned value to bytes and return that for
       
   250         Python 3 compatibility as shelx.split() don't accept bytes on Python 3.
       
   251         """
   244         ret = shlex.split(s.decode('latin-1'))
   252         ret = shlex.split(s.decode('latin-1'))
   245         return [a.encode('latin-1') for a in ret]
   253         return [a.encode('latin-1') for a in ret]
   246 
   254 
   247 else:
   255 else:
   248     import cStringIO
   256     import cStringIO
   257 
   265 
   258     # this can't be parsed on Python 3
   266     # this can't be parsed on Python 3
   259     exec('def raisewithtb(exc, tb):\n'
   267     exec('def raisewithtb(exc, tb):\n'
   260          '    raise exc, None, tb\n')
   268          '    raise exc, None, tb\n')
   261 
   269 
   262     # Partial backport from os.py in Python 3, which only accepts bytes.
       
   263     # In Python 2, our paths should only ever be bytes, a unicode path
       
   264     # indicates a bug.
       
   265     def fsencode(filename):
   270     def fsencode(filename):
       
   271         """
       
   272         Partial backport from os.py in Python 3, which only accepts bytes.
       
   273         In Python 2, our paths should only ever be bytes, a unicode path
       
   274         indicates a bug.
       
   275         """
   266         if isinstance(filename, str):
   276         if isinstance(filename, str):
   267             return filename
   277             return filename
   268         else:
   278         else:
   269             raise TypeError(
   279             raise TypeError(
   270                 "expect str, not %s" % type(filename).__name__)
   280                 "expect str, not %s" % type(filename).__name__)