diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 52822509..e63d5ef5 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -341,9 +341,9 @@ class Evaluator(object): c = atom.children if c[0].type == 'string': # Will be one string. - types = self._eval_atom(c[0]) + types = self._eval_atom(context, c[0]) for string in c[1:]: - right = self._eval_atom(string) + right = self._eval_atom(context, string) types = precedence.calculate(self, types, '+', right) return types # Parentheses without commas are not tuples. diff --git a/jedi/evaluate/context.py b/jedi/evaluate/context.py index bc30cd06..a5182de6 100644 --- a/jedi/evaluate/context.py +++ b/jedi/evaluate/context.py @@ -3,7 +3,11 @@ from jedi.common import unite class Context(object): type = None # TODO remove - api_type = '' + api_type = 'instance' + """ + Most contexts are just instances of something, therefore make this the + default to make subclassing a lot easier. + """ def __init__(self, evaluator, parent_context=None): self.evaluator = evaluator diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index d534c662..a02a4639 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -671,9 +671,8 @@ def check_tuple_assignments(evaluator, types, name): # index number is high. Therefore break if the loop is # finished. return set() - if lazy_context is None: - return types - return lazy_context.infer() + types = lazy_context.infer() + return types def filter_private_variable(scope, origin_node): diff --git a/jedi/evaluate/instance.py b/jedi/evaluate/instance.py index 3c1bde7f..3ad7cfc4 100644 --- a/jedi/evaluate/instance.py +++ b/jedi/evaluate/instance.py @@ -16,8 +16,6 @@ class AbstractInstanceContext(Context): """ This class is used to evaluate instances. """ - api_type = 'instance' - def __init__(self, evaluator, parent_context, class_context, var_args): super(AbstractInstanceContext, self).__init__(evaluator, parent_context) # Generated instances are classes that are just generated by self diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index 09806360..2708b1bc 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -265,7 +265,7 @@ class ArrayMixin(object): return self.evaluator.BUILTINS def dict_values(self): - return unite(self.evaluator.eval_element(v) for k, v in self._items()) + return unite(self._defining_context.eval_node(v) for k, v in self._items()) @register_builtin_method('values', type='dict') def _imitate_values(self): @@ -386,7 +386,7 @@ class ArrayLiteralContext(ArrayMixin, AbstractSequence): # We don't know which dict index comes first, therefore always # yield all the types. for _ in types: - yield types + yield context.LazyKnownContexts(types) else: for node in self._items(): yield context.LazyTreeContext(self._defining_context, node) @@ -847,8 +847,8 @@ class _ArrayInstance(IterableWrapper): class Slice(object): - def __init__(self, evaluator, start, stop, step): - self._evaluator = evaluator + def __init__(self, context, start, stop, step): + self._context = context # all of them are either a Precedence or None. self._start = start self._stop = stop @@ -864,7 +864,7 @@ class Slice(object): if element is None: return None - result = self._evaluator.eval_element(element) + result = self._context.eval_node(element) if len(result) != 1: # For simplicity, we want slices to be clear defined with just # one type. Otherwise we will return an empty slice object. @@ -886,7 +886,7 @@ def create_index_types(evaluator, context, index): """ if index == ':': # Like array[:] - return set([Slice(evaluator, None, None, None)]) + return set([Slice(context, None, None, None)]) elif tree.is_node(index, 'subscript'): # subscript is a slice operation. # Like array[:3] result = [] @@ -901,7 +901,7 @@ def create_index_types(evaluator, context, index): result.append(el) result += [None] * (3 - len(result)) - return set([Slice(evaluator, *result)]) + return set([Slice(context, *result)]) # No slices return context.eval_node(index) diff --git a/jedi/evaluate/precedence.py b/jedi/evaluate/precedence.py index b9e2f8c2..6fa4c9f8 100644 --- a/jedi/evaluate/precedence.py +++ b/jedi/evaluate/precedence.py @@ -131,7 +131,7 @@ def _element_calculate(evaluator, left, operator, right): r_is_num = _is_number(right) if operator == '*': # for iterables, ignore * operations - if isinstance(left, iterable.Array) or is_string(left): + if isinstance(left, iterable.AbstractSequence) or is_string(left): return set([left]) elif isinstance(right, iterable.Array) or is_string(right): return set([right]) diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 2fd45a9c..450facad 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -409,6 +409,8 @@ class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)) This class is not only important to extend `tree.Class`, it is also a important for descriptors (if the descriptor methods are evaluated or not). """ + api_type = 'class' + def __init__(self, evaluator, classdef, parent_context): super(ClassContext, self).__init__(evaluator, parent_context=parent_context) self.classdef = classdef @@ -519,6 +521,8 @@ class FunctionContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrappe """ Needed because of decorators. Decorators are evaluated here. """ + api_type = 'function' + def __init__(self, evaluator, parent_context, funcdef): """ This should not be called directly """ super(FunctionContext, self).__init__(evaluator, parent_context)