##// END OF EJS Templates
Hide dynamically defined metaclass base from Sphinx....
Thomas Kluyver -
Show More
@@ -1,242 +1,242 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 input = input
78 builtin_mod_name = "builtins"
78 builtin_mod_name = "builtins"
79 import builtins as builtin_mod
79 import builtins as builtin_mod
80
80
81 str_to_unicode = no_code
81 str_to_unicode = no_code
82 unicode_to_str = no_code
82 unicode_to_str = no_code
83 str_to_bytes = encode
83 str_to_bytes = encode
84 bytes_to_str = decode
84 bytes_to_str = decode
85 cast_bytes_py2 = no_code
85 cast_bytes_py2 = no_code
86
86
87 string_types = (str,)
87 string_types = (str,)
88 unicode_type = str
88 unicode_type = str
89
89
90 def isidentifier(s, dotted=False):
90 def isidentifier(s, dotted=False):
91 if dotted:
91 if dotted:
92 return all(isidentifier(a) for a in s.split("."))
92 return all(isidentifier(a) for a in s.split("."))
93 return s.isidentifier()
93 return s.isidentifier()
94
94
95 open = orig_open
95 open = orig_open
96 xrange = range
96 xrange = range
97 def iteritems(d): return iter(d.items())
97 def iteritems(d): return iter(d.items())
98 def itervalues(d): return iter(d.values())
98 def itervalues(d): return iter(d.values())
99 getcwd = os.getcwd
99 getcwd = os.getcwd
100
100
101 MethodType = types.MethodType
101 MethodType = types.MethodType
102
102
103 def execfile(fname, glob, loc=None):
103 def execfile(fname, glob, loc=None):
104 loc = loc if (loc is not None) else glob
104 loc = loc if (loc is not None) else glob
105 with open(fname, 'rb') as f:
105 with open(fname, 'rb') as f:
106 exec(compile(f.read(), fname, 'exec'), glob, loc)
106 exec(compile(f.read(), fname, 'exec'), glob, loc)
107
107
108 # Refactor print statements in doctests.
108 # Refactor print statements in doctests.
109 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
109 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
110 def _print_statement_sub(match):
110 def _print_statement_sub(match):
111 expr = match.groups('expr')
111 expr = match.groups('expr')
112 return "print(%s)" % expr
112 return "print(%s)" % expr
113
113
114 @_modify_str_or_docstring
114 @_modify_str_or_docstring
115 def doctest_refactor_print(doc):
115 def doctest_refactor_print(doc):
116 """Refactor 'print x' statements in a doctest to print(x) style. 2to3
116 """Refactor 'print x' statements in a doctest to print(x) style. 2to3
117 unfortunately doesn't pick up on our doctests.
117 unfortunately doesn't pick up on our doctests.
118
118
119 Can accept a string or a function, so it can be used as a decorator."""
119 Can accept a string or a function, so it can be used as a decorator."""
120 return _print_statement_re.sub(_print_statement_sub, doc)
120 return _print_statement_re.sub(_print_statement_sub, doc)
121
121
122 # Abstract u'abc' syntax:
122 # Abstract u'abc' syntax:
123 @_modify_str_or_docstring
123 @_modify_str_or_docstring
124 def u_format(s):
124 def u_format(s):
125 """"{u}'abc'" --> "'abc'" (Python 3)
125 """"{u}'abc'" --> "'abc'" (Python 3)
126
126
127 Accepts a string or a function, so it can be used as a decorator."""
127 Accepts a string or a function, so it can be used as a decorator."""
128 return s.format(u='')
128 return s.format(u='')
129
129
130 else:
130 else:
131 PY3 = False
131 PY3 = False
132
132
133 input = raw_input
133 input = raw_input
134 builtin_mod_name = "__builtin__"
134 builtin_mod_name = "__builtin__"
135 import __builtin__ as builtin_mod
135 import __builtin__ as builtin_mod
136
136
137 str_to_unicode = decode
137 str_to_unicode = decode
138 unicode_to_str = encode
138 unicode_to_str = encode
139 str_to_bytes = no_code
139 str_to_bytes = no_code
140 bytes_to_str = no_code
140 bytes_to_str = no_code
141 cast_bytes_py2 = cast_bytes
141 cast_bytes_py2 = cast_bytes
142
142
143 string_types = (str, unicode)
143 string_types = (str, unicode)
144 unicode_type = unicode
144 unicode_type = unicode
145
145
146 import re
146 import re
147 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
147 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
148 def isidentifier(s, dotted=False):
148 def isidentifier(s, dotted=False):
149 if dotted:
149 if dotted:
150 return all(isidentifier(a) for a in s.split("."))
150 return all(isidentifier(a) for a in s.split("."))
151 return bool(_name_re.match(s))
151 return bool(_name_re.match(s))
152
152
153 class open(object):
153 class open(object):
154 """Wrapper providing key part of Python 3 open() interface."""
154 """Wrapper providing key part of Python 3 open() interface."""
155 def __init__(self, fname, mode="r", encoding="utf-8"):
155 def __init__(self, fname, mode="r", encoding="utf-8"):
156 self.f = orig_open(fname, mode)
156 self.f = orig_open(fname, mode)
157 self.enc = encoding
157 self.enc = encoding
158
158
159 def write(self, s):
159 def write(self, s):
160 return self.f.write(s.encode(self.enc))
160 return self.f.write(s.encode(self.enc))
161
161
162 def read(self, size=-1):
162 def read(self, size=-1):
163 return self.f.read(size).decode(self.enc)
163 return self.f.read(size).decode(self.enc)
164
164
165 def close(self):
165 def close(self):
166 return self.f.close()
166 return self.f.close()
167
167
168 def __enter__(self):
168 def __enter__(self):
169 return self
169 return self
170
170
171 def __exit__(self, etype, value, traceback):
171 def __exit__(self, etype, value, traceback):
172 self.f.close()
172 self.f.close()
173
173
174 xrange = xrange
174 xrange = xrange
175 def iteritems(d): return d.iteritems()
175 def iteritems(d): return d.iteritems()
176 def itervalues(d): return d.itervalues()
176 def itervalues(d): return d.itervalues()
177 getcwd = os.getcwdu
177 getcwd = os.getcwdu
178
178
179 def MethodType(func, instance):
179 def MethodType(func, instance):
180 return types.MethodType(func, instance, type(instance))
180 return types.MethodType(func, instance, type(instance))
181
181
182 # don't override system execfile on 2.x:
182 # don't override system execfile on 2.x:
183 execfile = execfile
183 execfile = execfile
184
184
185 def doctest_refactor_print(func_or_str):
185 def doctest_refactor_print(func_or_str):
186 return func_or_str
186 return func_or_str
187
187
188
188
189 # Abstract u'abc' syntax:
189 # Abstract u'abc' syntax:
190 @_modify_str_or_docstring
190 @_modify_str_or_docstring
191 def u_format(s):
191 def u_format(s):
192 """"{u}'abc'" --> "u'abc'" (Python 2)
192 """"{u}'abc'" --> "u'abc'" (Python 2)
193
193
194 Accepts a string or a function, so it can be used as a decorator."""
194 Accepts a string or a function, so it can be used as a decorator."""
195 return s.format(u='u')
195 return s.format(u='u')
196
196
197 if sys.platform == 'win32':
197 if sys.platform == 'win32':
198 def execfile(fname, glob=None, loc=None):
198 def execfile(fname, glob=None, loc=None):
199 loc = loc if (loc is not None) else glob
199 loc = loc if (loc is not None) else glob
200 # The rstrip() is necessary b/c trailing whitespace in files will
200 # The rstrip() is necessary b/c trailing whitespace in files will
201 # cause an IndentationError in Python 2.6 (this was fixed in 2.7,
201 # cause an IndentationError in Python 2.6 (this was fixed in 2.7,
202 # but we still support 2.6). See issue 1027.
202 # but we still support 2.6). See issue 1027.
203 scripttext = builtin_mod.open(fname).read().rstrip() + '\n'
203 scripttext = builtin_mod.open(fname).read().rstrip() + '\n'
204 # compile converts unicode filename to str assuming
204 # compile converts unicode filename to str assuming
205 # ascii. Let's do the conversion before calling compile
205 # ascii. Let's do the conversion before calling compile
206 if isinstance(fname, unicode):
206 if isinstance(fname, unicode):
207 filename = unicode_to_str(fname)
207 filename = unicode_to_str(fname)
208 else:
208 else:
209 filename = fname
209 filename = fname
210 exec(compile(scripttext, filename, 'exec'), glob, loc)
210 exec(compile(scripttext, filename, 'exec'), glob, loc)
211 else:
211 else:
212 def execfile(fname, *where):
212 def execfile(fname, *where):
213 if isinstance(fname, unicode):
213 if isinstance(fname, unicode):
214 filename = fname.encode(sys.getfilesystemencoding())
214 filename = fname.encode(sys.getfilesystemencoding())
215 else:
215 else:
216 filename = fname
216 filename = fname
217 builtin_mod.execfile(filename, *where)
217 builtin_mod.execfile(filename, *where)
218
218
219 # Parts below taken from six:
219 # Parts below taken from six:
220 # Copyright (c) 2010-2013 Benjamin Peterson
220 # Copyright (c) 2010-2013 Benjamin Peterson
221 #
221 #
222 # Permission is hereby granted, free of charge, to any person obtaining a copy
222 # Permission is hereby granted, free of charge, to any person obtaining a copy
223 # of this software and associated documentation files (the "Software"), to deal
223 # of this software and associated documentation files (the "Software"), to deal
224 # in the Software without restriction, including without limitation the rights
224 # in the Software without restriction, including without limitation the rights
225 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
225 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
226 # copies of the Software, and to permit persons to whom the Software is
226 # copies of the Software, and to permit persons to whom the Software is
227 # furnished to do so, subject to the following conditions:
227 # furnished to do so, subject to the following conditions:
228 #
228 #
229 # The above copyright notice and this permission notice shall be included in all
229 # The above copyright notice and this permission notice shall be included in all
230 # copies or substantial portions of the Software.
230 # copies or substantial portions of the Software.
231 #
231 #
232 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
232 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
233 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
233 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
234 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
234 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
235 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
235 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
236 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
236 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
237 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
237 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
238 # SOFTWARE.
238 # SOFTWARE.
239
239
240 def with_metaclass(meta, *bases):
240 def with_metaclass(meta, *bases):
241 """Create a base class with a metaclass."""
241 """Create a base class with a metaclass."""
242 return meta("NewBase", bases, {})
242 return meta("_NewBase", bases, {})
General Comments 0
You need to be logged in to leave comments. Login now