##// END OF EJS Templates
STY: placate linter over single vs double quotes
STY: placate linter over single vs double quotes

File last commit:

r26669:b2433d61
r28349:43021533
Show More
completerlib.py
370 lines | 12.0 KiB | text/x-python | PythonLexer
Brian E. Granger
Initial messing around....
r17700 # encoding: utf-8
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 """Implementations for various useful completers.
These are all loaded by default by IPython.
"""
#-----------------------------------------------------------------------------
Matthias BUSSONNIER
update copyright to 2011/20xx-2011...
r5390 # Copyright (C) 2010-2011 The IPython Development Team.
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 #
# Distributed under the terms of the BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
# Stdlib imports
import glob
import inspect
import os
import re
import sys
Diego Garcia
use `import_module` instead of `__import__` ( FIX #10008 )
r22954 from importlib import import_module
Srinivas Reddy Thatiparthy
remove the code specific to 2.x
r23049 from importlib.machinery import all_suffixes
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
MinRK
use importlib.machinery when available...
r14914
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 # Third-party imports
from time import time
from zipimport import zipimporter
# Our own imports
Srinivas Reddy Thatiparthy
Change absolute imports to relative imports to facilitate processes embedding kernel or debugger
r25227 from .completer import expand_user, compress_user
from .error import TryNext
from ..utils._process_common import arg_split
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
# FIXME: this should be pulled in with the right call via the component system
MinRK
Don't rely on `get_ipython` in builtins in library code
r10580 from IPython import get_ipython
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
Matthias Bussonnier
Show signature with Jedi....
r23753 from typing import List
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 #-----------------------------------------------------------------------------
# Globals and constants
#-----------------------------------------------------------------------------
Srinivas Reddy Thatiparthy
remove the code specific to 2.x
r23049 _suffixes = all_suffixes()
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
# Time in seconds after which the rootmodules will be stored permanently in the
# ipython ip.db database (kept in the user's .ipython dir).
TIMEOUT_STORAGE = 2
# Time in seconds after which we give up
TIMEOUT_GIVEUP = 20
# Regular expression for the python import statement
Markus Wageringel
support for unicode identifiers...
r25595 import_re = re.compile(r'(?P<name>[^\W\d]\w*?)'
Bradley M. Froehle
Fix 'import '... completion for py3 & egg files....
r8892 r'(?P<package>[/\\]__init__)?'
r'(?P<suffix>%s)$' %
MinRK
use importlib.machinery when available...
r14914 r'|'.join(re.escape(s) for s in _suffixes))
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
# RE for the ipython %run command (python + ipython scripts)
Paul Ivanov
make %run magic complete on .ipynb files
r13645 magic_run_re = re.compile(r'.*(\.ipy|\.ipynb|\.py[w]?)$')
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
#-----------------------------------------------------------------------------
# Local utilities
#-----------------------------------------------------------------------------
def module_list(path):
"""
Return the list containing the names of the modules available in the given
folder.
"""
Thomas Kluyver
Fix completion when importing modules in the cwd.
r6163 # sys.path has the cwd as an empty string, but isdir/listdir need it as '.'
if path == '':
path = '.'
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
# A few local constants to be used in loops below
pjoin = os.path.join
Bernardo B. Marques
remove all trailling spaces
r4872
Bradley M. Froehle
Fix 'import '... completion for py3 & egg files....
r8892 if os.path.isdir(path):
# Build a list of all files in the directory and all files
# in its subdirectories. For performance reasons, do not
# recurse more than one level into subdirectories.
files = []
Xiuming Chen
Make tab completion for 'from' suggest symlinked folders/modules.
r17036 for root, dirs, nondirs in os.walk(path, followlinks=True):
Bradley M. Froehle
Fix 'import '... completion for py3 & egg files....
r8892 subdir = root[len(path)+1:]
if subdir:
files.extend(pjoin(subdir, f) for f in nondirs)
dirs[:] = [] # Do not recurse into additional subdirectories.
else:
files.extend(nondirs)
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
Bradley M. Froehle
Fix 'import '... completion for py3 & egg files....
r8892 else:
try:
files = list(zipimporter(path)._files.keys())
except:
files = []
# Build a list of modules which match the import_re regex.
modules = []
for f in files:
m = import_re.match(f)
if m:
modules.append(m.group('name'))
return list(set(modules))
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
Antony Lee
Key the root modules cache by sys.path entries....
r10125
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 def get_root_modules():
"""
Returns a list containing the names of all the modules available in the
folders of the pythonpath.
Antony Lee
Key the root modules cache by sys.path entries....
r10125
ip.db['rootmodules_cache'] maps sys.path entries to list of modules.
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 """
ip = get_ipython()
Thomas Kluyver
Skip scanning for module names with no global shell instance...
r23173 if ip is None:
# No global shell instance to store cached list of modules.
# Don't try to scan for modules every time.
return list(sys.builtin_module_names)
Antony Lee
Key the root modules cache by sys.path entries....
r10125 rootmodules_cache = ip.db.get('rootmodules_cache', {})
rootmodules = list(sys.builtin_module_names)
start_time = time()
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 store = False
for path in sys.path:
Antony Lee
Key the root modules cache by sys.path entries....
r10125 try:
modules = rootmodules_cache[path]
except KeyError:
modules = module_list(path)
try:
modules.remove('__init__')
except ValueError:
pass
if path not in ('', '.'): # cwd modules should not be cached
rootmodules_cache[path] = modules
if time() - start_time > TIMEOUT_STORAGE and not store:
store = True
print("\nCaching the list of root modules, please wait!")
print("(This will only be done once - type '%rehashx' to "
"reset cache!)\n")
sys.stdout.flush()
if time() - start_time > TIMEOUT_GIVEUP:
print("This is taking too long, we give up.\n")
return []
rootmodules.extend(modules)
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 if store:
Antony Lee
Key the root modules cache by sys.path entries....
r10125 ip.db['rootmodules_cache'] = rootmodules_cache
rootmodules = list(set(rootmodules))
return rootmodules
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
def is_importable(module, attr, only_modules):
if only_modules:
return inspect.ismodule(getattr(module, attr))
else:
return not(attr[:2] == '__' and attr[-2:] == '__')
Daniel Shimon
Only complete exported submodules in import statements...
r26669 def is_possible_submodule(module, attr):
try:
obj = getattr(module, attr)
except AttributeError:
# Is possilby an unimported submodule
return True
except TypeError:
# https://github.com/ipython/ipython/issues/9678
return False
return inspect.ismodule(obj)
Matthias Bussonnier
Don't fail when completing modules ending with dot....
r23214
Matthias Bussonnier
Show signature with Jedi....
r23753 def try_import(mod: str, only_modules=False) -> List[str]:
Matthias Bussonnier
Don't fail when completing modules ending with dot....
r23214 """
Try to import given module and return list of potential completions.
"""
mod = mod.rstrip('.')
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 try:
Diego Garcia
use `import_module` instead of `__import__` ( FIX #10008 )
r22954 m = import_module(mod)
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 except:
return []
Wei Yen
Ensure `try_import` does not fail on null module.__file__
r24420 m_is_init = '__init__' in (getattr(m, '__file__', '') or '')
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
completions = []
if (not hasattr(m, '__file__')) or (not only_modules) or m_is_init:
completions.extend( [attr for attr in dir(m) if
is_importable(m, attr, only_modules)])
Bernardo B. Marques
remove all trailling spaces
r4872
Daniel Shimon
Only complete exported submodules in import statements...
r26669 m_all = getattr(m, "__all__", [])
if only_modules:
completions.extend(attr for attr in m_all if is_possible_submodule(m, attr))
else:
completions.extend(m_all)
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 if m_is_init:
completions.extend(module_list(os.path.dirname(m.__file__)))
Matthias Bussonnier
Show signature with Jedi....
r23753 completions_set = {c for c in completions if isinstance(c, str)}
completions_set.discard('__init__')
return list(completions_set)
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
#-----------------------------------------------------------------------------
# Completion-related functions.
#-----------------------------------------------------------------------------
def quick_completer(cmd, completions):
Matthias Bussonnier
fix some other syntax warnings
r24780 r""" Easily create a trivial completer for a command.
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
Takes either a list of completions, or all completions in string (that will
be split on whitespace).
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 Example::
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 [d:\ipython]|1> import ipy_completers
[d:\ipython]|2> ipy_completers.quick_completer('foo', ['bar','baz'])
[d:\ipython]|3> foo b<TAB>
bar baz
[d:\ipython]|3> foo ba
"""
Bernardo B. Marques
remove all trailling spaces
r4872
Srinivas Reddy Thatiparthy
convert string_types to str
r23037 if isinstance(completions, str):
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 completions = completions.split()
def do_complete(self, event):
return completions
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 get_ipython().set_hook('complete_command',do_complete, str_key = cmd)
def module_completion(line):
"""
Returns a list containing the completion possibilities for an import line.
The line looks like this :
'import xml.d'
'from xml.dom import'
"""
words = line.split(' ')
nwords = len(words)
# from whatever <tab> -> 'import '
if nwords == 3 and words[0] == 'from':
return ['import ']
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 # 'from xy<tab>' or 'import xy<tab>'
Min RK
use module completion on %aimport
r21717 if nwords < 3 and (words[0] in {'%aimport', 'import', 'from'}) :
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 if nwords == 1:
return get_root_modules()
mod = words[1].split('.')
if len(mod) < 2:
return get_root_modules()
completion_list = try_import('.'.join(mod[:-1]), True)
return ['.'.join(mod[:-1] + [el]) for el in completion_list]
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 # 'from xyz import abc<tab>'
if nwords >= 3 and words[0] == 'from':
mod = words[1]
return try_import(mod)
#-----------------------------------------------------------------------------
# Completers
#-----------------------------------------------------------------------------
# These all have the func(self, event) signature to be used as custom
# completers
def module_completer(self,event):
"""Give completions after user has typed 'import ...' or 'from ...'"""
# This works in all versions of python. While 2.5 has
# pkgutil.walk_packages(), that particular routine is fairly dangerous,
# since it imports *EVERYTHING* on sys.path. That is: a) very slow b) full
# of possibly problematic side effects.
# This search the folders in the sys.path for available modules.
return module_completion(event.line)
Fernando Perez
Fix bugs with completions of paths that have ~ in them....
r2965 # FIXME: there's a lot of logic common to the run, cd and builtin file
# completers, that is currently reimplemented in each.
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
def magic_run_completer(self, event):
Paul Ivanov
make %run magic complete on .ipynb files
r13645 """Complete files that end in .py or .ipy or .ipynb for the %run command.
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 """
Min RK
use arg_split(...strict=False) in module_completer
r5689 comps = arg_split(event.line, strict=False)
Thomas Kluyver
Improve matching files after script name for magic %run....
r14815 # relpath should be the current token that we need to complete.
if (len(comps) > 1) and (not event.line.endswith(' ')):
relpath = comps[-1].strip("'\"")
else:
relpath = ''
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
Fernando Perez
Fix bugs with completions of paths that have ~ in them....
r2965 #print("\nev=", event) # dbg
#print("rp=", relpath) # dbg
#print('comps=', comps) # dbg
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
lglob = glob.glob
isdir = os.path.isdir
Fernando Perez
Fix bugs with completions of paths that have ~ in them....
r2965 relpath, tilde_expand, tilde_val = expand_user(relpath)
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 # Find if the user has already typed the first filename, after which we
# should complete on all files, since after the first one other files may
# be arguments to the input script.
Thomas Kluyver
Fix tests for core
r13375 if any(magic_run_re.match(c) for c in comps):
Thomas Kluyver
Fix duplicate directories in %run tab completion
r14818 matches = [f.replace('\\','/') + ('/' if isdir(f) else '')
for f in lglob(relpath+'*')]
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 else:
Thomas Kluyver
Fix duplicate directories in %run tab completion
r14818 dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*') if isdir(f)]
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 pys = [f.replace('\\','/')
for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy') +
Paul Ivanov
make %run magic complete on .ipynb files
r13645 lglob(relpath+'*.ipynb') + lglob(relpath + '*.pyw')]
Thomas Kluyver
Fix duplicate directories in %run tab completion
r14818
matches = dirs + pys
Fernando Perez
Fix bugs with completions of paths that have ~ in them....
r2965 #print('run comp:', dirs+pys) # dbg
Thomas Kluyver
Fix duplicate directories in %run tab completion
r14818 return [compress_user(p, tilde_expand, tilde_val) for p in matches]
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
def cd_completer(self, event):
"""Completer function for cd, which only returns directories."""
ip = get_ipython()
relpath = event.symbol
#print(event) # dbg
if event.line.endswith('-b') or ' -b ' in event.line:
# return only bookmark completions
bkms = self.db.get('bookmarks', None)
if bkms:
return bkms.keys()
else:
return []
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 if event.symbol == '-':
width_dh = str(len(str(len(ip.user_ns['_dh']) + 1)))
# jump in directory history by number
fmt = '-%0' + width_dh +'d [%s]'
ents = [ fmt % (i,s) for i,s in enumerate(ip.user_ns['_dh'])]
if len(ents) > 1:
return ents
return []
if event.symbol.startswith('--'):
return ["--" + os.path.basename(d) for d in ip.user_ns['_dh']]
Fernando Perez
Fix bugs with completions of paths that have ~ in them....
r2965
# Expand ~ in path and normalize directory separators.
relpath, tilde_expand, tilde_val = expand_user(relpath)
relpath = relpath.replace('\\','/')
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
found = []
for d in [f.replace('\\','/') + '/' for f in glob.glob(relpath+'*')
if os.path.isdir(f)]:
if ' ' in d:
# we don't want to deal with any of that, complex code
# for this is elsewhere
raise TryNext
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Fix bugs with completions of paths that have ~ in them....
r2965 found.append(d)
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
if not found:
if os.path.isdir(relpath):
Fernando Perez
Fix bugs with completions of paths that have ~ in them....
r2965 return [compress_user(relpath, tilde_expand, tilde_val)]
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959
# if no completions so far, try bookmarks
Thomas Kluyver
Remove uses of iterkeys
r13360 bks = self.db.get('bookmarks',{})
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 bkmatches = [s for s in bks if s.startswith(event.symbol)]
if bkmatches:
return bkmatches
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Restored major default completer functionality (cd, import, run)....
r2959 raise TryNext
Fernando Perez
Fix bugs with completions of paths that have ~ in them....
r2965 return [compress_user(p, tilde_expand, tilde_val) for p in found]
Paul Ivanov
making %clear a native magic
r5961
Paul Ivanov
%reset now takes optional in/out/dhist/array args...
r5965 def reset_completer(self, event):
"A completer for %reset magic"
return '-f -s in out array dhist'.split()