##// END OF EJS Templates
Function to refactor print statements in doctests to print() function calls for Python 3.
Thomas Kluyver -
Show More
@@ -1,99 +1,127 b''
1 1 # coding: utf-8
2 2 """Compatibility tricks for Python 3. Mainly to do with unicode."""
3 3 import sys
4 import re
4 5 import types
5 6
6 7 orig_open = open
7 8
8 9 def no_code(x, encoding=None):
9 10 return x
10 11
11 12 def decode(s, encoding=None):
12 13 encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding()
13 14 return s.decode(encoding, "replace")
14 15
15 16 def encode(u, encoding=None):
16 17 encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding()
17 18 return u.encode(encoding, "replace")
18 19
19 20 def cast_unicode(s, encoding=None):
20 21 if isinstance(s, bytes):
21 22 return decode(s, encoding)
22 23 return s
23 24
24 25 def cast_bytes(s, encoding=None):
25 26 if not isinstance(s, bytes):
26 27 return encode(s, encoding)
27 28 return s
28 29
29 30 if sys.version_info[0] >= 3:
30 31 PY3 = True
31 32
32 33 input = input
33 34 builtin_mod_name = "builtins"
34 35
35 36 str_to_unicode = no_code
36 37 unicode_to_str = no_code
37 38 str_to_bytes = encode
38 39 bytes_to_str = decode
39 40 cast_bytes_py2 = no_code
40 41
41 42 def isidentifier(s, dotted=False):
42 43 if dotted:
43 44 return all(isidentifier(a) for a in s.split("."))
44 45 return s.isidentifier()
45 46
46 47 open = orig_open
47 48
48 49 MethodType = types.MethodType
49 50
50 51 def execfile(fname, glob, loc=None):
51 52 loc = loc if (loc is not None) else glob
52 53 exec compile(open(fname).read(), fname, 'exec') in glob, loc
54
55 # Refactor print statements in doctests.
56 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
57 def _print_statement_sub(match):
58 expr = match.groups('expr')
59 return "print(%s)" % expr
60 def doctest_refactor_print(func_or_str):
61 """Refactor 'print x' statements in a doctest to print(x) style. 2to3
62 unfortunately doesn't pick up on our doctests.
63
64 Can accept a string or a function, so it can be used as a decorator."""
65 if isinstance(func_or_str, str):
66 func = None
67 doc = func_or_str
68 else:
69 func = func_or_str
70 doc = func.__doc__
71 doc = _print_statement_re.sub(_print_statement_sub, doc)
72
73 if func:
74 func.__doc__ = doc
75 return func
76 return doc
77
53 78
54 79 else:
55 80 PY3 = False
56 81
57 82 input = raw_input
58 83 builtin_mod_name = "__builtin__"
59 84
60 85 str_to_unicode = decode
61 86 unicode_to_str = encode
62 87 str_to_bytes = no_code
63 88 bytes_to_str = no_code
64 89 cast_bytes_py2 = cast_bytes
65 90
66 91 import re
67 92 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
68 93 def isidentifier(s, dotted=False):
69 94 if dotted:
70 95 return all(isidentifier(a) for a in s.split("."))
71 96 return bool(_name_re.match(s))
72 97
73 98 class open(object):
74 99 """Wrapper providing key part of Python 3 open() interface."""
75 100 def __init__(self, fname, mode="r", encoding="utf-8"):
76 101 self.f = orig_open(fname, mode)
77 102 self.enc = encoding
78 103
79 104 def write(self, s):
80 105 return self.f.write(s.encode(self.enc))
81 106
82 107 def read(self, size=-1):
83 108 return self.f.read(size).decode(self.enc)
84 109
85 110 def close(self):
86 111 return self.f.close()
87 112
88 113 def __enter__(self):
89 114 return self
90 115
91 116 def __exit__(self, etype, value, traceback):
92 117 self.f.close()
93 118
94 119 def MethodType(func, instance):
95 120 return types.MethodType(func, instance, type(instance))
96 121
97 122 # don't override system execfile on 2.x:
98 123 execfile = execfile
124
125 def doctest_refactor_print(func_or_str):
126 return func_or_str
99 127
General Comments 0
You need to be logged in to leave comments. Login now