##// END OF EJS Templates
Add a failing test for "%run -p -m ..."
Takafumi Arakaki -
Show More
@@ -1,393 +1,399 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 import unittest
19 import unittest
20 import textwrap
20 import textwrap
21 import random
21 import random
22
22
23 import nose.tools as nt
23 import nose.tools as nt
24 from nose import SkipTest
24 from nose import SkipTest
25
25
26 from IPython.testing import decorators as dec
26 from IPython.testing import decorators as dec
27 from IPython.testing import tools as tt
27 from IPython.testing import tools as tt
28 from IPython.utils import py3compat
28 from IPython.utils import py3compat
29 from IPython.utils.tempdir import TemporaryDirectory
29 from IPython.utils.tempdir import TemporaryDirectory
30
30
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32 # Test functions begin
32 # Test functions begin
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34
34
35 def doctest_refbug():
35 def doctest_refbug():
36 """Very nasty problem with references held by multiple runs of a script.
36 """Very nasty problem with references held by multiple runs of a script.
37 See: https://github.com/ipython/ipython/issues/141
37 See: https://github.com/ipython/ipython/issues/141
38
38
39 In [1]: _ip.clear_main_mod_cache()
39 In [1]: _ip.clear_main_mod_cache()
40 # random
40 # random
41
41
42 In [2]: %run refbug
42 In [2]: %run refbug
43
43
44 In [3]: call_f()
44 In [3]: call_f()
45 lowercased: hello
45 lowercased: hello
46
46
47 In [4]: %run refbug
47 In [4]: %run refbug
48
48
49 In [5]: call_f()
49 In [5]: call_f()
50 lowercased: hello
50 lowercased: hello
51 lowercased: hello
51 lowercased: hello
52 """
52 """
53
53
54
54
55 def doctest_run_builtins():
55 def doctest_run_builtins():
56 r"""Check that %run doesn't damage __builtins__.
56 r"""Check that %run doesn't damage __builtins__.
57
57
58 In [1]: import tempfile
58 In [1]: import tempfile
59
59
60 In [2]: bid1 = id(__builtins__)
60 In [2]: bid1 = id(__builtins__)
61
61
62 In [3]: fname = tempfile.mkstemp('.py')[1]
62 In [3]: fname = tempfile.mkstemp('.py')[1]
63
63
64 In [3]: f = open(fname,'w')
64 In [3]: f = open(fname,'w')
65
65
66 In [4]: dummy= f.write('pass\n')
66 In [4]: dummy= f.write('pass\n')
67
67
68 In [5]: f.flush()
68 In [5]: f.flush()
69
69
70 In [6]: t1 = type(__builtins__)
70 In [6]: t1 = type(__builtins__)
71
71
72 In [7]: %run $fname
72 In [7]: %run $fname
73
73
74 In [7]: f.close()
74 In [7]: f.close()
75
75
76 In [8]: bid2 = id(__builtins__)
76 In [8]: bid2 = id(__builtins__)
77
77
78 In [9]: t2 = type(__builtins__)
78 In [9]: t2 = type(__builtins__)
79
79
80 In [10]: t1 == t2
80 In [10]: t1 == t2
81 Out[10]: True
81 Out[10]: True
82
82
83 In [10]: bid1 == bid2
83 In [10]: bid1 == bid2
84 Out[10]: True
84 Out[10]: True
85
85
86 In [12]: try:
86 In [12]: try:
87 ....: os.unlink(fname)
87 ....: os.unlink(fname)
88 ....: except:
88 ....: except:
89 ....: pass
89 ....: pass
90 ....:
90 ....:
91 """
91 """
92
92
93
93
94 def doctest_run_option_parser():
94 def doctest_run_option_parser():
95 r"""Test option parser in %run.
95 r"""Test option parser in %run.
96
96
97 In [1]: %run print_argv.py
97 In [1]: %run print_argv.py
98 []
98 []
99
99
100 In [2]: %run print_argv.py print*.py
100 In [2]: %run print_argv.py print*.py
101 ['print_argv.py']
101 ['print_argv.py']
102
102
103 In [3]: %run -G print_argv.py print*.py
103 In [3]: %run -G print_argv.py print*.py
104 ['print*.py']
104 ['print*.py']
105
105
106 """
106 """
107
107
108
108
109 @dec.skip_win32
109 @dec.skip_win32
110 def doctest_run_option_parser_for_posix():
110 def doctest_run_option_parser_for_posix():
111 r"""Test option parser in %run (Linux/OSX specific).
111 r"""Test option parser in %run (Linux/OSX specific).
112
112
113 You need double quote to escape glob in POSIX systems:
113 You need double quote to escape glob in POSIX systems:
114
114
115 In [1]: %run print_argv.py print\\*.py
115 In [1]: %run print_argv.py print\\*.py
116 ['print*.py']
116 ['print*.py']
117
117
118 You can't use quote to escape glob in POSIX systems:
118 You can't use quote to escape glob in POSIX systems:
119
119
120 In [2]: %run print_argv.py 'print*.py'
120 In [2]: %run print_argv.py 'print*.py'
121 ['print_argv.py']
121 ['print_argv.py']
122
122
123 """
123 """
124
124
125
125
126 @dec.skip_if_not_win32
126 @dec.skip_if_not_win32
127 def doctest_run_option_parser_for_windows():
127 def doctest_run_option_parser_for_windows():
128 r"""Test option parser in %run (Windows specific).
128 r"""Test option parser in %run (Windows specific).
129
129
130 In Windows, you can't escape ``*` `by backslash:
130 In Windows, you can't escape ``*` `by backslash:
131
131
132 In [1]: %run print_argv.py print\\*.py
132 In [1]: %run print_argv.py print\\*.py
133 ['print\\*.py']
133 ['print\\*.py']
134
134
135 You can use quote to escape glob:
135 You can use quote to escape glob:
136
136
137 In [2]: %run print_argv.py 'print*.py'
137 In [2]: %run print_argv.py 'print*.py'
138 ['print*.py']
138 ['print*.py']
139
139
140 """
140 """
141
141
142
142
143 @py3compat.doctest_refactor_print
143 @py3compat.doctest_refactor_print
144 def doctest_reset_del():
144 def doctest_reset_del():
145 """Test that resetting doesn't cause errors in __del__ methods.
145 """Test that resetting doesn't cause errors in __del__ methods.
146
146
147 In [2]: class A(object):
147 In [2]: class A(object):
148 ...: def __del__(self):
148 ...: def __del__(self):
149 ...: print str("Hi")
149 ...: print str("Hi")
150 ...:
150 ...:
151
151
152 In [3]: a = A()
152 In [3]: a = A()
153
153
154 In [4]: get_ipython().reset()
154 In [4]: get_ipython().reset()
155 Hi
155 Hi
156
156
157 In [5]: 1+1
157 In [5]: 1+1
158 Out[5]: 2
158 Out[5]: 2
159 """
159 """
160
160
161 # For some tests, it will be handy to organize them in a class with a common
161 # For some tests, it will be handy to organize them in a class with a common
162 # setup that makes a temp file
162 # setup that makes a temp file
163
163
164 class TestMagicRunPass(tt.TempFileMixin):
164 class TestMagicRunPass(tt.TempFileMixin):
165
165
166 def setup(self):
166 def setup(self):
167 """Make a valid python temp file."""
167 """Make a valid python temp file."""
168 self.mktmp('pass\n')
168 self.mktmp('pass\n')
169
169
170 def run_tmpfile(self):
170 def run_tmpfile(self):
171 _ip = get_ipython()
171 _ip = get_ipython()
172 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
172 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
173 # See below and ticket https://bugs.launchpad.net/bugs/366353
173 # See below and ticket https://bugs.launchpad.net/bugs/366353
174 _ip.magic('run %s' % self.fname)
174 _ip.magic('run %s' % self.fname)
175
175
176 def run_tmpfile_p(self):
176 def run_tmpfile_p(self):
177 _ip = get_ipython()
177 _ip = get_ipython()
178 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
178 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
179 # See below and ticket https://bugs.launchpad.net/bugs/366353
179 # See below and ticket https://bugs.launchpad.net/bugs/366353
180 _ip.magic('run -p %s' % self.fname)
180 _ip.magic('run -p %s' % self.fname)
181
181
182 def test_builtins_id(self):
182 def test_builtins_id(self):
183 """Check that %run doesn't damage __builtins__ """
183 """Check that %run doesn't damage __builtins__ """
184 _ip = get_ipython()
184 _ip = get_ipython()
185 # Test that the id of __builtins__ is not modified by %run
185 # Test that the id of __builtins__ is not modified by %run
186 bid1 = id(_ip.user_ns['__builtins__'])
186 bid1 = id(_ip.user_ns['__builtins__'])
187 self.run_tmpfile()
187 self.run_tmpfile()
188 bid2 = id(_ip.user_ns['__builtins__'])
188 bid2 = id(_ip.user_ns['__builtins__'])
189 nt.assert_equal(bid1, bid2)
189 nt.assert_equal(bid1, bid2)
190
190
191 def test_builtins_type(self):
191 def test_builtins_type(self):
192 """Check that the type of __builtins__ doesn't change with %run.
192 """Check that the type of __builtins__ doesn't change with %run.
193
193
194 However, the above could pass if __builtins__ was already modified to
194 However, the above could pass if __builtins__ was already modified to
195 be a dict (it should be a module) by a previous use of %run. So we
195 be a dict (it should be a module) by a previous use of %run. So we
196 also check explicitly that it really is a module:
196 also check explicitly that it really is a module:
197 """
197 """
198 _ip = get_ipython()
198 _ip = get_ipython()
199 self.run_tmpfile()
199 self.run_tmpfile()
200 nt.assert_equal(type(_ip.user_ns['__builtins__']),type(sys))
200 nt.assert_equal(type(_ip.user_ns['__builtins__']),type(sys))
201
201
202 def test_prompts(self):
202 def test_prompts(self):
203 """Test that prompts correctly generate after %run"""
203 """Test that prompts correctly generate after %run"""
204 self.run_tmpfile()
204 self.run_tmpfile()
205 _ip = get_ipython()
205 _ip = get_ipython()
206 p2 = _ip.prompt_manager.render('in2').strip()
206 p2 = _ip.prompt_manager.render('in2').strip()
207 nt.assert_equal(p2[:3], '...')
207 nt.assert_equal(p2[:3], '...')
208
208
209 def test_run_profile( self ):
209 def test_run_profile( self ):
210 """Test that the option -p, which invokes the profiler, do not
210 """Test that the option -p, which invokes the profiler, do not
211 crash by invoking execfile"""
211 crash by invoking execfile"""
212 _ip = get_ipython()
212 _ip = get_ipython()
213 self.run_tmpfile_p()
213 self.run_tmpfile_p()
214
214
215
215
216 class TestMagicRunSimple(tt.TempFileMixin):
216 class TestMagicRunSimple(tt.TempFileMixin):
217
217
218 def test_simpledef(self):
218 def test_simpledef(self):
219 """Test that simple class definitions work."""
219 """Test that simple class definitions work."""
220 src = ("class foo: pass\n"
220 src = ("class foo: pass\n"
221 "def f(): return foo()")
221 "def f(): return foo()")
222 self.mktmp(src)
222 self.mktmp(src)
223 _ip.magic('run %s' % self.fname)
223 _ip.magic('run %s' % self.fname)
224 _ip.run_cell('t = isinstance(f(), foo)')
224 _ip.run_cell('t = isinstance(f(), foo)')
225 nt.assert_true(_ip.user_ns['t'])
225 nt.assert_true(_ip.user_ns['t'])
226
226
227 def test_obj_del(self):
227 def test_obj_del(self):
228 """Test that object's __del__ methods are called on exit."""
228 """Test that object's __del__ methods are called on exit."""
229 if sys.platform == 'win32':
229 if sys.platform == 'win32':
230 try:
230 try:
231 import win32api
231 import win32api
232 except ImportError:
232 except ImportError:
233 raise SkipTest("Test requires pywin32")
233 raise SkipTest("Test requires pywin32")
234 src = ("class A(object):\n"
234 src = ("class A(object):\n"
235 " def __del__(self):\n"
235 " def __del__(self):\n"
236 " print 'object A deleted'\n"
236 " print 'object A deleted'\n"
237 "a = A()\n")
237 "a = A()\n")
238 self.mktmp(py3compat.doctest_refactor_print(src))
238 self.mktmp(py3compat.doctest_refactor_print(src))
239 if dec.module_not_available('sqlite3'):
239 if dec.module_not_available('sqlite3'):
240 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
240 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
241 else:
241 else:
242 err = None
242 err = None
243 tt.ipexec_validate(self.fname, 'object A deleted', err)
243 tt.ipexec_validate(self.fname, 'object A deleted', err)
244
244
245 @dec.skip_known_failure
245 @dec.skip_known_failure
246 def test_aggressive_namespace_cleanup(self):
246 def test_aggressive_namespace_cleanup(self):
247 """Test that namespace cleanup is not too aggressive GH-238
247 """Test that namespace cleanup is not too aggressive GH-238
248
248
249 Returning from another run magic deletes the namespace"""
249 Returning from another run magic deletes the namespace"""
250 # see ticket https://github.com/ipython/ipython/issues/238
250 # see ticket https://github.com/ipython/ipython/issues/238
251 class secondtmp(tt.TempFileMixin): pass
251 class secondtmp(tt.TempFileMixin): pass
252 empty = secondtmp()
252 empty = secondtmp()
253 empty.mktmp('')
253 empty.mktmp('')
254 src = ("ip = get_ipython()\n"
254 src = ("ip = get_ipython()\n"
255 "for i in range(5):\n"
255 "for i in range(5):\n"
256 " try:\n"
256 " try:\n"
257 " ip.magic('run %s')\n"
257 " ip.magic('run %s')\n"
258 " except NameError as e:\n"
258 " except NameError as e:\n"
259 " print i;break\n" % empty.fname)
259 " print i;break\n" % empty.fname)
260 self.mktmp(py3compat.doctest_refactor_print(src))
260 self.mktmp(py3compat.doctest_refactor_print(src))
261 _ip.magic('run %s' % self.fname)
261 _ip.magic('run %s' % self.fname)
262 _ip.run_cell('ip == get_ipython()')
262 _ip.run_cell('ip == get_ipython()')
263 nt.assert_equal(_ip.user_ns['i'], 5)
263 nt.assert_equal(_ip.user_ns['i'], 5)
264
264
265 @dec.skip_win32
265 @dec.skip_win32
266 def test_tclass(self):
266 def test_tclass(self):
267 mydir = os.path.dirname(__file__)
267 mydir = os.path.dirname(__file__)
268 tc = os.path.join(mydir, 'tclass')
268 tc = os.path.join(mydir, 'tclass')
269 src = ("%%run '%s' C-first\n"
269 src = ("%%run '%s' C-first\n"
270 "%%run '%s' C-second\n"
270 "%%run '%s' C-second\n"
271 "%%run '%s' C-third\n") % (tc, tc, tc)
271 "%%run '%s' C-third\n") % (tc, tc, tc)
272 self.mktmp(src, '.ipy')
272 self.mktmp(src, '.ipy')
273 out = """\
273 out = """\
274 ARGV 1-: ['C-first']
274 ARGV 1-: ['C-first']
275 ARGV 1-: ['C-second']
275 ARGV 1-: ['C-second']
276 tclass.py: deleting object: C-first
276 tclass.py: deleting object: C-first
277 ARGV 1-: ['C-third']
277 ARGV 1-: ['C-third']
278 tclass.py: deleting object: C-second
278 tclass.py: deleting object: C-second
279 tclass.py: deleting object: C-third
279 tclass.py: deleting object: C-third
280 """
280 """
281 if dec.module_not_available('sqlite3'):
281 if dec.module_not_available('sqlite3'):
282 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
282 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
283 else:
283 else:
284 err = None
284 err = None
285 tt.ipexec_validate(self.fname, out, err)
285 tt.ipexec_validate(self.fname, out, err)
286
286
287 def test_run_i_after_reset(self):
287 def test_run_i_after_reset(self):
288 """Check that %run -i still works after %reset (gh-693)"""
288 """Check that %run -i still works after %reset (gh-693)"""
289 src = "yy = zz\n"
289 src = "yy = zz\n"
290 self.mktmp(src)
290 self.mktmp(src)
291 _ip.run_cell("zz = 23")
291 _ip.run_cell("zz = 23")
292 _ip.magic('run -i %s' % self.fname)
292 _ip.magic('run -i %s' % self.fname)
293 nt.assert_equal(_ip.user_ns['yy'], 23)
293 nt.assert_equal(_ip.user_ns['yy'], 23)
294 _ip.magic('reset -f')
294 _ip.magic('reset -f')
295 _ip.run_cell("zz = 23")
295 _ip.run_cell("zz = 23")
296 _ip.magic('run -i %s' % self.fname)
296 _ip.magic('run -i %s' % self.fname)
297 nt.assert_equal(_ip.user_ns['yy'], 23)
297 nt.assert_equal(_ip.user_ns['yy'], 23)
298
298
299 def test_unicode(self):
299 def test_unicode(self):
300 """Check that files in odd encodings are accepted."""
300 """Check that files in odd encodings are accepted."""
301 mydir = os.path.dirname(__file__)
301 mydir = os.path.dirname(__file__)
302 na = os.path.join(mydir, 'nonascii.py')
302 na = os.path.join(mydir, 'nonascii.py')
303 _ip.magic('run "%s"' % na)
303 _ip.magic('run "%s"' % na)
304 nt.assert_equal(_ip.user_ns['u'], u'ΠŽΡ‚β„–Π€')
304 nt.assert_equal(_ip.user_ns['u'], u'ΠŽΡ‚β„–Π€')
305
305
306 def test_run_py_file_attribute(self):
306 def test_run_py_file_attribute(self):
307 """Test handling of `__file__` attribute in `%run <file>.py`."""
307 """Test handling of `__file__` attribute in `%run <file>.py`."""
308 src = "t = __file__\n"
308 src = "t = __file__\n"
309 self.mktmp(src)
309 self.mktmp(src)
310 _missing = object()
310 _missing = object()
311 file1 = _ip.user_ns.get('__file__', _missing)
311 file1 = _ip.user_ns.get('__file__', _missing)
312 _ip.magic('run %s' % self.fname)
312 _ip.magic('run %s' % self.fname)
313 file2 = _ip.user_ns.get('__file__', _missing)
313 file2 = _ip.user_ns.get('__file__', _missing)
314
314
315 # Check that __file__ was equal to the filename in the script's
315 # Check that __file__ was equal to the filename in the script's
316 # namespace.
316 # namespace.
317 nt.assert_equal(_ip.user_ns['t'], self.fname)
317 nt.assert_equal(_ip.user_ns['t'], self.fname)
318
318
319 # Check that __file__ was not leaked back into user_ns.
319 # Check that __file__ was not leaked back into user_ns.
320 nt.assert_equal(file1, file2)
320 nt.assert_equal(file1, file2)
321
321
322 def test_run_ipy_file_attribute(self):
322 def test_run_ipy_file_attribute(self):
323 """Test handling of `__file__` attribute in `%run <file.ipy>`."""
323 """Test handling of `__file__` attribute in `%run <file.ipy>`."""
324 src = "t = __file__\n"
324 src = "t = __file__\n"
325 self.mktmp(src, ext='.ipy')
325 self.mktmp(src, ext='.ipy')
326 _missing = object()
326 _missing = object()
327 file1 = _ip.user_ns.get('__file__', _missing)
327 file1 = _ip.user_ns.get('__file__', _missing)
328 _ip.magic('run %s' % self.fname)
328 _ip.magic('run %s' % self.fname)
329 file2 = _ip.user_ns.get('__file__', _missing)
329 file2 = _ip.user_ns.get('__file__', _missing)
330
330
331 # Check that __file__ was equal to the filename in the script's
331 # Check that __file__ was equal to the filename in the script's
332 # namespace.
332 # namespace.
333 nt.assert_equal(_ip.user_ns['t'], self.fname)
333 nt.assert_equal(_ip.user_ns['t'], self.fname)
334
334
335 # Check that __file__ was not leaked back into user_ns.
335 # Check that __file__ was not leaked back into user_ns.
336 nt.assert_equal(file1, file2)
336 nt.assert_equal(file1, file2)
337
337
338 def test_run_formatting(self):
338 def test_run_formatting(self):
339 """ Test that %run -t -N<N> does not raise a TypeError for N > 1."""
339 """ Test that %run -t -N<N> does not raise a TypeError for N > 1."""
340 src = "pass"
340 src = "pass"
341 self.mktmp(src)
341 self.mktmp(src)
342 _ip.magic('run -t -N 1 %s' % self.fname)
342 _ip.magic('run -t -N 1 %s' % self.fname)
343 _ip.magic('run -t -N 10 %s' % self.fname)
343 _ip.magic('run -t -N 10 %s' % self.fname)
344
344
345
345
346 class TestMagicRunWithPackage(unittest.TestCase):
346 class TestMagicRunWithPackage(unittest.TestCase):
347
347
348 def writefile(self, name, content):
348 def writefile(self, name, content):
349 path = os.path.join(self.tempdir.name, name)
349 path = os.path.join(self.tempdir.name, name)
350 d = os.path.dirname(path)
350 d = os.path.dirname(path)
351 if not os.path.isdir(d):
351 if not os.path.isdir(d):
352 os.makedirs(d)
352 os.makedirs(d)
353 with open(path, 'w') as f:
353 with open(path, 'w') as f:
354 f.write(textwrap.dedent(content))
354 f.write(textwrap.dedent(content))
355
355
356 def setUp(self):
356 def setUp(self):
357 self.package = package = 'tmp{0}'.format(repr(random.random())[2:])
357 self.package = package = 'tmp{0}'.format(repr(random.random())[2:])
358 """Temporary valid python package name."""
358 """Temporary valid python package name."""
359
359
360 self.value = int(random.random() * 10000)
360 self.value = int(random.random() * 10000)
361
361
362 self.tempdir = TemporaryDirectory()
362 self.tempdir = TemporaryDirectory()
363 self.__orig_cwd = os.getcwdu()
363 self.__orig_cwd = os.getcwdu()
364 sys.path.insert(0, self.tempdir.name)
364 sys.path.insert(0, self.tempdir.name)
365
365
366 self.writefile(os.path.join(package, '__init__.py'), '')
366 self.writefile(os.path.join(package, '__init__.py'), '')
367 self.writefile(os.path.join(package, 'foo.py'), """
367 self.writefile(os.path.join(package, 'foo.py'), """
368 x = {0!r}
368 x = {0!r}
369 """.format(self.value))
369 """.format(self.value))
370 self.writefile(os.path.join(package, 'relative.py'), """
370 self.writefile(os.path.join(package, 'relative.py'), """
371 from .foo import x
371 from .foo import x
372 """)
372 """)
373 self.writefile(os.path.join(package, 'absolute.py'), """
373 self.writefile(os.path.join(package, 'absolute.py'), """
374 from {0}.foo import x
374 from {0}.foo import x
375 """.format(package))
375 """.format(package))
376
376
377 def tearDown(self):
377 def tearDown(self):
378 os.chdir(self.__orig_cwd)
378 os.chdir(self.__orig_cwd)
379 sys.path[:] = filter(lambda x: x != self.tempdir.name, sys.path)
379 sys.path[:] = filter(lambda x: x != self.tempdir.name, sys.path)
380 self.tempdir.cleanup()
380 self.tempdir.cleanup()
381
381
382 def check_run_submodule(self, submodule):
382 def check_run_submodule(self, submodule, opts=''):
383 _ip.magic('run -m {0}.{1}'.format(self.package, submodule))
383 _ip.magic('run {2} -m {0}.{1}'.format(self.package, submodule, opts))
384 self.assertEqual(_ip.user_ns['x'], self.value,
384 self.assertEqual(_ip.user_ns['x'], self.value,
385 'Variable `x` is not loaded from module `{0}`.'
385 'Variable `x` is not loaded from module `{0}`.'
386 .format(submodule))
386 .format(submodule))
387
387
388 def test_run_submodule_with_absolute_import(self):
388 def test_run_submodule_with_absolute_import(self):
389 self.check_run_submodule('absolute')
389 self.check_run_submodule('absolute')
390
390
391 def test_run_submodule_with_relative_import(self):
391 def test_run_submodule_with_relative_import(self):
392 """Run submodule that has a relative import statement (#2727)."""
392 """Run submodule that has a relative import statement (#2727)."""
393 self.check_run_submodule('relative')
393 self.check_run_submodule('relative')
394
395 def test_prun_submodule_with_absolute_import(self):
396 self.check_run_submodule('absolute', '-p')
397
398 def test_prun_submodule_with_relative_import(self):
399 self.check_run_submodule('relative', '-p')
General Comments 0
You need to be logged in to leave comments. Login now