##// END OF EJS Templates
Fix doctest_run_option_parser for Windows...
Takafumi Arakaki -
Show More
@@ -1,272 +1,301 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for code execution (%run and related), which is particularly tricky.
2 """Tests for code execution (%run and related), which is particularly tricky.
3
3
4 Because of how %run manages namespaces, and the fact that we are trying here to
4 Because of how %run manages namespaces, and the fact that we are trying here to
5 verify subtle object deletion and reference counting issues, the %run tests
5 verify subtle object deletion and reference counting issues, the %run tests
6 will be kept in this separate file. This makes it easier to aggregate in one
6 will be kept in this separate file. This makes it easier to aggregate in one
7 place the tricks needed to handle it; most other magics are much easier to test
7 place the tricks needed to handle it; most other magics are much easier to test
8 and we do so in a common test_magic file.
8 and we do so in a common test_magic file.
9 """
9 """
10 from __future__ import absolute_import
10 from __future__ import absolute_import
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 import os
16 import os
17 import sys
17 import sys
18 import tempfile
18 import tempfile
19
19
20 import nose.tools as nt
20 import nose.tools as nt
21 from nose import SkipTest
21 from nose import SkipTest
22
22
23 from IPython.testing import decorators as dec
23 from IPython.testing import decorators as dec
24 from IPython.testing import tools as tt
24 from IPython.testing import tools as tt
25 from IPython.utils import py3compat
25 from IPython.utils import py3compat
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Test functions begin
28 # Test functions begin
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31 def doctest_refbug():
31 def doctest_refbug():
32 """Very nasty problem with references held by multiple runs of a script.
32 """Very nasty problem with references held by multiple runs of a script.
33 See: https://github.com/ipython/ipython/issues/141
33 See: https://github.com/ipython/ipython/issues/141
34
34
35 In [1]: _ip.clear_main_mod_cache()
35 In [1]: _ip.clear_main_mod_cache()
36 # random
36 # random
37
37
38 In [2]: %run refbug
38 In [2]: %run refbug
39
39
40 In [3]: call_f()
40 In [3]: call_f()
41 lowercased: hello
41 lowercased: hello
42
42
43 In [4]: %run refbug
43 In [4]: %run refbug
44
44
45 In [5]: call_f()
45 In [5]: call_f()
46 lowercased: hello
46 lowercased: hello
47 lowercased: hello
47 lowercased: hello
48 """
48 """
49
49
50
50
51 def doctest_run_builtins():
51 def doctest_run_builtins():
52 r"""Check that %run doesn't damage __builtins__.
52 r"""Check that %run doesn't damage __builtins__.
53
53
54 In [1]: import tempfile
54 In [1]: import tempfile
55
55
56 In [2]: bid1 = id(__builtins__)
56 In [2]: bid1 = id(__builtins__)
57
57
58 In [3]: fname = tempfile.mkstemp('.py')[1]
58 In [3]: fname = tempfile.mkstemp('.py')[1]
59
59
60 In [3]: f = open(fname,'w')
60 In [3]: f = open(fname,'w')
61
61
62 In [4]: dummy= f.write('pass\n')
62 In [4]: dummy= f.write('pass\n')
63
63
64 In [5]: f.flush()
64 In [5]: f.flush()
65
65
66 In [6]: t1 = type(__builtins__)
66 In [6]: t1 = type(__builtins__)
67
67
68 In [7]: %run $fname
68 In [7]: %run $fname
69
69
70 In [7]: f.close()
70 In [7]: f.close()
71
71
72 In [8]: bid2 = id(__builtins__)
72 In [8]: bid2 = id(__builtins__)
73
73
74 In [9]: t2 = type(__builtins__)
74 In [9]: t2 = type(__builtins__)
75
75
76 In [10]: t1 == t2
76 In [10]: t1 == t2
77 Out[10]: True
77 Out[10]: True
78
78
79 In [10]: bid1 == bid2
79 In [10]: bid1 == bid2
80 Out[10]: True
80 Out[10]: True
81
81
82 In [12]: try:
82 In [12]: try:
83 ....: os.unlink(fname)
83 ....: os.unlink(fname)
84 ....: except:
84 ....: except:
85 ....: pass
85 ....: pass
86 ....:
86 ....:
87 """
87 """
88
88
89
89
90 def doctest_run_option_parser():
90 def doctest_run_option_parser():
91 r"""Test option parser in %run.
91 r"""Test option parser in %run.
92
92
93 In [1]: %run print_argv.py
93 In [1]: %run print_argv.py
94 []
94 []
95
95
96 In [2]: %run print_argv.py print*.py
96 In [2]: %run print_argv.py print*.py
97 ['print_argv.py']
97 ['print_argv.py']
98
98
99 In [3]: %run print_argv.py print\\*.py
99 In [3]: %run -G print_argv.py print*.py
100 ['print*.py']
100 ['print*.py']
101
101
102 In [4]: %run print_argv.py 'print*.py'
102 """
103
104
105 @dec.skip_win32
106 def doctest_run_option_parser_for_posix():
107 r"""Test option parser in %run (Linux/OSX specific).
108
109 You need double quote to escape glob in POSIX systems:
110
111 In [1]: %run print_argv.py print\\*.py
112 ['print*.py']
113
114 You can't use quote to escape glob in POSIX systems:
115
116 In [2]: %run print_argv.py 'print*.py'
103 ['print_argv.py']
117 ['print_argv.py']
104
118
105 In [5]: %run -G print_argv.py print*.py
119 """
120
121
122 @dec.skip_linux
123 @dec.skip_osx
124 def doctest_run_option_parser_for_windows():
125 r"""Test option parser in %run (Windows specific).
126
127 In Windows, you can't escape ``*` `by backslash:
128
129 In [1]: %run print_argv.py print\\*.py
130 ['print\\*.py']
131
132 You can use quote to escape glob:
133
134 In [2]: %run print_argv.py 'print*.py'
106 ['print*.py']
135 ['print*.py']
107
136
108 """
137 """
109
138
110
139
111 @py3compat.doctest_refactor_print
140 @py3compat.doctest_refactor_print
112 def doctest_reset_del():
141 def doctest_reset_del():
113 """Test that resetting doesn't cause errors in __del__ methods.
142 """Test that resetting doesn't cause errors in __del__ methods.
114
143
115 In [2]: class A(object):
144 In [2]: class A(object):
116 ...: def __del__(self):
145 ...: def __del__(self):
117 ...: print str("Hi")
146 ...: print str("Hi")
118 ...:
147 ...:
119
148
120 In [3]: a = A()
149 In [3]: a = A()
121
150
122 In [4]: get_ipython().reset()
151 In [4]: get_ipython().reset()
123 Hi
152 Hi
124
153
125 In [5]: 1+1
154 In [5]: 1+1
126 Out[5]: 2
155 Out[5]: 2
127 """
156 """
128
157
129 # For some tests, it will be handy to organize them in a class with a common
158 # For some tests, it will be handy to organize them in a class with a common
130 # setup that makes a temp file
159 # setup that makes a temp file
131
160
132 class TestMagicRunPass(tt.TempFileMixin):
161 class TestMagicRunPass(tt.TempFileMixin):
133
162
134 def setup(self):
163 def setup(self):
135 """Make a valid python temp file."""
164 """Make a valid python temp file."""
136 self.mktmp('pass\n')
165 self.mktmp('pass\n')
137
166
138 def run_tmpfile(self):
167 def run_tmpfile(self):
139 _ip = get_ipython()
168 _ip = get_ipython()
140 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
169 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
141 # See below and ticket https://bugs.launchpad.net/bugs/366353
170 # See below and ticket https://bugs.launchpad.net/bugs/366353
142 _ip.magic('run %s' % self.fname)
171 _ip.magic('run %s' % self.fname)
143
172
144 def run_tmpfile_p(self):
173 def run_tmpfile_p(self):
145 _ip = get_ipython()
174 _ip = get_ipython()
146 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
175 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
147 # See below and ticket https://bugs.launchpad.net/bugs/366353
176 # See below and ticket https://bugs.launchpad.net/bugs/366353
148 _ip.magic('run -p %s' % self.fname)
177 _ip.magic('run -p %s' % self.fname)
149
178
150 def test_builtins_id(self):
179 def test_builtins_id(self):
151 """Check that %run doesn't damage __builtins__ """
180 """Check that %run doesn't damage __builtins__ """
152 _ip = get_ipython()
181 _ip = get_ipython()
153 # Test that the id of __builtins__ is not modified by %run
182 # Test that the id of __builtins__ is not modified by %run
154 bid1 = id(_ip.user_ns['__builtins__'])
183 bid1 = id(_ip.user_ns['__builtins__'])
155 self.run_tmpfile()
184 self.run_tmpfile()
156 bid2 = id(_ip.user_ns['__builtins__'])
185 bid2 = id(_ip.user_ns['__builtins__'])
157 nt.assert_equal(bid1, bid2)
186 nt.assert_equal(bid1, bid2)
158
187
159 def test_builtins_type(self):
188 def test_builtins_type(self):
160 """Check that the type of __builtins__ doesn't change with %run.
189 """Check that the type of __builtins__ doesn't change with %run.
161
190
162 However, the above could pass if __builtins__ was already modified to
191 However, the above could pass if __builtins__ was already modified to
163 be a dict (it should be a module) by a previous use of %run. So we
192 be a dict (it should be a module) by a previous use of %run. So we
164 also check explicitly that it really is a module:
193 also check explicitly that it really is a module:
165 """
194 """
166 _ip = get_ipython()
195 _ip = get_ipython()
167 self.run_tmpfile()
196 self.run_tmpfile()
168 nt.assert_equal(type(_ip.user_ns['__builtins__']),type(sys))
197 nt.assert_equal(type(_ip.user_ns['__builtins__']),type(sys))
169
198
170 def test_prompts(self):
199 def test_prompts(self):
171 """Test that prompts correctly generate after %run"""
200 """Test that prompts correctly generate after %run"""
172 self.run_tmpfile()
201 self.run_tmpfile()
173 _ip = get_ipython()
202 _ip = get_ipython()
174 p2 = _ip.prompt_manager.render('in2').strip()
203 p2 = _ip.prompt_manager.render('in2').strip()
175 nt.assert_equal(p2[:3], '...')
204 nt.assert_equal(p2[:3], '...')
176
205
177 def test_run_profile( self ):
206 def test_run_profile( self ):
178 """Test that the option -p, which invokes the profiler, do not
207 """Test that the option -p, which invokes the profiler, do not
179 crash by invoking execfile"""
208 crash by invoking execfile"""
180 _ip = get_ipython()
209 _ip = get_ipython()
181 self.run_tmpfile_p()
210 self.run_tmpfile_p()
182
211
183
212
184 class TestMagicRunSimple(tt.TempFileMixin):
213 class TestMagicRunSimple(tt.TempFileMixin):
185
214
186 def test_simpledef(self):
215 def test_simpledef(self):
187 """Test that simple class definitions work."""
216 """Test that simple class definitions work."""
188 src = ("class foo: pass\n"
217 src = ("class foo: pass\n"
189 "def f(): return foo()")
218 "def f(): return foo()")
190 self.mktmp(src)
219 self.mktmp(src)
191 _ip.magic('run %s' % self.fname)
220 _ip.magic('run %s' % self.fname)
192 _ip.run_cell('t = isinstance(f(), foo)')
221 _ip.run_cell('t = isinstance(f(), foo)')
193 nt.assert_true(_ip.user_ns['t'])
222 nt.assert_true(_ip.user_ns['t'])
194
223
195 def test_obj_del(self):
224 def test_obj_del(self):
196 """Test that object's __del__ methods are called on exit."""
225 """Test that object's __del__ methods are called on exit."""
197 if sys.platform == 'win32':
226 if sys.platform == 'win32':
198 try:
227 try:
199 import win32api
228 import win32api
200 except ImportError:
229 except ImportError:
201 raise SkipTest("Test requires pywin32")
230 raise SkipTest("Test requires pywin32")
202 src = ("class A(object):\n"
231 src = ("class A(object):\n"
203 " def __del__(self):\n"
232 " def __del__(self):\n"
204 " print 'object A deleted'\n"
233 " print 'object A deleted'\n"
205 "a = A()\n")
234 "a = A()\n")
206 self.mktmp(py3compat.doctest_refactor_print(src))
235 self.mktmp(py3compat.doctest_refactor_print(src))
207 if dec.module_not_available('sqlite3'):
236 if dec.module_not_available('sqlite3'):
208 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
237 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
209 else:
238 else:
210 err = None
239 err = None
211 tt.ipexec_validate(self.fname, 'object A deleted', err)
240 tt.ipexec_validate(self.fname, 'object A deleted', err)
212
241
213 @dec.skip_known_failure
242 @dec.skip_known_failure
214 def test_aggressive_namespace_cleanup(self):
243 def test_aggressive_namespace_cleanup(self):
215 """Test that namespace cleanup is not too aggressive GH-238
244 """Test that namespace cleanup is not too aggressive GH-238
216
245
217 Returning from another run magic deletes the namespace"""
246 Returning from another run magic deletes the namespace"""
218 # see ticket https://github.com/ipython/ipython/issues/238
247 # see ticket https://github.com/ipython/ipython/issues/238
219 class secondtmp(tt.TempFileMixin): pass
248 class secondtmp(tt.TempFileMixin): pass
220 empty = secondtmp()
249 empty = secondtmp()
221 empty.mktmp('')
250 empty.mktmp('')
222 src = ("ip = get_ipython()\n"
251 src = ("ip = get_ipython()\n"
223 "for i in range(5):\n"
252 "for i in range(5):\n"
224 " try:\n"
253 " try:\n"
225 " ip.magic('run %s')\n"
254 " ip.magic('run %s')\n"
226 " except NameError as e:\n"
255 " except NameError as e:\n"
227 " print i;break\n" % empty.fname)
256 " print i;break\n" % empty.fname)
228 self.mktmp(py3compat.doctest_refactor_print(src))
257 self.mktmp(py3compat.doctest_refactor_print(src))
229 _ip.magic('run %s' % self.fname)
258 _ip.magic('run %s' % self.fname)
230 _ip.run_cell('ip == get_ipython()')
259 _ip.run_cell('ip == get_ipython()')
231 nt.assert_equal(_ip.user_ns['i'], 5)
260 nt.assert_equal(_ip.user_ns['i'], 5)
232
261
233 @dec.skip_win32
262 @dec.skip_win32
234 def test_tclass(self):
263 def test_tclass(self):
235 mydir = os.path.dirname(__file__)
264 mydir = os.path.dirname(__file__)
236 tc = os.path.join(mydir, 'tclass')
265 tc = os.path.join(mydir, 'tclass')
237 src = ("%%run '%s' C-first\n"
266 src = ("%%run '%s' C-first\n"
238 "%%run '%s' C-second\n"
267 "%%run '%s' C-second\n"
239 "%%run '%s' C-third\n") % (tc, tc, tc)
268 "%%run '%s' C-third\n") % (tc, tc, tc)
240 self.mktmp(src, '.ipy')
269 self.mktmp(src, '.ipy')
241 out = """\
270 out = """\
242 ARGV 1-: ['C-first']
271 ARGV 1-: ['C-first']
243 ARGV 1-: ['C-second']
272 ARGV 1-: ['C-second']
244 tclass.py: deleting object: C-first
273 tclass.py: deleting object: C-first
245 ARGV 1-: ['C-third']
274 ARGV 1-: ['C-third']
246 tclass.py: deleting object: C-second
275 tclass.py: deleting object: C-second
247 tclass.py: deleting object: C-third
276 tclass.py: deleting object: C-third
248 """
277 """
249 if dec.module_not_available('sqlite3'):
278 if dec.module_not_available('sqlite3'):
250 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
279 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
251 else:
280 else:
252 err = None
281 err = None
253 tt.ipexec_validate(self.fname, out, err)
282 tt.ipexec_validate(self.fname, out, err)
254
283
255 def test_run_i_after_reset(self):
284 def test_run_i_after_reset(self):
256 """Check that %run -i still works after %reset (gh-693)"""
285 """Check that %run -i still works after %reset (gh-693)"""
257 src = "yy = zz\n"
286 src = "yy = zz\n"
258 self.mktmp(src)
287 self.mktmp(src)
259 _ip.run_cell("zz = 23")
288 _ip.run_cell("zz = 23")
260 _ip.magic('run -i %s' % self.fname)
289 _ip.magic('run -i %s' % self.fname)
261 nt.assert_equal(_ip.user_ns['yy'], 23)
290 nt.assert_equal(_ip.user_ns['yy'], 23)
262 _ip.magic('reset -f')
291 _ip.magic('reset -f')
263 _ip.run_cell("zz = 23")
292 _ip.run_cell("zz = 23")
264 _ip.magic('run -i %s' % self.fname)
293 _ip.magic('run -i %s' % self.fname)
265 nt.assert_equal(_ip.user_ns['yy'], 23)
294 nt.assert_equal(_ip.user_ns['yy'], 23)
266
295
267 def test_unicode(self):
296 def test_unicode(self):
268 """Check that files in odd encodings are accepted."""
297 """Check that files in odd encodings are accepted."""
269 mydir = os.path.dirname(__file__)
298 mydir = os.path.dirname(__file__)
270 na = os.path.join(mydir, 'nonascii.py')
299 na = os.path.join(mydir, 'nonascii.py')
271 _ip.magic('run "%s"' % na)
300 _ip.magic('run "%s"' % na)
272 nt.assert_equal(_ip.user_ns['u'], u'Ўт№Ф')
301 nt.assert_equal(_ip.user_ns['u'], u'Ўт№Ф')
General Comments 0
You need to be logged in to leave comments. Login now