Skip to content

Commit eb5e086

Browse files
authored
Improves error message for parsing slice in annotations (#11241)
Closes #10266
1 parent 1b6f63b commit eb5e086

File tree

3 files changed

+87
-3
lines changed

3 files changed

+87
-3
lines changed

mypy/fastparse.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ def ast3_parse(source: Union[str, bytes], filename: str, mode: str,
130130

131131
INVALID_TYPE_IGNORE: Final = 'Invalid "type: ignore" comment'
132132

133+
INVALID_SLICE_ERROR: Final = 'Slice usage in type annotation is invalid'
134+
133135
TYPE_IGNORE_PATTERN = re.compile(r'[^#]*#\s*type:\s*ignore\s*(.*)')
134136

135137

@@ -1560,12 +1562,12 @@ def visit_Subscript(self, n: ast3.Subscript) -> Type:
15601562
if (isinstance(sliceval, ast3.Slice) or
15611563
(isinstance(sliceval, ast3.Tuple) and
15621564
any(isinstance(x, ast3.Slice) for x in sliceval.elts))):
1563-
self.fail(TYPE_COMMENT_SYNTAX_ERROR, self.line, getattr(n, 'col_offset', -1))
1565+
self.fail(INVALID_SLICE_ERROR, self.line, getattr(n, 'col_offset', -1))
15641566
return AnyType(TypeOfAny.from_error)
15651567
else:
15661568
# Python 3.8 or earlier use a different AST structure for subscripts
15671569
if not isinstance(n.slice, Index):
1568-
self.fail(TYPE_COMMENT_SYNTAX_ERROR, self.line, getattr(n, 'col_offset', -1))
1570+
self.fail(INVALID_SLICE_ERROR, self.line, getattr(n, 'col_offset', -1))
15691571
return AnyType(TypeOfAny.from_error)
15701572
sliceval = n.slice.value
15711573

test-data/unit/check-fastparse.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ x @= 1
322322
from typing import Dict
323323
x = None # type: Dict[x: y]
324324
[out]
325-
main:3: error: syntax error in type comment
325+
main:3: error: Slice usage in type annotation is invalid
326326

327327
[case testPrintStatementTrailingCommaFastParser_python2]
328328

test-data/unit/parse.test

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,88 @@ main:1: error: invalid syntax
949949
[out version>=3.10]
950950
main:1: error: invalid syntax. Perhaps you forgot a comma?
951951

952+
[case testSliceInAnnotation39]
953+
# flags: --python-version 3.9
954+
a: Annotated[int, 1:2] # E: Slice usage in type annotation is invalid
955+
b: Dict[int, x:y] # E: Slice usage in type annotation is invalid
956+
c: Dict[x:y] # E: Slice usage in type annotation is invalid
957+
[out]
958+
959+
[case testSliceInAnnotation38]
960+
# flags: --python-version 3.8
961+
a: Annotated[int, 1:2] # E: Slice usage in type annotation is invalid
962+
b: Dict[int, x:y] # E: Slice usage in type annotation is invalid
963+
c: Dict[x:y] # E: Slice usage in type annotation is invalid
964+
[out]
965+
966+
[case testSliceInAnnotationTypeComment39]
967+
# flags: --python-version 3.9
968+
a = None # type: Annotated[int, 1:2] # E: Slice usage in type annotation is invalid
969+
b = None # type: Dict[int, x:y] # E: Slice usage in type annotation is invalid
970+
c = None # type: Dict[x:y] # E: Slice usage in type annotation is invalid
971+
[out]
972+
973+
[case testCorrectSlicesInAnnotations39]
974+
# flags: --python-version 3.9
975+
a: Annotated[int, slice(1, 2)]
976+
b: Dict[int, {x:y}]
977+
c: Dict[{x:y}]
978+
[out]
979+
MypyFile:1(
980+
AssignmentStmt:2(
981+
NameExpr(a)
982+
TempNode:2(
983+
Any)
984+
Annotated?[int?, None])
985+
AssignmentStmt:3(
986+
NameExpr(b)
987+
TempNode:3(
988+
Any)
989+
Dict?[int?, None])
990+
AssignmentStmt:4(
991+
NameExpr(c)
992+
TempNode:4(
993+
Any)
994+
Dict?[None]))
995+
996+
[case testCorrectSlicesInAnnotations38]
997+
# flags: --python-version 3.8
998+
a: Annotated[int, slice(1, 2)]
999+
b: Dict[int, {x:y}]
1000+
c: Dict[{x:y}]
1001+
[out]
1002+
MypyFile:1(
1003+
AssignmentStmt:2(
1004+
NameExpr(a)
1005+
TempNode:2(
1006+
Any)
1007+
Annotated?[int?, None])
1008+
AssignmentStmt:3(
1009+
NameExpr(b)
1010+
TempNode:3(
1011+
Any)
1012+
Dict?[int?, None])
1013+
AssignmentStmt:4(
1014+
NameExpr(c)
1015+
TempNode:4(
1016+
Any)
1017+
Dict?[None]))
1018+
1019+
[case testSliceInList39]
1020+
# flags: --python-version 3.9
1021+
x = [1, 2][1:2]
1022+
[out]
1023+
MypyFile:1(
1024+
AssignmentStmt:2(
1025+
NameExpr(x)
1026+
IndexExpr:2(
1027+
ListExpr:2(
1028+
IntExpr(1)
1029+
IntExpr(2))
1030+
SliceExpr:2(
1031+
IntExpr(1)
1032+
IntExpr(2)))))
1033+
9521034
[case testDictionaryExpression]
9531035
{}
9541036
{1:x}

0 commit comments

Comments
 (0)