Show More
@@ -1,16 +1,16 b'' | |||
|
1 | 1 | """Tests for autoreload extension. |
|
2 | 2 | """ |
|
3 | #----------------------------------------------------------------------------- | |
|
3 | # ----------------------------------------------------------------------------- | |
|
4 | 4 | # Copyright (c) 2012 IPython Development Team. |
|
5 | 5 | # |
|
6 | 6 | # Distributed under the terms of the Modified BSD License. |
|
7 | 7 | # |
|
8 | 8 | # The full license is in the file COPYING.txt, distributed with this software. |
|
9 | #----------------------------------------------------------------------------- | |
|
9 | # ----------------------------------------------------------------------------- | |
|
10 | 10 | |
|
11 | #----------------------------------------------------------------------------- | |
|
11 | # ----------------------------------------------------------------------------- | |
|
12 | 12 | # Imports |
|
13 | #----------------------------------------------------------------------------- | |
|
13 | # ----------------------------------------------------------------------------- | |
|
14 | 14 | |
|
15 | 15 | import os |
|
16 | 16 | import sys |
@@ -29,26 +29,26 b' from unittest import TestCase' | |||
|
29 | 29 | from IPython.extensions.autoreload import AutoreloadMagics |
|
30 | 30 | from IPython.core.events import EventManager, pre_run_cell |
|
31 | 31 | |
|
32 | #----------------------------------------------------------------------------- | |
|
32 | # ----------------------------------------------------------------------------- | |
|
33 | 33 | # Test fixture |
|
34 | #----------------------------------------------------------------------------- | |
|
34 | # ----------------------------------------------------------------------------- | |
|
35 | 35 | |
|
36 | 36 | noop = lambda *a, **kw: None |
|
37 | 37 | |
|
38 | class FakeShell: | |
|
39 | 38 | |
|
39 | class FakeShell: | |
|
40 | 40 | def __init__(self): |
|
41 | 41 | self.ns = {} |
|
42 | 42 | self.user_ns = self.ns |
|
43 | 43 | self.user_ns_hidden = {} |
|
44 |
self.events = EventManager(self, { |
|
|
44 | self.events = EventManager(self, {"pre_run_cell", pre_run_cell}) | |
|
45 | 45 | self.auto_magics = AutoreloadMagics(shell=self) |
|
46 |
self.events.register( |
|
|
46 | self.events.register("pre_run_cell", self.auto_magics.pre_run_cell) | |
|
47 | 47 | |
|
48 | 48 | register_magics = set_hook = noop |
|
49 | 49 | |
|
50 | 50 | def run_code(self, code): |
|
51 |
self.events.trigger( |
|
|
51 | self.events.trigger("pre_run_cell") | |
|
52 | 52 | exec(code, self.user_ns) |
|
53 | 53 | self.auto_magics.post_execute_hook() |
|
54 | 54 | |
@@ -85,7 +85,7 b' class Fixture(TestCase):' | |||
|
85 | 85 | self.shell = None |
|
86 | 86 | |
|
87 | 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 | 89 | if module_name in sys.modules: |
|
90 | 90 | del sys.modules[module_name] |
|
91 | 91 | file_name = os.path.join(self.test_dir, module_name + ".py") |
@@ -111,19 +111,21 b' class Fixture(TestCase):' | |||
|
111 | 111 | time.sleep(1.05) |
|
112 | 112 | |
|
113 | 113 | # Write |
|
114 |
with open(filename, |
|
|
114 | with open(filename, "w") as f: | |
|
115 | 115 | f.write(content) |
|
116 | 116 | |
|
117 | 117 | def new_module(self, code): |
|
118 | 118 | code = textwrap.dedent(code) |
|
119 | 119 | mod_name, mod_fn = self.get_module() |
|
120 |
with open(mod_fn, |
|
|
120 | with open(mod_fn, "w") as f: | |
|
121 | 121 | f.write(code) |
|
122 | 122 | return mod_name, mod_fn |
|
123 | 123 | |
|
124 | #----------------------------------------------------------------------------- | |
|
124 | ||
|
125 | # ----------------------------------------------------------------------------- | |
|
125 | 126 | # Test automatic reloading |
|
126 | #----------------------------------------------------------------------------- | |
|
127 | # ----------------------------------------------------------------------------- | |
|
128 | ||
|
127 | 129 | |
|
128 | 130 | def pickle_get_current_class(obj): |
|
129 | 131 | """ |
@@ -136,25 +138,36 b' def pickle_get_current_class(obj):' | |||
|
136 | 138 | obj2 = getattr(obj2, subpath) |
|
137 | 139 | return obj2 |
|
138 | 140 | |
|
139 | class TestAutoreload(Fixture): | |
|
140 | 141 | |
|
142 | class TestAutoreload(Fixture): | |
|
141 | 143 | def test_reload_enums(self): |
|
142 |
mod_name, mod_fn = self.new_module( |
|
|
144 | mod_name, mod_fn = self.new_module( | |
|
145 | textwrap.dedent( | |
|
146 | """ | |
|
143 | 147 |
|
|
144 | 148 |
|
|
145 | 149 | A = 'A' |
|
146 | 150 | B = 'B' |
|
147 |
|
|
|
151 | """ | |
|
152 | ) | |
|
153 | ) | |
|
148 | 154 | self.shell.magic_autoreload("2") |
|
149 | 155 | self.shell.magic_aimport(mod_name) |
|
150 |
self.write_file( |
|
|
156 | self.write_file( | |
|
157 | mod_fn, | |
|
158 | textwrap.dedent( | |
|
159 | """ | |
|
151 | 160 |
|
|
152 | 161 |
|
|
153 | 162 | A = 'A' |
|
154 | 163 | B = 'B' |
|
155 | 164 | C = 'C' |
|
156 |
|
|
|
157 | with tt.AssertNotPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'): | |
|
165 | """ | |
|
166 | ), | |
|
167 | ) | |
|
168 | with tt.AssertNotPrints( | |
|
169 | ("[autoreload of %s failed:" % mod_name), channel="stderr" | |
|
170 | ): | |
|
158 | 171 | self.shell.run_code("pass") # trigger another reload |
|
159 | 172 | |
|
160 | 173 | def test_reload_class_type(self): |
@@ -195,7 +208,9 b' class TestAutoreload(Fixture):' | |||
|
195 | 208 | |
|
196 | 209 | def test_reload_class_attributes(self): |
|
197 | 210 | self.shell.magic_autoreload("2") |
|
198 |
mod_name, mod_fn = self.new_module( |
|
|
211 | mod_name, mod_fn = self.new_module( | |
|
212 | textwrap.dedent( | |
|
213 | """ | |
|
199 | 214 |
|
|
200 | 215 |
|
|
201 | 216 |
|
@@ -241,7 +256,7 b' class TestAutoreload(Fixture):' | |||
|
241 | 256 | |
|
242 | 257 | self.shell.run_code("second = MyClass(5)") |
|
243 | 258 | |
|
244 |
for object_name in { |
|
|
259 | for object_name in {"first", "second"}: | |
|
245 | 260 | self.shell.run_code(f"{object_name}.power(5)") |
|
246 | 261 | with nt.assert_raises(AttributeError): |
|
247 | 262 | self.shell.run_code(f"{object_name}.cube()") |
@@ -261,11 +276,11 b' class TestAutoreload(Fixture):' | |||
|
261 | 276 | self.shell.run_code(f"from {mod_name} import *") |
|
262 | 277 | self.shell.run_code("func1()") |
|
263 | 278 | with nt.assert_raises(NameError): |
|
264 |
self.shell.run_code( |
|
|
279 | self.shell.run_code("func2()") | |
|
265 | 280 | with nt.assert_raises(NameError): |
|
266 |
self.shell.run_code( |
|
|
281 | self.shell.run_code("t = Test()") | |
|
267 | 282 | with nt.assert_raises(NameError): |
|
268 |
self.shell.run_code( |
|
|
283 | self.shell.run_code("number") | |
|
269 | 284 | |
|
270 | 285 | # ----------- TEST NEW OBJ LOADED -------------------------- |
|
271 | 286 | |
@@ -287,7 +302,7 b' class TestAutoreload(Fixture):' | |||
|
287 | 302 | # test class now exists |
|
288 | 303 | self.shell.run_code("t = Test()") |
|
289 | 304 | # test global built-in var now exists |
|
290 |
self.shell.run_code( |
|
|
305 | self.shell.run_code("number") | |
|
291 | 306 | # test the enumerations gets loaded succesfully |
|
292 | 307 | self.shell.run_code("TestEnum.A") |
|
293 | 308 | |
@@ -314,7 +329,7 b' class TestAutoreload(Fixture):' | |||
|
314 | 329 | |
|
315 | 330 | # ----------- TEST IMPORT FROM MODULE -------------------------- |
|
316 | 331 | |
|
317 |
new_mod_code = |
|
|
332 | new_mod_code = """ | |
|
318 | 333 | from enum import Enum |
|
319 | 334 | class Ext(Enum): |
|
320 | 335 | A = 'ext' |
@@ -324,11 +339,11 b' class TestAutoreload(Fixture):' | |||
|
324 | 339 | def meth(self): |
|
325 | 340 | return 'ext' |
|
326 | 341 | ext_int = 2 |
|
327 |
|
|
|
342 | """ | |
|
328 | 343 | new_mod_name, new_mod_fn = self.new_module(textwrap.dedent(new_mod_code)) |
|
329 |
current_mod_code = f |
|
|
344 | current_mod_code = f""" | |
|
330 | 345 | from {new_mod_name} import * |
|
331 |
|
|
|
346 | """ | |
|
332 | 347 | self.write_file(mod_fn, textwrap.dedent(current_mod_code)) |
|
333 | 348 | self.shell.run_code("assert Ext.A.value == 'ext'") |
|
334 | 349 | self.shell.run_code("assert ext_func() == 'ext'") |
@@ -341,7 +356,8 b' class TestAutoreload(Fixture):' | |||
|
341 | 356 | '%autoreload 1' or '%autoreload 2' |
|
342 | 357 | """ |
|
343 | 358 | |
|
344 |
mod_name, mod_fn = self.new_module( |
|
|
359 | mod_name, mod_fn = self.new_module( | |
|
360 | """ | |
|
345 | 361 |
|
|
346 | 362 |
|
|
347 | 363 |
|
@@ -364,7 +380,8 b' class Baz(object):' | |||
|
364 | 380 | class Bar: # old-style class: weakref doesn't work for it on Python < 2.7 |
|
365 | 381 |
|
|
366 | 382 |
|
|
367 |
|
|
|
383 | """ | |
|
384 | ) | |
|
368 | 385 | |
|
369 | 386 | # |
|
370 | 387 | # Import module, and mark for reloading |
@@ -383,8 +400,9 b" class Bar: # old-style class: weakref doesn't work for it on Python < 2.7" | |||
|
383 | 400 | self.shell.run_code("import %s" % mod_name) |
|
384 | 401 | stream = StringIO() |
|
385 | 402 | self.shell.magic_aimport("", stream=stream) |
|
386 | nt.assert_true("Modules to reload:\nall-except-skipped" in | |
|
387 |
|
|
|
403 | nt.assert_true( | |
|
404 | "Modules to reload:\nall-except-skipped" in stream.getvalue() | |
|
405 | ) | |
|
388 | 406 | nt.assert_in(mod_name, self.shell.ns) |
|
389 | 407 | |
|
390 | 408 | mod = sys.modules[mod_name] |
@@ -419,20 +437,29 b" class Bar: # old-style class: weakref doesn't work for it on Python < 2.7" | |||
|
419 | 437 | # Simulate a failed reload: no reload should occur and exactly |
|
420 | 438 | # one error message should be printed |
|
421 | 439 | # |
|
422 |
self.write_file( |
|
|
440 | self.write_file( | |
|
441 | mod_fn, | |
|
442 | """ | |
|
423 | 443 |
|
|
424 |
|
|
|
444 | """, | |
|
445 | ) | |
|
425 | 446 | |
|
426 | with tt.AssertPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'): | |
|
427 | self.shell.run_code("pass") # trigger reload | |
|
428 | with tt.AssertNotPrints(('[autoreload of %s failed:' % mod_name), channel='stderr'): | |
|
429 |
self.shell.run_code("pass") # trigg |
|
|
447 | with tt.AssertPrints( | |
|
448 | ("[autoreload of %s failed:" % mod_name), channel="stderr" | |
|
449 | ): | |
|
450 | self.shell.run_code("pass") # trigger reload | |
|
451 | with tt.AssertNotPrints( | |
|
452 | ("[autoreload of %s failed:" % mod_name), channel="stderr" | |
|
453 | ): | |
|
454 | self.shell.run_code("pass") # trigger another reload | |
|
430 | 455 | check_module_contents() |
|
431 | 456 | |
|
432 | 457 | # |
|
433 | 458 | # Rewrite module (this time reload should succeed) |
|
434 | 459 | # |
|
435 |
self.write_file( |
|
|
460 | self.write_file( | |
|
461 | mod_fn, | |
|
462 | """ | |
|
436 | 463 |
|
|
437 | 464 |
|
|
438 | 465 |
|
@@ -450,30 +477,31 b' class Baz(object):' | |||
|
450 | 477 |
|
|
451 | 478 |
|
|
452 | 479 |
|
|
453 |
|
|
|
480 | """, | |
|
481 | ) | |
|
454 | 482 | |
|
455 | 483 | def check_module_contents(): |
|
456 | 484 | nt.assert_equal(mod.x, 10) |
|
457 |
nt.assert_false(hasattr(mod, |
|
|
485 | nt.assert_false(hasattr(mod, "z")) | |
|
458 | 486 | |
|
459 | nt.assert_equal(old_foo(0), 4) # superreload magic! | |
|
487 | nt.assert_equal(old_foo(0), 4) # superreload magic! | |
|
460 | 488 | nt.assert_equal(mod.foo(0), 4) |
|
461 | 489 | |
|
462 | 490 | obj = mod.Baz(9) |
|
463 | nt.assert_equal(old_obj.bar(1), 11) # superreload magic! | |
|
491 | nt.assert_equal(old_obj.bar(1), 11) # superreload magic! | |
|
464 | 492 | nt.assert_equal(obj.bar(1), 11) |
|
465 | 493 | |
|
466 | 494 | nt.assert_equal(old_obj.quux, 43) |
|
467 | 495 | nt.assert_equal(obj.quux, 43) |
|
468 | 496 | |
|
469 |
nt.assert_false(hasattr(old_obj, |
|
|
470 |
nt.assert_false(hasattr(obj, |
|
|
497 | nt.assert_false(hasattr(old_obj, "zzz")) | |
|
498 | nt.assert_false(hasattr(obj, "zzz")) | |
|
471 | 499 | |
|
472 | 500 | obj2 = mod.Bar() |
|
473 | 501 | nt.assert_equal(old_obj2.foo(), 2) |
|
474 | 502 | nt.assert_equal(obj2.foo(), 2) |
|
475 | 503 | |
|
476 | self.shell.run_code("pass") # trigger reload | |
|
504 | self.shell.run_code("pass") # trigger reload | |
|
477 | 505 | check_module_contents() |
|
478 | 506 | |
|
479 | 507 | # |
@@ -481,7 +509,7 b' class Bar: # old-style class' | |||
|
481 | 509 | # |
|
482 | 510 | os.unlink(mod_fn) |
|
483 | 511 | |
|
484 | self.shell.run_code("pass") # trigger reload | |
|
512 | self.shell.run_code("pass") # trigger reload | |
|
485 | 513 | check_module_contents() |
|
486 | 514 | |
|
487 | 515 | # |
@@ -491,19 +519,21 b' class Bar: # old-style class' | |||
|
491 | 519 | self.shell.magic_aimport("-" + mod_name) |
|
492 | 520 | stream = StringIO() |
|
493 | 521 | self.shell.magic_aimport("", stream=stream) |
|
494 | nt.assert_true(("Modules to skip:\n%s" % mod_name) in | |
|
495 | stream.getvalue()) | |
|
522 | nt.assert_true(("Modules to skip:\n%s" % mod_name) in stream.getvalue()) | |
|
496 | 523 | |
|
497 | 524 | # This should succeed, although no such module exists |
|
498 | 525 | self.shell.magic_aimport("-tmpmod_as318989e89ds") |
|
499 | 526 | else: |
|
500 | 527 | self.shell.magic_autoreload("0") |
|
501 | 528 | |
|
502 |
self.write_file( |
|
|
529 | self.write_file( | |
|
530 | mod_fn, | |
|
531 | """ | |
|
503 | 532 |
|
|
504 |
|
|
|
533 | """, | |
|
534 | ) | |
|
505 | 535 | |
|
506 | self.shell.run_code("pass") # trigger reload | |
|
536 | self.shell.run_code("pass") # trigger reload | |
|
507 | 537 | self.shell.run_code("pass") |
|
508 | 538 | check_module_contents() |
|
509 | 539 | |
@@ -515,7 +545,7 b' x = -99' | |||
|
515 | 545 | else: |
|
516 | 546 | self.shell.magic_autoreload("") |
|
517 | 547 | |
|
518 | self.shell.run_code("pass") # trigger reload | |
|
548 | self.shell.run_code("pass") # trigger reload | |
|
519 | 549 | nt.assert_equal(mod.x, -99) |
|
520 | 550 | |
|
521 | 551 | def test_smoketest_aimport(self): |
@@ -523,8 +553,3 b' x = -99' | |||
|
523 | 553 | |
|
524 | 554 | def test_smoketest_autoreload(self): |
|
525 | 555 | self._check_smoketest(use_aimport=False) |
|
526 | ||
|
527 | ||
|
528 | ||
|
529 | ||
|
530 |
General Comments 0
You need to be logged in to leave comments.
Login now