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