diff --git a/jedi/common/context.py b/jedi/common/context.py index 95c4671b..514a6ea3 100644 --- a/jedi/common/context.py +++ b/jedi/common/context.py @@ -42,7 +42,7 @@ class ContextSet(object): return '%s(%s)' % (self.__class__.__name__, ', '.join(str(s) for s in self._set)) def filter(self, filter_func): - return ContextSet(filter(filter_func, self._set)) + return ContextSet.from_iterable(filter(filter_func, self._set)) def __getattr__(self, name): def mapper(*args, **kwargs): diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 35c4256e..02b30eab 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -331,7 +331,8 @@ class Evaluator(object): ) break context_set = self.eval_trailer(context, context_set, trailer) - return context_set + return context_set + return NO_CONTEXTS elif typ in ('testlist_star_expr', 'testlist',): # The implicit tuple in statements. return ContextSet(iterable.SequenceLiteralContext(self, context, element)) diff --git a/jedi/evaluate/context.py b/jedi/evaluate/context.py index df73194f..7ff57d5d 100644 --- a/jedi/evaluate/context.py +++ b/jedi/evaluate/context.py @@ -40,7 +40,7 @@ class Context(object): Execute a function with already executed arguments. """ from jedi.evaluate.param import ValuesArguments - arguments = ValuesArguments([[value] for value in value_list]) + arguments = ValuesArguments([ContextSet(value) for value in value_list]) return self.execute(arguments) def eval_node(self, node): diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index dcc2b939..cbab52c6 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -297,8 +297,10 @@ class ArrayMixin(object): return self.evaluator.BUILTINS def dict_values(self): - return ContextSet.from_sets(self._defining_context.eval_node(v) - for k, v in self._items()) + return ContextSet.from_sets( + self._defining_context.eval_node(v) + for k, v in self._items() + ) class ListComprehension(ArrayMixin, Comprehension): @@ -649,6 +651,8 @@ def py__getitem__(evaluator, context, types, trailer): assert trailer_op == "[" assert trailer_cl == "]" + # TODO It's kind of stupid to cast this from a context set to a set. + types = set(types) # special case: PEP0484 typing module, see # https://github.com/davidhalter/jedi/issues/663 for typ in list(types): @@ -795,7 +799,7 @@ def get_dynamic_array_instance(instance): ai = _ArrayInstance(instance) from jedi.evaluate import param - return param.ValuesArguments([[ai]]) + return param.ValuesArguments([ContextSet(ai)]) class _ArrayInstance(object): diff --git a/jedi/evaluate/precedence.py b/jedi/evaluate/precedence.py index 72b7a432..abc73589 100644 --- a/jedi/evaluate/precedence.py +++ b/jedi/evaluate/precedence.py @@ -25,7 +25,7 @@ COMPARISON_OPERATORS = { def literals_to_types(evaluator, result): # Changes literals ('a', 1, 1.0, etc) to its type instances (str(), # int(), float(), etc). - new_result = set() + new_result = NO_CONTEXTS for typ in result: if is_literal(typ): # Literals are only valid as long as the operations are @@ -33,8 +33,8 @@ def literals_to_types(evaluator, result): cls = builtin_from_name(evaluator, typ.name.string_name) new_result |= cls.execute_evaluated() else: - new_result.add(typ) - return ContextSet.from_set(new_result) + new_result |= ContextSet(typ) + return new_result def calculate_children(evaluator, context, children): @@ -68,7 +68,7 @@ def calculate_children(evaluator, context, children): def calculate(evaluator, context, left_result, operator, right_result): if not left_result or not right_result: # illegal slices e.g. cause left/right_result to be None - result = (left_result or set()) | (right_result or set()) + result = (left_result or NO_CONTEXTS) | (right_result or NO_CONTEXTS) return literals_to_types(evaluator, result) else: # I don't think there's a reasonable chance that a string diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 8ccfc7b2..c427b786 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -335,7 +335,10 @@ class FunctionExecutionContext(context.TreeContext): debug.dbg('Return unreachable: %s', r) else: if check_yields: - context_set |= ContextSet(self._eval_yield(r)) + context_set |= ContextSet.from_sets( + lazy_context.infer() + for lazy_context in self._eval_yield(r) + ) else: try: children = r.children @@ -388,7 +391,7 @@ class FunctionExecutionContext(context.TreeContext): else: types = self.get_return_values(check_yields=True) if types: - yield context.get_merged_lazy_context(list(types)) + yield context.LazyKnownContexts(types) return last_for_stmt = for_stmt @@ -432,11 +435,7 @@ class ModuleAttributeName(AbstractNameDefinition): self.string_name = string_name def infer(self): - return ContextSet( - compiled.create(self.parent_context.evaluator, str).execute( - param.ValuesArguments([]) - ) - ) + return compiled.create(self.parent_context.evaluator, str).execute_evaluated() class ModuleName(ContextNameMixin, AbstractNameDefinition): diff --git a/jedi/evaluate/stdlib.py b/jedi/evaluate/stdlib.py index 053f2b9c..169e709e 100644 --- a/jedi/evaluate/stdlib.py +++ b/jedi/evaluate/stdlib.py @@ -186,7 +186,7 @@ def builtins_super(evaluator, types, objects, context): if isinstance(context, (InstanceFunctionExecution, AnonymousInstanceFunctionExecution)): su = context.instance.py__class__().py__bases__() - return unite(context.execute_evaluated() for context in su[0].infer()) + return su[0].infer().execute_evaluated() return NO_CONTEXTS @@ -208,7 +208,7 @@ def builtins_reversed(evaluator, sequences, obj, arguments): # would fail in certain cases like `reversed(x).__iter__` if we # just returned the result directly. seq = iterable.FakeSequence(evaluator, 'list', rev) - arguments = param.ValuesArguments([[seq]]) + arguments = param.ValuesArguments([ContextSet(seq)]) return ContextSet(CompiledInstance(evaluator, evaluator.BUILTINS, obj, arguments))