Skip to content

Commit

Permalink
Get parser errors working, fixes #1488
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhalter committed Feb 3, 2020
1 parent 3101e43 commit 2c62166
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 0 deletions.
4 changes: 4 additions & 0 deletions jedi/api/__init__.py
Expand Up @@ -30,6 +30,7 @@
from jedi.api.keywords import KeywordName
from jedi.api.environment import InterpreterEnvironment
from jedi.api.project import get_default_project, Project
from jedi.api.errors import parso_to_jedi_errors
from jedi.inference import InferenceState
from jedi.inference import imports
from jedi.inference.references import find_references
Expand Down Expand Up @@ -504,6 +505,9 @@ def get_names(self, **kwargs):
"""
return self._names(**kwargs) # Python 2...

def get_syntax_errors(self):
return parso_to_jedi_errors(self._grammar, self._module_node)

def _names(self, all_scopes=False, definitions=True, references=False):
def def_ref_filter(_def):
is_def = _def._name.tree_name.is_definition()
Expand Down
36 changes: 36 additions & 0 deletions jedi/api/errors.py
@@ -0,0 +1,36 @@
"""
This file is about errors in Python files and not about exception handling in
Jedi.
"""


def parso_to_jedi_errors(grammar, module_node):
return [SyntaxError(e) for e in grammar.iter_errors(module_node)]


class SyntaxError(object):
def __init__(self, parso_error):
self._parso_error = parso_error

@property
def line(self):
return self._parso_error.start_pos[0]

@property
def column(self):
return self._parso_error.start_pos[1]

@property
def until_line(self):
return self._parso_error.end_pos[0]

@property
def until_column(self):
return self._parso_error.end_pos[1]

def __repr__(self):
return '<%s from=%s to=%s>' % (
self.__class__.__name__,
self._parso_error.start_pos,
self._parso_error.end_pos,
)
54 changes: 54 additions & 0 deletions test/test_api/test_syntax_errors.py
@@ -0,0 +1,54 @@
"""
These tests test Jedi's Parso usage. Basically there's not a lot of tests here,
because we're just checking if the API works. Bugfixes should be done in parso,
mostly.
"""

from textwrap import dedent

import pytest


@pytest.mark.parametrize(
'code, line, column, until_line, until_column', [
('?\n', 1, 0, 1, 1),
('x %% y', 1, 3, 1, 4),
('"""\n\n', 1, 0, 3, 0),
('(1, 2\n', 2, 0, 2, 0),
('foo(1, 2\ndef x(): pass', 2, 0, 2, 3),
]
)
def test_simple_syntax_errors(Script, code, line, column, until_line, until_column):
e, = Script(code).get_syntax_errors()
assert e.line == line
assert e.column == column
assert e.until_line == until_line
assert e.until_column == until_column


@pytest.mark.parametrize(
'code', [
'x % y',
'def x(x): pass',
'def x(x):\n pass',
]
)
def test_no_syntax_errors(Script, code):
assert not Script(code).get_syntax_errors()


def test_multi_syntax_error(Script):
code = dedent('''\
def x():
1
def y()
1 + 1
1 *** 3
''')
x, y, power = Script(code).get_syntax_errors()
assert x.line == 2
assert x.column == 0
assert y.line == 3
assert y.column == 7
assert power.line == 5
assert power.column == 4

0 comments on commit 2c62166

Please sign in to comment.