##// END OF EJS Templates
Make test work (i.e. it now fails, as expected).
Thomas Kluyver -
Show More
@@ -1,185 +1,186 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 ...: 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
98
98 In [5]: 1+1
99 In [5]: 1+1
99 Out[5]: 2
100 Out[5]: 2
100 """
101 """
101
102
102 # 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
103 # setup that makes a temp file
104 # setup that makes a temp file
104
105
105 class TestMagicRunPass(tt.TempFileMixin):
106 class TestMagicRunPass(tt.TempFileMixin):
106
107
107 def setup(self):
108 def setup(self):
108 """Make a valid python temp file."""
109 """Make a valid python temp file."""
109 self.mktmp('pass\n')
110 self.mktmp('pass\n')
110
111
111 def run_tmpfile(self):
112 def run_tmpfile(self):
112 _ip = get_ipython()
113 _ip = get_ipython()
113 # 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.
114 # See below and ticket https://bugs.launchpad.net/bugs/366353
115 # See below and ticket https://bugs.launchpad.net/bugs/366353
115 _ip.magic('run %s' % self.fname)
116 _ip.magic('run %s' % self.fname)
116
117
117 def test_builtins_id(self):
118 def test_builtins_id(self):
118 """Check that %run doesn't damage __builtins__ """
119 """Check that %run doesn't damage __builtins__ """
119 _ip = get_ipython()
120 _ip = get_ipython()
120 # Test that the id of __builtins__ is not modified by %run
121 # Test that the id of __builtins__ is not modified by %run
121 bid1 = id(_ip.user_ns['__builtins__'])
122 bid1 = id(_ip.user_ns['__builtins__'])
122 self.run_tmpfile()
123 self.run_tmpfile()
123 bid2 = id(_ip.user_ns['__builtins__'])
124 bid2 = id(_ip.user_ns['__builtins__'])
124 tt.assert_equals(bid1, bid2)
125 tt.assert_equals(bid1, bid2)
125
126
126 def test_builtins_type(self):
127 def test_builtins_type(self):
127 """Check that the type of __builtins__ doesn't change with %run.
128 """Check that the type of __builtins__ doesn't change with %run.
128
129
129 However, the above could pass if __builtins__ was already modified to
130 However, the above could pass if __builtins__ was already modified to
130 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
131 also check explicitly that it really is a module:
132 also check explicitly that it really is a module:
132 """
133 """
133 _ip = get_ipython()
134 _ip = get_ipython()
134 self.run_tmpfile()
135 self.run_tmpfile()
135 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
136 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
136
137
137 def test_prompts(self):
138 def test_prompts(self):
138 """Test that prompts correctly generate after %run"""
139 """Test that prompts correctly generate after %run"""
139 self.run_tmpfile()
140 self.run_tmpfile()
140 _ip = get_ipython()
141 _ip = get_ipython()
141 p2 = str(_ip.displayhook.prompt2).strip()
142 p2 = str(_ip.displayhook.prompt2).strip()
142 nt.assert_equals(p2[:3], '...')
143 nt.assert_equals(p2[:3], '...')
143
144
144
145
145 class TestMagicRunSimple(tt.TempFileMixin):
146 class TestMagicRunSimple(tt.TempFileMixin):
146
147
147 def test_simpledef(self):
148 def test_simpledef(self):
148 """Test that simple class definitions work."""
149 """Test that simple class definitions work."""
149 src = ("class foo: pass\n"
150 src = ("class foo: pass\n"
150 "def f(): return foo()")
151 "def f(): return foo()")
151 self.mktmp(src)
152 self.mktmp(src)
152 _ip.magic('run %s' % self.fname)
153 _ip.magic('run %s' % self.fname)
153 _ip.runlines('t = isinstance(f(), foo)')
154 _ip.runlines('t = isinstance(f(), foo)')
154 nt.assert_true(_ip.user_ns['t'])
155 nt.assert_true(_ip.user_ns['t'])
155
156
156 # We have to skip these in win32 because getoutputerr() crashes,
157 # We have to skip these in win32 because getoutputerr() crashes,
157 # due to the fact that subprocess does not support close_fds when
158 # due to the fact that subprocess does not support close_fds when
158 # redirecting stdout/err. So unless someone who knows more tells us how to
159 # redirecting stdout/err. So unless someone who knows more tells us how to
159 # implement getoutputerr() in win32, we're stuck avoiding these.
160 # implement getoutputerr() in win32, we're stuck avoiding these.
160 @dec.skip_win32
161 @dec.skip_win32
161 def test_obj_del(self):
162 def test_obj_del(self):
162 """Test that object's __del__ methods are called on exit."""
163 """Test that object's __del__ methods are called on exit."""
163
164
164 # This test is known to fail on win32.
165 # This test is known to fail on win32.
165 # See ticket https://bugs.launchpad.net/bugs/366334
166 # See ticket https://bugs.launchpad.net/bugs/366334
166 src = ("class A(object):\n"
167 src = ("class A(object):\n"
167 " def __del__(self):\n"
168 " def __del__(self):\n"
168 " print 'object A deleted'\n"
169 " print 'object A deleted'\n"
169 "a = A()\n")
170 "a = A()\n")
170 self.mktmp(src)
171 self.mktmp(src)
171 tt.ipexec_validate(self.fname, 'object A deleted')
172 tt.ipexec_validate(self.fname, 'object A deleted')
172
173
173 @dec.skip_win32
174 @dec.skip_win32
174 def test_tclass(self):
175 def test_tclass(self):
175 mydir = os.path.dirname(__file__)
176 mydir = os.path.dirname(__file__)
176 tc = os.path.join(mydir, 'tclass')
177 tc = os.path.join(mydir, 'tclass')
177 src = ("%%run '%s' C-first\n"
178 src = ("%%run '%s' C-first\n"
178 "%%run '%s' C-second\n") % (tc, tc)
179 "%%run '%s' C-second\n") % (tc, tc)
179 self.mktmp(src, '.ipy')
180 self.mktmp(src, '.ipy')
180 out = """\
181 out = """\
181 ARGV 1-: ['C-first']
182 ARGV 1-: ['C-first']
182 ARGV 1-: ['C-second']
183 ARGV 1-: ['C-second']
183 tclass.py: deleting object: C-first
184 tclass.py: deleting object: C-first
184 """
185 """
185 tt.ipexec_validate(self.fname, out)
186 tt.ipexec_validate(self.fname, out)
General Comments 0
You need to be logged in to leave comments. Login now