##// END OF EJS Templates
Fix #4777 and #7887...
Fix #4777 and #7887 The function in charge of actually converting cursor offset to CodeMirror line number and character number was actually crashing when the cursor was at the last character (loop until undefined, then access length of variable, which is undefined). This was hiding a bug in which when you would completer to a single completion pressing tab after as-you-type filtering, the completion would be completed twice. The logic that was supposed to detect whether or not all completions had a common prefix was actually faulty as the common prefix used to be a string but was then changed to an object. Hence the logic to check whether or not there was actually a common prefix was always true, even for empty string, leading to the deletion of the line (replace by '') in some cases.

File last commit:

r15811:4986e3de
r20538:ae7f6d6a
Show More
deepreload.py
347 lines | 10.6 KiB | text/x-python | PythonLexer
Ville M. Vainio
crlf -> lf
r1032 # -*- coding: utf-8 -*-
"""
Thomas Kluyver
Update docstring for deepreload module
r15811 Provides a reload() function that acts recursively.
Fernando Perez
Fixes to testing....
r1376
Thomas Kluyver
Update docstring for deepreload module
r15811 Python's normal :func:`python:reload` function only reloads the module that it's
passed. The :func:`reload` function in this module also reloads everything
imported from that module, which is useful when you're changing files deep
inside a package.
To use this as your default reload function, type this for Python 2::
Brian Granger
More work addressing review comments for Fernando's branch....
r2499
Thomas Kluyver
Update docstring for deepreload module
r15811 import __builtin__
from IPython.lib import deepreload
__builtin__.reload = deepreload.reload
Brian Granger
More work addressing review comments for Fernando's branch....
r2499
Thomas Kluyver
Update docstring for deepreload module
r15811 Or this for Python 3::
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
Update docstring for deepreload module
r15811 import builtins
from IPython.lib import deepreload
builtins.reload = deepreload.reload
Brian Granger
More work addressing review comments for Fernando's branch....
r2499
Thomas Kluyver
Update docstring for deepreload module
r15811 A reference to the original :func:`python:reload` is stored in this module as
:data:`original_reload`, so you can restore it later.
Bernardo B. Marques
remove all trailling spaces
r4872
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 This code is almost entirely based on knee.py, which is a Python
re-implementation of hierarchical module import.
Fernando Perez
Remove svn-style $Id marks from docstrings and Release imports....
r1853 """
Thomas Kluyver
Convert print statements to print function calls...
r13348 from __future__ import print_function
Ville M. Vainio
crlf -> lf
r1032 #*****************************************************************************
# Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#*****************************************************************************
Thomas Kluyver
Fix deepreload on Python 3....
r6548 from contextlib import contextmanager
Ville M. Vainio
crlf -> lf
r1032 import imp
import sys
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 from types import ModuleType
from warnings import warn
Thomas Kluyver
Fix imports of builtins module
r13351 from IPython.utils.py3compat import builtin_mod, builtin_mod_name
original_import = builtin_mod.__import__
Thomas Kluyver
Fix deepreload on Python 3....
r6548
@contextmanager
def replace_import_hook(new_import):
Thomas Kluyver
Fix imports of builtins module
r13351 saved_import = builtin_mod.__import__
builtin_mod.__import__ = new_import
Thomas Kluyver
Fix deepreload on Python 3....
r6548 try:
yield
finally:
Thomas Kluyver
Fix imports of builtins module
r13351 builtin_mod.__import__ = saved_import
Thomas Kluyver
Fix deepreload on Python 3....
r6548
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 def get_parent(globals, level):
"""
parent, name = get_parent(globals, level)
Return the package that an import is being performed in. If globals comes
from the module foo.bar.bat (not itself a package), this returns the
sys.modules entry for foo.bar. If globals is from a package's __init__.py,
the package's entry in sys.modules is returned.
If globals doesn't come from a package or a module in a package, or a
corresponding entry is not found in sys.modules, None is returned.
"""
orig_level = level
Ville M. Vainio
crlf -> lf
r1032
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 if not level or not isinstance(globals, dict):
return None, ''
pkgname = globals.get('__package__', None)
if pkgname is not None:
# __package__ is set, so use it
if not hasattr(pkgname, 'rindex'):
raise ValueError('__package__ set to non-string')
if len(pkgname) == 0:
if level > 0:
raise ValueError('Attempted relative import in non-package')
return None, ''
name = pkgname
Ville M. Vainio
crlf -> lf
r1032 else:
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 # __package__ not set, so figure it out and set it
if '__name__' not in globals:
return None, ''
modname = globals['__name__']
if '__path__' in globals:
# __path__ is set, so modname is already the package name
globals['__package__'] = name = modname
else:
# Normal module, so work out the package name if any
lastdot = modname.rfind('.')
if lastdot < 0 and level > 0:
raise ValueError("Attempted relative import in non-package")
if lastdot < 0:
globals['__package__'] = None
return None, ''
globals['__package__'] = name = modname[:lastdot]
dot = len(name)
Thomas Kluyver
Fix references to xrange
r13356 for x in range(level, 1, -1):
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 try:
dot = name.rindex('.', 0, dot)
except ValueError:
raise ValueError("attempted relative import beyond top-level "
"package")
name = name[:dot]
try:
parent = sys.modules[name]
except:
if orig_level < 1:
warn("Parent module '%.200s' not found while handling absolute "
"import" % name)
parent = None
else:
raise SystemError("Parent module '%.200s' not loaded, cannot "
"perform relative import" % name)
# We expect, but can't guarantee, if parent != None, that:
# - parent.__name__ == name
# - parent.__dict__ is globals
# If this is violated... Who cares?
return parent, name
def load_next(mod, altmod, name, buf):
"""
mod, name, buf = load_next(mod, altmod, name, buf)
altmod is either None or same as mod
"""
if len(name) == 0:
# completely empty module name should only happen in
# 'from . import' (or '__import__("")')
return mod, None, buf
dot = name.find('.')
if dot == 0:
raise ValueError('Empty module name')
if dot < 0:
subname = name
next = None
Ville M. Vainio
crlf -> lf
r1032 else:
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 subname = name[:dot]
next = name[dot+1:]
Ville M. Vainio
crlf -> lf
r1032
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 if buf != '':
buf += '.'
buf += subname
result = import_submodule(mod, subname, buf)
if result is None and mod != altmod:
result = import_submodule(altmod, subname, subname)
if result is not None:
buf = subname
if result is None:
raise ImportError("No module named %.200s" % name)
return result, next, buf
Ville M. Vainio
crlf -> lf
r1032
# Need to keep track of what we've already reloaded to prevent cyclic evil
found_now = {}
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 def import_submodule(mod, subname, fullname):
"""m = import_submodule(mod, subname, fullname)"""
# Require:
# if mod == None: subname == fullname
# else: mod.__name__ + "." + subname == fullname
Ville M. Vainio
crlf -> lf
r1032 global found_now
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 if fullname in found_now and fullname in sys.modules:
m = sys.modules[fullname]
else:
Thomas Kluyver
Convert print statements to print function calls...
r13348 print('Reloading', fullname)
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 found_now[fullname] = 1
oldm = sys.modules.get(fullname, None)
if mod is None:
path = None
elif hasattr(mod, '__path__'):
path = mod.__path__
else:
return None
Ville M. Vainio
crlf -> lf
r1032 try:
Thomas Kluyver
Fix deepreload on Python 3....
r6548 # This appears to be necessary on Python 3, because imp.find_module()
# tries to import standard libraries (like io) itself, and we don't
# want them to be processed by our deep_import_hook.
with replace_import_hook(original_import):
fp, filename, stuff = imp.find_module(subname, path)
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 except ImportError:
return None
try:
m = imp.load_module(fullname, fp, filename, stuff)
except:
# load_module probably removed name from modules because of
# the error. Put back the original module object.
if oldm:
sys.modules[fullname] = oldm
raise
finally:
if fp: fp.close()
add_submodule(mod, m, fullname, subname)
return m
def add_submodule(mod, submod, fullname, subname):
"""mod.{subname} = submod"""
if mod is None:
return #Nothing to do here.
if submod is None:
submod = sys.modules[fullname]
Bernardo B. Marques
remove all trailling spaces
r4872
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 setattr(mod, subname, submod)
return
def ensure_fromlist(mod, fromlist, buf, recursive):
"""Handle 'from module import a, b, c' imports."""
if not hasattr(mod, '__path__'):
return
for item in fromlist:
if not hasattr(item, 'rindex'):
raise TypeError("Item in ``from list'' not a string")
if item == '*':
if recursive:
continue # avoid endless recursion
try:
all = mod.__all__
except AttributeError:
pass
else:
ret = ensure_fromlist(mod, all, buf, 1)
if not ret:
return 0
elif not hasattr(mod, item):
import_submodule(mod, item, buf + '.' + item)
Bradley M. Froehle
Keep original function names.
r6532 def deep_import_hook(name, globals=None, locals=None, fromlist=None, level=-1):
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 """Replacement for __import__()"""
parent, buf = get_parent(globals, level)
head, name, buf = load_next(parent, None if level < 0 else parent, name, buf)
tail = head
while name:
tail, name, buf = load_next(tail, tail, name, buf)
# If tail is None, both get_parent and load_next found
# an empty module name: someone called __import__("") or
# doctored faulty bytecode
if tail is None:
raise ValueError('Empty module name')
if not fromlist:
return head
Bernardo B. Marques
remove all trailling spaces
r4872
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 ensure_fromlist(tail, fromlist, buf, 0)
return tail
modules_reloading = {}
Bradley M. Froehle
Keep original function names.
r6532 def deep_reload_hook(m):
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 """Replacement for reload()."""
if not isinstance(m, ModuleType):
raise TypeError("reload() argument must be module")
name = m.__name__
if name not in sys.modules:
raise ImportError("reload(): module %.200s not in sys.modules" % name)
global modules_reloading
Ville M. Vainio
crlf -> lf
r1032 try:
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 return modules_reloading[name]
except:
modules_reloading[name] = m
dot = name.rfind('.')
if dot < 0:
subname = name
path = None
else:
try:
parent = sys.modules[name[:dot]]
except KeyError:
modules_reloading.clear()
raise ImportError("reload(): parent %.200s not in sys.modules" % name[:dot])
subname = name[dot+1:]
path = getattr(parent, "__path__", None)
Bernardo B. Marques
remove all trailling spaces
r4872
Ville M. Vainio
crlf -> lf
r1032 try:
Thomas Kluyver
Fix deepreload on Python 3....
r6548 # This appears to be necessary on Python 3, because imp.find_module()
# tries to import standard libraries (like io) itself, and we don't
# want them to be processed by our deep_import_hook.
with replace_import_hook(original_import):
fp, filename, stuff = imp.find_module(subname, path)
Ville M. Vainio
crlf -> lf
r1032 finally:
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 modules_reloading.clear()
Bernardo B. Marques
remove all trailling spaces
r4872
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 try:
newm = imp.load_module(name, fp, filename, stuff)
except:
# load_module probably removed name from modules because of
# the error. Put back the original module object.
sys.modules[name] = m
raise
finally:
if fp: fp.close()
Ville M. Vainio
crlf -> lf
r1032
Bradley M. Froehle
Update deepreload to use a rewritten knee.py. Fixes dreload(numpy)....
r6531 modules_reloading.clear()
return newm
Ville M. Vainio
crlf -> lf
r1032
# Save the original hooks
Thomas Kluyver
Small changes towards supporting Python 3.
r4753 try:
Thomas Kluyver
Fix imports of builtins module
r13351 original_reload = builtin_mod.reload
Thomas Kluyver
Small changes towards supporting Python 3.
r4753 except AttributeError:
original_reload = imp.reload # Python 3
Ville M. Vainio
crlf -> lf
r1032
# Replacement for reload()
Thomas Kluyver
Fix imports of builtins module
r13351 def reload(module, exclude=['sys', 'os.path', builtin_mod_name, '__main__']):
Ville M. Vainio
crlf -> lf
r1032 """Recursively reload all modules used in the given module. Optionally
takes a list of modules to exclude from reloading. The default exclude
Bernardo B. Marques
remove all trailling spaces
r4872 list contains sys, __main__, and __builtin__, to prevent, e.g., resetting
Ville M. Vainio
crlf -> lf
r1032 display, exception, and io hooks.
"""
global found_now
for i in exclude:
found_now[i] = 1
try:
Thomas Kluyver
Fix deepreload on Python 3....
r6548 with replace_import_hook(deep_import_hook):
Abhinav Upadhyay
Return value directly from the try block and avoid a variable...
r12882 return deep_reload_hook(module)
Ville M. Vainio
crlf -> lf
r1032 finally:
found_now = {}
# Uncomment the following to automatically activate deep reloading whenever
# this module is imported
Thomas Kluyver
Fix imports of builtins module
r13351 #builtin_mod.reload = reload