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