##// END OF EJS Templates
Merge pull request #13328 from Carreau/last-of-37...
Merge pull request #13328 from Carreau/last-of-37 remove last bits of pre-38 codepath.

File last commit:

r26962:3206fcd4
r27155:ec9fdb9f merge
Show More
autoreload.py
623 lines | 18.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:
``%autoreload``
Reload all modules (except those excluded by ``%aimport``)
automatically now.
``%autoreload 0``
Disable automatic reloading.
``%autoreload 1``
Reload all modules imported with ``%aimport`` every time before
executing the Python code typed.
``%autoreload 2``
Reload all modules (except those excluded by ``%aimport``) every
time before executing the Python code typed.
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 ``%autoreload 3``
Reload all modules AND autoload newly added objects
every time before executing the Python code typed.
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.
vivainio2
add ipy_autoreload (provided in #1540
r1035 """
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
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
# 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
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:
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:
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 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:
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
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
Fernando Perez
Renamed @register_magics to @magics_class to avoid confusion....
r6973 from IPython.core.magic import Magics, magics_class, line_magic
Pauli Virtanen
ipy_autoreload: tune documentation a bit, and strip trailing whitespace
r2004
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
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 def autoreload(self, parameter_s=""):
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 r"""%autoreload => Reload modules automatically
%autoreload
Reload all modules (except those excluded by %aimport) automatically
now.
%autoreload 0
Disable automatic reloading.
%autoreload 1
Reload all modules imported with %aimport every time before executing
the Python code typed.
%autoreload 2
Reload all modules (except those excluded by %aimport) every time
before executing the Python code typed.
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.
"""
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 if parameter_s == "":
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 self._reloader.check(True)
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 elif parameter_s == "0":
Pauli Virtanen
ENH: extensions/autoreload: move methods out of the Plugin class, and rewrite some code to be cleaner
r4840 self._reloader.enabled = False
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 elif parameter_s == "1":
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 self._reloader.check_all = False
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
Apply black to IPython/extensions/autoreload.py...
r26246 elif parameter_s == "2":
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 self._reloader.check_all = True
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.enabled = True
Spas Kalaydzhisyki
Apply black to IPython/extensions/autoreload.py...
r26246 elif parameter_s == "3":
Spas Kalaydzhisyki
Add new '%autoreload 3' option...
r26238 self._reloader.check_all = True
self._reloader.enabled = True
self._reloader.autoload_obj = True
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
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
ENH: extensions: port autoreload to current API
r4702 %aimport -foo
Mark module 'foo' to not be autoreloaded for %autoreload 1
"""
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))
elif modname.startswith("-"):
Pauli Virtanen
ENH: extensions: port autoreload to current API
r4702 modname = modname[1:]
Pauli Virtanen
ENH: extensions/autoreload: move methods out of the Plugin class, and rewrite some code to be cleaner
r4840 self._reloader.mark_module_skipped(modname)
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(",")]:
Srinivas Reddy Thatiparthy
load multiple modules simultaneously
r22988 top_module, top_name = self._reloader.aimport_module(_module)
vivainio2
add ipy_autoreload (provided in #1540
r1035
Srinivas Reddy Thatiparthy
load multiple modules simultaneously
r22988 # 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)