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