diff --git a/mypy/errorcodes.py b/mypy/errorcodes.py index d9e11a044a18..3ae079f08fda 100644 --- a/mypy/errorcodes.py +++ b/mypy/errorcodes.py @@ -135,6 +135,7 @@ def __str__(self) -> str: # Syntax errors are often blocking. SYNTAX: Final = ErrorCode("syntax", "Report syntax errors", "General") +SLICE_SYNTAX: Final = ErrorCode("slice-syntax", "Report slice syntax errors", "General") # This is a catch-all for remaining uncategorized errors. MISC: Final = ErrorCode("misc", "Miscellaneous other checks", "General") diff --git a/mypy/errors.py b/mypy/errors.py index 3a0e0e14d8b3..0917ac816af7 100644 --- a/mypy/errors.py +++ b/mypy/errors.py @@ -374,6 +374,16 @@ def add_error_info(self, info: ErrorInfo) -> None: return if file in self.ignored_files: return + if ( + not self.ignored_lines + and info.code + and self.is_error_code_enabled(info.code) is False + ): + # We also might want to ignore some errors during `fastparse`. + # At that moment `ignored_lines` might not be ready, + # so, we only check for specific error codes. + # For example, `Dict[{str: int}]` can be ignored this way. + return if info.only_once: if info.message in self.only_once_messages: return diff --git a/mypy/fastparse.py b/mypy/fastparse.py index a9c3bed9d5a7..ba5a8ebaa395 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -1359,9 +1359,13 @@ def parent(self) -> Optional[AST]: return None return self.node_stack[-2] - def fail(self, msg: str, line: int, column: int) -> None: + def fail(self, msg: str, line: int, column: int, + blocker: bool = True, + code: Optional[codes.ErrorCode] = None) -> None: + if code is None: + code = codes.SYNTAX if self.errors: - self.errors.report(line, column, msg, blocker=True, code=codes.SYNTAX) + self.errors.report(line, column, msg, blocker=blocker, code=code) def note(self, msg: str, line: int, column: int) -> None: if self.errors: @@ -1562,12 +1566,14 @@ def visit_Subscript(self, n: ast3.Subscript) -> Type: if (isinstance(sliceval, ast3.Slice) or (isinstance(sliceval, ast3.Tuple) and any(isinstance(x, ast3.Slice) for x in sliceval.elts))): - self.fail(INVALID_SLICE_ERROR, self.line, getattr(n, 'col_offset', -1)) + self.fail(INVALID_SLICE_ERROR, self.line, getattr(n, 'col_offset', -1), + blocker=False, code=codes.SLICE_SYNTAX) return AnyType(TypeOfAny.from_error) else: # Python 3.8 or earlier use a different AST structure for subscripts if not isinstance(n.slice, Index): - self.fail(INVALID_SLICE_ERROR, self.line, getattr(n, 'col_offset', -1)) + self.fail(INVALID_SLICE_ERROR, self.line, getattr(n, 'col_offset', -1), + blocker=False, code=codes.SLICE_SYNTAX) return AnyType(TypeOfAny.from_error) sliceval = n.slice.value diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index 207c2d9b99c1..6a09a49081bd 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -897,3 +897,24 @@ lst: List[int] = [] if lst: pass [builtins fixtures/list.pyi] + +[case testSliceAnnotatedErrorDisabled39] +# flags: --python-version 3.9 --disable-error-code slice-syntax +a: Annotated[int, 1:2] +b: Dict[int, x:y] +c: Dict[x:y] + +reveal_type(a) # N: Revealed type is "Any" +reveal_type(b) # N: Revealed type is "Any" +reveal_type(c) # N: Revealed type is "Any" + +[case testSliceAnnotatedErrorDisabled38] +# flags: --python-version 3.8 --disable-error-code slice-syntax + +a: Annotated[int, 1:2] +b: Dict[int, x:y] +c: Dict[x:y] + +reveal_type(a) # N: Revealed type is "Any" +reveal_type(b) # N: Revealed type is "Any" +reveal_type(c) # N: Revealed type is "Any" diff --git a/test-data/unit/check-fastparse.test b/test-data/unit/check-fastparse.test index 03aa1e4c3214..0766b46c6824 100644 --- a/test-data/unit/check-fastparse.test +++ b/test-data/unit/check-fastparse.test @@ -321,6 +321,7 @@ x @= 1 from typing import Dict x = None # type: Dict[x: y] +[builtins fixtures/dict.pyi] [out] main:3: error: Slice usage in type annotation is invalid