forked from VimPlug/jedi
Add api.Interpreter: Jedi API for Python REPLs
This commit is contained in:
59
jedi/api.py
59
jedi/api.py
@@ -54,13 +54,13 @@ class Script(object):
|
|||||||
:type source_encoding: str
|
:type source_encoding: str
|
||||||
"""
|
"""
|
||||||
def __init__(self, source, line, column, source_path,
|
def __init__(self, source, line, column, source_path,
|
||||||
source_encoding='utf-8'):
|
source_encoding='utf-8', fast=True):
|
||||||
api_classes._clear_caches()
|
api_classes._clear_caches()
|
||||||
debug.reset_time()
|
debug.reset_time()
|
||||||
self.source = modules.source_to_unicode(source, source_encoding)
|
self.source = modules.source_to_unicode(source, source_encoding)
|
||||||
self.pos = line, column
|
self.pos = line, column
|
||||||
self._module = modules.ModuleWithCursor(source_path,
|
self._module = modules.ModuleWithCursor(
|
||||||
source=self.source, position=self.pos)
|
source_path, source=self.source, position=self.pos, fast=fast)
|
||||||
self._source_path = source_path
|
self._source_path = source_path
|
||||||
self.source_path = None if source_path is None \
|
self.source_path = None if source_path is None \
|
||||||
else os.path.abspath(source_path)
|
else os.path.abspath(source_path)
|
||||||
@@ -503,6 +503,59 @@ class Script(object):
|
|||||||
return sorted(d, key=lambda x: (x.module_path or '', x.start_pos))
|
return sorted(d, key=lambda x: (x.module_path or '', x.start_pos))
|
||||||
|
|
||||||
|
|
||||||
|
class Interpreter(Script):
|
||||||
|
|
||||||
|
"""
|
||||||
|
Jedi API for Python REPLs.
|
||||||
|
|
||||||
|
>>> from itertools import chain
|
||||||
|
>>> script = Interpreter('cha', [locals()])
|
||||||
|
>>> script.complete()
|
||||||
|
[<Completion: chain>]
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, source, namespaces=[], line=None, column=None,
|
||||||
|
source_path=None, source_encoding='utf-8'):
|
||||||
|
lines = source.splitlines()
|
||||||
|
line = len(lines) if line is None else line
|
||||||
|
column = len(lines[-1]) if column is None else column
|
||||||
|
super(Interpreter, self).__init__(
|
||||||
|
source, line, column, source_path, source_encoding, fast=False)
|
||||||
|
for ns in namespaces:
|
||||||
|
self._import_raw_namespace(ns)
|
||||||
|
|
||||||
|
def _import_raw_namespace(self, raw_namespace):
|
||||||
|
for (variable, obj) in raw_namespace.items():
|
||||||
|
try:
|
||||||
|
module = obj.__module__
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
fakeimport = self._make_fakeimport(variable, module)
|
||||||
|
self._parser.scope.imports.append(fakeimport)
|
||||||
|
|
||||||
|
def _make_fakeimport(self, variable, module):
|
||||||
|
submodule = self._parser.scope._sub_module
|
||||||
|
varname = pr.Name(
|
||||||
|
module=submodule,
|
||||||
|
names=[(variable, (0, 0))],
|
||||||
|
start_pos=(0, 0),
|
||||||
|
end_pos=(None, None))
|
||||||
|
modname = pr.Name(
|
||||||
|
module=submodule,
|
||||||
|
names=[(module, (0, 0))],
|
||||||
|
start_pos=(0, 0),
|
||||||
|
end_pos=(None, None))
|
||||||
|
fakeimport = pr.Import(
|
||||||
|
module=submodule,
|
||||||
|
namespace=varname,
|
||||||
|
from_ns=modname,
|
||||||
|
start_pos=(0, 0),
|
||||||
|
end_pos=(None, None))
|
||||||
|
fakeimport.parent = submodule
|
||||||
|
return fakeimport
|
||||||
|
|
||||||
|
|
||||||
def defined_names(source, source_path=None, source_encoding='utf-8'):
|
def defined_names(source, source_path=None, source_encoding='utf-8'):
|
||||||
"""
|
"""
|
||||||
Get all definitions in `source` sorted by its position.
|
Get all definitions in `source` sorted by its position.
|
||||||
|
|||||||
@@ -92,8 +92,10 @@ class ModuleWithCursor(Module):
|
|||||||
:param position: The position, the user is currently in. Only important \
|
:param position: The position, the user is currently in. Only important \
|
||||||
for the main file.
|
for the main file.
|
||||||
"""
|
"""
|
||||||
def __init__(self, path, source, position):
|
def __init__(self, path, source, position, fast):
|
||||||
super(ModuleWithCursor, self).__init__(path, source)
|
super(ModuleWithCursor, self).__init__(path, source)
|
||||||
|
self._parserclass = fast_parser.FastParser if fast else \
|
||||||
|
parsing.Parser
|
||||||
self.position = position
|
self.position = position
|
||||||
|
|
||||||
# this two are only used, because there is no nonlocal in Python 2
|
# this two are only used, because there is no nonlocal in Python 2
|
||||||
@@ -112,7 +114,7 @@ class ModuleWithCursor(Module):
|
|||||||
# Call the parser already here, because it will be used anyways.
|
# Call the parser already here, because it will be used anyways.
|
||||||
# Also, the position is here important (which will not be used by
|
# Also, the position is here important (which will not be used by
|
||||||
# default), therefore fill the cache here.
|
# default), therefore fill the cache here.
|
||||||
self._parser = fast_parser.FastParser(self.source, self.path,
|
self._parser = self._parserclass(self.source, self.path,
|
||||||
self.position)
|
self.position)
|
||||||
# don't pickle that module, because it's changing fast
|
# don't pickle that module, because it's changing fast
|
||||||
cache.save_module(self.path, self.name, self._parser,
|
cache.save_module(self.path, self.name, self._parser,
|
||||||
|
|||||||
Reference in New Issue
Block a user