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