1
0
forked from VimPlug/jedi

Get closer to fixing a lot of issues with the completion for repl.

This commit is contained in:
Dave Halter
2016-05-15 14:26:10 +02:00
parent beeffd2dcd
commit cc331d62e0
6 changed files with 97 additions and 59 deletions

View File

@@ -626,46 +626,6 @@ class Interpreter(Script):
interpreter.add_namespaces_to_parser(self._evaluator, namespaces,
self._parser.module())
def _simple_complete(self, path, dot, like):
user_stmt = self._parser.user_stmt_with_whitespace()
is_simple_path = not path or re.search('^[\w][\w\d.]*$', path)
if isinstance(user_stmt, tree.Import) or not is_simple_path:
return super(Interpreter, self)._simple_complete(path, dot, like)
else:
# TODO Remove this branch? The above branch should be fast enough IMO.
class NamespaceModule(object):
def __getattr__(_, name):
for n in self.namespaces:
try:
return n[name]
except KeyError:
pass
raise AttributeError()
def __dir__(_):
gen = (n.keys() for n in self.namespaces)
return list(set(chain.from_iterable(gen)))
paths = path.split('.') if path else []
namespaces = (NamespaceModule(), builtins)
for p in paths:
old, namespaces = namespaces, []
for n in old:
try:
namespaces.append(getattr(n, p))
except Exception:
pass
completion_names = []
for namespace in namespaces:
for name in dir(namespace):
if name.lower().startswith(like.lower()):
scope = self._parser.module()
n = FakeName(name, scope)
completion_names.append(n)
return completion_names
def defined_names(source, path=None, encoding='utf-8'):
"""

View File

@@ -3,13 +3,13 @@ TODO Some parts of this module are still not well documented.
"""
import inspect
import re
import sys
from jedi._compatibility import builtins
from jedi import debug
from jedi.common import source_to_unicode
from jedi.cache import underscore_memoization
from jedi.evaluate import compiled
from jedi.evaluate.compiled.fake import get_module
from jedi.parser import tree as pt
from jedi.parser import load_grammar
from jedi.parser.fast import FastParser
@@ -42,6 +42,9 @@ class LazyName(helpers.FakeName):
def parent(self):
"""
Creating fake statements for the interpreter.
Here we are trying to link back to Python code, if possible. This means
we try to find the python module for a name (not the builtin).
"""
obj = self._value
parser_path = []
@@ -63,10 +66,10 @@ class LazyName(helpers.FakeName):
# Unfortunately in some cases like `int` there's no __module__
module = builtins
else:
# TODO this import is wrong. Yields x for x.y.z instead of z
module = __import__(module_name)
# If we put anything into fromlist, it will just return the
# latest name.
module = __import__(module_name, fromlist=[''])
parser_path = names
raw_module = get_module(self._value)
found = []
try:
@@ -74,17 +77,36 @@ class LazyName(helpers.FakeName):
except AttributeError:
pass
else:
# cut the `c` from `.pyc`
path = re.sub('c$', '', path)
# Find the corresponding Python file for an interpreted one.
path = re.sub(r'\.pyc$', '.py', path)
if path.endswith('.py'):
with open(path) as f:
source = source_to_unicode(f.read())
mod = FastParser(load_grammar(), source, path).module
mod = self._evaluator.wrap(mod)
# We have to make sure that the modules that we import are also
# part of evaluator.modules.
for module_name, module in sys.modules.items():
try:
iterated_path = module.__file__
except AttributeError:
pass
else:
if iterated_path == path:
self._evaluator.modules[module_name] = mod
break
else:
raise NotImplementedError('This should not happen, a module '
'should be part of sys.modules.')
if parser_path:
assert len(parser_path) == 1
found = self._evaluator.find_types(mod, parser_path[0], search_global=True)
found = list(self._evaluator.find_types(mod, parser_path[0],
search_global=True))
else:
found = [self._evaluator.wrap(mod)]
found = [mod]
if not found:
debug.warning('Interpreter lookup failed in global scope for %s',
@@ -94,11 +116,14 @@ class LazyName(helpers.FakeName):
evaluated = compiled.create(self._evaluator, obj)
found = [evaluated]
content = iterable.AlreadyEvaluated(found)
stmt = pt.ExprStmt([self, pt.Operator(pt.zero_position_modifier,
'=', (0, 0), ''), content])
stmt.parent = self._module
return stmt
if len(found) > 1 or True:
content = iterable.AlreadyEvaluated(found)
stmt = pt.ExprStmt([self, pt.Operator(pt.zero_position_modifier,
'=', (0, 0), ''), content])
stmt.parent = self._module
return stmt
else:
return found[0]
@parent.setter
def parent(self, value):