First steps
Type system reference
Configuring and running mypy
Miscellaneous
Project Links
This section documents various errors codes that mypy generates onlyif you enable certain options. SeeError codes for generaldocumentation about error codes and their configuration.Error codes enabled by default documents error codes that are enabled by default.
Note
The examples in this section useinline configuration to specify mypy options. You can also set the sameoptions by using aconfiguration file orcommand-line options.
If you use--disallow-any-generics, mypy requires that each generictype has values for each type argument. For example, the typeslist ordict would be rejected. You should instead use types likelist[int] ordict[str,int]. Any omitted generic type arguments get implicitAnyvalues. The typelist is equivalent tolist[Any], and so on.
Example:
# mypy: disallow-any-generics# Error: Missing type parameters for generic type "list" [type-arg]defremove_dups(items:list)->list:...
If you use--disallow-untyped-defs, mypy requires that all functionshave annotations (either a Python 3 annotation or a type comment).
Example:
# mypy: disallow-untyped-defsdefinc(x):# Error: Function is missing a type annotation [no-untyped-def]returnx+1definc_ok(x:int)->int:# OKreturnx+1classCounter:# Error: Function is missing a type annotation [no-untyped-def]def__init__(self):self.value=0classCounterOk:# OK: An explicit "-> None" is needed if "__init__" takes no argumentsdef__init__(self)->None:self.value=0
If you use--warn-redundant-casts, mypy will generate an error if the sourcetype of a cast is the same as the target type.
Example:
# mypy: warn-redundant-castsfromtypingimportcastCount=intdefexample(x:Count)->int:# Error: Redundant cast to "int" [redundant-cast]returncast(int,x)
If a method uses theSelf type in the return type or the type of anon-self argument, there is no need to annotate theself argumentexplicitly. Such annotations are allowed byPEP 673 but areredundant. If you enable this error code, mypy will generate an error ifthere is a redundantSelf type.
Example:
# mypy: enable-error-code="redundant-self"fromtypingimportSelfclassC:# Error: Redundant "Self" annotation for the first method argumentdefcopy(self:Self)->Self:returntype(self)()
If you use--strict-equality, mypy will generate an error if itthinks that a comparison operation is always true or false. These areoften bugs. Sometimes mypy is too picky and the comparison canactually be useful. Instead of disabling strict equality checkingeverywhere, you can use#type:ignore[comparison-overlap] toignore the issue on a particular line only.
Example:
# mypy: strict-equalitydefis_magic(x:bytes)->bool:# Error: Non-overlapping equality check (left operand type: "bytes",# right operand type: "str") [comparison-overlap]returnx=='magic'
We can fix the error by changing the string literal to a bytesliteral:
# mypy: strict-equalitydefis_magic(x:bytes)->bool:returnx==b'magic'# OK
--strict-equality does not include comparisons withNone:
# mypy: strict-equalitydefis_none(x:str)->bool:returnxisNone# OK
If you want such checks, you must also activate--strict-equality-for-none (we might mergethese two options later).
# mypy: strict-equality strict-equality-for-nonedefis_none(x:str)->bool:# Error: Non-overlapping identity check# (left operand type: "str", right operand type: "None")returnxisNone
If you use--disallow-untyped-calls, mypy generates an error when youcall an unannotated function in an annotated function.
Example:
# mypy: disallow-untyped-callsdefdo_it()->None:# Error: Call to untyped function "bad" in typed context [no-untyped-call]bad()defbad():...
If you use--warn-return-any, mypy generates an error if you return avalue with anAny type in a function that is annotated to return anon-Any value.
Example:
# mypy: warn-return-anydeffields(s):returns.split(',')deffirst_field(x:str)->str:# Error: Returning Any from function declared to return "str" [no-any-return]returnfields(x)[0]
If you use--disallow-any-unimported, mypy generates an error if a component ofa type becomesAny 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 moduleanimals, which meansthatCat falls back toAny in a type annotation:
# mypy: disallow-any-unimportedfromanimalsimportCat# type: ignore# Error: Argument 1 to "feed" becomes "Any" due to an unfollowed import [no-any-unimported]deffeed(cat:Cat)->None:...
If you use--warn-unreachable, mypy generates an error if itthinks that a statement or expression will never be executed. In most cases, this is due toincorrect control flow or conditional checks that are accidentally always true or false.
# mypy: warn-unreachabledefexample(x:int)->None:# Error: Right operand of "or" is never evaluated [unreachable]assertisinstance(x,int)orx=='unused'return# Error: Statement is unreachable [unreachable]print('unreachable')
If you use--enable-error-codedeprecated,mypy generates an error if your code imports a deprecated feature explicitly with afrommodimportdepr statement or uses a deprecated feature imported otherwise or definedlocally. Features are considered deprecated when decorated withwarnings.deprecated, asspecified inPEP 702.Use the--report-deprecated-as-note option toturn all such errors into notes.Use--deprecated-calls-exclude to hide warningsfor specific functions, classes and packages.
Note
Thewarnings module provides the@deprecated decorator since Python 3.13.To use it with older Python versions, import it fromtyping_extensions instead.
Examples:
# mypy: report-deprecated-as-error# Error: abc.abstractproperty is deprecated: Deprecated, use 'property' with 'abstractmethod' insteadfromabcimportabstractpropertyfromtyping_extensionsimportdeprecated@deprecated("use new_function")defold_function()->None:print("I am old")# Error: __main__.old_function is deprecated: use new_functionold_function()old_function()# type: ignore[deprecated]
If you use--enable-error-coderedundant-expr,mypy generates an error if it thinks that an expression is redundant.
# mypy: enable-error-code="redundant-expr"defexample(x:int)->None:# Error: Left operand of "and" is always true [redundant-expr]ifisinstance(x,int)andx>0:pass# Error: If condition is always true [redundant-expr]1ifisinstance(x,int)else0# Error: If condition in comprehension is always true [redundant-expr][iforiinrange(x)ifisinstance(i,int)]
If you use--enable-error-codepossibly-undefined,mypy generates an error if it cannot verify that a variable will be defined inall execution paths. This includes situations when a variable definitionappears in a loop, in a conditional branch, in an except handler, etc. Forexample:
# mypy: enable-error-code="possibly-undefined"fromcollections.abcimportIterabledeftest(values:Iterable[int],flag:bool)->None:ifflag:a=1z=a+1# Error: Name "a" may be undefined [possibly-undefined]forvinvalues:b=vz=b+1# Error: Name "b" may be undefined [possibly-undefined]
Warn when the type of an expression in a boolean context does notimplement__bool__ or__len__. Unless one of these isimplemented by a subtype, the expression will always be consideredtrue, and there may be a bug in the condition.
As an exception, theobject type is allowed in a boolean context.Using an iterable value in a boolean context has a separate error code(see below).
# mypy: enable-error-code="truthy-bool"classFoo:passfoo=Foo()# Error: "foo" has type "Foo" which does not implement __bool__ or __len__ so it could always be true in boolean contextiffoo:...
Generate an error if a value of typeIterable is used as a booleancondition, sinceIterable does not implement__len__ or__bool__.
Example:
fromcollections.abcimportIterabledeftransform(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]ifnotitems:return[42]return[x+1forxinitems]
Iftransform is called with aGenerator argument, such asint(x)forxin[], this function would not return[42] unlikewhat might be intended. Of course, it’s possible thattransform isonly called withlist or other container objects, and theifnotitems check is actually valid. If that is the case, it isrecommended to annotateitems asCollection[int] instead ofIterable[int].
#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 theexpected errors are silenced.
Example:
# mypy: enable-error-code="ignore-without-code"classFoo:def__init__(self,name:str)->None:self.name=namef=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]
If you use--enable-error-codeunused-awaitable,mypy generates an error if you don’t use a returned value that defines__await__.
Example:
# mypy: enable-error-code="unused-awaitable"importasyncioasyncdeff()->int:...asyncdefg()->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 tosilence the error:
asyncdefg()->None:_=asyncio.create_task(f())# No error
#type:ignore comment is used [unused-ignore]¶If you use--enable-error-codeunused-ignore,or--warn-unused-ignoresmypy generates an error if you don’t use a#type:ignore comment, i.e. ifthere is a comment, but there would be no error generated by mypy on this lineanyway.
Example:
# Use "mypy --warn-unused-ignores ..."defadd(a:int,b:int)->int:# Error: unused "type: ignore" commentreturna+b# type: ignore
Note that due to a specific nature of this comment, the only way to selectivelysilence it, is to include the error code explicitly. Also note that this error isnot shown if the#type:ignore is not used due to code being staticallyunreachable (e.g. due to platform or version checks).
Example:
# Use "mypy --warn-unused-ignores ..."importsystry:# The "[unused-ignore]" is needed to get a clean mypy run# on both Python 3.8, and 3.9 where this module was addedimportgraphlib# type: ignore[import,unused-ignore]exceptImportError:passifsys.version_info>=(3,9):# The following will not generate an error on either# Python 3.8, or Python 3.942+"testing..."# type: ignore
@override is used when overriding a base class method [explicit-override]¶If you use--enable-error-codeexplicit-overridemypy 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__. SeePEP 698.
Note
Starting with Python 3.12, the@override decorator can be imported fromtyping.To use it with older Python versions, import it fromtyping_extensions instead.
Example:
# mypy: enable-error-code="explicit-override"fromtypingimportoverrideclassParent:deff(self,x:int)->None:passdefg(self,y:int)->None:passclassChild(Parent):deff(self,x:int)->None:# Error: Missing @override decoratorpass@overridedefg(self,y:int)->None:pass
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 beflagged when this error code is enabled:
fromtypingimportAnyclassC:x:floaty:floatz:floatclassD(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# OKz:Any# OKdeff(c:C)->None:c.x=1.1d=D()f(d)d.x>>1# This will crash at runtime, because d.x is now float, not an int
reveal_type is imported from typing or typing_extensions [unimported-reveal]¶Mypy used to havereveal_type as a special builtinthat only existed during type-checking.In runtime it fails with expectedNameError,which can cause real problem in production, hidden from mypy.
But, in Python3.11typing.reveal_type() was added.typing_extensions ported this helper to all supported Python versions.
Now users can actually importreveal_type to make the runtime code safe.
Note
Starting with Python 3.11, thereveal_type function can be imported fromtyping.To use it with older Python versions, import it fromtyping_extensions instead.
# mypy: enable-error-code="unimported-reveal"x=1reveal_type(x)# Note: Revealed type is "builtins.int" \# Error: Name "reveal_type" is not defined
Correct usage:
# mypy: enable-error-code="unimported-reveal"fromtypingimportreveal_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, usingreveal_locals is always an error,because there’s no way one can import it.
If you use--disallow-any-explicit, mypy generates an errorif you use an explicitAny type annotation.
Example:
# mypy: disallow-any-explicitfromtypingimportAnyx:Any=1# Error: Explicit "Any" type annotation [explicit-any]
If enabled with--enable-error-codeexhaustive-match,mypy generates an error if a match statement does not match all possible cases/types.
Example:
importenumclassColor(enum.Enum):RED=1BLUE=2val:Color=Color.RED# OK without --enable-error-code exhaustive-matchmatchval:caseColor.RED:print("red")# With --enable-error-code exhaustive-match# Error: Match statement has unhandled case for values of type "Literal[Color.BLUE]"matchval:caseColor.RED:print("red")# OK with or without --enable-error-code exhaustive-match, since all cases are handledmatchval:caseColor.RED:print("red")case_:print("other")
If enabled with--disallow-untyped-decoratorsmypy 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:
defprinting_decorator(func):defwrapper(*args,**kwds):print("Calling",func)returnfunc(*args,**kwds)returnwrapper# A decorated function.@printing_decorator# E: Untyped decorator makes function "add_forty_two" untyped [untyped-decorator]defadd_forty_two(value:int)->int:returnvalue+42
#type:ignore include an error code [ignore-without-code]#type:ignore comment is used [unused-ignore]@override is used when overriding a base class method [explicit-override]reveal_type is imported from typing or typing_extensions [unimported-reveal]