Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing docs for error codes #15539

Merged
merged 1 commit into from
Jun 28, 2023
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
97 changes: 97 additions & 0 deletions docs/source/error_code_list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,38 @@ Example:
else:
raise ValueError('not defined for zero')

.. _code-empty-body:

Check that functions don't have empty bodies outside stubs [empty-body]
-----------------------------------------------------------------------

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
non-trivial return type). Such a distinction exists because in some contexts
an empty body can be valid, for example for an abstract method or in a stub
file. Also old versions of mypy used to unconditionally allow functions with
empty bodies, so having a dedicated error code simplifies cross-version
compatibility.

Note that empty bodies are allowed for methods in *protocols*, and such methods
are considered implicitly abstract:

.. code-block:: python

from abc import abstractmethod
from typing import Protocol

class RegularABC:
@abstractmethod
def foo(self) -> int:
pass # OK
def bar(self) -> int:
pass # Error: Missing return statement [empty-body]

class Proto(Protocol):
def bar(self) -> int:
pass # OK

.. _code-return-value:

Check that return value is compatible [return-value]
Expand Down Expand Up @@ -947,6 +979,28 @@ otherwise unused variable:

_ = f() # No error

.. _code-top-level-await:

Warn about top level await expressions [top-level-await]
--------------------------------------------------------

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
environments a user may want to use ``--disable-error-code=top-level-await``,
that allows to still have errors for other improper uses of ``await``, for
example:

.. code-block:: python

async def f() -> None:
...

top = await f() # Error: "await" outside function [top-level-await]

def g() -> None:
# This is a blocker error and cannot be silenced.
await f() # Error: "await" outside coroutine ("async def")

.. _code-assert-type:

Check types in assert_type [assert-type]
Expand Down Expand Up @@ -978,6 +1032,27 @@ Functions will always evaluate to true in boolean contexts.
if f: # Error: Function "Callable[[], Any]" could always be true in boolean context [truthy-function]
pass

.. _code-str-format:

Check that string formatting/interpolation is type-safe [str-format]
--------------------------------------------------------------------

Mypy will check that f-strings, ``str.format()`` calls, and ``%`` interpolations
are valid (when corresponding template is a literal string). This includes
checking number and types of replacements, for example:

.. code-block:: python

# Error: Cannot find replacement for positional format specifier 1 [str-format]
"{} and {}".format("spam")
"{} and {}".format("spam", "eggs") # OK
# Error: Not all arguments converted during string formatting [str-format]
"{} and {}".format("spam", "eggs", "cheese")

# Error: Incompatible types in string interpolation
# (expression has type "float", placeholder has type "int") [str-format]
"{:d}".format(3.14)

.. _code-str-bytes-safe:

Check for implicit bytes coercions [str-bytes-safe]
Expand All @@ -998,6 +1073,28 @@ 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-annotation-unchecked:

Notify about an annotation in an unchecked function [annotation-unchecked]
--------------------------------------------------------------------------

Sometimes a user may accidentally omit an annotation for a function, and mypy
will not check the body of this function (unless one uses
:option:`--check-untyped-defs <mypy --check-untyped-defs>` or
:option:`--disallow-untyped-defs <mypy --disallow-untyped-defs>`). To avoid
such situations go unnoticed, mypy will show a note, if there are any type
annotations in an unchecked function:

.. code-block:: python

def test_assignment(): # "-> None" return annotation is missing
# Note: By default the bodies of untyped functions are not checked,
# consider using --check-untyped-defs [annotation-unchecked]
x: int = "no way"

Note that mypy will still exit with return code ``0``, since such behaviour is
specified by :pep:`484`.

.. _code-syntax:

Report syntax errors [syntax]
Expand Down
26 changes: 26 additions & 0 deletions docs/source/error_code_list2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,32 @@ mypy generates an error if it thinks that an expression is redundant.
[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 --enable-error-code>`,
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

# Use "mypy --enable-error-code possibly-undefined ..."

from typing 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]
Expand Down
14 changes: 1 addition & 13 deletions docs/source/html_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,7 @@ def write_doc(self, docname: str, doctree: document) -> None:
def _verify_error_codes(self) -> None:
from mypy.errorcodes import error_codes

known_missing = {
# TODO: fix these before next release
"annotation-unchecked",
"empty-body",
"possibly-undefined",
"str-format",
"top-level-await",
}
missing_error_codes = {
c
for c in error_codes
if f"code-{c}" not in self._ref_to_doc and c not in known_missing
}
missing_error_codes = {c for c in error_codes if f"code-{c}" not in self._ref_to_doc}
if missing_error_codes:
raise ValueError(
f"Some error codes are not documented: {', '.join(sorted(missing_error_codes))}"
Expand Down
2 changes: 1 addition & 1 deletion mypy/errorcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def __hash__(self) -> int:
"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 experessions", "General"
"top-level-await", "Warn about top level await expressions", "General"
)

# These error codes aren't enabled by default.
Expand Down
Loading