Skip to content

Commit

Permalink
pythongh-123539: Improve SyntaxError msg for import as with not a name
Browse files Browse the repository at this point in the history
  • Loading branch information
sobolevn committed Sep 3, 2024
1 parent 9e079c2 commit b51aa0b
Show file tree
Hide file tree
Showing 4 changed files with 857 additions and 513 deletions.
22 changes: 16 additions & 6 deletions Grammar/python.gram
Original file line number Diff line number Diff line change
Expand Up @@ -218,15 +218,17 @@ import_from_targets[asdl_alias_seq*]:
import_from_as_names[asdl_alias_seq*]:
| a[asdl_alias_seq*]=','.import_from_as_name+ { a }
import_from_as_name[alias_ty]:
| a=NAME b=['as' z=NAME { z }] { _PyAST_alias(a->v.Name.id,
(b) ? ((expr_ty) b)->v.Name.id : NULL,
EXTRA) }
| a=NAME 'as' b=NAME &(',' | ')' | NEWLINE) {
_PyAST_alias(a->v.Name.id, b->v.Name.id, EXTRA) }
| invalid_import_from_as_name
| a=NAME { _PyAST_alias(a->v.Name.id, NULL, EXTRA) }
dotted_as_names[asdl_alias_seq*]:
| a[asdl_alias_seq*]=','.dotted_as_name+ { a }
dotted_as_name[alias_ty]:
| a=dotted_name b=['as' z=NAME { z }] { _PyAST_alias(a->v.Name.id,
(b) ? ((expr_ty) b)->v.Name.id : NULL,
EXTRA) }
| a=dotted_name 'as' b=NAME &(',' | NEWLINE) {
_PyAST_alias(a->v.Name.id, b->v.Name.id, EXTRA) }
| invalid_dotted_as_name
| a=dotted_name { _PyAST_alias(a->v.Name.id, NULL, EXTRA) }
dotted_name[expr_ty]:
| a=dotted_name '.' b=NAME { _PyPegen_join_names_with_dot(p, a, b) }
| NAME
Expand Down Expand Up @@ -1321,6 +1323,14 @@ invalid_import_from_targets:
RAISE_SYNTAX_ERROR("trailing comma not allowed without surrounding parentheses") }
| token=NEWLINE {
RAISE_SYNTAX_ERROR_STARTING_FROM(token, "Expected one or more names after 'import'") }
invalid_dotted_as_name:
| dotted_name 'as' a=expression {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a,
"cannot use %s as import target", _PyPegen_get_expr_name(a)) }
invalid_import_from_as_name:
| NAME 'as' a=expression {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a,
"cannot use %s as import target", _PyPegen_get_expr_name(a)) }

invalid_with_stmt:
| ['async'] 'with' ','.(expression ['as' star_target])+ NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
Expand Down
70 changes: 70 additions & 0 deletions Lib/test/test_syntax.py
Original file line number Diff line number Diff line change
Expand Up @@ -1832,6 +1832,56 @@
Traceback (most recent call last):
SyntaxError: Expected one or more names after 'import'
>>> import a as b.c
Traceback (most recent call last):
SyntaxError: cannot use attribute as import target
>>> import a.b as (a, b)
Traceback (most recent call last):
SyntaxError: cannot use tuple as import target
>>> import a, a.b as 1
Traceback (most recent call last):
SyntaxError: cannot use literal as import target
>>> import a.b as 'a', a
Traceback (most recent call last):
SyntaxError: cannot use literal as import target
>>> from a import (b as c.d)
Traceback (most recent call last):
SyntaxError: cannot use attribute as import target
>>> from a import b as 1
Traceback (most recent call last):
SyntaxError: cannot use literal as import target
>>> from a import (
... b as f())
Traceback (most recent call last):
SyntaxError: cannot use function call as import target
>>> from a import (
... b as [],
... )
Traceback (most recent call last):
SyntaxError: cannot use list as import target
>>> from a import (
... b,
... c as ()
... )
Traceback (most recent call last):
SyntaxError: cannot use tuple as import target
>>> from a import b, с as d[e]
Traceback (most recent call last):
SyntaxError: cannot use subscript as import target
>>> from a import с as d[e], b
Traceback (most recent call last):
SyntaxError: cannot use subscript as import target
>>> (): int
Traceback (most recent call last):
SyntaxError: only single target (not tuple) can be annotated
Expand Down Expand Up @@ -2857,6 +2907,26 @@ def test_match_stmt_invalid_as_expr(self):
end_offset=15 + len("obj.attr"),
)

def test_invalid_import_stmt_as_expr(self):
self._check_error(
"import a as obj.attr",
errtext="cannot use attribute as import target",
lineno=1,
end_lineno=1,
offset=13,
end_offset=13 + len("obj.attr"),
)

def test_invalid_import_from_stmt_as_expr(self):
self._check_error(
"from a import b as obj.attr",
errtext="cannot use attribute as import target",
lineno=1,
end_lineno=1,
offset=20,
end_offset=20 + len("obj.attr"),
)


def load_tests(loader, tests, pattern):
tests.addTest(doctest.DocTestSuite())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improve :exc:`SyntaxError` message for using ``import as`` with not a name.
Loading

0 comments on commit b51aa0b

Please sign in to comment.