##// END OF EJS Templates
Apply black to IPython/extensions/autoreload.py...
Spas Kalaydzhisyki -
Show More
@@ -100,21 +100,21 b' Some of the known remaining caveats are:'
100 100
101 101 skip_doctest = True
102 102
103 #-----------------------------------------------------------------------------
103 # -----------------------------------------------------------------------------
104 104 # Copyright (C) 2000 Thomas Heller
105 105 # Copyright (C) 2008 Pauli Virtanen <pav@iki.fi>
106 106 # Copyright (C) 2012 The IPython Development Team
107 107 #
108 108 # Distributed under the terms of the BSD License. The full license is in
109 109 # the file COPYING, distributed as part of this software.
110 #-----------------------------------------------------------------------------
110 # -----------------------------------------------------------------------------
111 111 #
112 112 # This IPython module is written by Pauli Virtanen, based on the autoreload
113 113 # code by Thomas Heller.
114 114
115 #-----------------------------------------------------------------------------
115 # -----------------------------------------------------------------------------
116 116 # Imports
117 #-----------------------------------------------------------------------------
117 # -----------------------------------------------------------------------------
118 118
119 119 import os
120 120 import sys
@@ -126,9 +126,10 b' from importlib import import_module'
126 126 from importlib.util import source_from_cache
127 127 from imp import reload
128 128
129 #------------------------------------------------------------------------------
129 # ------------------------------------------------------------------------------
130 130 # Autoreload functionality
131 #------------------------------------------------------------------------------
131 # ------------------------------------------------------------------------------
132
132 133
133 134 class ModuleReloader:
134 135 enabled = False
@@ -186,22 +187,22 b' class ModuleReloader:'
186 187 self.mark_module_reloadable(module_name)
187 188
188 189 import_module(module_name)
189 top_name = module_name.split('.')[0]
190 top_name = module_name.split(".")[0]
190 191 top_module = sys.modules[top_name]
191 192 return top_module, top_name
192 193
193 194 def filename_and_mtime(self, module):
194 if not hasattr(module, '__file__') or module.__file__ is None:
195 if not hasattr(module, "__file__") or module.__file__ is None:
195 196 return None, None
196 197
197 if getattr(module, '__name__', None) in [None, '__mp_main__', '__main__']:
198 if getattr(module, "__name__", None) in [None, "__mp_main__", "__main__"]:
198 199 # we cannot reload(__main__) or reload(__mp_main__)
199 200 return None, None
200 201
201 202 filename = module.__file__
202 203 path, ext = os.path.splitext(filename)
203 204
204 if ext.lower() == '.py':
205 if ext.lower() == ".py":
205 206 py_filename = filename
206 207 else:
207 208 try:
@@ -259,17 +260,28 b' class ModuleReloader:'
259 260 if py_filename in self.failed:
260 261 del self.failed[py_filename]
261 262 except:
262 print("[autoreload of {} failed: {}]".format(
263 modname, traceback.format_exc(10)), file=sys.stderr)
263 print(
264 "[autoreload of {} failed: {}]".format(
265 modname, traceback.format_exc(10)
266 ),
267 file=sys.stderr,
268 )
264 269 self.failed[py_filename] = pymtime
265 270
266 #------------------------------------------------------------------------------
271
272 # ------------------------------------------------------------------------------
267 273 # superreload
268 #------------------------------------------------------------------------------
274 # ------------------------------------------------------------------------------
269 275
270 276
271 func_attrs = ['__code__', '__defaults__', '__doc__',
272 '__closure__', '__globals__', '__dict__']
277 func_attrs = [
278 "__code__",
279 "__defaults__",
280 "__doc__",
281 "__closure__",
282 "__globals__",
283 "__dict__",
284 ]
273 285
274 286
275 287 def update_function(old, new):
@@ -285,7 +297,7 b' def update_instances(old, new):'
285 297 """Use garbage collector to find all instances that refer to the old
286 298 class definition and update their __class__ to point to the new class
287 299 definition"""
288
300
289 301 refs = gc.get_referrers(old)
290 302
291 303 for ref in refs:
@@ -312,19 +324,20 b' def update_class(old, new):'
312 324 pass
313 325 continue
314 326
315 if update_generic(old_obj, new_obj): continue
327 if update_generic(old_obj, new_obj):
328 continue
316 329
317 330 try:
318 331 setattr(old, key, getattr(new, key))
319 332 except (AttributeError, TypeError):
320 pass # skip non-writable attributes
333 pass # skip non-writable attributes
321 334
322 335 for key in list(new.__dict__.keys()):
323 336 if key not in list(old.__dict__.keys()):
324 337 try:
325 338 setattr(old, key, getattr(new, key))
326 339 except (AttributeError, TypeError):
327 pass # skip non-writable attributes
340 pass # skip non-writable attributes
328 341
329 342 # update all instances of class
330 343 update_instances(old, new)
@@ -342,16 +355,18 b' def isinstance2(a, b, typ):'
342 355
343 356
344 357 UPDATE_RULES = [
345 (lambda a, b: isinstance2(a, b, type),
346 update_class),
347 (lambda a, b: isinstance2(a, b, types.FunctionType),
348 update_function),
349 (lambda a, b: isinstance2(a, b, property),
350 update_property),
358 (lambda a, b: isinstance2(a, b, type), update_class),
359 (lambda a, b: isinstance2(a, b, types.FunctionType), update_function),
360 (lambda a, b: isinstance2(a, b, property), update_property),
351 361 ]
352 UPDATE_RULES.extend([(lambda a, b: isinstance2(a, b, types.MethodType),
353 lambda a, b: update_function(a.__func__, b.__func__)),
354 ])
362 UPDATE_RULES.extend(
363 [
364 (
365 lambda a, b: isinstance2(a, b, types.MethodType),
366 lambda a, b: update_function(a.__func__, b.__func__),
367 ),
368 ]
369 )
355 370
356 371
357 372 def update_generic(a, b):
@@ -365,15 +380,16 b' def update_generic(a, b):'
365 380 class StrongRef:
366 381 def __init__(self, obj):
367 382 self.obj = obj
383
368 384 def __call__(self):
369 385 return self.obj
370 386
371 387
372 388 def append_obj(module, d, name, obj, autoload=False):
373 not_in_mod = not hasattr(obj, '__module__') or obj.__module__ != module.__name__
389 not_in_mod = not hasattr(obj, "__module__") or obj.__module__ != module.__name__
374 390 if autoload:
375 391 # check needed for module global built-ins (int, str, dict,..)
376 if name.startswith('__') and not_in_mod:
392 if name.startswith("__") and not_in_mod:
377 393 return False
378 394 else:
379 395 if not_in_mod:
@@ -416,8 +432,8 b' def superreload(module, reload=reload, old_objects=None, shell=None):'
416 432 old_dict = module.__dict__.copy()
417 433 old_name = module.__name__
418 434 module.__dict__.clear()
419 module.__dict__['__name__'] = old_name
420 module.__dict__['__loader__'] = old_dict['__loader__']
435 module.__dict__["__name__"] = old_name
436 module.__dict__["__loader__"] = old_dict["__loader__"]
421 437 except (TypeError, AttributeError, KeyError):
422 438 pass
423 439
@@ -434,9 +450,9 b' def superreload(module, reload=reload, old_objects=None, shell=None):'
434 450 if key not in old_objects:
435 451 # here 'shell' acts both as a flag and as an output var
436 452 if (
437 shell is None or
438 name == 'Enum' or
439 not append_obj(module, old_objects, name, new_obj, True)
453 shell is None
454 or name == "Enum"
455 or not append_obj(module, old_objects, name, new_obj, True)
440 456 ):
441 457 continue
442 458 shell.user_ns[name] = new_obj
@@ -444,7 +460,8 b' def superreload(module, reload=reload, old_objects=None, shell=None):'
444 460 new_refs = []
445 461 for old_ref in old_objects[key]:
446 462 old_obj = old_ref()
447 if old_obj is None: continue
463 if old_obj is None:
464 continue
448 465 new_refs.append(old_ref)
449 466 update_generic(old_obj, new_obj)
450 467
@@ -455,12 +472,14 b' def superreload(module, reload=reload, old_objects=None, shell=None):'
455 472
456 473 return module
457 474
458 #------------------------------------------------------------------------------
475
476 # ------------------------------------------------------------------------------
459 477 # IPython connectivity
460 #------------------------------------------------------------------------------
478 # ------------------------------------------------------------------------------
461 479
462 480 from IPython.core.magic import Magics, magics_class, line_magic
463 481
482
464 483 @magics_class
465 484 class AutoreloadMagics(Magics):
466 485 def __init__(self, *a, **kw):
@@ -471,7 +490,7 b' class AutoreloadMagics(Magics):'
471 490 self.loaded_modules = set(sys.modules)
472 491
473 492 @line_magic
474 def autoreload(self, parameter_s=''):
493 def autoreload(self, parameter_s=""):
475 494 r"""%autoreload => Reload modules automatically
476 495
477 496 %autoreload
@@ -515,24 +534,24 b' class AutoreloadMagics(Magics):'
515 534 autoreloaded.
516 535
517 536 """
518 if parameter_s == '':
537 if parameter_s == "":
519 538 self._reloader.check(True)
520 elif parameter_s == '0':
539 elif parameter_s == "0":
521 540 self._reloader.enabled = False
522 elif parameter_s == '1':
541 elif parameter_s == "1":
523 542 self._reloader.check_all = False
524 543 self._reloader.enabled = True
525 elif parameter_s == '2':
544 elif parameter_s == "2":
526 545 self._reloader.check_all = True
527 546 self._reloader.enabled = True
528 547 self._reloader.enabled = True
529 elif parameter_s == '3':
548 elif parameter_s == "3":
530 549 self._reloader.check_all = True
531 550 self._reloader.enabled = True
532 551 self._reloader.autoload_obj = True
533 552
534 553 @line_magic
535 def aimport(self, parameter_s='', stream=None):
554 def aimport(self, parameter_s="", stream=None):
536 555 """%aimport => Import modules for automatic reloading.
537 556
538 557 %aimport
@@ -556,13 +575,13 b' class AutoreloadMagics(Magics):'
556 575 if self._reloader.check_all:
557 576 stream.write("Modules to reload:\nall-except-skipped\n")
558 577 else:
559 stream.write("Modules to reload:\n%s\n" % ' '.join(to_reload))
560 stream.write("\nModules to skip:\n%s\n" % ' '.join(to_skip))
561 elif modname.startswith('-'):
578 stream.write("Modules to reload:\n%s\n" % " ".join(to_reload))
579 stream.write("\nModules to skip:\n%s\n" % " ".join(to_skip))
580 elif modname.startswith("-"):
562 581 modname = modname[1:]
563 582 self._reloader.mark_module_skipped(modname)
564 583 else:
565 for _module in ([_.strip() for _ in modname.split(',')]):
584 for _module in [_.strip() for _ in modname.split(",")]:
566 585 top_module, top_name = self._reloader.aimport_module(_module)
567 586
568 587 # Inject module to user namespace
@@ -576,8 +595,7 b' class AutoreloadMagics(Magics):'
576 595 pass
577 596
578 597 def post_execute_hook(self):
579 """Cache the modification times of any modules imported in this execution
580 """
598 """Cache the modification times of any modules imported in this execution"""
581 599 newly_loaded_modules = set(sys.modules) - self.loaded_modules
582 600 for modname in newly_loaded_modules:
583 601 _, pymtime = self._reloader.filename_and_mtime(sys.modules[modname])
@@ -591,5 +609,5 b' def load_ipython_extension(ip):'
591 609 """Load the extension in IPython."""
592 610 auto_reload = AutoreloadMagics(ip)
593 611 ip.register_magics(auto_reload)
594 ip.events.register('pre_run_cell', auto_reload.pre_run_cell)
595 ip.events.register('post_execute', auto_reload.post_execute_hook)
612 ip.events.register("pre_run_cell", auto_reload.pre_run_cell)
613 ip.events.register("post_execute", auto_reload.post_execute_hook)
General Comments 0
You need to be logged in to leave comments. Login now