diff --git a/jedi/evaluate/precedence.py b/jedi/evaluate/precedence.py index 22527c30..ee92c21a 100644 --- a/jedi/evaluate/precedence.py +++ b/jedi/evaluate/precedence.py @@ -16,9 +16,10 @@ class PythonGrammar(object): def __new__(cls, first, second): self = str.__new__(cls, first) self.second = second + return self def __str__(self): - return self.__str__() + ' ' + self.second + return str.__str__(self) + ' ' + self.second FACTOR = '+', '-', '~' POWER = '**', @@ -31,7 +32,7 @@ class PythonGrammar(object): EXPR = '|', COMPARISON = ('<', '>', '==', '>=', '<=', '!=', 'in', - MultiPart('not', 'in'), MultiPart('is', 'not')), 'is' + MultiPart('not', 'in'), MultiPart('is', 'not'), 'is') NOT_TEST = 'not', AND_TEST = 'and', @@ -58,7 +59,7 @@ class Precedence(object): def parse_tree(self, strip_literals=False): def process(which): try: - which = which.parse_tree() + which = which.parse_tree(strip_literals) except AttributeError: pass if strip_literals and isinstance(which, pr.Literal): @@ -124,7 +125,10 @@ def _check_operator(iterator, priority=PythonGrammar.LOWEST_PRIORITY): next_tok = next(iterator) if next_tok != match.second: iterator.push_back(next_tok) - continue + if el == 'is': # `is not` special case + match = 'is' + else: + continue operator = match break @@ -132,7 +136,8 @@ def _check_operator(iterator, priority=PythonGrammar.LOWEST_PRIORITY): if operator is None: _syntax_error(el) continue + right = _check_operator(iterator, check_prio) if right is not None: - left = Precedence(left, operator, right) + left = Precedence(left, str(operator), right) return left diff --git a/test/test_evaluate/test_precedence.py b/test/test_evaluate/test_precedence.py index 65c3e1a4..9d7630ee 100644 --- a/test/test_evaluate/test_precedence.py +++ b/test/test_evaluate/test_precedence.py @@ -21,9 +21,25 @@ def test_simple(): assert parse_tree('+2') == (None, '+', 2) +def test_prefixed(): + assert parse_tree('--2') == (None, '-', (None, '-', 2)) + assert parse_tree('1 and not - 2') == (1, 'and', (None, '-', 2)) + + def test_invalid(): """Should just return a simple operation.""" assert parse_tree('1 +') == 1 assert parse_tree('+') is None assert parse_tree('* 1') == 1 + assert parse_tree('1 * * 1') == (1, '*', 1) + + # invalid operator + assert parse_tree('1 not - 1') == (1, '-', 1) + assert parse_tree('1 - not ~1') == (1, '-', (None, '~', 1)) + + +def test_multi_part(): + assert parse_tree('1 not in 2') == (1, 'not in', 2) + assert parse_tree('1 is not -1') == (1, 'is not', (None, '-', 1)) + assert parse_tree('1 is 1') == (1, 'is', 1)