mercurial/py3kcompat.py
author Mads Kiilerich <madski@unity3d.com>
Thu, 17 Apr 2014 20:01:39 +0200
changeset 21105 12312f066d93
parent 17424 e7cfe3587ea4
child 21291 007d276f8c94
permissions -rw-r--r--
backout: use commonancestorsheads for checking linear heritage If two revisions are linearly related, there will only be one ancestor, and commonancestors and commonancestorsheads would give the same result. commonancestorsheads is however slightly simpler, faster and more correct.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11748
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
     1
# py3kcompat.py - compatibility definitions for running hg in py3k
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
     2
#
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
     3
# Copyright 2010 Renato Cunha <renatoc@gmail.com>
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
     4
#
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
     7
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
     8
import os, builtins
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
     9
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    10
from numbers import Number
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    11
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    12
def bytesformatter(format, args):
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    13
    '''Custom implementation of a formatter for bytestrings.
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    14
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 11878
diff changeset
    15
    This function currently relies on the string formatter to do the
11748
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    16
    formatting and always returns bytes objects.
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    17
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    18
    >>> bytesformatter(20, 10)
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    19
    0
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    20
    >>> bytesformatter('unicode %s, %s!', ('string', 'foo'))
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    21
    b'unicode string, foo!'
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    22
    >>> bytesformatter(b'test %s', 'me')
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    23
    b'test me'
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    24
    >>> bytesformatter('test %s', 'me')
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    25
    b'test me'
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    26
    >>> bytesformatter(b'test %s', b'me')
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    27
    b'test me'
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    28
    >>> bytesformatter('test %s', b'me')
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    29
    b'test me'
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    30
    >>> bytesformatter('test %d: %s', (1, b'result'))
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    31
    b'test 1: result'
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    32
    '''
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    33
    # The current implementation just converts from bytes to unicode, do
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    34
    # what's needed and then convert the results back to bytes.
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    35
    # Another alternative is to use the Python C API implementation.
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    36
    if isinstance(format, Number):
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    37
        # If the fixer erroneously passes a number remainder operation to
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    38
        # bytesformatter, we just return the correct operation
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    39
        return format % args
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    40
    if isinstance(format, bytes):
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    41
        format = format.decode('utf-8', 'surrogateescape')
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    42
    if isinstance(args, bytes):
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    43
        args = args.decode('utf-8', 'surrogateescape')
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    44
    if isinstance(args, tuple):
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    45
        newargs = []
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    46
        for arg in args:
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    47
            if isinstance(arg, bytes):
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    48
                arg = arg.decode('utf-8', 'surrogateescape')
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    49
            newargs.append(arg)
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    50
        args = tuple(newargs)
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    51
    ret = format % args
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    52
    return ret.encode('utf-8', 'surrogateescape')
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    53
builtins.bytesformatter = bytesformatter
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    54
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    55
# Create bytes equivalents for os.environ values
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    56
for key in list(os.environ.keys()):
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    57
    # UTF-8 is fine for us
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    58
    bkey = key.encode('utf-8', 'surrogateescape')
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    59
    bvalue = os.environ[key].encode('utf-8', 'surrogateescape')
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    60
    os.environ[bkey] = bvalue
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    61
11878
8bb1481cf08f py3kcompat: added fake ord implementation for py3k
Renato Cunha <renatoc@gmail.com>
parents: 11748
diff changeset
    62
origord = builtins.ord
8bb1481cf08f py3kcompat: added fake ord implementation for py3k
Renato Cunha <renatoc@gmail.com>
parents: 11748
diff changeset
    63
def fakeord(char):
8bb1481cf08f py3kcompat: added fake ord implementation for py3k
Renato Cunha <renatoc@gmail.com>
parents: 11748
diff changeset
    64
    if isinstance(char, int):
8bb1481cf08f py3kcompat: added fake ord implementation for py3k
Renato Cunha <renatoc@gmail.com>
parents: 11748
diff changeset
    65
        return char
8bb1481cf08f py3kcompat: added fake ord implementation for py3k
Renato Cunha <renatoc@gmail.com>
parents: 11748
diff changeset
    66
    return origord(char)
8bb1481cf08f py3kcompat: added fake ord implementation for py3k
Renato Cunha <renatoc@gmail.com>
parents: 11748
diff changeset
    67
builtins.ord = fakeord
8bb1481cf08f py3kcompat: added fake ord implementation for py3k
Renato Cunha <renatoc@gmail.com>
parents: 11748
diff changeset
    68
11748
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    69
if __name__ == '__main__':
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    70
    import doctest
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    71
    doctest.testmod()
37a70a784397 py3kcompat: added a "compatibility layer" for py3k
Renato Cunha <renatoc@gmail.com>
parents:
diff changeset
    72