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