##// END OF EJS Templates
Add tests that the class attribute is properly updated
Matthias Bussonnier -
Show More
@@ -1,400 +1,449 b''
1 """Tests for autoreload extension.
1 """Tests for autoreload extension.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 IPython Development Team.
4 # Copyright (c) 2012 IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
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 import textwrap
18 import textwrap
19 import shutil
19 import shutil
20 import random
20 import random
21 import time
21 import time
22 from io import StringIO
22 from io import StringIO
23
23
24 import nose.tools as nt
24 import nose.tools as nt
25 import IPython.testing.tools as tt
25 import IPython.testing.tools as tt
26
26
27 from IPython.testing.decorators import skipif
27 from IPython.testing.decorators import skipif
28
28
29 from IPython.extensions.autoreload import AutoreloadMagics
29 from IPython.extensions.autoreload import AutoreloadMagics
30 from IPython.core.events import EventManager, pre_run_cell
30 from IPython.core.events import EventManager, pre_run_cell
31
31
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33 # Test fixture
33 # Test fixture
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35
35
36 noop = lambda *a, **kw: None
36 noop = lambda *a, **kw: None
37
37
38 class FakeShell:
38 class FakeShell:
39
39
40 def __init__(self):
40 def __init__(self):
41 self.ns = {}
41 self.ns = {}
42 self.user_ns = {}
42 self.user_ns = self.ns
43 self.user_ns_hidden = {}
43 self.user_ns_hidden = {}
44 self.events = EventManager(self, {'pre_run_cell', pre_run_cell})
44 self.events = EventManager(self, {'pre_run_cell', pre_run_cell})
45 self.auto_magics = AutoreloadMagics(shell=self)
45 self.auto_magics = AutoreloadMagics(shell=self)
46 self.events.register('pre_run_cell', self.auto_magics.pre_run_cell)
46 self.events.register('pre_run_cell', self.auto_magics.pre_run_cell)
47
47
48 register_magics = set_hook = noop
48 register_magics = set_hook = noop
49
49
50 def run_code(self, code):
50 def run_code(self, code):
51 self.events.trigger('pre_run_cell')
51 self.events.trigger('pre_run_cell')
52 exec(code, self.ns)
52 exec(code, self.user_ns)
53 self.auto_magics.post_execute_hook()
53 self.auto_magics.post_execute_hook()
54
54
55 def push(self, items):
55 def push(self, items):
56 self.ns.update(items)
56 self.ns.update(items)
57
57
58 def magic_autoreload(self, parameter):
58 def magic_autoreload(self, parameter):
59 self.auto_magics.autoreload(parameter)
59 self.auto_magics.autoreload(parameter)
60
60
61 def magic_aimport(self, parameter, stream=None):
61 def magic_aimport(self, parameter, stream=None):
62 self.auto_magics.aimport(parameter, stream=stream)
62 self.auto_magics.aimport(parameter, stream=stream)
63 self.auto_magics.post_execute_hook()
63 self.auto_magics.post_execute_hook()
64
64
65
65
66 class Fixture(object):
66 class Fixture(object):
67 """Fixture for creating test module files"""
67 """Fixture for creating test module files"""
68
68
69 test_dir = None
69 test_dir = None
70 old_sys_path = None
70 old_sys_path = None
71 filename_chars = "abcdefghijklmopqrstuvwxyz0123456789"
71 filename_chars = "abcdefghijklmopqrstuvwxyz0123456789"
72
72
73 def setUp(self):
73 def setUp(self):
74 self.test_dir = tempfile.mkdtemp()
74 self.test_dir = tempfile.mkdtemp()
75 self.old_sys_path = list(sys.path)
75 self.old_sys_path = list(sys.path)
76 sys.path.insert(0, self.test_dir)
76 sys.path.insert(0, self.test_dir)
77 self.shell = FakeShell()
77 self.shell = FakeShell()
78
78
79 def tearDown(self):
79 def tearDown(self):
80 shutil.rmtree(self.test_dir)
80 shutil.rmtree(self.test_dir)
81 sys.path = self.old_sys_path
81 sys.path = self.old_sys_path
82
82
83 self.test_dir = None
83 self.test_dir = None
84 self.old_sys_path = None
84 self.old_sys_path = None
85 self.shell = None
85 self.shell = None
86
86
87 def get_module(self):
87 def get_module(self):
88 module_name = "tmpmod_" + "".join(random.sample(self.filename_chars,20))
88 module_name = "tmpmod_" + "".join(random.sample(self.filename_chars,20))
89 if module_name in sys.modules:
89 if module_name in sys.modules:
90 del sys.modules[module_name]
90 del sys.modules[module_name]
91 file_name = os.path.join(self.test_dir, module_name + ".py")
91 file_name = os.path.join(self.test_dir, module_name + ".py")
92 return module_name, file_name
92 return module_name, file_name
93
93
94 def write_file(self, filename, content):
94 def write_file(self, filename, content):
95 """
95 """
96 Write a file, and force a timestamp difference of at least one second
96 Write a file, and force a timestamp difference of at least one second
97
97
98 Notes
98 Notes
99 -----
99 -----
100 Python's .pyc files record the timestamp of their compilation
100 Python's .pyc files record the timestamp of their compilation
101 with a time resolution of one second.
101 with a time resolution of one second.
102
102
103 Therefore, we need to force a timestamp difference between .py
103 Therefore, we need to force a timestamp difference between .py
104 and .pyc, without having the .py file be timestamped in the
104 and .pyc, without having the .py file be timestamped in the
105 future, and without changing the timestamp of the .pyc file
105 future, and without changing the timestamp of the .pyc file
106 (because that is stored in the file). The only reliable way
106 (because that is stored in the file). The only reliable way
107 to achieve this seems to be to sleep.
107 to achieve this seems to be to sleep.
108 """
108 """
109
109 content = textwrap.dedent(content)
110 # Sleep one second + eps
110 # Sleep one second + eps
111 time.sleep(1.05)
111 time.sleep(1.05)
112
112
113 # Write
113 # Write
114 with open(filename, 'w') as f:
114 with open(filename, 'w') as f:
115 f.write(content)
115 f.write(content)
116
116
117 def new_module(self, code):
117 def new_module(self, code):
118 code = textwrap.dedent(code)
118 mod_name, mod_fn = self.get_module()
119 mod_name, mod_fn = self.get_module()
119 with open(mod_fn, 'w') as f:
120 with open(mod_fn, 'w') as f:
120 f.write(code)
121 f.write(code)
121 return mod_name, mod_fn
122 return mod_name, mod_fn
122
123
123 #-----------------------------------------------------------------------------
124 #-----------------------------------------------------------------------------
124 # Test automatic reloading
125 # Test automatic reloading
125 #-----------------------------------------------------------------------------
126 #-----------------------------------------------------------------------------
126
127
128 def pickle_get_current_class(obj):
129 """
130 Original issue comes from pickle; hence the name.
131 """
132 name = obj.__class__.__name__
133 module_name = getattr(obj, "__module__", None)
134 obj2 = sys.modules[module_name]
135 for subpath in name.split("."):
136 obj2 = getattr(obj2, subpath)
137 return obj2
138
127 class TestAutoreload(Fixture):
139 class TestAutoreload(Fixture):
128
140
129 @skipif(sys.version_info < (3, 6))
141 @skipif(sys.version_info < (3, 6))
130 def test_reload_enums(self):
142 def test_reload_enums(self):
131 import enum
143 import enum
132 mod_name, mod_fn = self.new_module(textwrap.dedent("""
144 mod_name, mod_fn = self.new_module(textwrap.dedent("""
133 from enum import Enum
145 from enum import Enum
134 class MyEnum(Enum):
146 class MyEnum(Enum):
135 A = 'A'
147 A = 'A'
136 B = 'B'
148 B = 'B'
137 """))
149 """))
138 self.shell.magic_autoreload("2")
150 self.shell.magic_autoreload("2")
139 self.shell.magic_aimport(mod_name)
151 self.shell.magic_aimport(mod_name)
140 self.write_file(mod_fn, textwrap.dedent("""
152 self.write_file(mod_fn, textwrap.dedent("""
141 from enum import Enum
153 from enum import Enum
142 class MyEnum(Enum):
154 class MyEnum(Enum):
143 A = 'A'
155 A = 'A'
144 B = 'B'
156 B = 'B'
145 C = 'C'
157 C = 'C'
146 """))
158 """))
147 with tt.AssertNotPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'):
159 with tt.AssertNotPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'):
148 self.shell.run_code("pass") # trigger another reload
160 self.shell.run_code("pass") # trigger another reload
149
161
162 def test_reload_class_type(self):
163 self.shell.magic_autoreload("2")
164 mod_name, mod_fn = self.new_module(
165 """
166 class Test():
167 def meth(self):
168 return "old"
169 """
170 )
171 assert "test" not in self.shell.ns
172 assert "result" not in self.shell.ns
173
174 self.shell.run_code("from %s import Test" % mod_name)
175 self.shell.run_code("test = Test()")
176
177 self.write_file(
178 mod_fn,
179 """
180 class Test():
181 def meth(self):
182 return "new"
183 """,
184 )
185
186 test_object = self.shell.ns["test"]
187
188 # important to trigger autoreload logic !
189 self.shell.run_code("pass")
190
191 test_class = pickle_get_current_class(test_object)
192 assert isinstance(test_object, test_class)
193
194 # extra check.
195 self.shell.run_code("import pickle")
196 self.shell.run_code("p = pickle.dumps(test)")
197
150 def test_reload_class_attributes(self):
198 def test_reload_class_attributes(self):
151 self.shell.magic_autoreload("2")
199 self.shell.magic_autoreload("2")
152 mod_name, mod_fn = self.new_module(textwrap.dedent("""
200 mod_name, mod_fn = self.new_module(textwrap.dedent("""
153 class MyClass:
201 class MyClass:
154
202
155 def __init__(self, a=10):
203 def __init__(self, a=10):
156 self.a = a
204 self.a = a
157 self.b = 22
205 self.b = 22
158 # self.toto = 33
206 # self.toto = 33
159
207
160 def square(self):
208 def square(self):
161 print('compute square')
209 print('compute square')
162 return self.a*self.a
210 return self.a*self.a
163 """
211 """
164 )
212 )
165 )
213 )
166 self.shell.run_code("from %s import MyClass" % mod_name)
214 self.shell.run_code("from %s import MyClass" % mod_name)
167 self.shell.run_code("first = MyClass(5)")
215 self.shell.run_code("first = MyClass(5)")
168 self.shell.run_code("first.square()")
216 self.shell.run_code("first.square()")
169 with nt.assert_raises(AttributeError):
217 with nt.assert_raises(AttributeError):
170 self.shell.run_code("first.cube()")
218 self.shell.run_code("first.cube()")
171 with nt.assert_raises(AttributeError):
219 with nt.assert_raises(AttributeError):
172 self.shell.run_code("first.power(5)")
220 self.shell.run_code("first.power(5)")
173 self.shell.run_code("first.b")
221 self.shell.run_code("first.b")
174 with nt.assert_raises(AttributeError):
222 with nt.assert_raises(AttributeError):
175 self.shell.run_code("first.toto")
223 self.shell.run_code("first.toto")
176
224
177 # remove square, add power
225 # remove square, add power
178
226
179 self.write_file(
227 self.write_file(
180 mod_fn,
228 mod_fn,
181 textwrap.dedent(
229 textwrap.dedent(
182 """
230 """
183 class MyClass:
231 class MyClass:
184
232
185 def __init__(self, a=10):
233 def __init__(self, a=10):
186 self.a = a
234 self.a = a
187 self.b = 11
235 self.b = 11
188
236
189 def power(self, p):
237 def power(self, p):
190 print('compute power '+str(p))
238 print('compute power '+str(p))
191 return self.a**p
239 return self.a**p
192 """
240 """
193 ),
241 ),
194 )
242 )
195
243
196 self.shell.run_code("second = MyClass(5)")
244 self.shell.run_code("second = MyClass(5)")
197
245
198 for object_name in {'first', 'second'}:
246 for object_name in {'first', 'second'}:
199 self.shell.run_code("{object_name}.power(5)".format(object_name=object_name))
247 self.shell.run_code("{object_name}.power(5)".format(object_name=object_name))
200 with nt.assert_raises(AttributeError):
248 with nt.assert_raises(AttributeError):
201 self.shell.run_code("{object_name}.cube()".format(object_name=object_name))
249 self.shell.run_code("{object_name}.cube()".format(object_name=object_name))
202 with nt.assert_raises(AttributeError):
250 with nt.assert_raises(AttributeError):
203 self.shell.run_code("{object_name}.square()".format(object_name=object_name))
251 self.shell.run_code("{object_name}.square()".format(object_name=object_name))
204 self.shell.run_code("{object_name}.b".format(object_name=object_name))
252 self.shell.run_code("{object_name}.b".format(object_name=object_name))
205 self.shell.run_code("{object_name}.a".format(object_name=object_name))
253 self.shell.run_code("{object_name}.a".format(object_name=object_name))
206 with nt.assert_raises(AttributeError):
254 with nt.assert_raises(AttributeError):
207 self.shell.run_code("{object_name}.toto".format(object_name=object_name))
255 self.shell.run_code("{object_name}.toto".format(object_name=object_name))
208
256
209 def _check_smoketest(self, use_aimport=True):
257 def _check_smoketest(self, use_aimport=True):
210 """
258 """
211 Functional test for the automatic reloader using either
259 Functional test for the automatic reloader using either
212 '%autoreload 1' or '%autoreload 2'
260 '%autoreload 1' or '%autoreload 2'
213 """
261 """
214
262
215 mod_name, mod_fn = self.new_module("""
263 mod_name, mod_fn = self.new_module("""
216 x = 9
264 x = 9
217
265
218 z = 123 # this item will be deleted
266 z = 123 # this item will be deleted
219
267
220 def foo(y):
268 def foo(y):
221 return y + 3
269 return y + 3
222
270
223 class Baz(object):
271 class Baz(object):
224 def __init__(self, x):
272 def __init__(self, x):
225 self.x = x
273 self.x = x
226 def bar(self, y):
274 def bar(self, y):
227 return self.x + y
275 return self.x + y
228 @property
276 @property
229 def quux(self):
277 def quux(self):
230 return 42
278 return 42
231 def zzz(self):
279 def zzz(self):
232 '''This method will be deleted below'''
280 '''This method will be deleted below'''
233 return 99
281 return 99
234
282
235 class Bar: # old-style class: weakref doesn't work for it on Python < 2.7
283 class Bar: # old-style class: weakref doesn't work for it on Python < 2.7
236 def foo(self):
284 def foo(self):
237 return 1
285 return 1
238 """)
286 """)
239
287
240 #
288 #
241 # Import module, and mark for reloading
289 # Import module, and mark for reloading
242 #
290 #
243 if use_aimport:
291 if use_aimport:
244 self.shell.magic_autoreload("1")
292 self.shell.magic_autoreload("1")
245 self.shell.magic_aimport(mod_name)
293 self.shell.magic_aimport(mod_name)
246 stream = StringIO()
294 stream = StringIO()
247 self.shell.magic_aimport("", stream=stream)
295 self.shell.magic_aimport("", stream=stream)
248 nt.assert_in(("Modules to reload:\n%s" % mod_name), stream.getvalue())
296 nt.assert_in(("Modules to reload:\n%s" % mod_name), stream.getvalue())
249
297
250 with nt.assert_raises(ImportError):
298 with nt.assert_raises(ImportError):
251 self.shell.magic_aimport("tmpmod_as318989e89ds")
299 self.shell.magic_aimport("tmpmod_as318989e89ds")
252 else:
300 else:
253 self.shell.magic_autoreload("2")
301 self.shell.magic_autoreload("2")
254 self.shell.run_code("import %s" % mod_name)
302 self.shell.run_code("import %s" % mod_name)
255 stream = StringIO()
303 stream = StringIO()
256 self.shell.magic_aimport("", stream=stream)
304 self.shell.magic_aimport("", stream=stream)
257 nt.assert_true("Modules to reload:\nall-except-skipped" in
305 nt.assert_true("Modules to reload:\nall-except-skipped" in
258 stream.getvalue())
306 stream.getvalue())
259 nt.assert_in(mod_name, self.shell.ns)
307 nt.assert_in(mod_name, self.shell.ns)
260
308
261 mod = sys.modules[mod_name]
309 mod = sys.modules[mod_name]
262
310
263 #
311 #
264 # Test module contents
312 # Test module contents
265 #
313 #
266 old_foo = mod.foo
314 old_foo = mod.foo
267 old_obj = mod.Baz(9)
315 old_obj = mod.Baz(9)
268 old_obj2 = mod.Bar()
316 old_obj2 = mod.Bar()
269
317
270 def check_module_contents():
318 def check_module_contents():
271 nt.assert_equal(mod.x, 9)
319 nt.assert_equal(mod.x, 9)
272 nt.assert_equal(mod.z, 123)
320 nt.assert_equal(mod.z, 123)
273
321
274 nt.assert_equal(old_foo(0), 3)
322 nt.assert_equal(old_foo(0), 3)
275 nt.assert_equal(mod.foo(0), 3)
323 nt.assert_equal(mod.foo(0), 3)
276
324
277 obj = mod.Baz(9)
325 obj = mod.Baz(9)
278 nt.assert_equal(old_obj.bar(1), 10)
326 nt.assert_equal(old_obj.bar(1), 10)
279 nt.assert_equal(obj.bar(1), 10)
327 nt.assert_equal(obj.bar(1), 10)
280 nt.assert_equal(obj.quux, 42)
328 nt.assert_equal(obj.quux, 42)
281 nt.assert_equal(obj.zzz(), 99)
329 nt.assert_equal(obj.zzz(), 99)
282
330
283 obj2 = mod.Bar()
331 obj2 = mod.Bar()
284 nt.assert_equal(old_obj2.foo(), 1)
332 nt.assert_equal(old_obj2.foo(), 1)
285 nt.assert_equal(obj2.foo(), 1)
333 nt.assert_equal(obj2.foo(), 1)
286
334
287 check_module_contents()
335 check_module_contents()
288
336
289 #
337 #
290 # Simulate a failed reload: no reload should occur and exactly
338 # Simulate a failed reload: no reload should occur and exactly
291 # one error message should be printed
339 # one error message should be printed
292 #
340 #
293 self.write_file(mod_fn, """
341 self.write_file(mod_fn, """
294 a syntax error
342 a syntax error
295 """)
343 """)
296
344
297 with tt.AssertPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'):
345 with tt.AssertPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'):
298 self.shell.run_code("pass") # trigger reload
346 self.shell.run_code("pass") # trigger reload
299 with tt.AssertNotPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'):
347 with tt.AssertNotPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'):
300 self.shell.run_code("pass") # trigger another reload
348 self.shell.run_code("pass") # trigger another reload
301 check_module_contents()
349 check_module_contents()
302
350
303 #
351 #
304 # Rewrite module (this time reload should succeed)
352 # Rewrite module (this time reload should succeed)
305 #
353 #
306 self.write_file(mod_fn, """
354 self.write_file(mod_fn, """
307 x = 10
355 x = 10
308
356
309 def foo(y):
357 def foo(y):
310 return y + 4
358 return y + 4
311
359
312 class Baz(object):
360 class Baz(object):
313 def __init__(self, x):
361 def __init__(self, x):
314 self.x = x
362 self.x = x
315 def bar(self, y):
363 def bar(self, y):
316 return self.x + y + 1
364 return self.x + y + 1
317 @property
365 @property
318 def quux(self):
366 def quux(self):
319 return 43
367 return 43
320
368
321 class Bar: # old-style class
369 class Bar: # old-style class
322 def foo(self):
370 def foo(self):
323 return 2
371 return 2
324 """)
372 """)
325
373
326 def check_module_contents():
374 def check_module_contents():
327 nt.assert_equal(mod.x, 10)
375 nt.assert_equal(mod.x, 10)
328 nt.assert_false(hasattr(mod, 'z'))
376 nt.assert_false(hasattr(mod, 'z'))
329
377
330 nt.assert_equal(old_foo(0), 4) # superreload magic!
378 nt.assert_equal(old_foo(0), 4) # superreload magic!
331 nt.assert_equal(mod.foo(0), 4)
379 nt.assert_equal(mod.foo(0), 4)
332
380
333 obj = mod.Baz(9)
381 obj = mod.Baz(9)
334 nt.assert_equal(old_obj.bar(1), 11) # superreload magic!
382 nt.assert_equal(old_obj.bar(1), 11) # superreload magic!
335 nt.assert_equal(obj.bar(1), 11)
383 nt.assert_equal(obj.bar(1), 11)
336
384
337 nt.assert_equal(old_obj.quux, 43)
385 nt.assert_equal(old_obj.quux, 43)
338 nt.assert_equal(obj.quux, 43)
386 nt.assert_equal(obj.quux, 43)
339
387
340 nt.assert_false(hasattr(old_obj, 'zzz'))
388 nt.assert_false(hasattr(old_obj, 'zzz'))
341 nt.assert_false(hasattr(obj, 'zzz'))
389 nt.assert_false(hasattr(obj, 'zzz'))
342
390
343 obj2 = mod.Bar()
391 obj2 = mod.Bar()
344 nt.assert_equal(old_obj2.foo(), 2)
392 nt.assert_equal(old_obj2.foo(), 2)
345 nt.assert_equal(obj2.foo(), 2)
393 nt.assert_equal(obj2.foo(), 2)
346
394
347 self.shell.run_code("pass") # trigger reload
395 self.shell.run_code("pass") # trigger reload
348 check_module_contents()
396 check_module_contents()
349
397
350 #
398 #
351 # Another failure case: deleted file (shouldn't reload)
399 # Another failure case: deleted file (shouldn't reload)
352 #
400 #
353 os.unlink(mod_fn)
401 os.unlink(mod_fn)
354
402
355 self.shell.run_code("pass") # trigger reload
403 self.shell.run_code("pass") # trigger reload
356 check_module_contents()
404 check_module_contents()
357
405
358 #
406 #
359 # Disable autoreload and rewrite module: no reload should occur
407 # Disable autoreload and rewrite module: no reload should occur
360 #
408 #
361 if use_aimport:
409 if use_aimport:
362 self.shell.magic_aimport("-" + mod_name)
410 self.shell.magic_aimport("-" + mod_name)
363 stream = StringIO()
411 stream = StringIO()
364 self.shell.magic_aimport("", stream=stream)
412 self.shell.magic_aimport("", stream=stream)
365 nt.assert_true(("Modules to skip:\n%s" % mod_name) in
413 nt.assert_true(("Modules to skip:\n%s" % mod_name) in
366 stream.getvalue())
414 stream.getvalue())
367
415
368 # This should succeed, although no such module exists
416 # This should succeed, although no such module exists
369 self.shell.magic_aimport("-tmpmod_as318989e89ds")
417 self.shell.magic_aimport("-tmpmod_as318989e89ds")
370 else:
418 else:
371 self.shell.magic_autoreload("0")
419 self.shell.magic_autoreload("0")
372
420
373 self.write_file(mod_fn, """
421 self.write_file(mod_fn, """
374 x = -99
422 x = -99
375 """)
423 """)
376
424
377 self.shell.run_code("pass") # trigger reload
425 self.shell.run_code("pass") # trigger reload
378 self.shell.run_code("pass")
426 self.shell.run_code("pass")
379 check_module_contents()
427 check_module_contents()
380
428
381 #
429 #
382 # Re-enable autoreload: reload should now occur
430 # Re-enable autoreload: reload should now occur
383 #
431 #
384 if use_aimport:
432 if use_aimport:
385 self.shell.magic_aimport(mod_name)
433 self.shell.magic_aimport(mod_name)
386 else:
434 else:
387 self.shell.magic_autoreload("")
435 self.shell.magic_autoreload("")
388
436
389 self.shell.run_code("pass") # trigger reload
437 self.shell.run_code("pass") # trigger reload
390 nt.assert_equal(mod.x, -99)
438 nt.assert_equal(mod.x, -99)
391
439
392 def test_smoketest_aimport(self):
440 def test_smoketest_aimport(self):
393 self._check_smoketest(use_aimport=True)
441 self._check_smoketest(use_aimport=True)
394
442
395 def test_smoketest_autoreload(self):
443 def test_smoketest_autoreload(self):
396 self._check_smoketest(use_aimport=False)
444 self._check_smoketest(use_aimport=False)
397
445
398
446
399
447
400
448
449
General Comments 0
You need to be logged in to leave comments. Login now