First steps
Type system reference
Configuring and running mypy
Miscellaneous
Project Links
InDynamic vs static typing, we discussed how bodies of functionsthat don’t have any explicit type annotations in their function are “dynamically typed”and that mypy will not check them. In this section, we’ll talk a little bit moreabout what that means and how you can enable dynamic typing on a more fine grained basis.
In cases where your code is too magical for mypy to understand, you can make avariable or parameter dynamically typed by explicitly giving it the typeAny. Mypy will let you do basically anything with a value of typeAny,including assigning a value of typeAny to a variable of any type (or viceversa).
fromtypingimportAnynum=1# Statically typed (inferred to be int)num='x'# error: Incompatible types in assignment (expression has type "str", variable has type "int")dyn:Any=1# Dynamically typed (type Any)dyn='x'# OKnum=dyn# No error, mypy will let you assign a value of type Any to any variablenum+=1# Oops, mypy still thinks num is an int
You can think ofAny as a way to locally disable type checking.SeeSilencing type errors for other ways you can shut upthe type checker.
You can do anything using a value with typeAny, and the type checkerwill not complain:
deff(x:Any)->int:# All of these are valid!x.foobar(1,y=2)print(x[3]+'f')ifx:x.z=x(2)open(x).read()returnx
Values derived from anAny value also usually have the typeAnyimplicitly, as mypy can’t infer a more precise result type. Forexample, if you get the attribute of anAny value or call aAny value the result isAny:
deff(x:Any)->None:y=x.foo()reveal_type(y)# Revealed type is "Any"z=y.bar("mypy will let you do anything to y")reveal_type(z)# Revealed type is "Any"
Any types may propagate through your program, making type checkingless effective, unless you are careful.
Function parameters without annotations are also implicitlyAny:
deff(x)->None:reveal_type(x)# Revealed type is "Any"x.can.do["anything",x]("wants",2)
You can make mypy warn you about untyped function parameters using the--disallow-untyped-defs flag.
Generic types missing type parameters will have those parameters implicitlytreated asAny:
deff(x:list)->None:reveal_type(x)# Revealed type is "builtins.list[Any]"reveal_type(x[0])# Revealed type is "Any"x[0].anything_goes()# OK
You can make mypy warn you about missing generic parameters using the--disallow-any-generics flag.
Finally, another major source ofAny types leaking into your program is fromthird party libraries that mypy does not know about. This is particularly the casewhen using the--ignore-missing-importsflag. SeeMissing imports for more information about this.
The typeobject is another type that can have an instance of arbitrarytype as a value. UnlikeAny,object is an ordinary static type (itis similar toObject in Java), and only operations valid foralltypes are accepted forobject values. These are all valid:
deff(o:object)->None:ifo:print(o)print(isinstance(o,int))o=2o='foo'
These are, however, flagged as errors, since not all objects support theseoperations:
deff(o:object)->None:o.foo()# Error!o+2# Error!open(o)# Error!n:int=1n=o# Error!
If you’re not sure whether you need to useobject orAny, useobject – only switch to usingAny if you get a type checkercomplaint.
You can use differenttype narrowingtechniques to narrowobject to a more specifictype (subtype) such asint. Type narrowing is not needed withdynamically typed values (values with typeAny).