Skip to content
Merged
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
58 changes: 48 additions & 10 deletions mypy/fastparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ def __init__(
def note(self, msg: str, line: int, column: int) -> None:
self.errors.report(line, column, msg, severity="note", code=codes.SYNTAX)

def fail(self, msg: ErrorMessage, line: int, column: int, blocker: bool = True) -> None:
def fail(self, msg: ErrorMessage, line: int, column: int, blocker: bool) -> None:
if blocker or not self.options.ignore_errors:
# Make sure self.errors reflects any type ignores that we have parsed
self.errors.set_file_ignored_lines(
Expand Down Expand Up @@ -921,7 +921,12 @@ def do_func_def(
):
if n.returns:
# PEP 484 disallows both type annotations and type comments
self.fail(message_registry.DUPLICATE_TYPE_SIGNATURES, lineno, n.col_offset)
self.fail(
message_registry.DUPLICATE_TYPE_SIGNATURES,
lineno,
n.col_offset,
blocker=False,
)
arg_types = [
(
a.type_annotation
Expand All @@ -933,7 +938,12 @@ def do_func_def(
else:
# PEP 484 disallows both type annotations and type comments
if n.returns or any(a.type_annotation is not None for a in args):
self.fail(message_registry.DUPLICATE_TYPE_SIGNATURES, lineno, n.col_offset)
self.fail(
message_registry.DUPLICATE_TYPE_SIGNATURES,
lineno,
n.col_offset,
blocker=False,
)
translated_args: list[Type] = TypeConverter(
self.errors, line=lineno, override_column=n.col_offset
).translate_expr_list(func_type_ast.argtypes)
Expand All @@ -948,7 +958,7 @@ def do_func_def(
except SyntaxError:
stripped_type = n.type_comment.split("#", 2)[0].strip()
err_msg = message_registry.TYPE_COMMENT_SYNTAX_ERROR_VALUE.format(stripped_type)
self.fail(err_msg, lineno, n.col_offset)
self.fail(err_msg, lineno, n.col_offset, blocker=False)
if n.type_comment and n.type_comment[0] not in ["(", "#"]:
self.note(
"Suggestion: wrap argument types in parentheses", lineno, n.col_offset
Expand All @@ -970,7 +980,12 @@ def do_func_def(
func_type = None
if any(arg_types) or return_type:
if len(arg_types) != 1 and any(isinstance(t, EllipsisType) for t in arg_types):
self.fail(message_registry.ELLIPSIS_WITH_OTHER_TYPEARGS, lineno, n.col_offset)
self.fail(
message_registry.ELLIPSIS_WITH_OTHER_TYPEARGS,
lineno,
n.col_offset,
blocker=False,
)
elif len(arg_types) > len(arg_kinds):
self.fail(
message_registry.TYPE_SIGNATURE_TOO_MANY_ARGS,
Expand Down Expand Up @@ -1097,7 +1112,12 @@ def make_argument(
annotation = arg.annotation
type_comment = arg.type_comment
if annotation is not None and type_comment is not None:
self.fail(message_registry.DUPLICATE_TYPE_SIGNATURES, arg.lineno, arg.col_offset)
self.fail(
message_registry.DUPLICATE_TYPE_SIGNATURES,
arg.lineno,
arg.col_offset,
blocker=False,
)
arg_type = None
if annotation is not None:
arg_type = TypeConverter(self.errors, line=arg.lineno).visit(annotation)
Expand All @@ -1118,7 +1138,7 @@ def make_argument(
return argument

def fail_arg(self, msg: str, arg: ast3.arg) -> None:
self.fail(ErrorMessage(msg), arg.lineno, arg.col_offset)
self.fail(ErrorMessage(msg), arg.lineno, arg.col_offset, blocker=True)

# ClassDef(identifier name,
# expr* bases,
Expand Down Expand Up @@ -1164,18 +1184,21 @@ def validate_type_param(self, type_param: ast_TypeVar) -> None:
message_registry.TYPE_VAR_YIELD_EXPRESSION_IN_BOUND,
type_param.lineno,
type_param.col_offset,
blocker=True,
)
if isinstance(incorrect_expr, ast3.NamedExpr):
self.fail(
message_registry.TYPE_VAR_NAMED_EXPRESSION_IN_BOUND,
type_param.lineno,
type_param.col_offset,
blocker=True,
)
if isinstance(incorrect_expr, ast3.Await):
self.fail(
message_registry.TYPE_VAR_AWAIT_EXPRESSION_IN_BOUND,
type_param.lineno,
type_param.col_offset,
blocker=True,
)

def translate_type_params(self, type_params: list[Any]) -> list[TypeParam]:
Expand Down Expand Up @@ -1790,11 +1813,26 @@ def validate_type_alias(self, n: ast_TypeAlias) -> None:
if incorrect_expr is None:
return
if isinstance(incorrect_expr, (ast3.Yield, ast3.YieldFrom)):
self.fail(message_registry.TYPE_ALIAS_WITH_YIELD_EXPRESSION, n.lineno, n.col_offset)
self.fail(
message_registry.TYPE_ALIAS_WITH_YIELD_EXPRESSION,
n.lineno,
n.col_offset,
blocker=True,
)
if isinstance(incorrect_expr, ast3.NamedExpr):
self.fail(message_registry.TYPE_ALIAS_WITH_NAMED_EXPRESSION, n.lineno, n.col_offset)
self.fail(
message_registry.TYPE_ALIAS_WITH_NAMED_EXPRESSION,
n.lineno,
n.col_offset,
blocker=True,
)
if isinstance(incorrect_expr, ast3.Await):
self.fail(message_registry.TYPE_ALIAS_WITH_AWAIT_EXPRESSION, n.lineno, n.col_offset)
self.fail(
message_registry.TYPE_ALIAS_WITH_AWAIT_EXPRESSION,
n.lineno,
n.col_offset,
blocker=True,
)

# TypeAlias(identifier name, type_param* type_params, expr value)
def visit_TypeAlias(self, n: ast_TypeAlias) -> TypeAliasStmt | AssignmentStmt:
Expand Down
14 changes: 7 additions & 7 deletions test-data/unit/check-fastparse.test
Original file line number Diff line number Diff line change
Expand Up @@ -241,37 +241,37 @@ assert 1, f() # E: Name "f" is not defined

[case testFastParserConsistentFunctionTypes]

def f(x, y, z):
def f1(x, y, z):
# type: (int, int, int) -> int
pass

def f(x, # type: int # E: Function has duplicate type signatures
def f2(x, # type: int # E: Function has duplicate type signatures
y, # type: int
z # type: int
):
# type: (int, int, int) -> int
pass

def f(x, # type: int
def f3(x, # type: int
y, # type: int
z # type: int
):
# type: (...) -> int
pass

def f(x, y, z):
def f4(x, y, z):
# type: (int, int, int) -> int
pass

def f(x) -> int: # E: Function has duplicate type signatures
def f5(x) -> int: # E: Function has duplicate type signatures
# type: (int) -> int
pass

def f(x: int, y: int, z: int):
def f6(x: int, y: int, z: int):
# type: (...) -> int
pass

def f(x: int): # E: Function has duplicate type signatures
def f7(x: int): # E: Function has duplicate type signatures
# type: (int) -> int
pass

Expand Down