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