Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion mypy/nativeparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1579,7 +1579,14 @@ def read_expression(state: State, data: ReadBuffer) -> Expression:
elif tag == nodes.ASSIGNMENT_EXPR:
target = read_expression(state, data)
value = read_expression(state, data)
assert isinstance(target, NameExpr), f"Expected NameExpr for target, got {type(target)}"
if not isinstance(target, NameExpr):
# The only valid target of ":=" is a plain name, but ruff's error
# recovery can produce other targets for invalid code such as
# "(f() := 1)". Ruff already reports a syntax error in this case, so
# here we just recover with a placeholder name instead of crashing.
placeholder = NameExpr("")
placeholder.set_line(target)
target = placeholder
expr = AssignmentExpr(target, value)
read_loc(data, expr)
expect_end_tag(data)
Expand Down
10 changes: 10 additions & 0 deletions test-data/unit/native-parser.test
Original file line number Diff line number Diff line change
Expand Up @@ -2572,6 +2572,16 @@ MypyFile:1(
Block:3(
PassStmt:3())))

[case testSyntaxError10]
(f() := 1)
[out]
1:2: error: Assignment expression target must be an identifier
MypyFile:1(
ExpressionStmt:1(
AssignmentExpr:1(
NameExpr()
IntExpr(1))))

[case testArgConstructorTooManyArgs]
from typing import Callable
from mypy_extensions import Arg
Expand Down
Loading