From 15f42d93d74e33d0ae90d91386717106a5244fe7 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Tue, 22 Jul 2014 14:52:58 +0200 Subject: [PATCH] it should be possible to find the origin of an operation, if it's a faulty one (static analysis) --- jedi/evaluate/finder.py | 2 +- jedi/evaluate/precedence.py | 31 ++++++++++++++++++++++-------- test/static_analysis/operations.py | 2 +- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index a2b6867e..d38a44ac 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -157,7 +157,7 @@ class NameFinder(object): else: p = precedence.create_precedence(expression_list) if (isinstance(p, precedence.Precedence) - and p.operator == 'is not' + and p.operator.string == 'is not' and p.right.get_code() == 'None' and p.left.get_code() == unicode(self.name_str)): return True diff --git a/jedi/evaluate/precedence.py b/jedi/evaluate/precedence.py index c081506e..76f13100 100644 --- a/jedi/evaluate/precedence.py +++ b/jedi/evaluate/precedence.py @@ -71,7 +71,7 @@ class Precedence(object): which = which.value return which - return (process(self.left), self.operator, process(self.right)) + return (process(self.left), self.operator.string, process(self.right)) def __repr__(self): return '(%s %s %s)' % (self.left, self.operator, self.right) @@ -114,6 +114,21 @@ def _get_number(iterator, priority=PythonGrammar.LOWEST_PRIORITY): return el +class MergedOperator(pr.Operator): + """ + A way to merge the two operators `is not` and `not int`, which are two + words instead of one. + Maybe there's a better way (directly in the tokenizer/parser? but for now + this is fine.) + """ + def __init__(self, first, second): + string = first.string + ' ' + second.string + super(MergedOperator, self).__init__(string, first.start_pos) + + self.first = first + self.second = second + + def _check_operator(iterator, priority=PythonGrammar.LOWEST_PRIORITY): try: left = _get_number(iterator, priority) @@ -140,14 +155,14 @@ def _check_operator(iterator, priority=PythonGrammar.LOWEST_PRIORITY): match = check[match_index] if isinstance(match, PythonGrammar.MultiPart): next_tok = next(iterator) - if next_tok != match.second: + if next_tok == match.second: + el = MergedOperator(el, next_tok) + else: iterator.push_back(next_tok) - if el == 'is': # `is not` special case - match = 'is' - else: + if el == 'not': continue - operator = match + operator = el break if operator is None: @@ -171,9 +186,9 @@ def _check_operator(iterator, priority=PythonGrammar.LOWEST_PRIORITY): _syntax_error(iterator.current, 'SyntaxError operand missing') else: if operator in PythonGrammar.TERNARY: - left = TernaryPrecedence(left, str(operator), right, middle) + left = TernaryPrecedence(left, operator, right, middle) else: - left = Precedence(left, str(operator), right) + left = Precedence(left, operator, right) return left diff --git a/test/static_analysis/operations.py b/test/static_analysis/operations.py index afa47f9a..ec146361 100644 --- a/test/static_analysis/operations.py +++ b/test/static_analysis/operations.py @@ -1,4 +1,4 @@ -1 + 1 +-1 + 1 1 + 1.0 #! 6 type-error-operation 1 + '1'