diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 26eacbe9..943b73aa 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -197,6 +197,11 @@ class Evaluator(object): elif pr.is_node(element, 'testlist_star_expr', 'testlist'): # The implicit tuple in statements. return [iterable.Array(self, element, pr.Array.TUPLE)] + elif pr.is_node(element, 'not_test') or pr.is_node(element, 'factor'): + types = self.eval_element(element.children[-1]) + for operator in element.children[:-1]: + types = list(precedence.factor_calculate(self, types, operator)) + return types else: if element.children[0] == 'not': left = [] diff --git a/jedi/evaluate/precedence.py b/jedi/evaluate/precedence.py index 1bd5e1e1..3622fef6 100644 --- a/jedi/evaluate/precedence.py +++ b/jedi/evaluate/precedence.py @@ -218,12 +218,9 @@ def _literals_to_types(evaluator, result): return list(set(result)) -def process_precedence_element(evaluator, precedence): - if precedence is None: - return None - else: - if isinstance(precedence, Precedence): - left_objs = process_precedence_element(evaluator, precedence.left) +def process_children(evaluator, children): + #first = children[0] + #if isinstance(first, operator = precedence.operator lazy_right = lambda: process_precedence_element(evaluator, precedence.right) # handle lazy evaluation of and/or here. @@ -242,48 +239,41 @@ def process_precedence_element(evaluator, precedence): # Otherwise continue, because of uncertainty. return calculate(evaluator, left_objs, precedence.operator, lazy_right()) - else: - # normal element, no operators - return evaluator.eval_statement_element(precedence) def calculate(evaluator, left_result, operator, right_result): result = [] - if left_result is None and right_result: - # Cases like `-1`, `1 + ~1` or `not X`. - for right in right_result: - obj = _factor_calculate(evaluator, operator, right) - if obj is not None: - result.append(obj) - return result + if not left_result or not right_result: + # illegal slices e.g. cause left/right_result to be None + result = (left_result or []) + (right_result or []) + result = _literals_to_types(evaluator, result) else: - if not left_result or not right_result: - # illegal slices e.g. cause left/right_result to be None - result = (left_result or []) + (right_result or []) - result = _literals_to_types(evaluator, result) + # I don't think there's a reasonable chance that a string + # operation is still correct, once we pass something like six + # objects. + if len(left_result) * len(right_result) > 6: + result = _literals_to_types(evaluator, left_result + right_result) else: - # I don't think there's a reasonable chance that a string - # operation is still correct, once we pass something like six - # objects. - if len(left_result) * len(right_result) > 6: - result = _literals_to_types(evaluator, left_result + right_result) - else: - for left in left_result: - for right in right_result: - result += _element_calculate(evaluator, left, operator, right) + for left in left_result: + for right in right_result: + result += _element_calculate(evaluator, left, operator, right) return result -def _factor_calculate(evaluator, operator, right): - if _is_number(right): - if operator == '-': - return create(evaluator, -right.obj) - if operator == 'not': - value = right.py__bool__() - if value is None: # Uncertainty. - return None - return keyword_from_value(not value) - return right +def factor_calculate(evaluator, types, operator): + """ + Calculates `+`, `-`, `~` and `not` prefixes. + """ + for typ in types: + if _is_number(typ): + if operator == '-': + yield create(evaluator, -typ.obj) + if operator == 'not': + value = typ.py__bool__() + if value is None: # Uncertainty. + return + yield keyword_from_value(not value) + yield typ def _is_number(obj):