1 # py3kcompat.py - compatibility definitions for running hg in py3k |
|
2 # |
|
3 # Copyright 2010 Renato Cunha <renatoc@gmail.com> |
|
4 # |
|
5 # This software may be used and distributed according to the terms of the |
|
6 # GNU General Public License version 2 or any later version. |
|
7 |
|
8 from __future__ import absolute_import |
|
9 |
|
10 import builtins |
|
11 import numbers |
|
12 |
|
13 Number = numbers.Number |
|
14 |
|
15 def bytesformatter(format, args): |
|
16 '''Custom implementation of a formatter for bytestrings. |
|
17 |
|
18 This function currently relies on the string formatter to do the |
|
19 formatting and always returns bytes objects. |
|
20 |
|
21 >>> bytesformatter(20, 10) |
|
22 0 |
|
23 >>> bytesformatter('unicode %s, %s!', ('string', 'foo')) |
|
24 b'unicode string, foo!' |
|
25 >>> bytesformatter(b'test %s', 'me') |
|
26 b'test me' |
|
27 >>> bytesformatter('test %s', 'me') |
|
28 b'test me' |
|
29 >>> bytesformatter(b'test %s', b'me') |
|
30 b'test me' |
|
31 >>> bytesformatter('test %s', b'me') |
|
32 b'test me' |
|
33 >>> bytesformatter('test %d: %s', (1, b'result')) |
|
34 b'test 1: result' |
|
35 ''' |
|
36 # The current implementation just converts from bytes to unicode, do |
|
37 # what's needed and then convert the results back to bytes. |
|
38 # Another alternative is to use the Python C API implementation. |
|
39 if isinstance(format, Number): |
|
40 # If the fixer erroneously passes a number remainder operation to |
|
41 # bytesformatter, we just return the correct operation |
|
42 return format % args |
|
43 if isinstance(format, bytes): |
|
44 format = format.decode('utf-8', 'surrogateescape') |
|
45 if isinstance(args, bytes): |
|
46 args = args.decode('utf-8', 'surrogateescape') |
|
47 if isinstance(args, tuple): |
|
48 newargs = [] |
|
49 for arg in args: |
|
50 if isinstance(arg, bytes): |
|
51 arg = arg.decode('utf-8', 'surrogateescape') |
|
52 newargs.append(arg) |
|
53 args = tuple(newargs) |
|
54 ret = format % args |
|
55 return ret.encode('utf-8', 'surrogateescape') |
|
56 builtins.bytesformatter = bytesformatter |
|
57 |
|
58 origord = builtins.ord |
|
59 def fakeord(char): |
|
60 if isinstance(char, int): |
|
61 return char |
|
62 return origord(char) |
|
63 builtins.ord = fakeord |
|
64 |
|
65 if __name__ == '__main__': |
|
66 import doctest |
|
67 doctest.testmod() |
|
68 |
|