Skip to content

Commit 310b914

Browse files
authored
Add missing docs for error codes (#15539)
I am adding these mostly to get rid of the allowlist in `html_builder.py`, please feel free to tweak these docs, cc @JukkaL @hauntsaninja @JelleZijlstra
1 parent 4012c50 commit 310b914

File tree

4 files changed

+125
-14
lines changed

4 files changed

+125
-14
lines changed

docs/source/error_code_list.rst

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,38 @@ Example:
323323
else:
324324
raise ValueError('not defined for zero')
325325
326+
.. _code-empty-body:
327+
328+
Check that functions don't have empty bodies outside stubs [empty-body]
329+
-----------------------------------------------------------------------
330+
331+
This error code is similar to the ``[return]`` code but is emitted specifically
332+
for functions and methods with empty bodies (if they are annotated with
333+
non-trivial return type). Such a distinction exists because in some contexts
334+
an empty body can be valid, for example for an abstract method or in a stub
335+
file. Also old versions of mypy used to unconditionally allow functions with
336+
empty bodies, so having a dedicated error code simplifies cross-version
337+
compatibility.
338+
339+
Note that empty bodies are allowed for methods in *protocols*, and such methods
340+
are considered implicitly abstract:
341+
342+
.. code-block:: python
343+
344+
from abc import abstractmethod
345+
from typing import Protocol
346+
347+
class RegularABC:
348+
@abstractmethod
349+
def foo(self) -> int:
350+
pass # OK
351+
def bar(self) -> int:
352+
pass # Error: Missing return statement [empty-body]
353+
354+
class Proto(Protocol):
355+
def bar(self) -> int:
356+
pass # OK
357+
326358
.. _code-return-value:
327359

328360
Check that return value is compatible [return-value]
@@ -947,6 +979,28 @@ otherwise unused variable:
947979
948980
_ = f() # No error
949981
982+
.. _code-top-level-await:
983+
984+
Warn about top level await expressions [top-level-await]
985+
--------------------------------------------------------
986+
987+
This error code is separate from the general ``[syntax]`` errors, because in
988+
some environments (e.g. IPython) a top level ``await`` is allowed. In such
989+
environments a user may want to use ``--disable-error-code=top-level-await``,
990+
that allows to still have errors for other improper uses of ``await``, for
991+
example:
992+
993+
.. code-block:: python
994+
995+
async def f() -> None:
996+
...
997+
998+
top = await f() # Error: "await" outside function [top-level-await]
999+
1000+
def g() -> None:
1001+
# This is a blocker error and cannot be silenced.
1002+
await f() # Error: "await" outside coroutine ("async def")
1003+
9501004
.. _code-assert-type:
9511005

9521006
Check types in assert_type [assert-type]
@@ -978,6 +1032,27 @@ Functions will always evaluate to true in boolean contexts.
9781032
if f: # Error: Function "Callable[[], Any]" could always be true in boolean context [truthy-function]
9791033
pass
9801034
1035+
.. _code-str-format:
1036+
1037+
Check that string formatting/interpolation is type-safe [str-format]
1038+
--------------------------------------------------------------------
1039+
1040+
Mypy will check that f-strings, ``str.format()`` calls, and ``%`` interpolations
1041+
are valid (when corresponding template is a literal string). This includes
1042+
checking number and types of replacements, for example:
1043+
1044+
.. code-block:: python
1045+
1046+
# Error: Cannot find replacement for positional format specifier 1 [str-format]
1047+
"{} and {}".format("spam")
1048+
"{} and {}".format("spam", "eggs") # OK
1049+
# Error: Not all arguments converted during string formatting [str-format]
1050+
"{} and {}".format("spam", "eggs", "cheese")
1051+
1052+
# Error: Incompatible types in string interpolation
1053+
# (expression has type "float", placeholder has type "int") [str-format]
1054+
"{:d}".format(3.14)
1055+
9811056
.. _code-str-bytes-safe:
9821057

9831058
Check for implicit bytes coercions [str-bytes-safe]
@@ -998,6 +1073,28 @@ Warn about cases where a bytes object may be converted to a string in an unexpec
9981073
print(f"The alphabet starts with {b!r}") # The alphabet starts with b'abc'
9991074
print(f"The alphabet starts with {b.decode('utf-8')}") # The alphabet starts with abc
10001075
1076+
.. _code-annotation-unchecked:
1077+
1078+
Notify about an annotation in an unchecked function [annotation-unchecked]
1079+
--------------------------------------------------------------------------
1080+
1081+
Sometimes a user may accidentally omit an annotation for a function, and mypy
1082+
will not check the body of this function (unless one uses
1083+
:option:`--check-untyped-defs <mypy --check-untyped-defs>` or
1084+
:option:`--disallow-untyped-defs <mypy --disallow-untyped-defs>`). To avoid
1085+
such situations go unnoticed, mypy will show a note, if there are any type
1086+
annotations in an unchecked function:
1087+
1088+
.. code-block:: python
1089+
1090+
def test_assignment(): # "-> None" return annotation is missing
1091+
# Note: By default the bodies of untyped functions are not checked,
1092+
# consider using --check-untyped-defs [annotation-unchecked]
1093+
x: int = "no way"
1094+
1095+
Note that mypy will still exit with return code ``0``, since such behaviour is
1096+
specified by :pep:`484`.
1097+
10011098
.. _code-syntax:
10021099

10031100
Report syntax errors [syntax]

docs/source/error_code_list2.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,32 @@ mypy generates an error if it thinks that an expression is redundant.
255255
[i for i in range(x) if isinstance(i, int)]
256256
257257
258+
.. _code-possibly-undefined:
259+
260+
Warn about variables that are defined only in some execution paths [possibly-undefined]
261+
---------------------------------------------------------------------------------------
262+
263+
If you use :option:`--enable-error-code possibly-undefined <mypy --enable-error-code>`,
264+
mypy generates an error if it cannot verify that a variable will be defined in
265+
all execution paths. This includes situations when a variable definition
266+
appears in a loop, in a conditional branch, in an except handler, etc. For
267+
example:
268+
269+
.. code-block:: python
270+
271+
# Use "mypy --enable-error-code possibly-undefined ..."
272+
273+
from typing import Iterable
274+
275+
def test(values: Iterable[int], flag: bool) -> None:
276+
if flag:
277+
a = 1
278+
z = a + 1 # Error: Name "a" may be undefined [possibly-undefined]
279+
280+
for v in values:
281+
b = v
282+
z = b + 1 # Error: Name "b" may be undefined [possibly-undefined]
283+
258284
.. _code-truthy-bool:
259285

260286
Check that expression is not implicitly true in boolean context [truthy-bool]

docs/source/html_builder.py

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,7 @@ def write_doc(self, docname: str, doctree: document) -> None:
2323
def _verify_error_codes(self) -> None:
2424
from mypy.errorcodes import error_codes
2525

26-
known_missing = {
27-
# TODO: fix these before next release
28-
"annotation-unchecked",
29-
"empty-body",
30-
"possibly-undefined",
31-
"str-format",
32-
"top-level-await",
33-
}
34-
missing_error_codes = {
35-
c
36-
for c in error_codes
37-
if f"code-{c}" not in self._ref_to_doc and c not in known_missing
38-
}
26+
missing_error_codes = {c for c in error_codes if f"code-{c}" not in self._ref_to_doc}
3927
if missing_error_codes:
4028
raise ValueError(
4129
f"Some error codes are not documented: {', '.join(sorted(missing_error_codes))}"

mypy/errorcodes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def __hash__(self) -> int:
144144
"safe-super", "Warn about calls to abstract methods with empty/trivial bodies", "General"
145145
)
146146
TOP_LEVEL_AWAIT: Final = ErrorCode(
147-
"top-level-await", "Warn about top level await experessions", "General"
147+
"top-level-await", "Warn about top level await expressions", "General"
148148
)
149149

150150
# These error codes aren't enabled by default.

0 commit comments

Comments
 (0)