Skip to content

Commit

Permalink
Merge branch 'jedi_bump'
Browse files Browse the repository at this point in the history
  • Loading branch information
DamnWidget committed Jul 24, 2017
2 parents 1da26c1 + c9e3769 commit ba5febe
Show file tree
Hide file tree
Showing 46 changed files with 4,790 additions and 3,672 deletions.
17 changes: 13 additions & 4 deletions anaconda_lib/jedi/_compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@
except ImportError:
pass

# Cannot use sys.version.major and minor names, because in Python 2.6 it's not
# a namedtuple.
is_py3 = sys.version_info[0] >= 3
is_py33 = is_py3 and sys.version_info.minor >= 3
is_py34 = is_py3 and sys.version_info.minor >= 4
is_py35 = is_py3 and sys.version_info.minor >= 5
is_py33 = is_py3 and sys.version_info[1] >= 3
is_py34 = is_py3 and sys.version_info[1] >= 4
is_py35 = is_py3 and sys.version_info[1] >= 5
is_py26 = not is_py3 and sys.version_info[1] < 7
py_version = int(str(sys.version_info[0]) + str(sys.version_info[1]))


class DummyFile(object):
Expand Down Expand Up @@ -205,7 +208,8 @@ def u(string):
"""
if is_py3:
return str(string)
elif not isinstance(string, unicode):

if not isinstance(string, unicode):
return unicode(str(string), 'UTF-8')
return string

Expand All @@ -232,6 +236,11 @@ def literal_eval(string):
except ImportError:
from itertools import izip_longest as zip_longest # Python 2

try:
FileNotFoundError = FileNotFoundError
except NameError:
FileNotFoundError = IOError


def no_unicode_pprint(dct):
"""
Expand Down
116 changes: 68 additions & 48 deletions anaconda_lib/jedi/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
import warnings
import sys

from jedi._compatibility import unicode
from jedi.parser import load_grammar
from jedi.parser import tree
from jedi.parser.fast import FastParser
from jedi.parser.diff import FastParser
from jedi.parser.utils import save_parser
from jedi import debug
from jedi import settings
Expand All @@ -34,6 +33,7 @@
from jedi.evaluate.helpers import get_module_names
from jedi.evaluate.sys_path import get_venv_path
from jedi.evaluate.iterable import unpack_tuple_to_dict
from jedi.evaluate.filters import TreeNameDefinition

