##// END OF EJS Templates
always point py3compat.input to builtin_mod.input...
MinRK -
Show More
@@ -1,241 +1,249 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 functools
3 import functools
4 import os
4 import os
5 import sys
5 import sys
6 import re
6 import re
7 import types
7 import types
8
8
9 from .encoding import DEFAULT_ENCODING
9 from .encoding import DEFAULT_ENCODING
10
10
11 orig_open = open
11 orig_open = open
12
12
13 def no_code(x, encoding=None):
13 def no_code(x, encoding=None):
14 return x
14 return x
15
15
16 def decode(s, encoding=None):
16 def decode(s, encoding=None):
17 encoding = encoding or DEFAULT_ENCODING
17 encoding = encoding or DEFAULT_ENCODING
18 return s.decode(encoding, "replace")
18 return s.decode(encoding, "replace")
19
19
20 def encode(u, encoding=None):
20 def encode(u, encoding=None):
21 encoding = encoding or DEFAULT_ENCODING
21 encoding = encoding or DEFAULT_ENCODING
22 return u.encode(encoding, "replace")
22 return u.encode(encoding, "replace")
23
23
24
24
25 def cast_unicode(s, encoding=None):
25 def cast_unicode(s, encoding=None):
26 if isinstance(s, bytes):
26 if isinstance(s, bytes):
27 return decode(s, encoding)
27 return decode(s, encoding)
28 return s
28 return s
29
29
30 def cast_bytes(s, encoding=None):
30 def cast_bytes(s, encoding=None):
31 if not isinstance(s, bytes):
31 if not isinstance(s, bytes):
32 return encode(s, encoding)
32 return encode(s, encoding)
33 return s
33 return s
34
34
35 def _modify_str_or_docstring(str_change_func):
35 def _modify_str_or_docstring(str_change_func):
36 @functools.wraps(str_change_func)
36 @functools.wraps(str_change_func)
37 def wrapper(func_or_str):
37 def wrapper(func_or_str):
38 if isinstance(func_or_str, string_types):
38 if isinstance(func_or_str, string_types):
39 func = None
39 func = None
40 doc = func_or_str
40 doc = func_or_str
41 else:
41 else:
42 func = func_or_str
42 func = func_or_str
43 doc = func.__doc__
43 doc = func.__doc__
44
44
45 doc = str_change_func(doc)
45 doc = str_change_func(doc)
46
46
47 if func:
47 if func:
48 func.__doc__ = doc
48 func.__doc__ = doc
49 return func
49 return func
50 return doc
50 return doc
51 return wrapper
51 return wrapper
52
52
53 def safe_unicode(e):
53 def safe_unicode(e):
54 """unicode(e) with various fallbacks. Used for exceptions, which may not be
54 """unicode(e) with various fallbacks. Used for exceptions, which may not be
55 safe to call unicode() on.
55 safe to call unicode() on.
56 """
56 """
57 try:
57 try:
58 return unicode_type(e)
58 return unicode_type(e)
59 except UnicodeError:
59 except UnicodeError:
60 pass
60 pass
61
61
62 try:
62 try:
63 return str_to_unicode(str(e))
63 return str_to_unicode(str(e))
64 except UnicodeError:
64 except UnicodeError:
65 pass
65 pass
66
66
67 try:
67 try:
68 return str_to_unicode(repr(e))
68 return str_to_unicode(repr(e))
69 except UnicodeError:
69 except UnicodeError:
70 pass
70 pass
71
71
72 return u'Unrecoverably corrupt evalue'
72 return u'Unrecoverably corrupt evalue'
73
73
74 if sys.version_info[0] >= 3:
74 if sys.version_info[0] >= 3:
75 PY3 = True
75 PY3 = True
76
76
77 input = input
77 # keep reference to builtin_mod because the kernel overrides that value
78 # to forward requests to a frontend.
79 def input(prompt=''):
80 return builtin_mod.input(prompt)
81
78 builtin_mod_name = "builtins"
82 builtin_mod_name = "builtins"
79 import builtins as builtin_mod
83 import builtins as builtin_mod
80
84
81 str_to_unicode = no_code
85 str_to_unicode = no_code
82 unicode_to_str = no_code
86 unicode_to_str = no_code
83 str_to_bytes = encode
87 str_to_bytes = encode
84 bytes_to_str = decode
88 bytes_to_str = decode
85 cast_bytes_py2 = no_code
89 cast_bytes_py2 = no_code
86 cast_unicode_py2 = no_code
90 cast_unicode_py2 = no_code
87
91
88 string_types = (str,)
92 string_types = (str,)
89 unicode_type = str
93 unicode_type = str
90
94
91 def isidentifier(s, dotted=False):
95 def isidentifier(s, dotted=False):
92 if dotted:
96 if dotted:
93 return all(isidentifier(a) for a in s.split("."))
97 return all(isidentifier(a) for a in s.split("."))
94 return s.isidentifier()
98 return s.isidentifier()
95
99
96 open = orig_open
100 open = orig_open
97 xrange = range
101 xrange = range
98 def iteritems(d): return iter(d.items())
102 def iteritems(d): return iter(d.items())
99 def itervalues(d): return iter(d.values())
103 def itervalues(d): return iter(d.values())
100 getcwd = os.getcwd
104 getcwd = os.getcwd
101
105
102 MethodType = types.MethodType
106 MethodType = types.MethodType
103
107
104 def execfile(fname, glob, loc=None):
108 def execfile(fname, glob, loc=None):
105 loc = loc if (loc is not None) else glob
109 loc = loc if (loc is not None) else glob
106 with open(fname, 'rb') as f:
110 with open(fname, 'rb') as f:
107 exec(compile(f.read(), fname, 'exec'), glob, loc)
111 exec(compile(f.read(), fname, 'exec'), glob, loc)
108
112
109 # Refactor print statements in doctests.
113 # Refactor print statements in doctests.
110 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
114 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
111 def _print_statement_sub(match):
115 def _print_statement_sub(match):
112 expr = match.groups('expr')
116 expr = match.groups('expr')
113 return "print(%s)" % expr
117 return "print(%s)" % expr
114
118
115 @_modify_str_or_docstring
119 @_modify_str_or_docstring
116 def doctest_refactor_print(doc):
120 def doctest_refactor_print(doc):
117 """Refactor 'print x' statements in a doctest to print(x) style. 2to3
121 """Refactor 'print x' statements in a doctest to print(x) style. 2to3
118 unfortunately doesn't pick up on our doctests.
122 unfortunately doesn't pick up on our doctests.
119
123
120 Can accept a string or a function, so it can be used as a decorator."""
124 Can accept a string or a function, so it can be used as a decorator."""
121 return _print_statement_re.sub(_print_statement_sub, doc)
125 return _print_statement_re.sub(_print_statement_sub, doc)
122
126
123 # Abstract u'abc' syntax:
127 # Abstract u'abc' syntax:
124 @_modify_str_or_docstring
128 @_modify_str_or_docstring
125 def u_format(s):
129 def u_format(s):
126 """"{u}'abc'" --> "'abc'" (Python 3)
130 """"{u}'abc'" --> "'abc'" (Python 3)
127
131
128 Accepts a string or a function, so it can be used as a decorator."""
132 Accepts a string or a function, so it can be used as a decorator."""
129 return s.format(u='')
133 return s.format(u='')
130
134
131 else:
135 else:
132 PY3 = False
136 PY3 = False
133
137
134 input = raw_input
138 # keep reference to builtin_mod because the kernel overrides that value
139 # to forward requests to a frontend.
140 def input(prompt=''):
141 return builtin_mod.raw_input(prompt)
142
135 builtin_mod_name = "__builtin__"
143 builtin_mod_name = "__builtin__"
136 import __builtin__ as builtin_mod
144 import __builtin__ as builtin_mod
137
145
138 str_to_unicode = decode
146 str_to_unicode = decode
139 unicode_to_str = encode
147 unicode_to_str = encode
140 str_to_bytes = no_code
148 str_to_bytes = no_code
141 bytes_to_str = no_code
149 bytes_to_str = no_code
142 cast_bytes_py2 = cast_bytes
150 cast_bytes_py2 = cast_bytes
143 cast_unicode_py2 = cast_unicode
151 cast_unicode_py2 = cast_unicode
144
152
145 string_types = (str, unicode)
153 string_types = (str, unicode)
146 unicode_type = unicode
154 unicode_type = unicode
147
155
148 import re
156 import re
149 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
157 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
150 def isidentifier(s, dotted=False):
158 def isidentifier(s, dotted=False):
151 if dotted:
159 if dotted:
152 return all(isidentifier(a) for a in s.split("."))
160 return all(isidentifier(a) for a in s.split("."))
153 return bool(_name_re.match(s))
161 return bool(_name_re.match(s))
154
162
155 class open(object):
163 class open(object):
156 """Wrapper providing key part of Python 3 open() interface."""
164 """Wrapper providing key part of Python 3 open() interface."""
157 def __init__(self, fname, mode="r", encoding="utf-8"):
165 def __init__(self, fname, mode="r", encoding="utf-8"):
158 self.f = orig_open(fname, mode)
166 self.f = orig_open(fname, mode)
159 self.enc = encoding
167 self.enc = encoding
160
168
161 def write(self, s):
169 def write(self, s):
162 return self.f.write(s.encode(self.enc))
170 return self.f.write(s.encode(self.enc))
163
171
164 def read(self, size=-1):
172 def read(self, size=-1):
165 return self.f.read(size).decode(self.enc)
173 return self.f.read(size).decode(self.enc)
166
174
167 def close(self):
175 def close(self):
168 return self.f.close()
176 return self.f.close()
169
177
170 def __enter__(self):
178 def __enter__(self):
171 return self
179 return self
172
180
173 def __exit__(self, etype, value, traceback):
181 def __exit__(self, etype, value, traceback):
174 self.f.close()
182 self.f.close()
175
183
176 xrange = xrange
184 xrange = xrange
177 def iteritems(d): return d.iteritems()
185 def iteritems(d): return d.iteritems()
178 def itervalues(d): return d.itervalues()
186 def itervalues(d): return d.itervalues()
179 getcwd = os.getcwdu
187 getcwd = os.getcwdu
180
188
181 def MethodType(func, instance):
189 def MethodType(func, instance):
182 return types.MethodType(func, instance, type(instance))
190 return types.MethodType(func, instance, type(instance))
183
191
184 def doctest_refactor_print(func_or_str):
192 def doctest_refactor_print(func_or_str):
185 return func_or_str
193 return func_or_str
186
194
187
195
188 # Abstract u'abc' syntax:
196 # Abstract u'abc' syntax:
189 @_modify_str_or_docstring
197 @_modify_str_or_docstring
190 def u_format(s):
198 def u_format(s):
191 """"{u}'abc'" --> "u'abc'" (Python 2)
199 """"{u}'abc'" --> "u'abc'" (Python 2)
192
200
193 Accepts a string or a function, so it can be used as a decorator."""
201 Accepts a string or a function, so it can be used as a decorator."""
194 return s.format(u='u')
202 return s.format(u='u')
195
203
196 if sys.platform == 'win32':
204 if sys.platform == 'win32':
197 def execfile(fname, glob=None, loc=None):
205 def execfile(fname, glob=None, loc=None):
198 loc = loc if (loc is not None) else glob
206 loc = loc if (loc is not None) else glob
199 # The rstrip() is necessary b/c trailing whitespace in files will
207 # The rstrip() is necessary b/c trailing whitespace in files will
200 # cause an IndentationError in Python 2.6 (this was fixed in 2.7,
208 # cause an IndentationError in Python 2.6 (this was fixed in 2.7,
201 # but we still support 2.6). See issue 1027.
209 # but we still support 2.6). See issue 1027.
202 scripttext = builtin_mod.open(fname).read().rstrip() + '\n'
210 scripttext = builtin_mod.open(fname).read().rstrip() + '\n'
203 # compile converts unicode filename to str assuming
211 # compile converts unicode filename to str assuming
204 # ascii. Let's do the conversion before calling compile
212 # ascii. Let's do the conversion before calling compile
205 if isinstance(fname, unicode):
213 if isinstance(fname, unicode):
206 filename = unicode_to_str(fname)
214 filename = unicode_to_str(fname)
207 else:
215 else:
208 filename = fname
216 filename = fname
209 exec(compile(scripttext, filename, 'exec'), glob, loc)
217 exec(compile(scripttext, filename, 'exec'), glob, loc)
210 else:
218 else:
211 def execfile(fname, *where):
219 def execfile(fname, *where):
212 if isinstance(fname, unicode):
220 if isinstance(fname, unicode):
213 filename = fname.encode(sys.getfilesystemencoding())
221 filename = fname.encode(sys.getfilesystemencoding())
214 else:
222 else:
215 filename = fname
223 filename = fname
216 builtin_mod.execfile(filename, *where)
224 builtin_mod.execfile(filename, *where)
217
225
218 # Parts below taken from six:
226 # Parts below taken from six:
219 # Copyright (c) 2010-2013 Benjamin Peterson
227 # Copyright (c) 2010-2013 Benjamin Peterson
220 #
228 #
221 # Permission is hereby granted, free of charge, to any person obtaining a copy
229 # Permission is hereby granted, free of charge, to any person obtaining a copy
222 # of this software and associated documentation files (the "Software"), to deal
230 # of this software and associated documentation files (the "Software"), to deal
223 # in the Software without restriction, including without limitation the rights
231 # in the Software without restriction, including without limitation the rights
224 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
232 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
225 # copies of the Software, and to permit persons to whom the Software is
233 # copies of the Software, and to permit persons to whom the Software is
226 # furnished to do so, subject to the following conditions:
234 # furnished to do so, subject to the following conditions:
227 #
235 #
228 # The above copyright notice and this permission notice shall be included in all
236 # The above copyright notice and this permission notice shall be included in all
229 # copies or substantial portions of the Software.
237 # copies or substantial portions of the Software.
230 #
238 #
231 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
239 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
232 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
240 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
233 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
241 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
234 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
242 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
235 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
243 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
236 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
244 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
237 # SOFTWARE.
245 # SOFTWARE.
238
246
239 def with_metaclass(meta, *bases):
247 def with_metaclass(meta, *bases):
240 """Create a base class with a metaclass."""
248 """Create a base class with a metaclass."""
241 return meta("_NewBase", bases, {})
249 return meta("_NewBase", bases, {})
General Comments 0
You need to be logged in to leave comments. Login now