##// END OF EJS Templates
Use skip_if_not_win32 instead of skip_linux+osx
Takafumi Arakaki -
Show More
@@ -1,301 +1,300 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 -G print_argv.py print*.py
99 In [3]: %run -G print_argv.py print*.py
100 ['print*.py']
100 ['print*.py']
101
101
102 """
102 """
103
103
104
104
105 @dec.skip_win32
105 @dec.skip_win32
106 def doctest_run_option_parser_for_posix():
106 def doctest_run_option_parser_for_posix():
107 r"""Test option parser in %run (Linux/OSX specific).
107 r"""Test option parser in %run (Linux/OSX specific).
108
108
109 You need double quote to escape glob in POSIX systems:
109 You need double quote to escape glob in POSIX systems:
110
110
111 In [1]: %run print_argv.py print\\*.py
111 In [1]: %run print_argv.py print\\*.py
112 ['print*.py']
112 ['print*.py']
113
113
114 You can't use quote to escape glob in POSIX systems:
114 You can't use quote to escape glob in POSIX systems:
115
115
116 In [2]: %run print_argv.py 'print*.py'
116 In [2]: %run print_argv.py 'print*.py'
117 ['print_argv.py']
117 ['print_argv.py']
118
118
119 """
119 """
120
120
121
121
122 @dec.skip_linux
122 @dec.skip_if_not_win32
123 @dec.skip_osx
124 def doctest_run_option_parser_for_windows():
123 def doctest_run_option_parser_for_windows():
125 r"""Test option parser in %run (Windows specific).
124 r"""Test option parser in %run (Windows specific).
126
125
127 In Windows, you can't escape ``*` `by backslash:
126 In Windows, you can't escape ``*` `by backslash:
128
127
129 In [1]: %run print_argv.py print\\*.py
128 In [1]: %run print_argv.py print\\*.py
130 ['print\\*.py']
129 ['print\\*.py']
131
130
132 You can use quote to escape glob:
131 You can use quote to escape glob:
133
132
134 In [2]: %run print_argv.py 'print*.py'
133 In [2]: %run print_argv.py 'print*.py'
135 ['print*.py']
134 ['print*.py']
136
135
137 """
136 """
138
137
139
138
140 @py3compat.doctest_refactor_print
139 @py3compat.doctest_refactor_print
141 def doctest_reset_del():
140 def doctest_reset_del():
142 """Test that resetting doesn't cause errors in __del__ methods.
141 """Test that resetting doesn't cause errors in __del__ methods.
143
142
144 In [2]: class A(object):
143 In [2]: class A(object):
145 ...: def __del__(self):
144 ...: def __del__(self):
146 ...: print str("Hi")
145 ...: print str("Hi")
147 ...:
146 ...:
148
147
149 In [3]: a = A()
148 In [3]: a = A()
150
149
151 In [4]: get_ipython().reset()
150 In [4]: get_ipython().reset()
152 Hi
151 Hi
153
152
154 In [5]: 1+1
153 In [5]: 1+1
155 Out[5]: 2
154 Out[5]: 2
156 """
155 """
157
156
158 # For some tests, it will be handy to organize them in a class with a common
157 # For some tests, it will be handy to organize them in a class with a common
159 # setup that makes a temp file
158 # setup that makes a temp file
160
159
161 class TestMagicRunPass(tt.TempFileMixin):
160 class TestMagicRunPass(tt.TempFileMixin):
162
161
163 def setup(self):
162 def setup(self):
164 """Make a valid python temp file."""
163 """Make a valid python temp file."""
165 self.mktmp('pass\n')
164 self.mktmp('pass\n')
166
165
167 def run_tmpfile(self):
166 def run_tmpfile(self):
168 _ip = get_ipython()
167 _ip = get_ipython()
169 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
168 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
170 # See below and ticket https://bugs.launchpad.net/bugs/366353
169 # See below and ticket https://bugs.launchpad.net/bugs/366353
171 _ip.magic('run %s' % self.fname)
170 _ip.magic('run %s' % self.fname)
172
171
173 def run_tmpfile_p(self):
172 def run_tmpfile_p(self):
174 _ip = get_ipython()
173 _ip = get_ipython()
175 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
174 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
176 # See below and ticket https://bugs.launchpad.net/bugs/366353
175 # See below and ticket https://bugs.launchpad.net/bugs/366353
177 _ip.magic('run -p %s' % self.fname)
176 _ip.magic('run -p %s' % self.fname)
178
177
179 def test_builtins_id(self):
178 def test_builtins_id(self):
180 """Check that %run doesn't damage __builtins__ """
179 """Check that %run doesn't damage __builtins__ """
181 _ip = get_ipython()
180 _ip = get_ipython()
182 # Test that the id of __builtins__ is not modified by %run
181 # Test that the id of __builtins__ is not modified by %run
183 bid1 = id(_ip.user_ns['__builtins__'])
182 bid1 = id(_ip.user_ns['__builtins__'])
184 self.run_tmpfile()
183 self.run_tmpfile()
185 bid2 = id(_ip.user_ns['__builtins__'])
184 bid2 = id(_ip.user_ns['__builtins__'])
186 nt.assert_equal(bid1, bid2)
185 nt.assert_equal(bid1, bid2)
187
186
188 def test_builtins_type(self):
187 def test_builtins_type(self):
189 """Check that the type of __builtins__ doesn't change with %run.
188 """Check that the type of __builtins__ doesn't change with %run.
190
189
191 However, the above could pass if __builtins__ was already modified to
190 However, the above could pass if __builtins__ was already modified to
192 be a dict (it should be a module) by a previous use of %run. So we
191 be a dict (it should be a module) by a previous use of %run. So we
193 also check explicitly that it really is a module:
192 also check explicitly that it really is a module:
194 """
193 """
195 _ip = get_ipython()
194 _ip = get_ipython()
196 self.run_tmpfile()
195 self.run_tmpfile()
197 nt.assert_equal(type(_ip.user_ns['__builtins__']),type(sys))
196 nt.assert_equal(type(_ip.user_ns['__builtins__']),type(sys))
198
197
199 def test_prompts(self):
198 def test_prompts(self):
200 """Test that prompts correctly generate after %run"""
199 """Test that prompts correctly generate after %run"""
201 self.run_tmpfile()
200 self.run_tmpfile()
202 _ip = get_ipython()
201 _ip = get_ipython()
203 p2 = _ip.prompt_manager.render('in2').strip()
202 p2 = _ip.prompt_manager.render('in2').strip()
204 nt.assert_equal(p2[:3], '...')
203 nt.assert_equal(p2[:3], '...')
205
204
206 def test_run_profile( self ):
205 def test_run_profile( self ):
207 """Test that the option -p, which invokes the profiler, do not
206 """Test that the option -p, which invokes the profiler, do not
208 crash by invoking execfile"""
207 crash by invoking execfile"""
209 _ip = get_ipython()
208 _ip = get_ipython()
210 self.run_tmpfile_p()
209 self.run_tmpfile_p()
211
210
212
211
213 class TestMagicRunSimple(tt.TempFileMixin):
212 class TestMagicRunSimple(tt.TempFileMixin):
214
213
215 def test_simpledef(self):
214 def test_simpledef(self):
216 """Test that simple class definitions work."""
215 """Test that simple class definitions work."""
217 src = ("class foo: pass\n"
216 src = ("class foo: pass\n"
218 "def f(): return foo()")
217 "def f(): return foo()")
219 self.mktmp(src)
218 self.mktmp(src)
220 _ip.magic('run %s' % self.fname)
219 _ip.magic('run %s' % self.fname)
221 _ip.run_cell('t = isinstance(f(), foo)')
220 _ip.run_cell('t = isinstance(f(), foo)')
222 nt.assert_true(_ip.user_ns['t'])
221 nt.assert_true(_ip.user_ns['t'])
223
222
224 def test_obj_del(self):
223 def test_obj_del(self):
225 """Test that object's __del__ methods are called on exit."""
224 """Test that object's __del__ methods are called on exit."""
226 if sys.platform == 'win32':
225 if sys.platform == 'win32':
227 try:
226 try:
228 import win32api
227 import win32api
229 except ImportError:
228 except ImportError:
230 raise SkipTest("Test requires pywin32")
229 raise SkipTest("Test requires pywin32")
231 src = ("class A(object):\n"
230 src = ("class A(object):\n"
232 " def __del__(self):\n"
231 " def __del__(self):\n"
233 " print 'object A deleted'\n"
232 " print 'object A deleted'\n"
234 "a = A()\n")
233 "a = A()\n")
235 self.mktmp(py3compat.doctest_refactor_print(src))
234 self.mktmp(py3compat.doctest_refactor_print(src))
236 if dec.module_not_available('sqlite3'):
235 if dec.module_not_available('sqlite3'):
237 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
236 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
238 else:
237 else:
239 err = None
238 err = None
240 tt.ipexec_validate(self.fname, 'object A deleted', err)
239 tt.ipexec_validate(self.fname, 'object A deleted', err)
241
240
242 @dec.skip_known_failure
241 @dec.skip_known_failure
243 def test_aggressive_namespace_cleanup(self):
242 def test_aggressive_namespace_cleanup(self):
244 """Test that namespace cleanup is not too aggressive GH-238
243 """Test that namespace cleanup is not too aggressive GH-238
245
244
246 Returning from another run magic deletes the namespace"""
245 Returning from another run magic deletes the namespace"""
247 # see ticket https://github.com/ipython/ipython/issues/238
246 # see ticket https://github.com/ipython/ipython/issues/238
248 class secondtmp(tt.TempFileMixin): pass
247 class secondtmp(tt.TempFileMixin): pass
249 empty = secondtmp()
248 empty = secondtmp()
250 empty.mktmp('')
249 empty.mktmp('')
251 src = ("ip = get_ipython()\n"
250 src = ("ip = get_ipython()\n"
252 "for i in range(5):\n"
251 "for i in range(5):\n"
253 " try:\n"
252 " try:\n"
254 " ip.magic('run %s')\n"
253 " ip.magic('run %s')\n"
255 " except NameError as e:\n"
254 " except NameError as e:\n"
256 " print i;break\n" % empty.fname)
255 " print i;break\n" % empty.fname)
257 self.mktmp(py3compat.doctest_refactor_print(src))
256 self.mktmp(py3compat.doctest_refactor_print(src))
258 _ip.magic('run %s' % self.fname)
257 _ip.magic('run %s' % self.fname)
259 _ip.run_cell('ip == get_ipython()')
258 _ip.run_cell('ip == get_ipython()')
260 nt.assert_equal(_ip.user_ns['i'], 5)
259 nt.assert_equal(_ip.user_ns['i'], 5)
261
260
262 @dec.skip_win32
261 @dec.skip_win32
263 def test_tclass(self):
262 def test_tclass(self):
264 mydir = os.path.dirname(__file__)
263 mydir = os.path.dirname(__file__)
265 tc = os.path.join(mydir, 'tclass')
264 tc = os.path.join(mydir, 'tclass')
266 src = ("%%run '%s' C-first\n"
265 src = ("%%run '%s' C-first\n"
267 "%%run '%s' C-second\n"
266 "%%run '%s' C-second\n"
268 "%%run '%s' C-third\n") % (tc, tc, tc)
267 "%%run '%s' C-third\n") % (tc, tc, tc)
269 self.mktmp(src, '.ipy')
268 self.mktmp(src, '.ipy')
270 out = """\
269 out = """\
271 ARGV 1-: ['C-first']
270 ARGV 1-: ['C-first']
272 ARGV 1-: ['C-second']
271 ARGV 1-: ['C-second']
273 tclass.py: deleting object: C-first
272 tclass.py: deleting object: C-first
274 ARGV 1-: ['C-third']
273 ARGV 1-: ['C-third']
275 tclass.py: deleting object: C-second
274 tclass.py: deleting object: C-second
276 tclass.py: deleting object: C-third
275 tclass.py: deleting object: C-third
277 """
276 """
278 if dec.module_not_available('sqlite3'):
277 if dec.module_not_available('sqlite3'):
279 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
278 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
280 else:
279 else:
281 err = None
280 err = None
282 tt.ipexec_validate(self.fname, out, err)
281 tt.ipexec_validate(self.fname, out, err)
283
282
284 def test_run_i_after_reset(self):
283 def test_run_i_after_reset(self):
285 """Check that %run -i still works after %reset (gh-693)"""
284 """Check that %run -i still works after %reset (gh-693)"""
286 src = "yy = zz\n"
285 src = "yy = zz\n"
287 self.mktmp(src)
286 self.mktmp(src)
288 _ip.run_cell("zz = 23")
287 _ip.run_cell("zz = 23")
289 _ip.magic('run -i %s' % self.fname)
288 _ip.magic('run -i %s' % self.fname)
290 nt.assert_equal(_ip.user_ns['yy'], 23)
289 nt.assert_equal(_ip.user_ns['yy'], 23)
291 _ip.magic('reset -f')
290 _ip.magic('reset -f')
292 _ip.run_cell("zz = 23")
291 _ip.run_cell("zz = 23")
293 _ip.magic('run -i %s' % self.fname)
292 _ip.magic('run -i %s' % self.fname)
294 nt.assert_equal(_ip.user_ns['yy'], 23)
293 nt.assert_equal(_ip.user_ns['yy'], 23)
295
294
296 def test_unicode(self):
295 def test_unicode(self):
297 """Check that files in odd encodings are accepted."""
296 """Check that files in odd encodings are accepted."""
298 mydir = os.path.dirname(__file__)
297 mydir = os.path.dirname(__file__)
299 na = os.path.join(mydir, 'nonascii.py')
298 na = os.path.join(mydir, 'nonascii.py')
300 _ip.magic('run "%s"' % na)
299 _ip.magic('run "%s"' % na)
301 nt.assert_equal(_ip.user_ns['u'], u'Ўт№Ф')
300 nt.assert_equal(_ip.user_ns['u'], u'Ўт№Ф')
General Comments 0
You need to be logged in to leave comments. Login now