# Jedi uses lots and lots of recursion. By setting this a little bit higher, we
# can remove some "maximum recursion depth" errors.
Expand Down Expand Up @@ -131,15 +131,20 @@ def __init__(self, source=None, line=None, column=None, path=None,
self._evaluator = Evaluator(self._grammar, sys_path=sys_path)
debug.speed('init')

def _get_module(self):
@cache.memoize_method
def _get_module_node(self):
cache.invalidate_star_import_cache(self._path)
parser = FastParser(self._grammar, self._source, self.path)
save_parser(self.path, parser, pickling=False)

module = self._evaluator.wrap(parser.module)
imports.add_module(self._evaluator, unicode(module.name), module)
return parser.module

@cache.memoize_method
def _get_module(self):
module = er.ModuleContext(self._evaluator, self._get_module_node())
imports.add_module(self._evaluator, module.name.string_name, module)
return module

@property
def source_path(self):
"""
Expand Down Expand Up @@ -182,12 +187,15 @@ def goto_definitions(self):
:rtype: list of :class:`classes.Definition`
"""
leaf = self._get_module().name_for_position(self._pos)
module_node = self._get_module_node()
leaf = module_node.name_for_position(self._pos)
if leaf is None:
leaf = self._get_module().get_leaf_for_position(self._pos)
leaf = module_node.get_leaf_for_position(self._pos)
if leaf is None:
return []
definitions = helpers.evaluate_goto_definition(self._evaluator, leaf)

context = self._evaluator.create_context(self._get_module(), leaf)
definitions = helpers.evaluate_goto_definition(self._evaluator, context, leaf)

names = [s.name for s in definitions]
defs = [classes.Definition(self._evaluator, name) for name in names]
Expand All @@ -207,11 +215,9 @@ def goto_assignments(self, follow_imports=False):
"""
def filter_follow_imports(names):
for name in names:
definition = name.get_definition()
if definition.type in ('import_name', 'import_from'):
imp = imports.ImportWrapper(self._evaluator, name)
for name in filter_follow_imports(imp.follow(is_goto=True)):
yield name
if isinstance(name, (imports.ImportName, TreeNameDefinition)):
for context in name.infer():
yield context.name
else:
yield name

Expand All @@ -226,10 +232,11 @@ def _goto(self):
"""
Used for goto_assignments and usages.
"""
name = self._get_module().name_for_position(self._pos)
name = self._get_module_node().name_for_position(self._pos)
if name is None:
return []
return list(self._evaluator.goto(name))
context = self._evaluator.create_context(self._get_module(), name)
return list(self._evaluator.goto(context, name))

def usages(self, additional_module_paths=()):
"""
Expand All @@ -245,37 +252,33 @@ def usages(self, additional_module_paths=()):
temp, settings.dynamic_flow_information = \
settings.dynamic_flow_information, False
try:
user_stmt = self._get_module().get_statement_for_position(self._pos)
definitions = self._goto()
if not definitions and isinstance(user_stmt, tree.Import):
module_node = self._get_module_node()
user_stmt = module_node.get_statement_for_position(self._pos)
definition_names = self._goto()
if not definition_names and isinstance(user_stmt, tree.Import):
# For not defined imports (goto doesn't find something, we take
# the name as a definition. This is enough, because every name
# points to it.
name = user_stmt.name_for_position(self._pos)
if name is None:
# Must be syntax
return []
definitions = [name]
definition_names = [TreeNameDefinition(self._get_module(), name)]

if not definitions:
if not definition_names:
# Without a definition for a name we cannot find references.
return []

if not isinstance(user_stmt, tree.Import):
# import case is looked at with add_import_name option
definitions = usages.usages_add_import_modules(self._evaluator,
definitions)

module = set([d.get_parent_until() for d in definitions])
module.add(self._get_module())
names = usages.usages(self._evaluator, definitions, module)
definition_names = usages.resolve_potential_imports(self._evaluator,
definition_names)

for d in set(definitions):
names.append(classes.Definition(self._evaluator, d))
modules = set([d.get_root_context() for d in definition_names])
modules.add(self._get_module())
definitions = usages.usages(self._evaluator, definition_names, modules)
finally:
settings.dynamic_flow_information = temp

return helpers.sorted_definitions(set(names))
return helpers.sorted_definitions(set(definitions))

def call_signatures(self):
"""
Expand All @@ -294,13 +297,18 @@ def call_signatures(self):
:rtype: list of :class:`classes.CallSignature`
"""
call_signature_details = \
helpers.get_call_signature_details(self._get_module(), self._pos)
helpers.get_call_signature_details(self._get_module_node(), self._pos)
if call_signature_details is None:
return []

context = self._evaluator.create_context(
self._get_module(),
call_signature_details.bracket_leaf
)
with common.scale_speed_settings(settings.scale_call_signatures):
definitions = helpers.cache_call_signatures(
self._evaluator,
context,
call_signature_details.bracket_leaf,
self._code_lines,
self._pos
Expand All @@ -315,27 +323,29 @@ def call_signatures(self):

def _analysis(self):
self._evaluator.is_analysis = True
self._evaluator.analysis_modules = [self._get_module()]
module_node = self._get_module_node()
self._evaluator.analysis_modules = [module_node]
try:
for node in self._get_module().nodes_to_execute():
for node in module_node.nodes_to_execute():
context = self._get_module().create_context(node)
if node.type in ('funcdef', 'classdef'):
if node.type == 'classdef':
continue
raise NotImplementedError
er.Function(self._evaluator, node).get_decorated_func()
# TODO This is stupid, should be private
from jedi.evaluate.finder import _name_to_types
# Resolve the decorators.
_name_to_types(self._evaluator, context, node.children[1])
elif isinstance(node, tree.Import):
import_names = set(node.get_defined_names())
if node.is_nested():
import_names |= set(path[-1] for path in node.paths())
for n in import_names:
imports.ImportWrapper(self._evaluator, n).follow()
imports.infer_import(context, n)
elif node.type == 'expr_stmt':
types = self._evaluator.eval_element(node)
types = context.eval_node(node)
for testlist in node.children[:-1:2]:
# Iterate tuples.
unpack_tuple_to_dict(self._evaluator, types, testlist)
else:
try_iter_content(self._evaluator.goto_definitions(node))
try_iter_content(self._evaluator.goto_definitions(context, node))
self._evaluator.reset_recursion_limitations()

ana = [a for a in self._evaluator.analysis if self.path == a.path]
Expand Down Expand Up @@ -382,11 +392,13 @@ def __init__(self, source, namespaces, **kwds):
super(Interpreter, self).__init__(source, **kwds)
self.namespaces = namespaces

parser_module = super(Interpreter, self)._get_module()
self._module = interpreter.MixedModule(self._evaluator, parser_module, self.namespaces)

def _get_module(self):
return self._module
parser_module = super(Interpreter, self)._get_module_node()
return interpreter.MixedModuleContext(
self._evaluator,
parser_module,
self.namespaces
)


def defined_names(source, path=None, encoding='utf-8'):
Expand Down Expand Up @@ -426,13 +438,21 @@ def names(source=None, path=None, encoding='utf-8', all_scopes=False,
``definitions=True``. E.g. ``a = b`` returns ``b``.
"""
def def_ref_filter(_def):
is_def = _def.is_definition()
is_def = _def._name.tree_name.is_definition()
return definitions and is_def or references and not is_def

# Set line/column to a random position, because they don't matter.
script = Script(source, line=1, column=0, path=path, encoding=encoding)
defs = [classes.Definition(script._evaluator, name_part)
for name_part in get_module_names(script._get_module(), all_scopes)]
module_context = script._get_module()
defs = [
classes.Definition(
script._evaluator,
TreeNameDefinition(
module_context.create_context(name.parent),
name
)
) for name in get_module_names(script._get_module_node(), all_scopes)
]
return sorted(filter(def_ref_filter, defs), key=lambda x: (x.line, x.column))


Expand Down
Loading

0 comments on commit ba5febe

Please sign in to comment.