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