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