diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:39 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:39 +0300 |
commit | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (patch) | |
tree | 64175d5cadab313b3e7039ebaa06c5bc3295e274 /contrib/python/ipython/py3/IPython/extensions | |
parent | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (diff) | |
download | ydb-e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/python/ipython/py3/IPython/extensions')
6 files changed, 850 insertions, 850 deletions
diff --git a/contrib/python/ipython/py3/IPython/extensions/__init__.py b/contrib/python/ipython/py3/IPython/extensions/__init__.py index acc4dc7601..db7f79fca6 100644 --- a/contrib/python/ipython/py3/IPython/extensions/__init__.py +++ b/contrib/python/ipython/py3/IPython/extensions/__init__.py @@ -1,2 +1,2 @@ -# -*- coding: utf-8 -*- -"""This directory is meant for IPython extensions.""" +# -*- coding: utf-8 -*- +"""This directory is meant for IPython extensions.""" diff --git a/contrib/python/ipython/py3/IPython/extensions/autoreload.py b/contrib/python/ipython/py3/IPython/extensions/autoreload.py index 274b8bfd88..ada680fcf0 100644 --- a/contrib/python/ipython/py3/IPython/extensions/autoreload.py +++ b/contrib/python/ipython/py3/IPython/extensions/autoreload.py @@ -1,550 +1,550 @@ -"""IPython extension to reload modules before executing user code. - -``autoreload`` reloads modules automatically before entering the execution of -code typed at the IPython prompt. - -This makes for example the following workflow possible: - -.. 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 - -The module was reloaded without reloading it explicitly, and the object -imported with ``from foo import ...`` was also updated. - -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. - -``%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`` - -``%aimport foo, bar`` - - Import modules 'foo', 'bar' and mark them to be autoreloaded for ``%autoreload 1`` - -``%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. - -- C extension modules cannot be reloaded, and so cannot be autoreloaded. -""" - -skip_doctest = True - -#----------------------------------------------------------------------------- -# 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. -#----------------------------------------------------------------------------- -# -# This IPython module is written by Pauli Virtanen, based on the autoreload -# code by Thomas Heller. - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -import os -import sys -import traceback -import types -import weakref -import gc -from importlib import import_module -from importlib.util import source_from_cache -from imp import reload - -#------------------------------------------------------------------------------ -# Autoreload functionality -#------------------------------------------------------------------------------ - -class ModuleReloader(object): - enabled = False - """Whether this reloader is enabled""" - - check_all = True - """Autoreload all modules, not just those listed in 'modules'""" - - def __init__(self): - # 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 = {} - - # Cache module modification times - self.check(check_all=True, do_reload=False) - - 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) - - import_module(module_name) - top_name = module_name.split('.')[0] - top_module = sys.modules[top_name] - return top_module, top_name - - def filename_and_mtime(self, module): - if not hasattr(module, '__file__') or module.__file__ is None: - return None, None - - if getattr(module, '__name__', None) in [None, '__mp_main__', '__main__']: - # we cannot reload(__main__) or reload(__mp_main__) - return None, None - - filename = module.__file__ - path, ext = os.path.splitext(filename) - - if ext.lower() == '.py': - py_filename = filename - else: - try: - py_filename = source_from_cache(filename) - 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): - """Check whether some modules need to be reloaded.""" - - if not self.enabled and not check_all: - return - - if check_all or self.check_all: - modules = list(sys.modules.keys()) - else: - modules = list(self.modules.keys()) - - for modname in modules: - m = sys.modules.get(modname, None) - - if modname in self.skip_modules: - continue - - py_filename, pymtime = self.filename_and_mtime(m) - if py_filename is None: - continue - - try: - if pymtime <= self.modules_mtimes[modname]: - continue - except KeyError: - self.modules_mtimes[modname] = pymtime - continue - else: - if self.failed.get(py_filename, None) == pymtime: - continue - - self.modules_mtimes[modname] = pymtime - - # If we've reached this point, we should try to reload the module - if do_reload: - try: - superreload(m, reload, self.old_objects) - if py_filename in self.failed: - del self.failed[py_filename] - except: - print("[autoreload of %s failed: %s]" % ( - modname, traceback.format_exc(10)), file=sys.stderr) - self.failed[py_filename] = pymtime - -#------------------------------------------------------------------------------ -# superreload -#------------------------------------------------------------------------------ - - -func_attrs = ['__code__', '__defaults__', '__doc__', - '__closure__', '__globals__', '__dict__'] - - -def update_function(old, new): - """Upgrade the code object of a function""" - for name in func_attrs: - try: - setattr(old, name, getattr(new, name)) - except (AttributeError, TypeError): - pass - - -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""" - - refs = gc.get_referrers(old) - - for ref in refs: - if type(ref) is old: - ref.__class__ = new - - -def update_class(old, new): - """Replace stuff in the __dict__ of a class, and upgrade - method code objects, and add new methods, if any""" - for key in list(old.__dict__.keys()): - old_obj = getattr(old, key) - try: - new_obj = getattr(new, key) - # explicitly checking that comparison returns True to handle - # cases where `==` doesn't return a boolean. - if (old_obj == new_obj) is True: - continue - except AttributeError: - # obsolete attribute: remove it - try: - delattr(old, key) - except (AttributeError, TypeError): - pass - continue - - if update_generic(old_obj, new_obj): continue - - try: - setattr(old, key, getattr(new, key)) - except (AttributeError, TypeError): - pass # skip non-writable attributes - - 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): - pass # skip non-writable attributes - - # update all instances of class - update_instances(old, new) - - -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) - - -def isinstance2(a, b, typ): - return isinstance(a, typ) and isinstance(b, typ) - - -UPDATE_RULES = [ - (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), -] -UPDATE_RULES.extend([(lambda a, b: isinstance2(a, b, types.MethodType), - lambda a, b: update_function(a.__func__, b.__func__)), -]) - - -def update_generic(a, b): - for type_check, update in UPDATE_RULES: - if type_check(a, b): - update(a, b) - return True - return False - - -class StrongRef(object): - def __init__(self, obj): - self.obj = obj - def __call__(self): - return self.obj - - -def superreload(module, reload=reload, old_objects=None): - """Enhanced version of the builtin reload function. - - 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 - - """ - if old_objects is None: - old_objects = {} - - # collect old objects in the module - for name, obj in list(module.__dict__.items()): - if not hasattr(obj, '__module__') or obj.__module__ != module.__name__: - continue - key = (module.__name__, name) - try: - old_objects.setdefault(key, []).append(weakref.ref(obj)) - except TypeError: - pass - - # reload module - try: - # clear namespace first from old cruft - old_dict = module.__dict__.copy() - old_name = module.__name__ - module.__dict__.clear() - module.__dict__['__name__'] = old_name - module.__dict__['__loader__'] = old_dict['__loader__'] - except (TypeError, AttributeError, KeyError): - pass - - try: - module = reload(module) - except: - # restore module dictionary on failed reload - module.__dict__.update(old_dict) - raise - - # iterate over all objects and update functions & classes - for name, new_obj in list(module.__dict__.items()): - key = (module.__name__, name) - if key not in old_objects: continue - - new_refs = [] - for old_ref in old_objects[key]: - old_obj = old_ref() - if old_obj is None: continue - new_refs.append(old_ref) - update_generic(old_obj, new_obj) - - if new_refs: - old_objects[key] = new_refs - else: - del old_objects[key] - - return module - -#------------------------------------------------------------------------------ -# IPython connectivity -#------------------------------------------------------------------------------ - -from IPython.core.magic import Magics, magics_class, line_magic - -@magics_class -class AutoreloadMagics(Magics): - def __init__(self, *a, **kw): - super(AutoreloadMagics, self).__init__(*a, **kw) - self._reloader = ModuleReloader() - self._reloader.check_all = False - self.loaded_modules = set(sys.modules) - - @line_magic - def autoreload(self, parameter_s=''): - 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. - - """ - if parameter_s == '': - self._reloader.check(True) - elif parameter_s == '0': - self._reloader.enabled = False - elif parameter_s == '1': - self._reloader.check_all = False - self._reloader.enabled = True - elif parameter_s == '2': - self._reloader.check_all = True - self._reloader.enabled = True - - @line_magic - def aimport(self, parameter_s='', stream=None): - """%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 - - %aimport foo, bar - Import modules 'foo', 'bar' and mark them to be autoreloaded for %autoreload 1 - - %aimport -foo - Mark module 'foo' to not be autoreloaded for %autoreload 1 - """ - modname = parameter_s - if not modname: - to_reload = sorted(self._reloader.modules.keys()) - to_skip = sorted(self._reloader.skip_modules.keys()) - if stream is None: - stream = sys.stdout - if self._reloader.check_all: - stream.write("Modules to reload:\nall-except-skipped\n") - else: - 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('-'): - modname = modname[1:] - self._reloader.mark_module_skipped(modname) - else: - for _module in ([_.strip() for _ in modname.split(',')]): - top_module, top_name = self._reloader.aimport_module(_module) - - # Inject module to user namespace - self.shell.push({top_name: top_module}) - - def pre_run_cell(self): - if self._reloader.enabled: - try: - self._reloader.check() - except: - pass - - def post_execute_hook(self): - """Cache the modification times of any modules imported in this execution - """ - 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) - - -def load_ipython_extension(ip): - """Load the extension in IPython.""" - auto_reload = AutoreloadMagics(ip) - ip.register_magics(auto_reload) - ip.events.register('pre_run_cell', auto_reload.pre_run_cell) - ip.events.register('post_execute', auto_reload.post_execute_hook) +"""IPython extension to reload modules before executing user code. + +``autoreload`` reloads modules automatically before entering the execution of +code typed at the IPython prompt. + +This makes for example the following workflow possible: + +.. 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 + +The module was reloaded without reloading it explicitly, and the object +imported with ``from foo import ...`` was also updated. + +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. + +``%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`` + +``%aimport foo, bar`` + + Import modules 'foo', 'bar' and mark them to be autoreloaded for ``%autoreload 1`` + +``%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. + +- C extension modules cannot be reloaded, and so cannot be autoreloaded. +""" + +skip_doctest = True + +#----------------------------------------------------------------------------- +# 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. +#----------------------------------------------------------------------------- +# +# This IPython module is written by Pauli Virtanen, based on the autoreload +# code by Thomas Heller. + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import os +import sys +import traceback +import types +import weakref +import gc +from importlib import import_module +from importlib.util import source_from_cache +from imp import reload + +#------------------------------------------------------------------------------ +# Autoreload functionality +#------------------------------------------------------------------------------ + +class ModuleReloader(object): + enabled = False + """Whether this reloader is enabled""" + + check_all = True + """Autoreload all modules, not just those listed in 'modules'""" + + def __init__(self): + # 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 = {} + + # Cache module modification times + self.check(check_all=True, do_reload=False) + + 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) + + import_module(module_name) + top_name = module_name.split('.')[0] + top_module = sys.modules[top_name] + return top_module, top_name + + def filename_and_mtime(self, module): + if not hasattr(module, '__file__') or module.__file__ is None: + return None, None + + if getattr(module, '__name__', None) in [None, '__mp_main__', '__main__']: + # we cannot reload(__main__) or reload(__mp_main__) + return None, None + + filename = module.__file__ + path, ext = os.path.splitext(filename) + + if ext.lower() == '.py': + py_filename = filename + else: + try: + py_filename = source_from_cache(filename) + 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): + """Check whether some modules need to be reloaded.""" + + if not self.enabled and not check_all: + return + + if check_all or self.check_all: + modules = list(sys.modules.keys()) + else: + modules = list(self.modules.keys()) + + for modname in modules: + m = sys.modules.get(modname, None) + + if modname in self.skip_modules: + continue + + py_filename, pymtime = self.filename_and_mtime(m) + if py_filename is None: + continue + + try: + if pymtime <= self.modules_mtimes[modname]: + continue + except KeyError: + self.modules_mtimes[modname] = pymtime + continue + else: + if self.failed.get(py_filename, None) == pymtime: + continue + + self.modules_mtimes[modname] = pymtime + + # If we've reached this point, we should try to reload the module + if do_reload: + try: + superreload(m, reload, self.old_objects) + if py_filename in self.failed: + del self.failed[py_filename] + except: + print("[autoreload of %s failed: %s]" % ( + modname, traceback.format_exc(10)), file=sys.stderr) + self.failed[py_filename] = pymtime + +#------------------------------------------------------------------------------ +# superreload +#------------------------------------------------------------------------------ + + +func_attrs = ['__code__', '__defaults__', '__doc__', + '__closure__', '__globals__', '__dict__'] + + +def update_function(old, new): + """Upgrade the code object of a function""" + for name in func_attrs: + try: + setattr(old, name, getattr(new, name)) + except (AttributeError, TypeError): + pass + + +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""" + + refs = gc.get_referrers(old) + + for ref in refs: + if type(ref) is old: + ref.__class__ = new + + +def update_class(old, new): + """Replace stuff in the __dict__ of a class, and upgrade + method code objects, and add new methods, if any""" + for key in list(old.__dict__.keys()): + old_obj = getattr(old, key) + try: + new_obj = getattr(new, key) + # explicitly checking that comparison returns True to handle + # cases where `==` doesn't return a boolean. + if (old_obj == new_obj) is True: + continue + except AttributeError: + # obsolete attribute: remove it + try: + delattr(old, key) + except (AttributeError, TypeError): + pass + continue + + if update_generic(old_obj, new_obj): continue + + try: + setattr(old, key, getattr(new, key)) + except (AttributeError, TypeError): + pass # skip non-writable attributes + + 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): + pass # skip non-writable attributes + + # update all instances of class + update_instances(old, new) + + +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) + + +def isinstance2(a, b, typ): + return isinstance(a, typ) and isinstance(b, typ) + + +UPDATE_RULES = [ + (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), +] +UPDATE_RULES.extend([(lambda a, b: isinstance2(a, b, types.MethodType), + lambda a, b: update_function(a.__func__, b.__func__)), +]) + + +def update_generic(a, b): + for type_check, update in UPDATE_RULES: + if type_check(a, b): + update(a, b) + return True + return False + + +class StrongRef(object): + def __init__(self, obj): + self.obj = obj + def __call__(self): + return self.obj + + +def superreload(module, reload=reload, old_objects=None): + """Enhanced version of the builtin reload function. + + 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 + + """ + if old_objects is None: + old_objects = {} + + # collect old objects in the module + for name, obj in list(module.__dict__.items()): + if not hasattr(obj, '__module__') or obj.__module__ != module.__name__: + continue + key = (module.__name__, name) + try: + old_objects.setdefault(key, []).append(weakref.ref(obj)) + except TypeError: + pass + + # reload module + try: + # clear namespace first from old cruft + old_dict = module.__dict__.copy() + old_name = module.__name__ + module.__dict__.clear() + module.__dict__['__name__'] = old_name + module.__dict__['__loader__'] = old_dict['__loader__'] + except (TypeError, AttributeError, KeyError): + pass + + try: + module = reload(module) + except: + # restore module dictionary on failed reload + module.__dict__.update(old_dict) + raise + + # iterate over all objects and update functions & classes + for name, new_obj in list(module.__dict__.items()): + key = (module.__name__, name) + if key not in old_objects: continue + + new_refs = [] + for old_ref in old_objects[key]: + old_obj = old_ref() + if old_obj is None: continue + new_refs.append(old_ref) + update_generic(old_obj, new_obj) + + if new_refs: + old_objects[key] = new_refs + else: + del old_objects[key] + + return module + +#------------------------------------------------------------------------------ +# IPython connectivity +#------------------------------------------------------------------------------ + +from IPython.core.magic import Magics, magics_class, line_magic + +@magics_class +class AutoreloadMagics(Magics): + def __init__(self, *a, **kw): + super(AutoreloadMagics, self).__init__(*a, **kw) + self._reloader = ModuleReloader() + self._reloader.check_all = False + self.loaded_modules = set(sys.modules) + + @line_magic + def autoreload(self, parameter_s=''): + 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. + + """ + if parameter_s == '': + self._reloader.check(True) + elif parameter_s == '0': + self._reloader.enabled = False + elif parameter_s == '1': + self._reloader.check_all = False + self._reloader.enabled = True + elif parameter_s == '2': + self._reloader.check_all = True + self._reloader.enabled = True + + @line_magic + def aimport(self, parameter_s='', stream=None): + """%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 + + %aimport foo, bar + Import modules 'foo', 'bar' and mark them to be autoreloaded for %autoreload 1 + + %aimport -foo + Mark module 'foo' to not be autoreloaded for %autoreload 1 + """ + modname = parameter_s + if not modname: + to_reload = sorted(self._reloader.modules.keys()) + to_skip = sorted(self._reloader.skip_modules.keys()) + if stream is None: + stream = sys.stdout + if self._reloader.check_all: + stream.write("Modules to reload:\nall-except-skipped\n") + else: + 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('-'): + modname = modname[1:] + self._reloader.mark_module_skipped(modname) + else: + for _module in ([_.strip() for _ in modname.split(',')]): + top_module, top_name = self._reloader.aimport_module(_module) + + # Inject module to user namespace + self.shell.push({top_name: top_module}) + + def pre_run_cell(self): + if self._reloader.enabled: + try: + self._reloader.check() + except: + pass + + def post_execute_hook(self): + """Cache the modification times of any modules imported in this execution + """ + 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) + + +def load_ipython_extension(ip): + """Load the extension in IPython.""" + auto_reload = AutoreloadMagics(ip) + ip.register_magics(auto_reload) + ip.events.register('pre_run_cell', auto_reload.pre_run_cell) + ip.events.register('post_execute', auto_reload.post_execute_hook) diff --git a/contrib/python/ipython/py3/IPython/extensions/cythonmagic.py b/contrib/python/ipython/py3/IPython/extensions/cythonmagic.py index 65c3e39548..3c88e7c2a1 100644 --- a/contrib/python/ipython/py3/IPython/extensions/cythonmagic.py +++ b/contrib/python/ipython/py3/IPython/extensions/cythonmagic.py @@ -1,21 +1,21 @@ -# -*- coding: utf-8 -*- -""" -**DEPRECATED** - -The cython magic has been integrated into Cython itself, -which is now released in version 0.21. - -cf github `Cython` organisation, `Cython` repo, under the -file `Cython/Build/IpythonMagic.py` -""" -#----------------------------------------------------------------------------- -# Copyright (C) 2010-2011, IPython Development Team. -#----------------------------------------------------------------------------- - -import warnings - -## still load the magic in IPython 3.x, remove completely in future versions. -def load_ipython_extension(ip): - """Load the extension in IPython.""" - - warnings.warn("""The Cython magic has been moved to the Cython package""") +# -*- coding: utf-8 -*- +""" +**DEPRECATED** + +The cython magic has been integrated into Cython itself, +which is now released in version 0.21. + +cf github `Cython` organisation, `Cython` repo, under the +file `Cython/Build/IpythonMagic.py` +""" +#----------------------------------------------------------------------------- +# Copyright (C) 2010-2011, IPython Development Team. +#----------------------------------------------------------------------------- + +import warnings + +## still load the magic in IPython 3.x, remove completely in future versions. +def load_ipython_extension(ip): + """Load the extension in IPython.""" + + warnings.warn("""The Cython magic has been moved to the Cython package""") diff --git a/contrib/python/ipython/py3/IPython/extensions/rmagic.py b/contrib/python/ipython/py3/IPython/extensions/rmagic.py index ecc25bc4f8..ec5763972e 100644 --- a/contrib/python/ipython/py3/IPython/extensions/rmagic.py +++ b/contrib/python/ipython/py3/IPython/extensions/rmagic.py @@ -1,12 +1,12 @@ -# -*- coding: utf-8 -*- - -#----------------------------------------------------------------------------- -# Copyright (C) 2012 The IPython Development Team -#----------------------------------------------------------------------------- - -import warnings - -def load_ipython_extension(ip): - """Load the extension in IPython.""" - warnings.warn("The rmagic extension in IPython has moved to " - "`rpy2.ipython`, please see `rpy2` documentation.") +# -*- coding: utf-8 -*- + +#----------------------------------------------------------------------------- +# Copyright (C) 2012 The IPython Development Team +#----------------------------------------------------------------------------- + +import warnings + +def load_ipython_extension(ip): + """Load the extension in IPython.""" + warnings.warn("The rmagic extension in IPython has moved to " + "`rpy2.ipython`, please see `rpy2` documentation.") diff --git a/contrib/python/ipython/py3/IPython/extensions/storemagic.py b/contrib/python/ipython/py3/IPython/extensions/storemagic.py index 6854044e3f..51b79ad314 100644 --- a/contrib/python/ipython/py3/IPython/extensions/storemagic.py +++ b/contrib/python/ipython/py3/IPython/extensions/storemagic.py @@ -1,233 +1,233 @@ -# -*- coding: utf-8 -*- -""" -%store magic for lightweight persistence. - -Stores variables, aliases and macros in IPython's database. - -To automatically restore stored variables at startup, add this to your -:file:`ipython_config.py` file:: - - c.StoreMagics.autorestore = True -""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import inspect, os, sys, textwrap - -from IPython.core.error import UsageError -from IPython.core.magic import Magics, magics_class, line_magic -from traitlets import Bool - - -def restore_aliases(ip, alias=None): - staliases = ip.db.get('stored_aliases', {}) - if alias is None: - for k,v in staliases.items(): - #print "restore alias",k,v # dbg - #self.alias_table[k] = v - ip.alias_manager.define_alias(k,v) - else: - ip.alias_manager.define_alias(alias, staliases[alias]) - - -def refresh_variables(ip): - db = ip.db - for key in db.keys('autorestore/*'): - # strip autorestore - justkey = os.path.basename(key) - try: - obj = db[key] - except KeyError: - print("Unable to restore variable '%s', ignoring (use %%store -d to forget!)" % justkey) - print("The error was:", sys.exc_info()[0]) - else: - #print "restored",justkey,"=",obj #dbg - ip.user_ns[justkey] = obj - - -def restore_dhist(ip): - ip.user_ns['_dh'] = ip.db.get('dhist',[]) - - -def restore_data(ip): - refresh_variables(ip) - restore_aliases(ip) - restore_dhist(ip) - - -@magics_class -class StoreMagics(Magics): - """Lightweight persistence for python variables. - - Provides the %store magic.""" - - autorestore = Bool(False, help= - """If True, any %store-d variables will be automatically restored - when IPython starts. - """ - ).tag(config=True) - - def __init__(self, shell): - super(StoreMagics, self).__init__(shell=shell) - self.shell.configurables.append(self) - if self.autorestore: - restore_data(self.shell) - - @line_magic - def store(self, parameter_s=''): - """Lightweight persistence for python variables. - - Example:: - - In [1]: l = ['hello',10,'world'] - In [2]: %store l - In [3]: exit - - (IPython session is closed and started again...) - - ville@badger:~$ ipython - In [1]: l - NameError: name 'l' is not defined - In [2]: %store -r - In [3]: l - Out[3]: ['hello', 10, 'world'] - - Usage: - - * ``%store`` - Show list of all variables and their current - values - * ``%store spam bar`` - Store the *current* value of the variables spam - and bar to disk - * ``%store -d spam`` - Remove the variable and its value from storage - * ``%store -z`` - Remove all variables from storage - * ``%store -r`` - Refresh all variables, aliases and directory history - from store (overwrite current vals) - * ``%store -r spam bar`` - Refresh specified variables and aliases from store - (delete current val) - * ``%store foo >a.txt`` - Store value of foo to new file a.txt - * ``%store foo >>a.txt`` - Append value of foo to file a.txt - - It should be noted that if you change the value of a variable, you - need to %store it again if you want to persist the new value. - - Note also that the variables will need to be pickleable; most basic - python types can be safely %store'd. - - Also aliases can be %store'd across sessions. - To remove an alias from the storage, use the %unalias magic. - """ - - opts,argsl = self.parse_options(parameter_s,'drz',mode='string') - args = argsl.split() - ip = self.shell - db = ip.db - # delete - if 'd' in opts: - try: - todel = args[0] - except IndexError: - raise UsageError('You must provide the variable to forget') - else: - try: - del db['autorestore/' + todel] - except: - raise UsageError("Can't delete variable '%s'" % todel) - # reset - elif 'z' in opts: - for k in db.keys('autorestore/*'): - del db[k] - - elif 'r' in opts: - if args: - for arg in args: - try: - obj = db['autorestore/' + arg] - except KeyError: - try: - restore_aliases(ip, alias=arg) - except KeyError: - print("no stored variable or alias %s" % arg) - else: - ip.user_ns[arg] = obj - else: - restore_data(ip) - - # run without arguments -> list variables & values - elif not args: - vars = db.keys('autorestore/*') - vars.sort() - if vars: - size = max(map(len, vars)) - else: - size = 0 - - print('Stored variables and their in-db values:') - fmt = '%-'+str(size)+'s -> %s' - get = db.get - for var in vars: - justkey = os.path.basename(var) - # print 30 first characters from every var - print(fmt % (justkey, repr(get(var, '<unavailable>'))[:50])) - - # default action - store the variable - else: - # %store foo >file.txt or >>file.txt - if len(args) > 1 and args[1].startswith('>'): - fnam = os.path.expanduser(args[1].lstrip('>').lstrip()) - if args[1].startswith('>>'): - fil = open(fnam, 'a') - else: - fil = open(fnam, 'w') - with fil: - obj = ip.ev(args[0]) - print("Writing '%s' (%s) to file '%s'." % (args[0], - obj.__class__.__name__, fnam)) - - if not isinstance (obj, str): - from pprint import pprint - pprint(obj, fil) - else: - fil.write(obj) - if not obj.endswith('\n'): - fil.write('\n') - - return - - # %store foo - for arg in args: - try: - obj = ip.user_ns[arg] - except KeyError: - # it might be an alias - name = arg - try: - cmd = ip.alias_manager.retrieve_alias(name) - except ValueError: - raise UsageError("Unknown variable '%s'" % name) - - staliases = db.get('stored_aliases',{}) - staliases[name] = cmd - db['stored_aliases'] = staliases - print("Alias stored: %s (%s)" % (name, cmd)) - return - - else: - modname = getattr(inspect.getmodule(obj), '__name__', '') - if modname == '__main__': - print(textwrap.dedent("""\ - Warning:%s is %s - Proper storage of interactively declared classes (or instances - of those classes) is not possible! Only instances - of classes in real modules on file system can be %%store'd. - """ % (arg, obj) )) - return - #pickled = pickle.dumps(obj) - db[ 'autorestore/' + arg ] = obj - print("Stored '%s' (%s)" % (arg, obj.__class__.__name__)) - - -def load_ipython_extension(ip): - """Load the extension in IPython.""" - ip.register_magics(StoreMagics) - +# -*- coding: utf-8 -*- +""" +%store magic for lightweight persistence. + +Stores variables, aliases and macros in IPython's database. + +To automatically restore stored variables at startup, add this to your +:file:`ipython_config.py` file:: + + c.StoreMagics.autorestore = True +""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import inspect, os, sys, textwrap + +from IPython.core.error import UsageError +from IPython.core.magic import Magics, magics_class, line_magic +from traitlets import Bool + + +def restore_aliases(ip, alias=None): + staliases = ip.db.get('stored_aliases', {}) + if alias is None: + for k,v in staliases.items(): + #print "restore alias",k,v # dbg + #self.alias_table[k] = v + ip.alias_manager.define_alias(k,v) + else: + ip.alias_manager.define_alias(alias, staliases[alias]) + + +def refresh_variables(ip): + db = ip.db + for key in db.keys('autorestore/*'): + # strip autorestore + justkey = os.path.basename(key) + try: + obj = db[key] + except KeyError: + print("Unable to restore variable '%s', ignoring (use %%store -d to forget!)" % justkey) + print("The error was:", sys.exc_info()[0]) + else: + #print "restored",justkey,"=",obj #dbg + ip.user_ns[justkey] = obj + + +def restore_dhist(ip): + ip.user_ns['_dh'] = ip.db.get('dhist',[]) + + +def restore_data(ip): + refresh_variables(ip) + restore_aliases(ip) + restore_dhist(ip) + + +@magics_class +class StoreMagics(Magics): + """Lightweight persistence for python variables. + + Provides the %store magic.""" + + autorestore = Bool(False, help= + """If True, any %store-d variables will be automatically restored + when IPython starts. + """ + ).tag(config=True) + + def __init__(self, shell): + super(StoreMagics, self).__init__(shell=shell) + self.shell.configurables.append(self) + if self.autorestore: + restore_data(self.shell) + + @line_magic + def store(self, parameter_s=''): + """Lightweight persistence for python variables. + + Example:: + + In [1]: l = ['hello',10,'world'] + In [2]: %store l + In [3]: exit + + (IPython session is closed and started again...) + + ville@badger:~$ ipython + In [1]: l + NameError: name 'l' is not defined + In [2]: %store -r + In [3]: l + Out[3]: ['hello', 10, 'world'] + + Usage: + + * ``%store`` - Show list of all variables and their current + values + * ``%store spam bar`` - Store the *current* value of the variables spam + and bar to disk + * ``%store -d spam`` - Remove the variable and its value from storage + * ``%store -z`` - Remove all variables from storage + * ``%store -r`` - Refresh all variables, aliases and directory history + from store (overwrite current vals) + * ``%store -r spam bar`` - Refresh specified variables and aliases from store + (delete current val) + * ``%store foo >a.txt`` - Store value of foo to new file a.txt + * ``%store foo >>a.txt`` - Append value of foo to file a.txt + + It should be noted that if you change the value of a variable, you + need to %store it again if you want to persist the new value. + + Note also that the variables will need to be pickleable; most basic + python types can be safely %store'd. + + Also aliases can be %store'd across sessions. + To remove an alias from the storage, use the %unalias magic. + """ + + opts,argsl = self.parse_options(parameter_s,'drz',mode='string') + args = argsl.split() + ip = self.shell + db = ip.db + # delete + if 'd' in opts: + try: + todel = args[0] + except IndexError: + raise UsageError('You must provide the variable to forget') + else: + try: + del db['autorestore/' + todel] + except: + raise UsageError("Can't delete variable '%s'" % todel) + # reset + elif 'z' in opts: + for k in db.keys('autorestore/*'): + del db[k] + + elif 'r' in opts: + if args: + for arg in args: + try: + obj = db['autorestore/' + arg] + except KeyError: + try: + restore_aliases(ip, alias=arg) + except KeyError: + print("no stored variable or alias %s" % arg) + else: + ip.user_ns[arg] = obj + else: + restore_data(ip) + + # run without arguments -> list variables & values + elif not args: + vars = db.keys('autorestore/*') + vars.sort() + if vars: + size = max(map(len, vars)) + else: + size = 0 + + print('Stored variables and their in-db values:') + fmt = '%-'+str(size)+'s -> %s' + get = db.get + for var in vars: + justkey = os.path.basename(var) + # print 30 first characters from every var + print(fmt % (justkey, repr(get(var, '<unavailable>'))[:50])) + + # default action - store the variable + else: + # %store foo >file.txt or >>file.txt + if len(args) > 1 and args[1].startswith('>'): + fnam = os.path.expanduser(args[1].lstrip('>').lstrip()) + if args[1].startswith('>>'): + fil = open(fnam, 'a') + else: + fil = open(fnam, 'w') + with fil: + obj = ip.ev(args[0]) + print("Writing '%s' (%s) to file '%s'." % (args[0], + obj.__class__.__name__, fnam)) + + if not isinstance (obj, str): + from pprint import pprint + pprint(obj, fil) + else: + fil.write(obj) + if not obj.endswith('\n'): + fil.write('\n') + + return + + # %store foo + for arg in args: + try: + obj = ip.user_ns[arg] + except KeyError: + # it might be an alias + name = arg + try: + cmd = ip.alias_manager.retrieve_alias(name) + except ValueError: + raise UsageError("Unknown variable '%s'" % name) + + staliases = db.get('stored_aliases',{}) + staliases[name] = cmd + db['stored_aliases'] = staliases + print("Alias stored: %s (%s)" % (name, cmd)) + return + + else: + modname = getattr(inspect.getmodule(obj), '__name__', '') + if modname == '__main__': + print(textwrap.dedent("""\ + Warning:%s is %s + Proper storage of interactively declared classes (or instances + of those classes) is not possible! Only instances + of classes in real modules on file system can be %%store'd. + """ % (arg, obj) )) + return + #pickled = pickle.dumps(obj) + db[ 'autorestore/' + arg ] = obj + print("Stored '%s' (%s)" % (arg, obj.__class__.__name__)) + + +def load_ipython_extension(ip): + """Load the extension in IPython.""" + ip.register_magics(StoreMagics) + diff --git a/contrib/python/ipython/py3/IPython/extensions/sympyprinting.py b/contrib/python/ipython/py3/IPython/extensions/sympyprinting.py index 8d41983c43..e6a83cd34b 100644 --- a/contrib/python/ipython/py3/IPython/extensions/sympyprinting.py +++ b/contrib/python/ipython/py3/IPython/extensions/sympyprinting.py @@ -1,32 +1,32 @@ -""" -**DEPRECATED** - -A print function that pretty prints sympy Basic objects. - -:moduleauthor: Brian Granger - -Usage -===== - -Once the extension is loaded, Sympy Basic objects are automatically -pretty-printed. - -As of SymPy 0.7.2, maintenance of this extension has moved to SymPy under -sympy.interactive.ipythonprinting, any modifications to account for changes to -SymPy should be submitted to SymPy rather than changed here. This module is -maintained here for backwards compatibility with old SymPy versions. - -""" -#----------------------------------------------------------------------------- -# Copyright (C) 2008 The IPython Development Team -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -import warnings - -def load_ipython_extension(ip): - warnings.warn("The sympyprinting extension has moved to `sympy`, " - "use `from sympy import init_printing; init_printing()`") +""" +**DEPRECATED** + +A print function that pretty prints sympy Basic objects. + +:moduleauthor: Brian Granger + +Usage +===== + +Once the extension is loaded, Sympy Basic objects are automatically +pretty-printed. + +As of SymPy 0.7.2, maintenance of this extension has moved to SymPy under +sympy.interactive.ipythonprinting, any modifications to account for changes to +SymPy should be submitted to SymPy rather than changed here. This module is +maintained here for backwards compatibility with old SymPy versions. + +""" +#----------------------------------------------------------------------------- +# Copyright (C) 2008 The IPython Development Team +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import warnings + +def load_ipython_extension(ip): + warnings.warn("The sympyprinting extension has moved to `sympy`, " + "use `from sympy import init_printing; init_printing()`") |