##// END OF EJS Templates
IPython.core.tests.test_run.test_obj_del apparently no longer fails on Windows, so we don't need to skip it....
Thomas Kluyver -
Show More
@@ -1,210 +1,205 b''
1 """Tests for code execution (%run and related), which is particularly tricky.
1 """Tests for code execution (%run and related), which is particularly tricky.
2
2
3 Because of how %run manages namespaces, and the fact that we are trying here to
3 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
4 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
5 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
6 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.
7 and we do so in a common test_magic file.
8 """
8 """
9 from __future__ import absolute_import
9 from __future__ import absolute_import
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 import os
15 import os
16 import sys
16 import sys
17 import tempfile
17 import tempfile
18
18
19 import nose.tools as nt
19 import nose.tools as nt
20
20
21 from IPython.testing import decorators as dec
21 from IPython.testing import decorators as dec
22 from IPython.testing import tools as tt
22 from IPython.testing import tools as tt
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Test functions begin
25 # Test functions begin
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 def doctest_refbug():
28 def doctest_refbug():
29 """Very nasty problem with references held by multiple runs of a script.
29 """Very nasty problem with references held by multiple runs of a script.
30 See: https://bugs.launchpad.net/ipython/+bug/269966
30 See: https://bugs.launchpad.net/ipython/+bug/269966
31
31
32 In [1]: _ip.clear_main_mod_cache()
32 In [1]: _ip.clear_main_mod_cache()
33 # random
33 # random
34
34
35 In [2]: %run refbug
35 In [2]: %run refbug
36
36
37 In [3]: call_f()
37 In [3]: call_f()
38 lowercased: hello
38 lowercased: hello
39
39
40 In [4]: %run refbug
40 In [4]: %run refbug
41
41
42 In [5]: call_f()
42 In [5]: call_f()
43 lowercased: hello
43 lowercased: hello
44 lowercased: hello
44 lowercased: hello
45 """
45 """
46
46
47
47
48 def doctest_run_builtins():
48 def doctest_run_builtins():
49 r"""Check that %run doesn't damage __builtins__.
49 r"""Check that %run doesn't damage __builtins__.
50
50
51 In [1]: import tempfile
51 In [1]: import tempfile
52
52
53 In [2]: bid1 = id(__builtins__)
53 In [2]: bid1 = id(__builtins__)
54
54
55 In [3]: fname = tempfile.mkstemp('.py')[1]
55 In [3]: fname = tempfile.mkstemp('.py')[1]
56
56
57 In [3]: f = open(fname,'w')
57 In [3]: f = open(fname,'w')
58
58
59 In [4]: f.write('pass\n')
59 In [4]: f.write('pass\n')
60
60
61 In [5]: f.flush()
61 In [5]: f.flush()
62
62
63 In [6]: t1 = type(__builtins__)
63 In [6]: t1 = type(__builtins__)
64
64
65 In [7]: %run $fname
65 In [7]: %run $fname
66
66
67 In [7]: f.close()
67 In [7]: f.close()
68
68
69 In [8]: bid2 = id(__builtins__)
69 In [8]: bid2 = id(__builtins__)
70
70
71 In [9]: t2 = type(__builtins__)
71 In [9]: t2 = type(__builtins__)
72
72
73 In [10]: t1 == t2
73 In [10]: t1 == t2
74 Out[10]: True
74 Out[10]: True
75
75
76 In [10]: bid1 == bid2
76 In [10]: bid1 == bid2
77 Out[10]: True
77 Out[10]: True
78
78
79 In [12]: try:
79 In [12]: try:
80 ....: os.unlink(fname)
80 ....: os.unlink(fname)
81 ....: except:
81 ....: except:
82 ....: pass
82 ....: pass
83 ....:
83 ....:
84 """
84 """
85
85
86 def doctest_reset_del():
86 def doctest_reset_del():
87 """Test that resetting doesn't cause errors in __del__ methods.
87 """Test that resetting doesn't cause errors in __del__ methods.
88
88
89 In [2]: class A(object):
89 In [2]: class A(object):
90 ...: def __del__(self):
90 ...: def __del__(self):
91 ...: print str("Hi")
91 ...: print str("Hi")
92 ...:
92 ...:
93
93
94 In [3]: a = A()
94 In [3]: a = A()
95
95
96 In [4]: get_ipython().reset()
96 In [4]: get_ipython().reset()
97 Hi
97 Hi
98
98
99 In [5]: 1+1
99 In [5]: 1+1
100 Out[5]: 2
100 Out[5]: 2
101 """
101 """
102
102
103 # For some tests, it will be handy to organize them in a class with a common
103 # For some tests, it will be handy to organize them in a class with a common
104 # setup that makes a temp file
104 # setup that makes a temp file
105
105
106 class TestMagicRunPass(tt.TempFileMixin):
106 class TestMagicRunPass(tt.TempFileMixin):
107
107
108 def setup(self):
108 def setup(self):
109 """Make a valid python temp file."""
109 """Make a valid python temp file."""
110 self.mktmp('pass\n')
110 self.mktmp('pass\n')
111
111
112 def run_tmpfile(self):
112 def run_tmpfile(self):
113 _ip = get_ipython()
113 _ip = get_ipython()
114 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
114 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
115 # See below and ticket https://bugs.launchpad.net/bugs/366353
115 # See below and ticket https://bugs.launchpad.net/bugs/366353
116 _ip.magic('run %s' % self.fname)
116 _ip.magic('run %s' % self.fname)
117
117
118 def test_builtins_id(self):
118 def test_builtins_id(self):
119 """Check that %run doesn't damage __builtins__ """
119 """Check that %run doesn't damage __builtins__ """
120 _ip = get_ipython()
120 _ip = get_ipython()
121 # Test that the id of __builtins__ is not modified by %run
121 # Test that the id of __builtins__ is not modified by %run
122 bid1 = id(_ip.user_ns['__builtins__'])
122 bid1 = id(_ip.user_ns['__builtins__'])
123 self.run_tmpfile()
123 self.run_tmpfile()
124 bid2 = id(_ip.user_ns['__builtins__'])
124 bid2 = id(_ip.user_ns['__builtins__'])
125 tt.assert_equals(bid1, bid2)
125 tt.assert_equals(bid1, bid2)
126
126
127 def test_builtins_type(self):
127 def test_builtins_type(self):
128 """Check that the type of __builtins__ doesn't change with %run.
128 """Check that the type of __builtins__ doesn't change with %run.
129
129
130 However, the above could pass if __builtins__ was already modified to
130 However, the above could pass if __builtins__ was already modified to
131 be a dict (it should be a module) by a previous use of %run. So we
131 be a dict (it should be a module) by a previous use of %run. So we
132 also check explicitly that it really is a module:
132 also check explicitly that it really is a module:
133 """
133 """
134 _ip = get_ipython()
134 _ip = get_ipython()
135 self.run_tmpfile()
135 self.run_tmpfile()
136 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
136 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
137
137
138 def test_prompts(self):
138 def test_prompts(self):
139 """Test that prompts correctly generate after %run"""
139 """Test that prompts correctly generate after %run"""
140 self.run_tmpfile()
140 self.run_tmpfile()
141 _ip = get_ipython()
141 _ip = get_ipython()
142 p2 = str(_ip.displayhook.prompt2).strip()
142 p2 = str(_ip.displayhook.prompt2).strip()
143 nt.assert_equals(p2[:3], '...')
143 nt.assert_equals(p2[:3], '...')
144
144
145
145
146 class TestMagicRunSimple(tt.TempFileMixin):
146 class TestMagicRunSimple(tt.TempFileMixin):
147
147
148 def test_simpledef(self):
148 def test_simpledef(self):
149 """Test that simple class definitions work."""
149 """Test that simple class definitions work."""
150 src = ("class foo: pass\n"
150 src = ("class foo: pass\n"
151 "def f(): return foo()")
151 "def f(): return foo()")
152 self.mktmp(src)
152 self.mktmp(src)
153 _ip.magic('run %s' % self.fname)
153 _ip.magic('run %s' % self.fname)
154 _ip.run_cell('t = isinstance(f(), foo)')
154 _ip.run_cell('t = isinstance(f(), foo)')
155 nt.assert_true(_ip.user_ns['t'])
155 nt.assert_true(_ip.user_ns['t'])
156
156
157 # We have to skip these in win32 because getoutputerr() crashes,
158 # due to the fact that subprocess does not support close_fds when
159 # redirecting stdout/err. So unless someone who knows more tells us how to
160 # implement getoutputerr() in win32, we're stuck avoiding these.
161 @dec.skip_win32
162 def test_obj_del(self):
157 def test_obj_del(self):
163 """Test that object's __del__ methods are called on exit."""
158 """Test that object's __del__ methods are called on exit."""
164
159
165 # This test is known to fail on win32.
160 # This test is known to fail on win32.
166 # See ticket https://bugs.launchpad.net/bugs/366334
161 # See ticket https://bugs.launchpad.net/bugs/366334
167 src = ("class A(object):\n"
162 src = ("class A(object):\n"
168 " def __del__(self):\n"
163 " def __del__(self):\n"
169 " print 'object A deleted'\n"
164 " print 'object A deleted'\n"
170 "a = A()\n")
165 "a = A()\n")
171 self.mktmp(src)
166 self.mktmp(src)
172 tt.ipexec_validate(self.fname, 'object A deleted')
167 tt.ipexec_validate(self.fname, 'object A deleted')
173
168
174 @dec.skip_known_failure
169 @dec.skip_known_failure
175 def test_aggressive_namespace_cleanup(self):
170 def test_aggressive_namespace_cleanup(self):
176 """Test that namespace cleanup is not too aggressive GH-238
171 """Test that namespace cleanup is not too aggressive GH-238
177
172
178 Returning from another run magic deletes the namespace"""
173 Returning from another run magic deletes the namespace"""
179 # see ticket https://github.com/ipython/ipython/issues/238
174 # see ticket https://github.com/ipython/ipython/issues/238
180 class secondtmp(tt.TempFileMixin): pass
175 class secondtmp(tt.TempFileMixin): pass
181 empty = secondtmp()
176 empty = secondtmp()
182 empty.mktmp('')
177 empty.mktmp('')
183 src = ("ip = get_ipython()\n"
178 src = ("ip = get_ipython()\n"
184 "for i in range(5):\n"
179 "for i in range(5):\n"
185 " try:\n"
180 " try:\n"
186 " ip.magic('run %s')\n"
181 " ip.magic('run %s')\n"
187 " except NameError, e:\n"
182 " except NameError, e:\n"
188 " print i;break\n" % empty.fname)
183 " print i;break\n" % empty.fname)
189 self.mktmp(src)
184 self.mktmp(src)
190 _ip.magic('run %s' % self.fname)
185 _ip.magic('run %s' % self.fname)
191 _ip.run_cell('ip == get_ipython()')
186 _ip.run_cell('ip == get_ipython()')
192 tt.assert_equals(_ip.user_ns['i'], 5)
187 tt.assert_equals(_ip.user_ns['i'], 5)
193
188
194 @dec.skip_win32
189 @dec.skip_win32
195 def test_tclass(self):
190 def test_tclass(self):
196 mydir = os.path.dirname(__file__)
191 mydir = os.path.dirname(__file__)
197 tc = os.path.join(mydir, 'tclass')
192 tc = os.path.join(mydir, 'tclass')
198 src = ("%%run '%s' C-first\n"
193 src = ("%%run '%s' C-first\n"
199 "%%run '%s' C-second\n"
194 "%%run '%s' C-second\n"
200 "%%run '%s' C-third\n") % (tc, tc, tc)
195 "%%run '%s' C-third\n") % (tc, tc, tc)
201 self.mktmp(src, '.ipy')
196 self.mktmp(src, '.ipy')
202 out = """\
197 out = """\
203 ARGV 1-: [u'C-first']
198 ARGV 1-: [u'C-first']
204 ARGV 1-: [u'C-second']
199 ARGV 1-: [u'C-second']
205 tclass.py: deleting object: C-first
200 tclass.py: deleting object: C-first
206 ARGV 1-: [u'C-third']
201 ARGV 1-: [u'C-third']
207 tclass.py: deleting object: C-second
202 tclass.py: deleting object: C-second
208 tclass.py: deleting object: C-third
203 tclass.py: deleting object: C-third
209 """
204 """
210 tt.ipexec_validate(self.fname, out)
205 tt.ipexec_validate(self.fname, out)
General Comments 0
You need to be logged in to leave comments. Login now