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