Tipragot
628be439b8
Cela permet de ne pas avoir de problèmes de compatibilité car python est dans le git.
264 lines
9.6 KiB
Python
264 lines
9.6 KiB
Python
"""Classification of possible errors mypy can detect.
|
|
|
|
These can be used for filtering specific errors.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections import defaultdict
|
|
from typing import Final
|
|
|
|
from mypy_extensions import mypyc_attr
|
|
|
|
error_codes: dict[str, ErrorCode] = {}
|
|
sub_code_map: dict[str, set[str]] = defaultdict(set)
|
|
|
|
|
|
@mypyc_attr(allow_interpreted_subclasses=True)
|
|
class ErrorCode:
|
|
def __init__(
|
|
self,
|
|
code: str,
|
|
description: str,
|
|
category: str,
|
|
default_enabled: bool = True,
|
|
sub_code_of: ErrorCode | None = None,
|
|
) -> None:
|
|
self.code = code
|
|
self.description = description
|
|
self.category = category
|
|
self.default_enabled = default_enabled
|
|
self.sub_code_of = sub_code_of
|
|
if sub_code_of is not None:
|
|
assert sub_code_of.sub_code_of is None, "Nested subcategories are not supported"
|
|
sub_code_map[sub_code_of.code].add(code)
|
|
error_codes[code] = self
|
|
|
|
def __str__(self) -> str:
|
|
return f"<ErrorCode {self.code}>"
|
|
|
|
def __eq__(self, other: object) -> bool:
|
|
if not isinstance(other, ErrorCode):
|
|
return False
|
|
return self.code == other.code
|
|
|
|
def __hash__(self) -> int:
|
|
return hash((self.code,))
|
|
|
|
|
|
ATTR_DEFINED: Final = ErrorCode("attr-defined", "Check that attribute exists", "General")
|
|
NAME_DEFINED: Final = ErrorCode("name-defined", "Check that name is defined", "General")
|
|
CALL_ARG: Final[ErrorCode] = ErrorCode(
|
|
"call-arg", "Check number, names and kinds of arguments in calls", "General"
|
|
)
|
|
ARG_TYPE: Final = ErrorCode("arg-type", "Check argument types in calls", "General")
|
|
CALL_OVERLOAD: Final = ErrorCode(
|
|
"call-overload", "Check that an overload variant matches arguments", "General"
|
|
)
|
|
VALID_TYPE: Final[ErrorCode] = ErrorCode(
|
|
"valid-type", "Check that type (annotation) is valid", "General"
|
|
)
|
|
VAR_ANNOTATED: Final = ErrorCode(
|
|
"var-annotated", "Require variable annotation if type can't be inferred", "General"
|
|
)
|
|
OVERRIDE: Final = ErrorCode(
|
|
"override", "Check that method override is compatible with base class", "General"
|
|
)
|
|
RETURN: Final[ErrorCode] = ErrorCode(
|
|
"return", "Check that function always returns a value", "General"
|
|
)
|
|
RETURN_VALUE: Final[ErrorCode] = ErrorCode(
|
|
"return-value", "Check that return value is compatible with signature", "General"
|
|
)
|
|
ASSIGNMENT: Final[ErrorCode] = ErrorCode(
|
|
"assignment", "Check that assigned value is compatible with target", "General"
|
|
)
|
|
METHOD_ASSIGN: Final[ErrorCode] = ErrorCode(
|
|
"method-assign",
|
|
"Check that assignment target is not a method",
|
|
"General",
|
|
sub_code_of=ASSIGNMENT,
|
|
)
|
|
TYPE_ARG: Final = ErrorCode("type-arg", "Check that generic type arguments are present", "General")
|
|
TYPE_VAR: Final = ErrorCode("type-var", "Check that type variable values are valid", "General")
|
|
UNION_ATTR: Final = ErrorCode(
|
|
"union-attr", "Check that attribute exists in each item of a union", "General"
|
|
)
|
|
INDEX: Final = ErrorCode("index", "Check indexing operations", "General")
|
|
OPERATOR: Final = ErrorCode("operator", "Check that operator is valid for operands", "General")
|
|
LIST_ITEM: Final = ErrorCode(
|
|
"list-item", "Check list items in a list expression [item, ...]", "General"
|
|
)
|
|
DICT_ITEM: Final = ErrorCode(
|
|
"dict-item", "Check dict items in a dict expression {key: value, ...}", "General"
|
|
)
|
|
TYPEDDICT_ITEM: Final = ErrorCode(
|
|
"typeddict-item", "Check items when constructing TypedDict", "General"
|
|
)
|
|
TYPEDDICT_UNKNOWN_KEY: Final = ErrorCode(
|
|
"typeddict-unknown-key",
|
|
"Check unknown keys when constructing TypedDict",
|
|
"General",
|
|
sub_code_of=TYPEDDICT_ITEM,
|
|
)
|
|
HAS_TYPE: Final = ErrorCode(
|
|
"has-type", "Check that type of reference can be determined", "General"
|
|
)
|
|
IMPORT: Final = ErrorCode(
|
|
"import", "Require that imported module can be found or has stubs", "General"
|
|
)
|
|
IMPORT_NOT_FOUND: Final = ErrorCode(
|
|
"import-not-found", "Require that imported module can be found", "General", sub_code_of=IMPORT
|
|
)
|
|
IMPORT_UNTYPED: Final = ErrorCode(
|
|
"import-untyped", "Require that imported module has stubs", "General", sub_code_of=IMPORT
|
|
)
|
|
NO_REDEF: Final = ErrorCode("no-redef", "Check that each name is defined once", "General")
|
|
FUNC_RETURNS_VALUE: Final = ErrorCode(
|
|
"func-returns-value", "Check that called function returns a value in value context", "General"
|
|
)
|
|
ABSTRACT: Final = ErrorCode(
|
|
"abstract", "Prevent instantiation of classes with abstract attributes", "General"
|
|
)
|
|
TYPE_ABSTRACT: Final = ErrorCode(
|
|
"type-abstract", "Require only concrete classes where Type[...] is expected", "General"
|
|
)
|
|
VALID_NEWTYPE: Final = ErrorCode(
|
|
"valid-newtype", "Check that argument 2 to NewType is valid", "General"
|
|
)
|
|
STRING_FORMATTING: Final = ErrorCode(
|
|
"str-format", "Check that string formatting/interpolation is type-safe", "General"
|
|
)
|
|
STR_BYTES_PY3: Final = ErrorCode(
|
|
"str-bytes-safe", "Warn about implicit coercions related to bytes and string types", "General"
|
|
)
|
|
EXIT_RETURN: Final = ErrorCode(
|
|
"exit-return", "Warn about too general return type for '__exit__'", "General"
|
|
)
|
|
LITERAL_REQ: Final = ErrorCode("literal-required", "Check that value is a literal", "General")
|
|
UNUSED_COROUTINE: Final = ErrorCode(
|
|
"unused-coroutine", "Ensure that all coroutines are used", "General"
|
|
)
|
|
# TODO: why do we need the explicit type here? Without it mypyc CI builds fail with
|
|
# mypy/message_registry.py:37: error: Cannot determine type of "EMPTY_BODY" [has-type]
|
|
EMPTY_BODY: Final[ErrorCode] = ErrorCode(
|
|
"empty-body",
|
|
"A dedicated error code to opt out return errors for empty/trivial bodies",
|
|
"General",
|
|
)
|
|
SAFE_SUPER: Final = ErrorCode(
|
|
"safe-super", "Warn about calls to abstract methods with empty/trivial bodies", "General"
|
|
)
|
|
TOP_LEVEL_AWAIT: Final = ErrorCode(
|
|
"top-level-await", "Warn about top level await expressions", "General"
|
|
)
|
|
AWAIT_NOT_ASYNC: Final = ErrorCode(
|
|
"await-not-async", 'Warn about "await" outside coroutine ("async def")', "General"
|
|
)
|
|
# These error codes aren't enabled by default.
|
|
NO_UNTYPED_DEF: Final[ErrorCode] = ErrorCode(
|
|
"no-untyped-def", "Check that every function has an annotation", "General"
|
|
)
|
|
NO_UNTYPED_CALL: Final = ErrorCode(
|
|
"no-untyped-call",
|
|
"Disallow calling functions without type annotations from annotated functions",
|
|
"General",
|
|
)
|
|
REDUNDANT_CAST: Final = ErrorCode(
|
|
"redundant-cast", "Check that cast changes type of expression", "General"
|
|
)
|
|
ASSERT_TYPE: Final = ErrorCode("assert-type", "Check that assert_type() call succeeds", "General")
|
|
COMPARISON_OVERLAP: Final = ErrorCode(
|
|
"comparison-overlap", "Check that types in comparisons and 'in' expressions overlap", "General"
|
|
)
|
|
NO_ANY_UNIMPORTED: Final = ErrorCode(
|
|
"no-any-unimported", 'Reject "Any" types from unfollowed imports', "General"
|
|
)
|
|
NO_ANY_RETURN: Final = ErrorCode(
|
|
"no-any-return",
|
|
'Reject returning value with "Any" type if return type is not "Any"',
|
|
"General",
|
|
)
|
|
UNREACHABLE: Final = ErrorCode(
|
|
"unreachable", "Warn about unreachable statements or expressions", "General"
|
|
)
|
|
ANNOTATION_UNCHECKED = ErrorCode(
|
|
"annotation-unchecked", "Notify about type annotations in unchecked functions", "General"
|
|
)
|
|
POSSIBLY_UNDEFINED: Final[ErrorCode] = ErrorCode(
|
|
"possibly-undefined",
|
|
"Warn about variables that are defined only in some execution paths",
|
|
"General",
|
|
default_enabled=False,
|
|
)
|
|
REDUNDANT_EXPR: Final = ErrorCode(
|
|
"redundant-expr", "Warn about redundant expressions", "General", default_enabled=False
|
|
)
|
|
TRUTHY_BOOL: Final[ErrorCode] = ErrorCode(
|
|
"truthy-bool",
|
|
"Warn about expressions that could always evaluate to true in boolean contexts",
|
|
"General",
|
|
default_enabled=False,
|
|
)
|
|
TRUTHY_FUNCTION: Final[ErrorCode] = ErrorCode(
|
|
"truthy-function",
|
|
"Warn about function that always evaluate to true in boolean contexts",
|
|
"General",
|
|
)
|
|
TRUTHY_ITERABLE: Final[ErrorCode] = ErrorCode(
|
|
"truthy-iterable",
|
|
"Warn about Iterable expressions that could always evaluate to true in boolean contexts",
|
|
"General",
|
|
default_enabled=False,
|
|
)
|
|
NAME_MATCH: Final = ErrorCode(
|
|
"name-match", "Check that type definition has consistent naming", "General"
|
|
)
|
|
NO_OVERLOAD_IMPL: Final = ErrorCode(
|
|
"no-overload-impl",
|
|
"Check that overloaded functions outside stub files have an implementation",
|
|
"General",
|
|
)
|
|
IGNORE_WITHOUT_CODE: Final = ErrorCode(
|
|
"ignore-without-code",
|
|
"Warn about '# type: ignore' comments which do not have error codes",
|
|
"General",
|
|
default_enabled=False,
|
|
)
|
|
UNUSED_AWAITABLE: Final = ErrorCode(
|
|
"unused-awaitable",
|
|
"Ensure that all awaitable values are used",
|
|
"General",
|
|
default_enabled=False,
|
|
)
|
|
REDUNDANT_SELF_TYPE = ErrorCode(
|
|
"redundant-self",
|
|
"Warn about redundant Self type annotations on method first argument",
|
|
"General",
|
|
default_enabled=False,
|
|
)
|
|
USED_BEFORE_DEF: Final[ErrorCode] = ErrorCode(
|
|
"used-before-def", "Warn about variables that are used before they are defined", "General"
|
|
)
|
|
UNUSED_IGNORE: Final = ErrorCode(
|
|
"unused-ignore", "Ensure that all type ignores are used", "General", default_enabled=False
|
|
)
|
|
EXPLICIT_OVERRIDE_REQUIRED: Final = ErrorCode(
|
|
"explicit-override",
|
|
"Require @override decorator if method is overriding a base class method",
|
|
"General",
|
|
default_enabled=False,
|
|
)
|
|
|
|
|
|
# Syntax errors are often blocking.
|
|
SYNTAX: Final[ErrorCode] = ErrorCode("syntax", "Report syntax errors", "General")
|
|
|
|
# This is an internal marker code for a whole-file ignore. It is not intended to
|
|
# be user-visible.
|
|
FILE: Final = ErrorCode("file", "Internal marker for a whole file being ignored", "General")
|
|
del error_codes[FILE.code]
|
|
|
|
# This is a catch-all for remaining uncategorized errors.
|
|
MISC: Final = ErrorCode("misc", "Miscellaneous other checks", "General")
|