##// END OF EJS Templates
Add option to %autoreload to hide errors when reloading code
Add option to %autoreload to hide errors when reloading code

File last commit:

r28273:998efb1a
r28273:998efb1a
Show More
autoreload.py
727 lines | 22.9 KiB | text/x-python | PythonLexer
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937 """IPython extension to reload modules before executing user code.
``autoreload`` reloads modules automatically before entering the execution of
code typed at the IPython prompt.
vivainio2
add ipy_autoreload (provided in #1540
r1035
Pauli Virtanen
DOC: extensions/autoreload: better extension module docstring
r4843 This makes for example the following workflow possible:
vivainio2
autoreload docstring
r1037
Pauli Virtanen
DOC: extensions/autoreload: better extension module docstring
r4843 .. sourcecode:: ipython
In [1]: %load_ext autoreload
In [2]: %autoreload 2
In [3]: from foo import some_function
In [4]: some_function()
Out[4]: 42
In [5]: # open foo.py in an editor and change some_function to return 43
In [6]: some_function()
Out[6]: 43
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937 The module was reloaded without reloading it explicitly, and the object
imported with ``from foo import ...`` was also updated.
Pauli Virtanen
DOC: extensions/autoreload: better extension module docstring
r4843
Usage
=====
The following magic commands are provided:
Emilio Graff
Verbose version of `%autoreload` command
r27800 ``%autoreload``, ``%autoreload now``
Pauli Virtanen
DOC: extensions/autoreload: better extension module docstring
r4843
Reload all modules (except those excluded by ``%aimport``)
automatically now.
Emilio Graff
Verbose version of `%autoreload` command
r27800 ``%autoreload 0``, ``%autoreload off``
Pauli Virtanen
DOC: extensions/autoreload: better extension module docstring
r4843
Disable automatic reloading.
Emilio Graff
Verbose version of `%autoreload` command
r27800 ``%autoreload 1``, ``%autoreload explicit``
Pauli Virtanen
DOC: extensions/autoreload: better extension module docstring
r4843
Reload all modules imported with ``%aimport`` every time before
executing the Python code typed.
Emilio Graff
Verbose version of `%autoreload` command
r27800 ``%autoreload 2``, ``%autoreload all``
Pauli Virtanen
DOC: extensions/autoreload: better extension module docstring
r4843
Reload all modules (except those excluded by ``%aimport``) every
time before executing the Python code typed.
Emilio Graff
Verbose version of `%autoreload` command
r27800 ``%autoreload 3``, ``%autoreload complete``
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238
Emilio Graff
Correct documentation for mode 3
r27804 Same as 2/all, but also adds any new objects in the module. See
unit test at IPython/extensions/tests/test_autoreload.py::test_autoload_newly_added_objects
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238
Emilio Graff
Replace `%averbose` with args to `%autoreload`
r27931 Adding ``--print`` or ``-p`` to the ``%autoreload`` line will print autoreload activity to
standard out. ``--log`` or ``-l`` will do it to the log at INFO level; both can be used
simultaneously.
Pauli Virtanen
DOC: extensions/autoreload: better extension module docstring
r4843 ``%aimport``
List modules which are to be automatically imported or not to be imported.
``%aimport foo``
Import module 'foo' and mark it to be autoreloaded for ``%autoreload 1``
Matthias Bussonnier
Switch module separator to comas to be consistent.
r23000 ``%aimport foo, bar``
Srinivas Reddy Thatiparthy
load multiple modules simultaneously
r22988
Import modules 'foo', 'bar' and mark them to be autoreloaded for ``%autoreload 1``
Pauli Virtanen
DOC: extensions/autoreload: better extension module docstring
r4843 ``%aimport -foo``
Mark module 'foo' to not be autoreloaded.
Caveats
=======
Reloading Python modules in a reliable way is in general difficult,
and unexpected things may occur. ``%autoreload`` tries to work around
common pitfalls by replacing function code objects and parts of
classes previously in the module with new versions. This makes the
following things to work:
- Functions and classes imported via 'from xxx import foo' are upgraded
to new versions when 'xxx' is reloaded.
- Methods and properties of classes are upgraded on reload, so that
calling 'c.foo()' on an object 'c' created before the reload causes
the new code for 'foo' to be executed.
Some of the known remaining caveats are:
- Replacing code objects does not always succeed: changing a @property
in a class to an ordinary method or a method to a member variable
can cause problems (but in old objects only).
- Functions that are removed (eg. via monkey-patching) from a module
before it is reloaded are not upgraded.
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937 - C extension modules cannot be reloaded, and so cannot be autoreloaded.
nouman
Update autoreload.py...
r27792
- While comparing Enum and Flag, the 'is' Identity Operator is used (even in the case '==' has been used (Similar to the 'None' keyword)).
- Reloading a module, or importing the same module by a different name, creates new Enums. These may look the same, but are not.
vivainio2
add ipy_autoreload (provided in #1540
r1035 """
Emilio Graff
Replace `%averbose` with args to `%autoreload`
r27931 from IPython.core import magic_arguments
Emilio Graff
Remove copy-paste error
r27799 from IPython.core.magic import Magics, magics_class, line_magic
Emilio Graff
Fixes from `darker`
r27809
Nikita Kniazev
Fix unintentional skipping of module level doctests...
r26873 __skip_doctest__ = True
Fernando Perez
Skip doctesting of module docstring....
r4866
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 # -----------------------------------------------------------------------------
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937 # Copyright (C) 2000 Thomas Heller
# Copyright (C) 2008 Pauli Virtanen <pav@iki.fi>
# Copyright (C) 2012 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 # -----------------------------------------------------------------------------
vivainio2
add ipy_autoreload (provided in #1540
r1035 #
# This IPython module is written by Pauli Virtanen, based on the autoreload
# code by Thomas Heller.
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 # -----------------------------------------------------------------------------
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937 # Imports
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 # -----------------------------------------------------------------------------
Brian Granger
Cleaning up extensions that used plugins.
r8197
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937 import os
import sys
import traceback
import types
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 import weakref
Niclas
switching to gc.get_referrers() allows for a very simple and (hopefully) efficient update of old class instances
r25185 import gc
Emilio Graff
Add `%averbose` magic command.
r27803 import logging
Erik
Import `reload` from `importlib` instead of `imp`...
r26962 from importlib import import_module, reload
Matthias Bussonnier
Remove import indirection and deprecated private function....
r24337 from importlib.util import source_from_cache
vivainio2
add ipy_autoreload (provided in #1540
r1035
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 # ------------------------------------------------------------------------------
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937 # Autoreload functionality
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 # ------------------------------------------------------------------------------
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937
Spas Kalaydzhisyki
Apply pyupgrade to IPython/extensions/autoreload.py...
r26244 class ModuleReloader:
Pauli Virtanen
ENH: extensions/autoreload: move methods out of the Plugin class, and rewrite some code to be cleaner
r4840 enabled = False
"""Whether this reloader is enabled"""
vivainio2
add ipy_autoreload (provided in #1540
r1035 check_all = True
"""Autoreload all modules, not just those listed in 'modules'"""
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 autoload_obj = False
"""Autoreload all modules AND autoload all new objects"""
def __init__(self, shell=None):
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 # Modules that failed to reload: {module: mtime-on-failed-reload, ...}
self.failed = {}
# Modules specially marked as autoreloadable.
self.modules = {}
# Modules specially marked as not autoreloadable.
self.skip_modules = {}
# (module-name, name) -> weakref, for replacing old code objects
self.old_objects = {}
# Module modification timestamps
self.modules_mtimes = {}
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 self.shell = shell
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682
Emilio Graff
Add `%averbose` magic command.
r27803 # Reporting callable for verbosity
self._report = lambda msg: None # by default, be quiet.
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 # Cache module modification times
self.check(check_all=True, do_reload=False)
Pauli Virtanen
ipy_autoreload: tune documentation a bit, and strip trailing whitespace
r2004
Carlos Cordoba
Add option to %autoreload to hide errors when reloading code
r28273 # To hide autoreload errors
self.hide_errors = False
Pauli Virtanen
ENH: extensions/autoreload: move methods out of the Plugin class, and rewrite some code to be cleaner
r4840 def mark_module_skipped(self, module_name):
"""Skip reloading the named module in the future"""
try:
del self.modules[module_name]
except KeyError:
pass
self.skip_modules[module_name] = True
def mark_module_reloadable(self, module_name):
"""Reload the named module in the future (if it is imported)"""
try:
del self.skip_modules[module_name]
except KeyError:
pass
self.modules[module_name] = True
def aimport_module(self, module_name):
"""Import a module, and mark it reloadable
Returns
-------
top_module : module
The imported module if it is top-level, or the top-level
top_name : module
Name of top_module
"""
self.mark_module_reloadable(module_name)
Diego Garcia
use `import_module` instead of `__import__` ( FIX #10008 )
r22954 import_module(module_name)
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 top_name = module_name.split(".")[0]
Pauli Virtanen
ENH: extensions/autoreload: move methods out of the Plugin class, and rewrite some code to be cleaner
r4840 top_module = sys.modules[top_name]
return top_module, top_name
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 def filename_and_mtime(self, module):
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 if not hasattr(module, "__file__") or module.__file__ is None:
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 return None, None
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 if getattr(module, "__name__", None) in [None, "__mp_main__", "__main__"]:
Luke Pfister
Don't reload __mp_main__...
r23600 # we cannot reload(__main__) or reload(__mp_main__)
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 return None, None
filename = module.__file__
path, ext = os.path.splitext(filename)
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 if ext.lower() == ".py":
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 py_filename = filename
else:
try:
Matthias Bussonnier
Remove import indirection and deprecated private function....
r24337 py_filename = source_from_cache(filename)
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 except ValueError:
return None, None
try:
pymtime = os.stat(py_filename).st_mtime
except OSError:
return None, None
return py_filename, pymtime
def check(self, check_all=False, do_reload=True):
vivainio2
add ipy_autoreload (provided in #1540
r1035 """Check whether some modules need to be reloaded."""
Pauli Virtanen
ipy_autoreload: tune documentation a bit, and strip trailing whitespace
r2004
Pauli Virtanen
ENH: extensions/autoreload: move methods out of the Plugin class, and rewrite some code to be cleaner
r4840 if not self.enabled and not check_all:
return
vivainio2
add ipy_autoreload (provided in #1540
r1035 if check_all or self.check_all:
Thomas Kluyver
Fix autoreload tests
r13384 modules = list(sys.modules.keys())
vivainio2
add ipy_autoreload (provided in #1540
r1035 else:
Thomas Kluyver
Fix autoreload tests
r13384 modules = list(self.modules.keys())
Pauli Virtanen
ipy_autoreload: tune documentation a bit, and strip trailing whitespace
r2004
vivainio2
add ipy_autoreload (provided in #1540
r1035 for modname in modules:
m = sys.modules.get(modname, None)
if modname in self.skip_modules:
continue
Pauli Virtanen
ipy_autoreload: tune documentation a bit, and strip trailing whitespace
r2004
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 py_filename, pymtime = self.filename_and_mtime(m)
if py_filename is None:
vivainio2
add ipy_autoreload (provided in #1540
r1035 continue
Pauli Virtanen
ipy_autoreload: tune documentation a bit, and strip trailing whitespace
r2004
vivainio2
add ipy_autoreload (provided in #1540
r1035 try:
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 if pymtime <= self.modules_mtimes[modname]:
vivainio2
add ipy_autoreload (provided in #1540
r1035 continue
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 except KeyError:
self.modules_mtimes[modname] = pymtime
continue
else:
Pauli Virtanen
ENH: extensions/autoreload: move methods out of the Plugin class, and rewrite some code to be cleaner
r4840 if self.failed.get(py_filename, None) == pymtime:
vivainio2
add ipy_autoreload (provided in #1540
r1035 continue
Pauli Virtanen
ipy_autoreload: tune documentation a bit, and strip trailing whitespace
r2004
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 self.modules_mtimes[modname] = pymtime
# If we've reached this point, we should try to reload the module
if do_reload:
Emilio Graff
Add `%averbose` magic command.
r27803 self._report(f"Reloading '{modname}'.")
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 try:
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 if self.autoload_obj:
superreload(m, reload, self.old_objects, self.shell)
else:
superreload(m, reload, self.old_objects)
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 if py_filename in self.failed:
del self.failed[py_filename]
except:
Carlos Cordoba
Add option to %autoreload to hide errors when reloading code
r28273 if not self.hide_errors:
print(
"[autoreload of {} failed: {}]".format(
modname, traceback.format_exc(10)
),
file=sys.stderr,
)
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 self.failed[py_filename] = pymtime
vivainio2
add ipy_autoreload (provided in #1540
r1035
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246
# ------------------------------------------------------------------------------
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 # superreload
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 # ------------------------------------------------------------------------------
vivainio2
add ipy_autoreload (provided in #1540
r1035
Srinivas Reddy Thatiparthy
remove python2 code
r23088
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 func_attrs = [
"__code__",
"__defaults__",
"__doc__",
"__closure__",
"__globals__",
"__dict__",
]
Thomas Kluyver
Make autoreload extension work on Python 3....
r5911
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 def update_function(old, new):
"""Upgrade the code object of a function"""
Thomas Kluyver
Make autoreload extension work on Python 3....
r5911 for name in func_attrs:
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 try:
setattr(old, name, getattr(new, name))
except (AttributeError, TypeError):
pass
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937
Niclas
switching to gc.get_referrers() allows for a very simple and (hopefully) efficient update of old class instances
r25185 def update_instances(old, new):
"""Use garbage collector to find all instances that refer to the old
class definition and update their __class__ to point to the new class
definition"""
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246
Niclas
switching to gc.get_referrers() allows for a very simple and (hopefully) efficient update of old class instances
r25185 refs = gc.get_referrers(old)
for ref in refs:
if type(ref) is old:
Hugues Hoppe
Let %autoreload work on modules with frozen dataclasses...
r27716 object.__setattr__(ref, "__class__", new)
Niclas
allow type of already existing class instances to be updated
r24965
Niclas
Combined recursive approach with check for already visited objects to avoid infinite recursion....
r24992
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 def update_class(old, new):
"""Replace stuff in the __dict__ of a class, and upgrade
oscar6echo
Add new methods in update_class()
r24514 method code objects, and add new methods, if any"""
Thomas Kluyver
Fix autoreload tests
r13384 for key in list(old.__dict__.keys()):
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 old_obj = getattr(old, key)
try:
new_obj = getattr(new, key)
Sanyam Agarwal
autoreload: explicitly check for True when updating attributes. Fixes #11558
r24910 # explicitly checking that comparison returns True to handle
# cases where `==` doesn't return a boolean.
if (old_obj == new_obj) is True:
Matthias Bussonnier
Allow reloads of Enums....
r23397 continue
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 except AttributeError:
# obsolete attribute: remove it
Pauli Virtanen
ipy_autoreload: tune documentation a bit, and strip trailing whitespace
r2004 try:
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 delattr(old, key)
except (AttributeError, TypeError):
pass
continue
sleeping
fix comparing nested structures containing numpy arrays
r27330 except ValueError:
# can't compare nested structures containing
# numpy arrays using `==`
pass
Pauli Virtanen
ipy_autoreload: tune documentation a bit, and strip trailing whitespace
r2004
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 if update_generic(old_obj, new_obj):
continue
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245
try:
setattr(old, key, getattr(new, key))
except (AttributeError, TypeError):
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 pass # skip non-writable attributes
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245
oscar6echo
Add new methods in update_class()
r24514 for key in list(new.__dict__.keys()):
if key not in list(old.__dict__.keys()):
try:
setattr(old, key, getattr(new, key))
except (AttributeError, TypeError):
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 pass # skip non-writable attributes
oscar6echo
Add new methods in update_class()
r24514
Niclas
allow type of already existing class instances to be updated
r24965 # update all instances of class
Niclas
Combined recursive approach with check for already visited objects to avoid infinite recursion....
r24992 update_instances(old, new)
Niclas
allow type of already existing class instances to be updated
r24965
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 def update_property(old, new):
"""Replace get/set/del functions of a property"""
update_generic(old.fdel, new.fdel)
update_generic(old.fget, new.fget)
update_generic(old.fset, new.fset)
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 def isinstance2(a, b, typ):
return isinstance(a, typ) and isinstance(b, typ)
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 UPDATE_RULES = [
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 (lambda a, b: isinstance2(a, b, type), update_class),
(lambda a, b: isinstance2(a, b, types.FunctionType), update_function),
(lambda a, b: isinstance2(a, b, property), update_property),
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 ]
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 UPDATE_RULES.extend(
[
(
lambda a, b: isinstance2(a, b, types.MethodType),
lambda a, b: update_function(a.__func__, b.__func__),
),
]
)
Mikhail Korobov
Remove outdated code from extensions.autoreload....
r9108
Thomas Kluyver
Make autoreload extension work on Python 3....
r5911
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 def update_generic(a, b):
for type_check, update in UPDATE_RULES:
if type_check(a, b):
update(a, b)
return True
return False
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937
Spas Kalaydzhisyki
Apply pyupgrade to IPython/extensions/autoreload.py...
r26244 class StrongRef:
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 def __init__(self, obj):
self.obj = obj
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 def __call__(self):
return self.obj
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937
Spas Kalaydzhisyki
Apply pyupgrade to IPython/extensions/autoreload.py...
r26249 mod_attrs = [
"__name__",
"__doc__",
"__package__",
"__loader__",
"__spec__",
"__file__",
"__cached__",
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26251 "__builtins__",
Spas Kalaydzhisyki
Apply pyupgrade to IPython/extensions/autoreload.py...
r26249 ]
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 def append_obj(module, d, name, obj, autoload=False):
Spas Kalaydzhisyki
remove unnecessary negation from var name
r26253 in_module = hasattr(obj, "__module__") and obj.__module__ == module.__name__
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 if autoload:
Spas Kalaydzhisyki
Apply pyupgrade to IPython/extensions/autoreload.py...
r26249 # check needed for module global built-ins
Spas Kalaydzhisyki
remove unnecessary negation from var name
r26253 if not in_module and name in mod_attrs:
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 return False
else:
Spas Kalaydzhisyki
remove unnecessary negation from var name
r26253 if not in_module:
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 return False
key = (module.__name__, name)
try:
d.setdefault(key, []).append(weakref.ref(obj))
except TypeError:
pass
return True
def superreload(module, reload=reload, old_objects=None, shell=None):
vivainio2
add ipy_autoreload (provided in #1540
r1035 """Enhanced version of the builtin reload function.
Pauli Virtanen
ipy_autoreload: tune documentation a bit, and strip trailing whitespace
r2004
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 superreload remembers objects previously in the module, and
- upgrades the class dictionary of every old class in the module
- upgrades the code object of every old function and method
- clears the module's namespace before reloading
Pauli Virtanen
ipy_autoreload: tune documentation a bit, and strip trailing whitespace
r2004
vivainio2
add ipy_autoreload (provided in #1540
r1035 """
Emil Hessman
Avoid modifying mutable default value
r24618 if old_objects is None:
old_objects = {}
Pauli Virtanen
ipy_autoreload: tune documentation a bit, and strip trailing whitespace
r2004
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 # collect old objects in the module
Thomas Kluyver
Fix autoreload tests
r13384 for name, obj in list(module.__dict__.items()):
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 if not append_obj(module, old_objects, name, obj):
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 continue
key = (module.__name__, name)
try:
old_objects.setdefault(key, []).append(weakref.ref(obj))
except TypeError:
Srinivas Reddy Thatiparthy
remove dead code
r23103 pass
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245
# reload module
try:
# clear namespace first from old cruft
Pauli Virtanen
BUG: extensions/autoreload: don't clobber module dictionary if reload fails
r4841 old_dict = module.__dict__.copy()
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 old_name = module.__name__
module.__dict__.clear()
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 module.__dict__["__name__"] = old_name
module.__dict__["__loader__"] = old_dict["__loader__"]
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 except (TypeError, AttributeError, KeyError):
pass
Pauli Virtanen
BUG: extensions/autoreload: don't clobber module dictionary if reload fails
r4841
try:
module = reload(module)
except:
# restore module dictionary on failed reload
module.__dict__.update(old_dict)
raise
Pauli Virtanen
ipy_autoreload: tune documentation a bit, and strip trailing whitespace
r2004
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 # iterate over all objects and update functions & classes
Thomas Kluyver
Fix autoreload tests
r13384 for name, new_obj in list(module.__dict__.items()):
vivainio2
add ipy_autoreload (provided in #1540
r1035 key = (module.__name__, name)
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 if key not in old_objects:
# here 'shell' acts both as a flag and as an output var
if (
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 shell is None
or name == "Enum"
or not append_obj(module, old_objects, name, new_obj, True)
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 ):
continue
shell.user_ns[name] = new_obj
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245
new_refs = []
for old_ref in old_objects[key]:
old_obj = old_ref()
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 if old_obj is None:
continue
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 new_refs.append(old_ref)
update_generic(old_obj, new_obj)
if new_refs:
old_objects[key] = new_refs
else:
del old_objects[key]
vivainio2
add ipy_autoreload (provided in #1540
r1035 return module
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246
# ------------------------------------------------------------------------------
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245 # IPython connectivity
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 # ------------------------------------------------------------------------------
Ville M. Vainio
Pauli's autoreload patch to do proper "superreload", i.e. replace code objects of used function objects. Fixes #237691
r1245
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246
Fernando Perez
Renamed @register_magics to @magics_class to avoid confusion....
r6973 @magics_class
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937 class AutoreloadMagics(Magics):
Pauli Virtanen
ENH: extensions/autoreload: move methods out of the Plugin class, and rewrite some code to be cleaner
r4840 def __init__(self, *a, **kw):
Spas Kalaydzhisyki
Apply pyupgrade to IPython/extensions/autoreload.py...
r26244 super().__init__(*a, **kw)
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 self._reloader = ModuleReloader(self.shell)
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 self._reloader.check_all = False
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 self._reloader.autoload_obj = False
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 self.loaded_modules = set(sys.modules)
Pauli Virtanen
ipy_autoreload: tune documentation a bit, and strip trailing whitespace
r2004
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937 @line_magic
Emilio Graff
Replace `%averbose` with args to `%autoreload`
r27931 @magic_arguments.magic_arguments()
Emilio Graff
Format with `black`
r27933 @magic_arguments.argument(
"mode",
type=str,
default="now",
nargs="?",
help="""blank or 'now' - Reload all modules (except those excluded by %%aimport)
automatically now.
'0' or 'off' - Disable automatic reloading.
'1' or 'explicit' - Reload only modules imported with %%aimport every
time before executing the Python code typed.
'2' or 'all' - Reload all modules (except those excluded by %%aimport)
every time before executing the Python code typed.
'3' or 'complete' - Same as 2/all, but also but also adds any new
objects in the module.
""",
)
@magic_arguments.argument(
"-p",
"--print",
action="store_true",
default=False,
help="Show autoreload activity using `print` statements",
)
@magic_arguments.argument(
"-l",
"--log",
action="store_true",
default=False,
help="Show autoreload activity using the logger",
)
Carlos Cordoba
Add option to %autoreload to hide errors when reloading code
r28273 @magic_arguments.argument(
"--hide-errors",
action="store_true",
default=False,
help="Hide autoreload errors",
)
Emilio Graff
Replace `%averbose` with args to `%autoreload`
r27931 def autoreload(self, line=""):
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 r"""%autoreload => Reload modules automatically
Emilio Graff
Verbose version of `%autoreload` command
r27800 %autoreload or %autoreload now
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 Reload all modules (except those excluded by %aimport) automatically
now.
Emilio Graff
Verbose version of `%autoreload` command
r27800 %autoreload 0 or %autoreload off
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 Disable automatic reloading.
Emilio Graff
Verbose version of `%autoreload` command
r27800 %autoreload 1 or %autoreload explicit
Reload only modules imported with %aimport every time before executing
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 the Python code typed.
Emilio Graff
Verbose version of `%autoreload` command
r27800 %autoreload 2 or %autoreload all
Reload all modules (except those excluded by %aimport) every time
before executing the Python code typed.
%autoreload 3 or %autoreload complete
Emilio Graff
Correct documentation for mode 3
r27804 Same as 2/all, but also but also adds any new objects in the module. See
unit test at IPython/extensions/tests/test_autoreload.py::test_autoload_newly_added_objects
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702
Emilio Graff
Replace `%averbose` with args to `%autoreload`
r27931 The optional arguments --print and --log control display of autoreload activity. The default
is to act silently; --print (or -p) will print out the names of modules that are being
reloaded, and --log (or -l) outputs them to the log at INFO level.
Carlos Cordoba
Add option to %autoreload to hide errors when reloading code
r28273 The optional argument --hide-errors hides any errors that can happen when trying to
reload code.
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 Reloading Python modules in a reliable way is in general
difficult, and unexpected things may occur. %autoreload tries to
work around common pitfalls by replacing function code objects and
parts of classes previously in the module with new versions. This
makes the following things to work:
- Functions and classes imported via 'from xxx import foo' are upgraded
to new versions when 'xxx' is reloaded.
- Methods and properties of classes are upgraded on reload, so that
calling 'c.foo()' on an object 'c' created before the reload causes
the new code for 'foo' to be executed.
Some of the known remaining caveats are:
- Replacing code objects does not always succeed: changing a @property
in a class to an ordinary method or a method to a member variable
can cause problems (but in old objects only).
- Functions that are removed (eg. via monkey-patching) from a module
before it is reloaded are not upgraded.
- C extension modules cannot be reloaded, and so cannot be
autoreloaded.
"""
Emilio Graff
Replace `%averbose` with args to `%autoreload`
r27931 args = magic_arguments.parse_argstring(self.autoreload, line)
mode = args.mode.lower()
Emilio Graff
Format with `black`
r27933
Emilio Graff
Fix formatting
r27956 p = print
Emilio Graff
Format with `black`
r27933
Emilio Graff
Apply suggestions from code review...
r27952 logger = logging.getLogger("autoreload")
Emilio Graff
`l` doesn't need to be a function
r27955
l = logger.info
Emilio Graff
Replace `%averbose` with args to `%autoreload`
r27931
def pl(msg):
p(msg)
l(msg)
if args.print is False and args.log is False:
self._reloader._report = lambda msg: None
elif args.print is True:
if args.log is True:
Emilio Graff
Apply suggestions from code review...
r27952 self._reloader._report = pl
Emilio Graff
Replace `%averbose` with args to `%autoreload`
r27931 else:
Emilio Graff
Apply suggestions from code review...
r27952 self._reloader._report = p
Emilio Graff
Replace `%averbose` with args to `%autoreload`
r27931 elif args.log is True:
Emilio Graff
Apply suggestions from code review...
r27952 self._reloader._report = l
Emilio Graff
Replace `%averbose` with args to `%autoreload`
r27931
Carlos Cordoba
Add option to %autoreload to hide errors when reloading code
r28273 self._reloader.hide_errors = args.hide_errors
Emilio Graff
Replace `%averbose` with args to `%autoreload`
r27931 if mode == "" or mode == "now":
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 self._reloader.check(True)
Emilio Graff
Replace `%averbose` with args to `%autoreload`
r27931 elif mode == "0" or mode == "off":
Pauli Virtanen
ENH: extensions/autoreload: move methods out of the Plugin class, and rewrite some code to be cleaner
r4840 self._reloader.enabled = False
Emilio Graff
Replace `%averbose` with args to `%autoreload`
r27931 elif mode == "1" or mode == "explicit":
Pauli Virtanen
ENH: extensions/autoreload: move methods out of the Plugin class, and rewrite some code to be cleaner
r4840 self._reloader.enabled = True
Emilio Graff
Fully undo mode flags
r27957 self._reloader.check_all = False
self._reloader.autoload_obj = False
Emilio Graff
Replace `%averbose` with args to `%autoreload`
r27931 elif mode == "2" or mode == "all":
Pauli Virtanen
ENH: extensions/autoreload: move methods out of the Plugin class, and rewrite some code to be cleaner
r4840 self._reloader.enabled = True
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 self._reloader.check_all = True
Emilio Graff
Fully undo mode flags
r27957 self._reloader.autoload_obj = False
elif mode == "3" or mode == "complete":
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 self._reloader.enabled = True
Emilio Graff
Fully undo mode flags
r27957 self._reloader.check_all = True
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 self._reloader.autoload_obj = True
Emilio Graff
Raise error on bad parameter
r27802 else:
Emilio Graff
Replace `%averbose` with args to `%autoreload`
r27931 raise ValueError(f'Unrecognized autoreload mode "{mode}".')
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937 @line_magic
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 def aimport(self, parameter_s="", stream=None):
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 """%aimport => Import modules for automatic reloading.
%aimport
List modules to automatically import and not to import.
%aimport foo
Emilio Graff
Use new names in docstring.
r27954 Import module 'foo' and mark it to be autoreloaded for %autoreload explicit
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702
Matthias Bussonnier
Switch module separator to comas to be consistent.
r23000 %aimport foo, bar
Emilio Graff
Use new names in docstring.
r27954 Import modules 'foo', 'bar' and mark them to be autoreloaded for %autoreload explicit
Srinivas Reddy Thatiparthy
load multiple modules simultaneously
r22988
Emilio Graff
Improve parsing for `%aimport`
r27801 %aimport -foo, bar
Emilio Graff
Use new names in docstring.
r27954 Mark module 'foo' to not be autoreloaded for %autoreload explicit, all, or complete, and 'bar'
to be autoreloaded for mode explicit.
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 """
modname = parameter_s
if not modname:
Thomas Kluyver
Fix autoreload tests
r13384 to_reload = sorted(self._reloader.modules.keys())
to_skip = sorted(self._reloader.skip_modules.keys())
Pauli Virtanen
ENH: extensions/autoreload: move methods out of the Plugin class, and rewrite some code to be cleaner
r4840 if stream is None:
stream = sys.stdout
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 if self._reloader.check_all:
Pauli Virtanen
ENH: extensions/autoreload: move methods out of the Plugin class, and rewrite some code to be cleaner
r4840 stream.write("Modules to reload:\nall-except-skipped\n")
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 else:
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 stream.write("Modules to reload:\n%s\n" % " ".join(to_reload))
stream.write("\nModules to skip:\n%s\n" % " ".join(to_skip))
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 else:
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 for _module in [_.strip() for _ in modname.split(",")]:
Emilio Graff
Improve parsing for `%aimport`
r27801 if _module.startswith("-"):
_module = _module[1:].strip()
self._reloader.mark_module_skipped(_module)
else:
top_module, top_name = self._reloader.aimport_module(_module)
# Inject module to user namespace
self.shell.push({top_name: top_module})
vivainio2
add ipy_autoreload (provided in #1540
r1035
Thomas Kluyver
Rename pre/post_execute_explicit events to pre/post_run_cell
r15607 def pre_run_cell(self):
Thomas Kluyver
Use callbacks system for autoreload
r15603 if self._reloader.enabled:
try:
self._reloader.check()
except:
pass
Pauli Virtanen
ENH: extensions/autoreload: move methods out of the Plugin class, and rewrite some code to be cleaner
r4840
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 def post_execute_hook(self):
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 """Cache the modification times of any modules imported in this execution"""
Thomas Kluyver
Store timestamps for modules to autoreload...
r15682 newly_loaded_modules = set(sys.modules) - self.loaded_modules
for modname in newly_loaded_modules:
_, pymtime = self._reloader.filename_and_mtime(sys.modules[modname])
if pymtime is not None:
self._reloader.modules_mtimes[modname] = pymtime
self.loaded_modules.update(newly_loaded_modules)
Fernando Perez
Update autoreload: new magics api, various format fixes.
r6937
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 def load_ipython_extension(ip):
"""Load the extension in IPython."""
Thomas Kluyver
Extensions no longer responsible for checking if they are already loaded
r8552 auto_reload = AutoreloadMagics(ip)
ip.register_magics(auto_reload)
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 ip.events.register("pre_run_cell", auto_reload.pre_run_cell)
ip.events.register("post_execute", auto_reload.post_execute_hook)