diff --git a/docs/source/error_code_list2.rst b/docs/source/error_code_list2.rst deleted file mode 100644 index bd2436061974..000000000000 --- a/docs/source/error_code_list2.rst +++ /dev/null @@ -1,701 +0,0 @@ -.. _error-codes-optional: - -Error codes for optional checks -=============================== - -This section documents various errors codes that mypy generates only -if you enable certain options. See :ref:`error-codes` for general -documentation about error codes and their configuration. -:ref:`error-code-list` documents error codes that are enabled by default. - -.. note:: - - The examples in this section use :ref:`inline configuration - ` to specify mypy options. You can also set the same - options by using a :ref:`configuration file ` or - :ref:`command-line options `. - -.. _code-type-arg: - -Check that type arguments exist [type-arg] ------------------------------------------- - -If you use :option:`--disallow-any-generics `, mypy requires that each generic -type has values for each type argument. For example, the types ``list`` or -``dict`` would be rejected. You should instead use types like ``list[int]`` or -``dict[str, int]``. Any omitted generic type arguments get implicit ``Any`` -values. The type ``list`` is equivalent to ``list[Any]``, and so on. - -Example: - -.. code-block:: python - - # mypy: disallow-any-generics - - # Error: Missing type parameters for generic type "list" [type-arg] - def remove_dups(items: list) -> list: - ... - -.. _code-no-untyped-def: - -Check that every function has an annotation [no-untyped-def] ------------------------------------------------------------- - -If you use :option:`--disallow-untyped-defs `, mypy requires that all functions -have annotations (either a Python 3 annotation or a type comment). - -Example: - -.. code-block:: python - - # mypy: disallow-untyped-defs - - def inc(x): # Error: Function is missing a type annotation [no-untyped-def] - return x + 1 - - def inc_ok(x: int) -> int: # OK - return x + 1 - - class Counter: - # Error: Function is missing a type annotation [no-untyped-def] - def __init__(self): - self.value = 0 - - class CounterOk: - # OK: An explicit "-> None" is needed if "__init__" takes no arguments - def __init__(self) -> None: - self.value = 0 - -.. _code-redundant-cast: - -Check that cast is not redundant [redundant-cast] -------------------------------------------------- - -If you use :option:`--warn-redundant-casts `, mypy will generate an error if the source -type of a cast is the same as the target type. - -Example: - -.. code-block:: python - - # mypy: warn-redundant-casts - - from typing import cast - - Count = int - - def example(x: Count) -> int: - # Error: Redundant cast to "int" [redundant-cast] - return cast(int, x) - -.. _code-redundant-self: - -Check that methods do not have redundant Self annotations [redundant-self] --------------------------------------------------------------------------- - -If a method uses the ``Self`` type in the return type or the type of a -non-self argument, there is no need to annotate the ``self`` argument -explicitly. Such annotations are allowed by :pep:`673` but are -redundant. If you enable this error code, mypy will generate an error if -there is a redundant ``Self`` type. - -Example: - -.. code-block:: python - - # mypy: enable-error-code="redundant-self" - - from typing import Self - - class C: - # Error: Redundant "Self" annotation for the first method argument - def copy(self: Self) -> Self: - return type(self)() - -.. _code-comparison-overlap: - -Check that comparisons are overlapping [comparison-overlap] ------------------------------------------------------------ - -If you use :option:`--strict-equality `, mypy will generate an error if it -thinks that a comparison operation is always true or false. These are -often bugs. Sometimes mypy is too picky and the comparison can -actually be useful. Instead of disabling strict equality checking -everywhere, you can use ``# type: ignore[comparison-overlap]`` to -ignore the issue on a particular line only. - -Example: - -.. code-block:: python - - # mypy: strict-equality - - def is_magic(x: bytes) -> bool: - # Error: Non-overlapping equality check (left operand type: "bytes", - # right operand type: "str") [comparison-overlap] - return x == 'magic' - -We can fix the error by changing the string literal to a bytes -literal: - -.. code-block:: python - - # mypy: strict-equality - - def is_magic(x: bytes) -> bool: - return x == b'magic' # OK - -:option:`--strict-equality ` does not include comparisons with -``None``: - -.. code-block:: python - - # mypy: strict-equality - - def is_none(x: str) -> bool: - return x is None # OK - -If you want such checks, you must also activate -:option:`--strict-equality-for-none ` (we might merge -these two options later). - -.. code-block:: python - - # mypy: strict-equality strict-equality-for-none - - def is_none(x: str) -> bool: - # Error: Non-overlapping identity check - # (left operand type: "str", right operand type: "None") - return x is None - -.. _code-no-untyped-call: - -Check that no untyped functions are called [no-untyped-call] ------------------------------------------------------------- - -If you use :option:`--disallow-untyped-calls `, mypy generates an error when you -call an unannotated function in an annotated function. - -Example: - -.. code-block:: python - - # mypy: disallow-untyped-calls - - def do_it() -> None: - # Error: Call to untyped function "bad" in typed context [no-untyped-call] - bad() - - def bad(): - ... - -.. _code-no-any-return: - -Check that function does not return Any value [no-any-return] -------------------------------------------------------------- - -If you use :option:`--warn-return-any `, mypy generates an error if you return a -value with an ``Any`` type in a function that is annotated to return a -non-``Any`` value. - -Example: - -.. code-block:: python - - # mypy: warn-return-any - - def fields(s): - return s.split(',') - - def first_field(x: str) -> str: - # Error: Returning Any from function declared to return "str" [no-any-return] - return fields(x)[0] - -.. _code-no-any-unimported: - -Check that types have no Any components due to missing imports [no-any-unimported] ----------------------------------------------------------------------------------- - -If you use :option:`--disallow-any-unimported `, mypy generates an error if a component of -a type becomes ``Any`` because mypy couldn't resolve an import. These "stealth" -``Any`` types can be surprising and accidentally cause imprecise type checking. - -In this example, we assume that mypy can't find the module ``animals``, which means -that ``Cat`` falls back to ``Any`` in a type annotation: - -.. code-block:: python - - # mypy: disallow-any-unimported - - from animals import Cat # type: ignore - - # Error: Argument 1 to "feed" becomes "Any" due to an unfollowed import [no-any-unimported] - def feed(cat: Cat) -> None: - ... - -.. _code-unreachable: - -Check that statement or expression is unreachable [unreachable] ---------------------------------------------------------------- - -If you use :option:`--warn-unreachable `, mypy generates an error if it -thinks that a statement or expression will never be executed. In most cases, this is due to -incorrect control flow or conditional checks that are accidentally always true or false. - -.. code-block:: python - - # mypy: warn-unreachable - - def example(x: int) -> None: - # Error: Right operand of "or" is never evaluated [unreachable] - assert isinstance(x, int) or x == 'unused' - - return - # Error: Statement is unreachable [unreachable] - print('unreachable') - -.. _code-deprecated: - -Check that imported or used feature is deprecated [deprecated] --------------------------------------------------------------- - -If you use :option:`--enable-error-code deprecated `, -mypy generates an error if your code imports a deprecated feature explicitly with a -``from mod import depr`` statement or uses a deprecated feature imported otherwise or defined -locally. Features are considered deprecated when decorated with ``warnings.deprecated``, as -specified in `PEP 702 `_. -Use the :option:`--report-deprecated-as-note ` option to -turn all such errors into notes. -Use :option:`--deprecated-calls-exclude ` to hide warnings -for specific functions, classes and packages. - -.. note:: - - The ``warnings`` module provides the ``@deprecated`` decorator since Python 3.13. - To use it with older Python versions, import it from ``typing_extensions`` instead. - -Examples: - -.. code-block:: python - - # mypy: report-deprecated-as-error - - # Error: abc.abstractproperty is deprecated: Deprecated, use 'property' with 'abstractmethod' instead - from abc import abstractproperty - - from typing_extensions import deprecated - - @deprecated("use new_function") - def old_function() -> None: - print("I am old") - - # Error: __main__.old_function is deprecated: use new_function - old_function() - old_function() # type: ignore[deprecated] - - -.. _code-redundant-expr: - -Check that expression is redundant [redundant-expr] ---------------------------------------------------- - -If you use :option:`--enable-error-code redundant-expr `, -mypy generates an error if it thinks that an expression is redundant. - -.. code-block:: python - - # mypy: enable-error-code="redundant-expr" - - def example(x: int) -> None: - # Error: Left operand of "and" is always true [redundant-expr] - if isinstance(x, int) and x > 0: - pass - - # Error: If condition is always true [redundant-expr] - 1 if isinstance(x, int) else 0 - - # Error: If condition in comprehension is always true [redundant-expr] - [i for i in range(x) if isinstance(i, int)] - - -.. _code-possibly-undefined: - -Warn about variables that are defined only in some execution paths [possibly-undefined] ---------------------------------------------------------------------------------------- - -If you use :option:`--enable-error-code possibly-undefined `, -mypy generates an error if it cannot verify that a variable will be defined in -all execution paths. This includes situations when a variable definition -appears in a loop, in a conditional branch, in an except handler, etc. For -example: - -.. code-block:: python - - # mypy: enable-error-code="possibly-undefined" - - from collections.abc import Iterable - - def test(values: Iterable[int], flag: bool) -> None: - if flag: - a = 1 - z = a + 1 # Error: Name "a" may be undefined [possibly-undefined] - - for v in values: - b = v - z = b + 1 # Error: Name "b" may be undefined [possibly-undefined] - -.. _code-truthy-bool: - -Check that expression is not implicitly true in boolean context [truthy-bool] ------------------------------------------------------------------------------ - -Warn when the type of an expression in a boolean context does not -implement ``__bool__`` or ``__len__``. Unless one of these is -implemented by a subtype, the expression will always be considered -true, and there may be a bug in the condition. - -As an exception, the ``object`` type is allowed in a boolean context. -Using an iterable value in a boolean context has a separate error code -(see below). - -.. code-block:: python - - # mypy: enable-error-code="truthy-bool" - - class Foo: - pass - foo = Foo() - # Error: "foo" has type "Foo" which does not implement __bool__ or __len__ so it could always be true in boolean context - if foo: - ... - -.. _code-truthy-iterable: - -Check that iterable is not implicitly true in boolean context [truthy-iterable] -------------------------------------------------------------------------------- - -Generate an error if a value of type ``Iterable`` is used as a boolean -condition, since ``Iterable`` does not implement ``__len__`` or ``__bool__``. - -Example: - -.. code-block:: python - - from collections.abc import Iterable - - def transform(items: Iterable[int]) -> list[int]: - # Error: "items" has type "Iterable[int]" which can always be true in boolean context. Consider using "Collection[int]" instead. [truthy-iterable] - if not items: - return [42] - return [x + 1 for x in items] - -If ``transform`` is called with a ``Generator`` argument, such as -``int(x) for x in []``, this function would not return ``[42]`` unlike -what might be intended. Of course, it's possible that ``transform`` is -only called with ``list`` or other container objects, and the ``if not -items`` check is actually valid. If that is the case, it is -recommended to annotate ``items`` as ``Collection[int]`` instead of -``Iterable[int]``. - -.. _code-ignore-without-code: - -Check that ``# type: ignore`` include an error code [ignore-without-code] -------------------------------------------------------------------------- - -Warn when a ``# type: ignore`` comment does not specify any error codes. -This clarifies the intent of the ignore and ensures that only the -expected errors are silenced. - -Example: - -.. code-block:: python - - # mypy: enable-error-code="ignore-without-code" - - class Foo: - def __init__(self, name: str) -> None: - self.name = name - - f = Foo('foo') - - # This line has a typo that mypy can't help with as both: - # - the expected error 'assignment', and - # - the unexpected error 'attr-defined' - # are silenced. - # Error: "type: ignore" comment without error code (consider "type: ignore[attr-defined]" instead) - f.nme = 42 # type: ignore - - # This line warns correctly about the typo in the attribute name - # Error: "Foo" has no attribute "nme"; maybe "name"? - f.nme = 42 # type: ignore[assignment] - -.. _code-unused-awaitable: - -Check that awaitable return value is used [unused-awaitable] ------------------------------------------------------------- - -If you use :option:`--enable-error-code unused-awaitable `, -mypy generates an error if you don't use a returned value that defines ``__await__``. - -Example: - -.. code-block:: python - - # mypy: enable-error-code="unused-awaitable" - - import asyncio - - async def f() -> int: ... - - async def g() -> None: - # Error: Value of type "Task[int]" must be used - # Are you missing an await? - asyncio.create_task(f()) - -You can assign the value to a temporary, otherwise unused variable to -silence the error: - -.. code-block:: python - - async def g() -> None: - _ = asyncio.create_task(f()) # No error - -.. _code-unused-ignore: - -Check that ``# type: ignore`` comment is used [unused-ignore] -------------------------------------------------------------- - -If you use :option:`--enable-error-code unused-ignore `, -or :option:`--warn-unused-ignores ` -mypy generates an error if you don't use a ``# type: ignore`` comment, i.e. if -there is a comment, but there would be no error generated by mypy on this line -anyway. - -Example: - -.. code-block:: python - - # Use "mypy --warn-unused-ignores ..." - - def add(a: int, b: int) -> int: - # Error: unused "type: ignore" comment - return a + b # type: ignore - -Note that due to a specific nature of this comment, the only way to selectively -silence it, is to include the error code explicitly. Also note that this error is -not shown if the ``# type: ignore`` is not used due to code being statically -unreachable (e.g. due to platform or version checks). - -Example: - -.. code-block:: python - - # Use "mypy --warn-unused-ignores ..." - - import sys - - try: - # The "[unused-ignore]" is needed to get a clean mypy run - # on both Python 3.8, and 3.9 where this module was added - import graphlib # type: ignore[import,unused-ignore] - except ImportError: - pass - - if sys.version_info >= (3, 9): - # The following will not generate an error on either - # Python 3.8, or Python 3.9 - 42 + "testing..." # type: ignore - -.. _code-explicit-override: - -Check that ``@override`` is used when overriding a base class method [explicit-override] ----------------------------------------------------------------------------------------- - -If you use :option:`--enable-error-code explicit-override ` -mypy generates an error if you override a base class method without using the -``@override`` decorator. An error will not be emitted for overrides of ``__init__`` -or ``__new__``. See `PEP 698 `_. - -.. note:: - - Starting with Python 3.12, the ``@override`` decorator can be imported from ``typing``. - To use it with older Python versions, import it from ``typing_extensions`` instead. - -Example: - -.. code-block:: python - - # mypy: enable-error-code="explicit-override" - - from typing import override - - class Parent: - def f(self, x: int) -> None: - pass - - def g(self, y: int) -> None: - pass - - - class Child(Parent): - def f(self, x: int) -> None: # Error: Missing @override decorator - pass - - @override - def g(self, y: int) -> None: - pass - -.. _code-mutable-override: - -Check that overrides of mutable attributes are safe [mutable-override] ----------------------------------------------------------------------- - -`mutable-override` will enable the check for unsafe overrides of mutable attributes. -For historical reasons, and because this is a relatively common pattern in Python, -this check is not enabled by default. The example below is unsafe, and will be -flagged when this error code is enabled: - -.. code-block:: python - - from typing import Any - - class C: - x: float - y: float - z: float - - class D(C): - x: int # Error: Covariant override of a mutable attribute - # (base class "C" defined the type as "float", - # expression has type "int") [mutable-override] - y: float # OK - z: Any # OK - - def f(c: C) -> None: - c.x = 1.1 - d = D() - f(d) - d.x >> 1 # This will crash at runtime, because d.x is now float, not an int - -.. _code-unimported-reveal: - -Check that ``reveal_type`` is imported from typing or typing_extensions [unimported-reveal] -------------------------------------------------------------------------------------------- - -Mypy used to have ``reveal_type`` as a special builtin -that only existed during type-checking. -In runtime it fails with expected ``NameError``, -which can cause real problem in production, hidden from mypy. - -But, in Python3.11 :py:func:`typing.reveal_type` was added. -``typing_extensions`` ported this helper to all supported Python versions. - -Now users can actually import ``reveal_type`` to make the runtime code safe. - -.. note:: - - Starting with Python 3.11, the ``reveal_type`` function can be imported from ``typing``. - To use it with older Python versions, import it from ``typing_extensions`` instead. - -.. code-block:: python - - # mypy: enable-error-code="unimported-reveal" - - x = 1 - reveal_type(x) # Note: Revealed type is "builtins.int" \ - # Error: Name "reveal_type" is not defined - -Correct usage: - -.. code-block:: python - - # mypy: enable-error-code="unimported-reveal" - from typing import reveal_type # or `typing_extensions` - - x = 1 - # This won't raise an error: - reveal_type(x) # Note: Revealed type is "builtins.int" - -When this code is enabled, using ``reveal_locals`` is always an error, -because there's no way one can import it. - - -.. _code-explicit-any: - -Check that explicit Any type annotations are not allowed [explicit-any] ------------------------------------------------------------------------ - -If you use :option:`--disallow-any-explicit `, mypy generates an error -if you use an explicit ``Any`` type annotation. - -Example: - -.. code-block:: python - - # mypy: disallow-any-explicit - from typing import Any - x: Any = 1 # Error: Explicit "Any" type annotation [explicit-any] - - -.. _code-exhaustive-match: - -Check that match statements match exhaustively [exhaustive-match] ------------------------------------------------------------------------ - -If enabled with :option:`--enable-error-code exhaustive-match `, -mypy generates an error if a match statement does not match all possible cases/types. - - -Example: - -.. code-block:: python - - import enum - - - class Color(enum.Enum): - RED = 1 - BLUE = 2 - - val: Color = Color.RED - - # OK without --enable-error-code exhaustive-match - match val: - case Color.RED: - print("red") - - # With --enable-error-code exhaustive-match - # Error: Match statement has unhandled case for values of type "Literal[Color.BLUE]" - match val: - case Color.RED: - print("red") - - # OK with or without --enable-error-code exhaustive-match, since all cases are handled - match val: - case Color.RED: - print("red") - case _: - print("other") - -.. _code-untyped-decorator: - -Error if an untyped decorator makes a typed function effectively untyped [untyped-decorator] --------------------------------------------------------------------------------------------- - -If enabled with :option:`--disallow-untyped-decorators ` -mypy generates an error if a typed function is wrapped by an untyped decorator -(as this would effectively remove the benefits of typing the function). - -Example: - -.. code-block:: python - - def printing_decorator(func): - def wrapper(*args, **kwds): - print("Calling", func) - return func(*args, **kwds) - return wrapper - # A decorated function. - @printing_decorator # E: Untyped decorator makes function "add_forty_two" untyped [untyped-decorator] - def add_forty_two(value: int) -> int: - return value + 42 diff --git a/docs/source/error_code_list.rst b/docs/source/error_codes_merged.rst similarity index 57% rename from docs/source/error_code_list.rst rename to docs/source/error_codes_merged.rst index d4e2c83323ac..245582fe715f 100644 --- a/docs/source/error_code_list.rst +++ b/docs/source/error_codes_merged.rst @@ -1,3 +1,34 @@ +.. _error-codes: + +Error codes +=========== + +Mypy can optionally display an error code such as ``[attr-defined]`` +after each error message. Error codes serve two purposes: + +1. It's possible to silence specific error codes on a line using ``# + type: ignore[code]``. This way you won't accidentally ignore other, + potentially more serious errors. + +2. The error code can be used to find documentation about the error. + The next two topics (:ref:`error-code-list` and + :ref:`error-codes-optional`) document the various error codes + mypy can report. + +Most error codes are shared between multiple related error messages. +Error codes may change in future mypy releases. + +.. _error-code-list-merged: + +List of All Error Codes +======================= + +This section documents all error codes mypy can generate. Each entry indicates whether the check is enabled by default. + +.. contents:: + :local: + :depth: 2 + .. _error-code-list: Error codes enabled by default @@ -12,6 +43,7 @@ error codes that you can enable. Check that attribute exists [attr-defined] ------------------------------------------ +**Default enabled:** Yes Mypy checks that an attribute is defined in the target class or module when using the dot operator. This applies to both getting and setting @@ -49,6 +81,7 @@ be important if you silence the error. Check that attribute exists in each union item [union-attr] ----------------------------------------------------------- +**Default enabled:** Yes If you access the attribute of a value with a union type, mypy checks that the attribute is defined for *every* type in that @@ -81,6 +114,7 @@ than what mypy thinks. Check that name is defined [name-defined] ----------------------------------------- +**Default enabled:** Yes Mypy expects that all references to names have a corresponding definition in an active scope, such as an assignment, function @@ -97,6 +131,7 @@ This example accidentally calls ``sort()`` instead of :py:func:`sorted`: Check that a variable is not used before it's defined [used-before-def] ----------------------------------------------------------------------- +**Default enabled:** Yes Mypy will generate an error if a name is used before it's defined. While the name-defined check will catch issues with names that are undefined, @@ -114,6 +149,7 @@ Example: Check arguments in calls [call-arg] ----------------------------------- +**Default enabled:** Yes Mypy expects that the number and names of arguments match the called function. Note that argument type checks have a separate error code ``arg-type``. @@ -132,6 +168,7 @@ Example: Check argument types [arg-type] ------------------------------- +**Default enabled:** Yes Mypy checks that argument types in a call match the declared argument types in the signature of the called function (if one exists). @@ -152,6 +189,7 @@ Example: Check calls to overloaded functions [call-overload] --------------------------------------------------- +**Default enabled:** Yes When you call an overloaded function, mypy checks that at least one of the signatures of the overload items match the argument types in the @@ -185,6 +223,7 @@ Example: Check validity of types [valid-type] ------------------------------------ +**Default enabled:** Yes Mypy checks that each type annotation and any expression that represents a type is a valid type. Examples of valid types include @@ -215,10 +254,34 @@ You can use :py:class:`~collections.abc.Callable` as the type for callable objec for x in objs: f(x) +.. _code-nonetype-type: + +Check that NoneType is not used as a type (annotation) [nonetype-type] +---------------------------------------------------------------------- +**Default enabled:** Yes + +The preferred way to annotate the type of `None` is `None`. +`NoneType` is equivalent, but mypy won't allow it by default. + +.. code-block:: python + + from types import NoneType + def f(x: None) -> None: + reveal_type(x) # note: Revealed type is "None" + + # error: NoneType should not be used as a type, please use None instead [nonetype-type] + def g(x: NoneType) -> None: + reveal_type(x) # note: Revealed type is "None" + + # error: NoneType should not be used as a type, please use None instead [nonetype-type] + x1: NoneType = None + x2: None = None # OK + .. _code-metaclass: Check the validity of a class's metaclass [metaclass] ----------------------------------------------------- +**Default enabled:** Yes Mypy checks whether the metaclass of a class is valid. The metaclass must be a subclass of ``type``. Further, the class hierarchy must yield @@ -248,6 +311,7 @@ Example with an error: Require annotation if variable type is unclear [var-annotated] -------------------------------------------------------------- +**Default enabled:** Yes In some cases mypy can't infer the type of a variable without an explicit annotation. Mypy treats this as an error. This typically @@ -282,6 +346,7 @@ To address this, we add an explicit annotation: Check validity of overrides [override] -------------------------------------- +**Default enabled:** Yes Mypy checks that an overridden method or attribute is compatible with the base class. A method in a subclass must accept all arguments @@ -318,6 +383,7 @@ Example: Check that function returns a value [return] -------------------------------------------- +**Default enabled:** Yes If a function has a non-``None`` return type, mypy expects that the function always explicitly returns a value (or raises an exception). @@ -348,6 +414,7 @@ Example: Check that functions don't have empty bodies outside stubs [empty-body] ----------------------------------------------------------------------- +**Default enabled:** Yes This error code is similar to the ``[return]`` code but is emitted specifically for functions and methods with empty bodies (if they are annotated with @@ -380,6 +447,7 @@ are considered implicitly abstract: Check that return value is compatible [return-value] ---------------------------------------------------- +**Default enabled:** Yes Mypy checks that the returned value is compatible with the type signature of the function. @@ -396,6 +464,7 @@ Example: Check types in assignment statement [assignment] ------------------------------------------------ +**Default enabled:** Yes Mypy checks that the assigned expression is compatible with the assignment target (or targets). @@ -420,6 +489,7 @@ Example: Check that assignment target is not a method [method-assign] ------------------------------------------------------------ +**Default enabled:** Yes In general, assigning to a method on class object or instance (a.k.a. monkey-patching) is ambiguous in terms of types, since Python's static type @@ -451,6 +521,7 @@ so only the second assignment will still generate an error. Check type variable values [type-var] ------------------------------------- +**Default enabled:** Yes Mypy checks that value of a type variable is compatible with a value restriction or the upper bound type. @@ -471,6 +542,7 @@ Example (Python 3.12 syntax): Check uses of various operators [operator] ------------------------------------------ +**Default enabled:** Yes Mypy checks that operands support a binary or unary operation, such as ``+`` or ``~``. Indexing operations are so common that they have their @@ -487,6 +559,7 @@ Example: Check indexing operations [index] --------------------------------- +**Default enabled:** Yes Mypy checks that the indexed value in indexing operation such as ``x[y]`` supports indexing, and that the index expression has a valid @@ -510,6 +583,7 @@ Example: Check list items [list-item] ---------------------------- +**Default enabled:** Yes When constructing a list using ``[item, ...]``, mypy checks that each item is compatible with the list type that is inferred from the surrounding @@ -526,6 +600,7 @@ Example: Check dict items [dict-item] ---------------------------- +**Default enabled:** Yes When constructing a dictionary using ``{key: value, ...}`` or ``dict(key=value, ...)``, mypy checks that each key and value is compatible with the dictionary type that is @@ -542,6 +617,7 @@ Example: Check TypedDict items [typeddict-item] -------------------------------------- +**Default enabled:** Yes When constructing a TypedDict object, mypy checks that each key and value is compatible with the TypedDict type that is inferred from the surrounding context. @@ -568,6 +644,7 @@ Example: Check TypedDict Keys [typeddict-unknown-key] -------------------------------------------- +**Default enabled:** Yes When constructing a TypedDict object, mypy checks whether the definition contains unknown keys, to catch invalid keys and @@ -626,6 +703,7 @@ runtime: Check that type of target is known [has-type] --------------------------------------------- +**Default enabled:** Yes Mypy sometimes generates an error when it hasn't inferred any type for a variable being referenced. This can happen for references to @@ -667,6 +745,7 @@ the issue: Check for an issue with imports [import] ---------------------------------------- +**Default enabled:** Yes Mypy generates an error if it can't resolve an `import` statement. This is a parent error code of `import-not-found` and `import-untyped` @@ -677,6 +756,7 @@ See :ref:`ignore-missing-imports` for how to work around these errors. Check that import target can be found [import-not-found] -------------------------------------------------------- +**Default enabled:** Yes Mypy generates an error if it can't find the source code or a stub file for an imported module. @@ -694,6 +774,7 @@ See :ref:`ignore-missing-imports` for how to work around these errors. Check that import target can be found [import-untyped] -------------------------------------------------------- +**Default enabled:** Yes Mypy generates an error if it can find the source code for an imported module, but that module does not provide type annotations (via :ref:`PEP 561 `). @@ -714,6 +795,7 @@ stub package. See :ref:`ignore-missing-imports` for more details. Check that each name is defined once [no-redef] ----------------------------------------------- +**Default enabled:** Yes Mypy may generate an error if you have multiple definitions for a name in the same namespace. The reason is that this is often an error, as @@ -742,6 +824,7 @@ Example: Check that called function returns a value [func-returns-value] --------------------------------------------------------------- +**Default enabled:** Yes Mypy reports an error if you call a function with a ``None`` return type and don't ignore the return value, as this is @@ -766,6 +849,7 @@ returns ``None``: Check instantiation of abstract classes [abstract] -------------------------------------------------- +**Default enabled:** Yes Mypy generates an error if you try to instantiate an abstract base class (ABC). An abstract base class is a class with at least one @@ -799,6 +883,7 @@ Example: Safe handling of abstract type object types [type-abstract] ----------------------------------------------------------- +**Default enabled:** Yes Mypy always allows instantiating (calling) type objects typed as ``type[t]``, even if it is not known that ``t`` is non-abstract, since it is a common @@ -825,6 +910,7 @@ Example (Python 3.12 syntax): Check that call to an abstract method via super is valid [safe-super] --------------------------------------------------------------------- +**Default enabled:** Yes Abstract methods often don't have any default implementation, i.e. their bodies are just empty. Calling such methods in subclasses via ``super()`` @@ -849,6 +935,7 @@ ellipsis ``...``, a docstring, and a ``raise NotImplementedError`` statement. Check the target of NewType [valid-newtype] ------------------------------------------- +**Default enabled:** Yes The target of a :py:class:`~typing.NewType` definition must be a class type. It can't be a union type, ``Any``, or various other special types. @@ -875,6 +962,7 @@ for more information. Check the return type of __exit__ [exit-return] ----------------------------------------------- +**Default enabled:** Yes If mypy can determine that :py:meth:`__exit__ ` always returns ``False``, mypy checks that the return type is *not* ``bool``. The boolean value of @@ -933,6 +1021,7 @@ You can also use ``None``: Check that naming is consistent [name-match] -------------------------------------------- +**Default enabled:** Yes The definition of a named tuple or a TypedDict must be named consistently when using the call-based syntax. Example: @@ -948,6 +1037,7 @@ consistently when using the call-based syntax. Example: Check that literal is used where expected [literal-required] ------------------------------------------------------------ +**Default enabled:** Yes There are some places where only a (string) literal value is expected for the purposes of static type checking, for example a ``TypedDict`` key, or @@ -979,6 +1069,7 @@ or ``Literal`` variables. Example: Check that overloaded functions have an implementation [no-overload-impl] ------------------------------------------------------------------------- +**Default enabled:** Yes Overloaded functions outside of stub files must be followed by a non overloaded implementation. @@ -1003,6 +1094,7 @@ implementation. Check that coroutine return value is used [unused-coroutine] ------------------------------------------------------------ +**Default enabled:** Yes Mypy ensures that return values of async def functions are not ignored, as this is usually a programming error, as the coroutine @@ -1028,6 +1120,7 @@ otherwise unused variable: Warn about top level await expressions [top-level-await] -------------------------------------------------------- +**Default enabled:** Yes This error code is separate from the general ``[syntax]`` errors, because in some environments (e.g. IPython) a top level ``await`` is allowed. In such @@ -1046,6 +1139,7 @@ for example: Warn about await expressions used outside of coroutines [await-not-async] ------------------------------------------------------------------------- +**Default enabled:** Yes ``await`` must be used inside a coroutine. @@ -1061,6 +1155,7 @@ Warn about await expressions used outside of coroutines [await-not-async] Check types in assert_type [assert-type] ---------------------------------------- +**Default enabled:** Yes The inferred type for an expression passed to ``assert_type`` must match the provided type. @@ -1077,6 +1172,7 @@ the provided type. Check that function isn't used in boolean context [truthy-function] ------------------------------------------------------------------- +**Default enabled:** Yes Functions will always evaluate to true in boolean contexts. @@ -1092,6 +1188,7 @@ Functions will always evaluate to true in boolean contexts. Check that string formatting/interpolation is type-safe [str-format] -------------------------------------------------------------------- +**Default enabled:** Yes Mypy will check that f-strings, ``str.format()`` calls, and ``%`` interpolations are valid (when corresponding template is a literal string). This includes @@ -1113,6 +1210,7 @@ checking number and types of replacements, for example: Check for implicit bytes coercions [str-bytes-safe] ------------------------------------------------------------------- +**Default enabled:** Yes Warn about cases where a bytes object may be converted to a string in an unexpected manner. @@ -1129,10 +1227,31 @@ Warn about cases where a bytes object may be converted to a string in an unexpec print(f"The alphabet starts with {b!r}") # The alphabet starts with b'abc' print(f"The alphabet starts with {b.decode('utf-8')}") # The alphabet starts with abc +.. _code-str-unpack: + +Check that ``str`` is not unpacked [str-unpack] +--------------------------------------------------------- +**Default enabled:** Yes + +It can sometimes be surprising that ``str`` is iterable, especially when unpacking +in an assignment. + +Example: + +.. code-block:: python + + def print_dict(d: dict[str, str]) -> int: + # We meant to do d.items(), but instead we're unpacking the str keys of d + + # Error: Unpacking a string is disallowed + for k, v in d: + print(k, v) + .. _code-overload-overlap: Check that overloaded functions don't overlap [overload-overlap] ---------------------------------------------------------------- +**Default enabled:** Yes Warn if multiple ``@overload`` variants overlap in potentially unsafe ways. This guards against the following situation: @@ -1169,6 +1288,7 @@ See :ref:`overloading ` for more explanation. Check for overload signatures that cannot match [overload-cannot-match] -------------------------------------------------------------------------- +**Default enabled:** Yes Warn if an ``@overload`` variant can never be matched, because an earlier overload has a wider signature. For example, this can happen if the two @@ -1196,6 +1316,7 @@ Example: Notify about an annotation in an unchecked function [annotation-unchecked] -------------------------------------------------------------------------- +**Default enabled:** Yes Sometimes a user may accidentally omit an annotation for a function, and mypy will not check the body of this function (unless one uses @@ -1218,6 +1339,7 @@ specified by :pep:`484`. Decorator preceding property not supported [prop-decorator] ----------------------------------------------------------- +**Default enabled:** Yes Mypy does not yet support analysis of decorators that precede the property decorator. If the decorator does not preserve the declared type of the property, @@ -1241,6 +1363,7 @@ comment: Report syntax errors [syntax] ----------------------------- +**Default enabled:** Yes If the code being checked is not syntactically valid, mypy issues a syntax error. Most, but not all, syntax errors are *blocking errors*: @@ -1250,6 +1373,7 @@ they can't be ignored with a ``# type: ignore`` comment. ReadOnly key of a TypedDict is mutated [typeddict-readonly-mutated] ------------------------------------------------------------------- +**Default enabled:** Yes Consider this example: @@ -1274,6 +1398,7 @@ how ``ReadOnly`` special form works for ``TypedDict`` objects. Check that ``TypeIs`` narrows types [narrowed-type-not-subtype] --------------------------------------------------------------- +**Default enabled:** Yes :pep:`742` requires that when ``TypeIs`` is used, the narrowed type must be a subtype of the original type:: @@ -1290,6 +1415,7 @@ type must be a subtype of the original type:: String appears in a context which expects a TypeForm [maybe-unrecognized-str-typeform] -------------------------------------------------------------------------------------- +**Default enabled:** Yes TypeForm literals may contain string annotations: @@ -1349,6 +1475,7 @@ to the line with the string literal: Miscellaneous checks [misc] --------------------------- +**Default enabled:** Yes Mypy performs numerous other, less commonly failing checks that don't have specific error codes. These use the ``misc`` error code. Other @@ -1363,3 +1490,826 @@ this can certainly happen once in a while. Future mypy versions will likely add new error codes for some errors that currently use the ``misc`` error code. + +.. _error-codes-optional: + +Error codes for optional checks +=============================== + +This section documents various errors codes that mypy generates only +if you enable certain options. See :ref:`error-codes` for general +documentation about error codes and their configuration. +:ref:`error-code-list` documents error codes that are enabled by default. + +.. note:: + + The examples in this section use :ref:`inline configuration + ` to specify mypy options. You can also set the same + options by using a :ref:`configuration file ` or + :ref:`command-line options `. + +.. _code-type-arg: + +Check that type arguments exist [type-arg] +------------------------------------------ +**Default enabled:** No (requires ``--disallow-any-generics``) + +If you use :option:`--disallow-any-generics `, mypy requires that each generic +type has values for each type argument. For example, the types ``list`` or +``dict`` would be rejected. You should instead use types like ``list[int]`` or +``dict[str, int]``. Any omitted generic type arguments get implicit ``Any`` +values. The type ``list`` is equivalent to ``list[Any]``, and so on. + +Example: + +.. code-block:: python + + # mypy: disallow-any-generics + + # Error: Missing type parameters for generic type "list" [type-arg] + def remove_dups(items: list) -> list: + ... + +.. _code-no-untyped-def: + +Check that every function has an annotation [no-untyped-def] +------------------------------------------------------------ +**Default enabled:** No (requires ``--disallow-untyped-defs``) + +If you use :option:`--disallow-untyped-defs `, mypy requires that all functions +have annotations (either a Python 3 annotation or a type comment). + +Example: + +.. code-block:: python + + # mypy: disallow-untyped-defs + + def inc(x): # Error: Function is missing a type annotation [no-untyped-def] + return x + 1 + + def inc_ok(x: int) -> int: # OK + return x + 1 + + class Counter: + # Error: Function is missing a type annotation [no-untyped-def] + def __init__(self): + self.value = 0 + + class CounterOk: + # OK: An explicit "-> None" is needed if "__init__" takes no arguments + def __init__(self) -> None: + self.value = 0 + +.. _code-redundant-cast: + +Check that cast is not redundant [redundant-cast] +------------------------------------------------- +**Default enabled:** No (requires ``--warn-redundant-casts``) + +If you use :option:`--warn-redundant-casts `, mypy will generate an error if the source +type of a cast is the same as the target type. + +Example: + +.. code-block:: python + + # mypy: warn-redundant-casts + + from typing import cast + + Count = int + + def example(x: Count) -> int: + # Error: Redundant cast to "int" [redundant-cast] + return cast(int, x) + +.. _code-redundant-self: + +Check that methods do not have redundant Self annotations [redundant-self] +-------------------------------------------------------------------------- +**Default enabled:** No (requires ``--enable-error-code=redundant-self``) + +If a method uses the ``Self`` type in the return type or the type of a +non-self argument, there is no need to annotate the ``self`` argument +explicitly. Such annotations are allowed by :pep:`673` but are +redundant. If you enable this error code, mypy will generate an error if +there is a redundant ``Self`` type. + +Example: + +.. code-block:: python + + # mypy: enable-error-code="redundant-self" + + from typing import Self + + class C: + # Error: Redundant "Self" annotation for the first method argument + def copy(self: Self) -> Self: + return type(self)() + +.. _code-comparison-overlap: + +Check that comparisons are overlapping [comparison-overlap] +----------------------------------------------------------- +**Default enabled:** No (requires ``--strict-equality``) + +If you use :option:`--strict-equality `, mypy will generate an error if it +thinks that a comparison operation is always true or false. These are +often bugs. Sometimes mypy is too picky and the comparison can +actually be useful. Instead of disabling strict equality checking +everywhere, you can use ``# type: ignore[comparison-overlap]`` to +ignore the issue on a particular line only. + +Example: + +.. code-block:: python + + # mypy: strict-equality + + def is_magic(x: bytes) -> bool: + # Error: Non-overlapping equality check (left operand type: "bytes", + # right operand type: "str") [comparison-overlap] + return x == 'magic' + +We can fix the error by changing the string literal to a bytes +literal: + +.. code-block:: python + + # mypy: strict-equality + + def is_magic(x: bytes) -> bool: + return x == b'magic' # OK + +:option:`--strict-equality ` does not include comparisons with +``None``: + +.. code-block:: python + + # mypy: strict-equality + + def is_none(x: str) -> bool: + return x is None # OK + +If you want such checks, you must also activate +:option:`--strict-equality-for-none ` (we might merge +these two options later). + +.. code-block:: python + + # mypy: strict-equality strict-equality-for-none + + def is_none(x: str) -> bool: + # Error: Non-overlapping identity check + # (left operand type: "str", right operand type: "None") + return x is None + +.. _code-no-untyped-call: + +Check that no untyped functions are called [no-untyped-call] +------------------------------------------------------------ +**Default enabled:** No (requires ``--disallow-untyped-calls``) + +If you use :option:`--disallow-untyped-calls `, mypy generates an error when you +call an unannotated function in an annotated function. + +Example: + +.. code-block:: python + + # mypy: disallow-untyped-calls + + def do_it() -> None: + # Error: Call to untyped function "bad" in typed context [no-untyped-call] + bad() + + def bad(): + ... + +.. _code-no-any-return: + +Check that function does not return Any value [no-any-return] +------------------------------------------------------------- +**Default enabled:** No (requires ``--warn-return-any``) + +If you use :option:`--warn-return-any `, mypy generates an error if you return a +value with an ``Any`` type in a function that is annotated to return a +non-``Any`` value. + +Example: + +.. code-block:: python + + # mypy: warn-return-any + + def fields(s): + return s.split(',') + + def first_field(x: str) -> str: + # Error: Returning Any from function declared to return "str" [no-any-return] + return fields(x)[0] + +.. _code-no-any-unimported: + +Check that types have no Any components due to missing imports [no-any-unimported] +---------------------------------------------------------------------------------- +**Default enabled:** No (requires ``--disallow-any-unimported``) + +If you use :option:`--disallow-any-unimported `, mypy generates an error if a component of +a type becomes ``Any`` because mypy couldn't resolve an import. These "stealth" +``Any`` types can be surprising and accidentally cause imprecise type checking. + +In this example, we assume that mypy can't find the module ``animals``, which means +that ``Cat`` falls back to ``Any`` in a type annotation: + +.. code-block:: python + + # mypy: disallow-any-unimported + + from animals import Cat # type: ignore + + # Error: Argument 1 to "feed" becomes "Any" due to an unfollowed import [no-any-unimported] + def feed(cat: Cat) -> None: + ... + +.. _code-unreachable: + +Check that statement or expression is unreachable [unreachable] +--------------------------------------------------------------- +**Default enabled:** No (requires ``--warn-unreachable``) + +If you use :option:`--warn-unreachable `, mypy generates an error if it +thinks that a statement or expression will never be executed. In most cases, this is due to +incorrect control flow or conditional checks that are accidentally always true or false. + +.. code-block:: python + + # mypy: warn-unreachable + + def example(x: int) -> None: + # Error: Right operand of "or" is never evaluated [unreachable] + assert isinstance(x, int) or x == 'unused' + + return + # Error: Statement is unreachable [unreachable] + print('unreachable') + +.. _code-deprecated: + +Check that imported or used feature is deprecated [deprecated] +-------------------------------------------------------------- +**Default enabled:** No (requires ``--enable-error-code=deprecated``) + +If you use :option:`--enable-error-code deprecated `, +mypy generates an error if your code imports a deprecated feature explicitly with a +``from mod import depr`` statement or uses a deprecated feature imported otherwise or defined +locally. Features are considered deprecated when decorated with ``warnings.deprecated``, as +specified in `PEP 702 `_. +Use the :option:`--report-deprecated-as-note ` option to +turn all such errors into notes. +Use :option:`--deprecated-calls-exclude ` to hide warnings +for specific functions, classes and packages. + +.. note:: + + The ``warnings`` module provides the ``@deprecated`` decorator since Python 3.13. + To use it with older Python versions, import it from ``typing_extensions`` instead. + +Examples: + +.. code-block:: python + + # mypy: report-deprecated-as-error + + # Error: abc.abstractproperty is deprecated: Deprecated, use 'property' with 'abstractmethod' instead + from abc import abstractproperty + + from typing_extensions import deprecated + + @deprecated("use new_function") + def old_function() -> None: + print("I am old") + + # Error: __main__.old_function is deprecated: use new_function + old_function() + old_function() # type: ignore[deprecated] + + +.. _code-redundant-expr: + +Check that expression is redundant [redundant-expr] +--------------------------------------------------- +**Default enabled:** No (requires ``--enable-error-code=redundant-expr``) + +If you use :option:`--enable-error-code redundant-expr `, +mypy generates an error if it thinks that an expression is redundant. + +.. code-block:: python + + # mypy: enable-error-code="redundant-expr" + + def example(x: int) -> None: + # Error: Left operand of "and" is always true [redundant-expr] + if isinstance(x, int) and x > 0: + pass + + # Error: If condition is always true [redundant-expr] + 1 if isinstance(x, int) else 0 + + # Error: If condition in comprehension is always true [redundant-expr] + [i for i in range(x) if isinstance(i, int)] + + +.. _code-possibly-undefined: + +Warn about variables that are defined only in some execution paths [possibly-undefined] +--------------------------------------------------------------------------------------- +**Default enabled:** No (requires ``--enable-error-code=possibly-undefined``) + +If you use :option:`--enable-error-code possibly-undefined `, +mypy generates an error if it cannot verify that a variable will be defined in +all execution paths. This includes situations when a variable definition +appears in a loop, in a conditional branch, in an except handler, etc. For +example: + +.. code-block:: python + + # mypy: enable-error-code="possibly-undefined" + + from collections.abc import Iterable + + def test(values: Iterable[int], flag: bool) -> None: + if flag: + a = 1 + z = a + 1 # Error: Name "a" may be undefined [possibly-undefined] + + for v in values: + b = v + z = b + 1 # Error: Name "b" may be undefined [possibly-undefined] + +.. _code-truthy-bool: + +Check that expression is not implicitly true in boolean context [truthy-bool] +----------------------------------------------------------------------------- +**Default enabled:** No (requires ``--enable-error-code=truthy-bool``) + +Warn when the type of an expression in a boolean context does not +implement ``__bool__`` or ``__len__``. Unless one of these is +implemented by a subtype, the expression will always be considered +true, and there may be a bug in the condition. + +As an exception, the ``object`` type is allowed in a boolean context. +Using an iterable value in a boolean context has a separate error code +(see below). + +.. code-block:: python + + # mypy: enable-error-code="truthy-bool" + + class Foo: + pass + foo = Foo() + # Error: "foo" has type "Foo" which does not implement __bool__ or __len__ so it could always be true in boolean context + if foo: + ... + +.. _code-truthy-iterable: + +Check that iterable is not implicitly true in boolean context [truthy-iterable] +------------------------------------------------------------------------------- +**Default enabled:** No (requires ``--enable-error-code=truthy-iterable``) + +Generate an error if a value of type ``Iterable`` is used as a boolean +condition, since ``Iterable`` does not implement ``__len__`` or ``__bool__``. + +Example: + +.. code-block:: python + + from collections.abc import Iterable + + def transform(items: Iterable[int]) -> list[int]: + # Error: "items" has type "Iteredable[int]" which can always be true in boolean context. Consider using "Collection[int]" instead. [truthy-iterable] + if not items: + return [42] + return [x + 1 for x in items] + +If ``transform`` is called with a ``Generator`` argument, such as +``int(x) for x in []``, this function would not return ``[42]`` unlike +what might be intended. Of course, it's possible that ``transform`` is +only called with ``list`` or other container objects, and the ``if not +items`` check is actually valid. If that is the case, it is +recommended to annotate ``items`` as ``Collection[int]`` instead of +``Iterable[int]``. + +.. _code-ignore-without-code: + +Check that ``# type: ignore`` include an error code [ignore-without-code] +------------------------------------------------------------------------- +**Default enabled:** No (requires ``--enable-error-code=ignore-without-code``) + +Warn when a ``# type: ignore`` comment does not specify any error codes. +This clarifies the intent of the ignore and ensures that only the +expected errors are silenced. + +Example: + +.. code-block:: python + + # mypy: enable-error-code="ignore-without-code" + + class Foo: + def __init__(self, name: str) -> None: + self.name = name + + f = Foo('foo') + + # This line has a typo that mypy can't help with as both: + # - the expected error 'assignment', and + # - the unexpected error 'attr-defined' + # are silenced. + # Error: "type: ignore" comment without error code (consider "type: ignore[attr-defined]" instead) + f.nme = 42 # type: ignore + + # This line warns correctly about the typo in the attribute name + # Error: "Foo" has no attribute "nme"; maybe "name"? + f.nme = 42 # type: ignore[assignment] + +.. _code-unused-awaitable: + +Check that awaitable return value is used [unused-awaitable] +------------------------------------------------------------ +**Default enabled:** No (requires ``--enable-error-code=unused-awaitable``) + +If you use :option:`--enable-error-code unused-awaitable `, +mypy generates an error if you don't use a returned value that defines ``__await__``. + +Example: + +.. code-block:: python + + # mypy: enable-error-code="unused-awaitable" + + import asyncio + + async def f() -> int: ... + + async def g() -> None: + # Error: Value of type "Task[int]" must be used + # Are you missing an await? + asyncio.create_task(f()) + +You can assign the value to a temporary, otherwise unused variable to +silence the error: + +.. code-block:: python + + async def g() -> None: + _ = asyncio.create_task(f()) # No error + +.. _code-unused-ignore: + +Check that ``# type: ignore`` comment is used [unused-ignore] +------------------------------------------------------------- +**Default enabled:** No (requires ``--warn-unused-ignores`` or ``--enable-error-code=unused-ignore``) + +If you use :option:`--enable-error-code unused-ignore `, +or :option:`--warn-unused-ignores ` +mypy generates an error if you don't use a ``# type: ignore`` comment, i.e. if +there is a comment, but there would be no error generated by mypy on this line +anyway. + +Example: + +.. code-block:: python + + # Use "mypy --warn-unused-ignores ..." + + def add(a: int, b: int) -> int: + # Error: unused "type: ignore" comment + return a + b # type: ignore + +Note that due to a specific nature of this comment, the only way to selectively +silence it, is to include the error code explicitly. Also note that this error is +not shown if the ``# type: ignore`` is not used due to code being statically +unreachable (e.g. due to platform or version checks). + +Example: + +.. code-block:: python + + # Use "mypy --warn-unused-ignores ..." + + import sys + + try: + # The "[unused-ignore]" is needed to get a clean mypy run + # on both Python 3.8, and 3.9 where this module was added + import graphlib # type: ignore[import,unused-ignore] + except ImportError: + pass + + if sys.version_info >= (3, 9): + # The following will not generate an error on either + # Python 3.8, or Python 3.9 + 42 + "testing..." # type: ignore + +.. _code-explicit-override: + +Check that ``@override`` is used when overriding a base class method [explicit-override] +---------------------------------------------------------------------------------------- +**Default enabled:** No (requires ``--enable-error-code=explicit-override``) + +If you use :option:`--enable-error-code explicit-override ` +mypy generates an error if you override a base class method without using the +``@override`` decorator. An error will not be emitted for overrides of ``__init__`` +or ``__new__``. See `PEP 698 `_. + +.. note:: + + Starting with Python 3.12, the ``@override`` decorator can be imported from ``typing``. + To use it with older Python versions, import it from ``typing_extensions`` instead. + +Example: + +.. code-block:: python + + # mypy: enable-error-code="explicit-override" + + from typing import override + + class Parent: + def f(self, x: int) -> None: + pass + + def g(self, y: int) -> None: + pass + + + class Child(Parent): + def f(self, x: int) -> None: # Error: Missing @override decorator + pass + + @override + def g(self, y: int) -> None: + pass + +.. _code-mutable-override: + +Check that overrides of mutable attributes are safe [mutable-override] +---------------------------------------------------------------------- +**Default enabled:** No (requires ``--enable-error-code=mutable-override``) + +`mutable-override` will enable the check for unsafe overrides of mutable attributes. +For historical reasons, and because this is a relatively common pattern in Python, +this check is not enabled by default. The example below is unsafe, and will be +flagged when this error code is enabled: + +.. code-block:: python + + from typing import Any + + class C: + x: float + y: float + z: float + + class D(C): + x: int # Error: Covariant override of a mutable attribute + # (base class "C" defined the type as "float", + # expression has type "int") [mutable-override] + y: float # OK + z: Any # OK + + def f(c: C) -> None: + c.x = 1.1 + d = D() + f(d) + d.x >> 1 # This will crash at runtime, because d.x is now float, not an int + +.. _code-unimported-reveal: + +Check that ``reveal_type`` is imported from typing or typing_extensions [unimported-reveal] +------------------------------------------------------------------------------------------- +**Default enabled:** No (requires ``--enable-error-code=unimported-reveal``) + +Mypy used to have ``reveal_type`` as a special builtin +that only existed during type-checking. +In runtime it fails with expected ``NameError``, +which can cause real problem in production, hidden from mypy. + +But, in Python3.11 :py:func:`typing.reveal_type` was added. +``typing_extensions`` ported this helper to all supported Python versions. + +Now users can actually import ``reveal_type`` to make the runtime code safe. + +.. note:: + + Starting with Python 3.11, the ``reveal_type`` function can be imported from ``typing``. + To use it with older Python versions, import it from ``typing_extensions`` instead. + +.. code-block:: python + + # mypy: enable-error-code="unimported-reveal" + + x = 1 + reveal_type(x) # Note: Revealed type is "builtins.int" \ + # Error: Name "reveal_type" is not defined + +Correct usage: + +.. code-block:: python + + # mypy: enable-error-code="unimported-reveal" + from typing import reveal_type # or `typing_extensions` + + x = 1 + # This won't raise an error: + reveal_type(x) # Note: Revealed type is "builtins.int" + +When this code is enabled, using ``reveal_locals`` is always an error, +because there's no way one can import it. + + +.. _code-explicit-any: + +Check that explicit Any type annotations are not allowed [explicit-any] +----------------------------------------------------------------------- +**Default enabled:** No (requires ``--disallow-any-explicit``) + +If you use :option:`--disallow-any-explicit `, mypy generates an error +if you use an explicit ``Any`` type annotation. + +Example: + +.. code-block:: python + + # mypy: disallow-any-explicit + from typing import Any + x: Any = 1 # Error: Explicit "Any" type annotation [explicit-any] + + +.. _code-exhaustive-match: + +Check that match statements match exhaustively [exhaustive-match] +----------------------------------------------------------------------- +**Default enabled:** No (requires ``--enable-error-code=exhaustive-match``) + +If enabled with :option:`--enable-error-code exhaustive-match `, +mypy generates an error if a match statement does not match all possible cases/types. + + +Example: + +.. code-block:: python + + import enum + + + class Color(enum.Enum): + RED = 1 + BLUE = 2 + + val: Color = Color.RED + + # OK without --enable-error-code exhaustive-match + match val: + case Color.RED: + print("red") + + # With --enable-error-code exhaustive-match + # Error: Match statement has unhandled case for values of type "Literal[Color.BLUE]" + match val: + case Color.RED: + print("red") + + # OK with or without --enable-error-code exhaustive-match, since all cases are handled + match val: + case Color.RED: + print("red") + case _: + print("other") + +.. _code-untyped-decorator: + +Error if an untyped decorator makes a typed function effectively untyped [untyped-decorator] +-------------------------------------------------------------------------------------------- +**Default enabled:** No (requires ``--disallow-untyped-decorators``) + +If enabled with :option:`--disallow-untyped-decorators ` +mypy generates an error if a typed function is wrapped by an untyped decorator +(as this would effectively remove the benefits of typing the function). + +Example: + +.. code-block:: python + + def printing_decorator(func): + def wrapper(*args, **kwds): + print("Calling", func) + return func(*args, **kwds) + return wrapper + # A decorated function. + @printing_decorator # E: Untyped decorator makes function "add_forty_two" untyped [untyped-decorator] + def add_forty_two(value: int) -> int: + return value + 42 + +.. _silence-error-codes: + +Silencing errors based on error codes +------------------------------------- + +You can use a special comment ``# type: ignore[code, ...]`` to only +ignore errors with a specific error code (or codes) on a particular +line. This can be used even if you have not configured mypy to show +error codes. + +This example shows how to ignore an error about an imported name mypy +thinks is undefined: + +.. code-block:: python + + # 'foo' is defined in 'foolib', even though mypy can't see the + # definition. + from foolib import foo # type: ignore[attr-defined] + +Enabling/disabling specific error codes globally +------------------------------------------------ + +There are command-line flags and config file settings for enabling +certain optional error codes, such as :option:`--disallow-untyped-defs `, +which enables the ``no-untyped-def`` error code. + +You can use :option:`--enable-error-code ` +and :option:`--disable-error-code ` +to enable or disable specific error codes that don't have a dedicated +command-line flag or config file setting. + +Per-module enabling/disabling error codes +----------------------------------------- + +You can use :ref:`configuration file ` sections to enable or +disable specific error codes only in some modules. For example, this ``mypy.ini`` +config will enable non-annotated empty containers in tests, while keeping +other parts of code checked in strict mode: + +.. code-block:: ini + + [mypy] + strict = True + + [mypy-tests.*] + allow_untyped_defs = True + allow_untyped_calls = True + disable_error_code = var-annotated, has-type + +Note that per-module enabling/disabling acts as override over the global +options. So that you don't need to repeat the error code lists for each +module if you have them in global config section. For example: + +.. code-block:: ini + + [mypy] + enable_error_code = truthy-bool, ignore-without-code, unused-awaitable + + [mypy-extensions.*] + disable_error_code = unused-awaitable + +The above config will allow unused awaitables in extension modules, but will +still keep the other two error codes enabled. The overall logic is following: + +* Command line and/or config main section set global error codes + +* Individual config sections *adjust* them per glob/module + +* Inline ``# mypy: disable-error-code="..."`` and ``# mypy: enable-error-code="..."`` + comments can further *adjust* them for a specific file. + For example: + +.. code-block:: python + + # mypy: enable-error-code="truthy-bool, ignore-without-code" + +So one can e.g. enable some code globally, disable it for all tests in +the corresponding config section, and then re-enable it with an inline +comment in some specific test. + +Subcodes of error codes +----------------------- + +In some cases, mostly for backwards compatibility reasons, an error +code may be covered also by another, wider error code. For example, an error with +code ``[method-assign]`` can be ignored by ``# type: ignore[assignment]``. +Similar logic works for disabling error codes globally. If a given error code +is a subcode of another one, it will be mentioned in the documentation for the narrower +code. This hierarchy is not nested: there cannot be subcodes of other +subcodes. + + +Requiring error codes +--------------------- + +It's possible to require error codes be specified in ``type: ignore`` comments. +See :ref:`ignore-without-code` for more information. diff --git a/docs/source/index.rst b/docs/source/index.rst index de3286d58ace..c9b20e538ee0 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -99,8 +99,7 @@ Contents common_issues supported_python_features error_codes - error_code_list - error_code_list2 + error_codes_merged additional_features faq changelog