Movatterモバイル変換


[0]ホーム

URL:


ContentsMenuExpandLight modeDark modeAuto light/dark, in light modeAuto light/dark, in dark modeSkip to content
mypy 1.16.1 documentation
Logo
mypy 1.16.1 documentation

First steps

Type system reference

Configuring and running mypy

Miscellaneous

Project Links

Back to top

Running mypy and managing imports

TheGetting started page should have already introduced youto the basics of how to run mypy – pass in the files and directoriesyou want to type check via the command line:

$ mypy foo.py bar.py some_directory

This page discusses in more detail how exactly to specify what filesyou want mypy to type check, how mypy discovers imported modules,and recommendations on how to handle any issues you may encounteralong the way.

If you are interested in learning about how to configure theactual way mypy type checks your code, see ourThe mypy command line guide.

Specifying code to be checked

Mypy lets you specify what files it should type check in several different ways.

  1. First, you can pass in paths to Python files and directories youwant to type check. For example:

    $ mypy file_1.py foo/file_2.py file_3.pyi some/directory

    The above command tells mypy it should type check all of the providedfiles together. In addition, mypy will recursively type check theentire contents of any provided directories.

    For more details about how exactly this is done, seeMapping file paths to modules.

  2. Second, you can use the-m flag (long form:--module) tospecify a module name to be type checked. The name of a moduleis identical to the name you would use to import that modulewithin a Python program. For example, running:

    $ mypy -m html.parser

    …will type check the modulehtml.parser (this happens to bea library stub).

    Mypy will use an algorithm very similar to the one Python uses tofind where modules and imports are located on the file system.For more details, seeHow imports are found.

  3. Third, you can use the-p (long form:--package) flag tospecify a package to be (recursively) type checked. This flagis almost identical to the-m flag except that if you give ita package name, mypy will recursively type check all submodulesand subpackages of that package. For example, running:

    $ mypy -p html

    …will type check the entirehtml package (of library stubs).In contrast, if we had used the-m flag, mypy would have typechecked justhtml’s__init__.py file and anything importedfrom there.

    Note that we can specify multiple packages and modules on thecommand line. For example:

    $ mypy --package p.a --package p.b --module c
  4. Fourth, you can also instruct mypy to directly type check smallstrings as programs by using the-c (long form:--command)flag. For example:

    $ mypy -c 'x = [1, 2]; print(x())'

    …will type check the above string as a mini-program (and in this case,will report thatlist[int] is not callable).

You can also use thefiles option in yourmypy.ini file to specify whichfiles to check, in which case you can simply runmypy with no arguments.

Reading a list of files from a file

Finally, any command-line argument starting with@ reads additionalcommand-line arguments from the file following the@ character.This is primarily useful if you have a file containing a list of filesthat you want to be type-checked: instead of using shell syntax like:

$ mypy $(cat file_of_files.txt)

you can use this instead:

$ mypy @file_of_files.txt

This file can technically also contain any command line flag, notjust file paths. However, if you want to configure many differentflags, the recommended approach is to use aconfiguration file instead.

Mapping file paths to modules

One of the main ways you can tell mypy what to type checkis by providing mypy a list of paths. For example:

$ mypy file_1.py foo/file_2.py file_3.pyi some/directory

This section describes how exactly mypy maps the provided pathsto modules to type check.

  • Mypy will check all paths provided that correspond to files.

  • Mypy will recursively discover and check all files ending in.py or.pyi in directory paths provided, after accounting for--exclude.

  • For each file to be checked, mypy will attempt to associate the file (e.g.project/foo/bar/baz.py) with a fully qualified module name (e.g.foo.bar.baz). The directory the package is in (project) is thenadded to mypy’s module search paths.

How mypy determines fully qualified module names depends on if the options--no-namespace-packages and--explicit-package-bases are set.

  1. If--no-namespace-packages is set,mypy will rely solely upon the presence of__init__.py[i] files todetermine the fully qualified module name. That is, mypy will crawl up thedirectory tree for as long as it continues to find__init__.py (or__init__.pyi) files.

    For example, if your directory tree consists ofpkg/subpkg/mod.py, mypywould requirepkg/__init__.py andpkg/subpkg/__init__.py to exist inorder correctly associatemod.py withpkg.subpkg.mod

  2. The default case. If--namespace-packages is on, but--explicit-package-bases is off, mypy will allow for the possibility thatdirectories without__init__.py[i] are packages. Specifically, mypy willlook at all parent directories of the file and use the location of thehighest__init__.py[i] in the directory tree to determine the top-levelpackage.

    For example, say your directory tree consists solely ofpkg/__init__.pyandpkg/a/b/c/d/mod.py. When determiningmod.py’s fully qualifiedmodule name, mypy will look atpkg/__init__.py and conclude that theassociated module name ispkg.a.b.c.d.mod.

  3. You’ll notice that the above case still relies on__init__.py. Ifyou can’t put an__init__.py in your top-level package, but still wish topass paths (as opposed to packages or modules using the-p or-mflags),--explicit-package-basesprovides a solution.

    With--explicit-package-bases, mypywill locate the nearest parent directory that is a member of theMYPYPATHenvironment variable, themypy_path config or is the currentworking directory. Mypy will then use the relative path to determine thefully qualified module name.

    For example, say your directory tree consists solely ofsrc/namespace_pkg/mod.py. If you run the following command, mypywill correctly associatemod.py withnamespace_pkg.mod:

    $ MYPYPATH=src mypy --namespace-packages --explicit-package-bases .

If you pass a file not ending in.py[i], the module name assumed is__main__ (matching the behavior of the Python interpreter), unless--scripts-are-modules is passed.

Passing-v will show you the files and associated modulenames that mypy will check.

How mypy handles imports

When mypy encounters animport statement, it will firstattempt to locate that moduleor type stubs for that module in the file system. Mypy will thentype check the imported module. There are three different outcomesof this process:

  1. Mypy is unable to follow the import: the module either does notexist, or is a third party library that does not use type hints.

  2. Mypy is able to follow and type check the import, but you didnot want mypy to type check that module at all.

  3. Mypy is able to successfully both follow and type check themodule, and you want mypy to type check that module.

The third outcome is what mypy will do in the ideal case. The followingsections will discuss what to do in the other two cases.

Missing imports

When you import a module, mypy may report that it is unable to followthe import. This can cause errors that look like the following:

main.py:1: error: Skipping analyzing 'django': module is installed, but missing library stubs or py.typed markermain.py:2: error: Library stubs not installed for "requests"main.py:3: error: Cannot find implementation or library stub for module named "this_module_does_not_exist"

If you get any of these errors on an import, mypy will assume the type of thatmodule isAny, the dynamic type. This means attempting to access anyattribute of the module will automatically succeed:

# Error: Cannot find implementation or library stub for module named 'does_not_exist'importdoes_not_exist# But this type checks, and x will have type 'Any'x=does_not_exist.foobar()

This can result in mypy failing to warn you about errors in your code. Sinceoperations onAny result inAny, these dynamic types can propagatethrough your code, making type checking less effective. SeeDynamically typed code for more information.

The next sections describe what each of these errors means and recommended next steps; scroll tothe section that matches your error.

Missing library stubs or py.typed marker

If you are getting aSkippinganalyzingX:moduleisinstalled,butmissinglibrarystubsorpy.typedmarker,error, this means mypy was able to find the module you were importing, but nocorresponding type hints.

Mypy will not try inferring the types of any 3rd party libraries you have installedunless they either have declared themselves to bePEP 561 compliant stub package (e.g. with apy.typed file) or have registeredthemselves ontypeshed, the repositoryof types for the standard library and some 3rd party libraries.

If you are getting this error, try to obtain type hints for the library you’re using:

  1. Upgrading the version of the library you’re using, in case a newer versionhas started to include type hints.

  2. Searching to see if there is aPEP 561 compliant stub packagecorresponding to your third party library. Stub packages let you installtype hints independently from the library itself.

    For example, if you want type hints for thedjango library, you caninstall thedjango-stubs package.

  3. Writing your own stub files containing type hints forthe library. You can point mypy at your type hints either by passingthem in via the command line, by using thefiles ormypy_pathconfig file options, or byadding the location to theMYPYPATH environment variable.

    These stub files do not need to be complete! A good strategy is to usestubgen, a program that comes bundled with mypy, to generate a firstrough draft of the stubs. You can then iterate on just the parts of thelibrary you need.

    If you want to share your work, you can try contributing your stubs backto the library – see our documentation on creatingPEP 561 compliant packages.

  4. Force mypy to analyze the library as best as it can (as if the library providedapy.typed file), despite it likely missing any type annotations. In general,the quality of type checking will be poor and mypy may have issues whenanalyzing code not designed to be type checked.

    You can do this via setting the--follow-untyped-importscommand line flag orfollow_untyped_imports config file option to True.This option can be specified on a per-module basis as well:

    [mypy-untyped_package.*]follow_untyped_imports=True
    [[tool.mypy.overrides]]module=["untyped_package.*"]follow_untyped_imports=true

If you are unable to find any existing type hints nor have time to write yourown, you can insteadsuppress the errors.

All this will do is make mypy stop reporting an error on the line containing theimport: the imported module will continue to be of typeAny, and mypy maynot catch errors in its use.

  1. To suppress asingle missing import error, add a#type:ignore at the end of theline containing the import.

  2. To suppressall missing import errors from a single library, adda per-module section to yourmypy config file settingignore_missing_imports to True for that library. For example,suppose your codebasemakes heavy use of an (untyped) library namedfoobar. You can silenceall import errors associated with that library and that library alone byadding the following section to your config file:

    [mypy-foobar.*]ignore_missing_imports=True
    [[tool.mypy.overrides]]module=["foobar.*"]ignore_missing_imports=true

    Note: this option is equivalent to adding a#type:ignore to everyimport offoobar in your codebase. For more information, see thedocumentation about configuringimport discovery in config files.The.* afterfoobar will ignore imports offoobar modulesand subpackages in addition to thefoobar top-level package namespace.

  3. To suppressall missing import errors forall untyped librariesin your codebase, use--disable-error-code=import-untyped.SeeCheck that import target can be found [import-untyped] for more details on this error code.

    You can also setdisable_error_code, like so:

    [mypy]disable_error_code=import-untyped
    [tool.mypy]disable_error_code=["import-untyped"]

    You can also set the--ignore-missing-importscommand line flag or set theignore_missing_imports config fileoption to True in theglobal section of your mypy config file. Werecommend avoiding--ignore-missing-imports if possible: it’s equivalentto adding a#type:ignore to all unresolved imports in your codebase.

Library stubs not installed

If mypy can’t find stubs for a third-party library, and it knows that stubs exist forthe library, you will get a message like this:

main.py:1: error: Library stubs not installed for "yaml"main.py:1: note: Hint: "python3 -m pip install types-PyYAML"main.py:1: note: (or run "mypy --install-types" to install all missing stub packages)

You can resolve the issue by running the suggested pip commands.If you’re running mypy in CI, you can ensure the presence of any stub packagesyou need the same as you would any other test dependency, e.g. by adding them tothe appropriaterequirements.txt file.

Alternatively, add the--install-typesto your mypy command to install all known missing stubs:

mypy --install-types

This is slower than explicitly installing stubs, since it effectivelyruns mypy twice – the first time to find the missing stubs, andthe second time to type check your code properly after mypy hasinstalled the stubs. It also can make controlling stub versions harder,resulting in less reproducible type checking.

By default,--install-types shows a confirmation prompt.Use--non-interactive to install all suggestedstub packages without asking for confirmationand type check your code:

If you’ve already installed the relevant third-party libraries in an environmentother than the one mypy is running in, you can use--python-executable flag to point to the Python executable for thatenvironment, and mypy will find packages installed for that Python executable.

If you’ve installed the relevant stub packages and are still getting this error,see thesection below.

Cannot find implementation or library stub

If you are getting aCannotfindimplementationorlibrarystubformoduleerror, this means mypy was not able to find the module you are trying toimport, whether it comes bundled with type hints or not. If you are gettingthis error, try:

  1. Making sure your import does not contain a typo.

  2. If the module is a third party library, making sure that mypy is ableto find the interpreter containing the installed library.

    For example, if you are running your code in a virtualenv, make sureto install and use mypy within the virtualenv. Alternatively, if youwant to use a globally installed mypy, set the--python-executable commandline flag to point the Python interpreter containing your installedthird party packages.

    You can confirm that you are running mypy from the environment you expectby running it likepython-mmypy.... You can confirm that you areinstalling into the environment you expect by running pip likepython-mpip....

  3. Reading theHow imports are found section below to make sure youunderstand how exactly mypy searches for and finds modules and modifyhow you’re invoking mypy accordingly.

  4. Directly specifying the directory containing the module you want totype check from the command line, by using themypy_pathorfiles config file options,or by using theMYPYPATH environment variable.

    Note: if the module you are trying to import is actually asubmodule ofsome package, you should specify the directory containing theentire package.For example, suppose you are trying to add the modulefoo.bar.bazwhich is located at~/foo-project/src/foo/bar/baz.py. In this case,you must runmypy~/foo-project/src (or set theMYPYPATH to~/foo-project/src).

How imports are found

When mypy encounters animport statement or receives modulenames from the command line via the--module or--packageflags, mypy tries to find the module on the file system similarto the way Python finds it. However, there are some differences.

First, mypy has its own search path.This is computed from the following items:

  • TheMYPYPATH environment variable(a list of directories, colon-separated on UNIX systems, semicolon-separated on Windows).

  • Themypy_path config file option.

  • The directories containing the sources given on the command line(seeMapping file paths to modules).

  • The installed packages marked as safe for type checking (seePEP 561 support)

  • The relevant directories of thetypeshed repo.

Note

You cannot point to a stub-only package (PEP 561) via theMYPYPATH, it must beinstalled (seePEP 561 support)

Second, mypy searches for stub files in addition to regular Python filesand packages.The rules for searching for a modulefoo are as follows:

  • The search looks in each of the directories in the search path(see above) until a match is found.

  • If a package namedfoo is found (i.e. a directoryfoo containing an__init__.py or__init__.pyi file)that’s a match.

  • If a stub file namedfoo.pyi is found, that’s a match.

  • If a Python module namedfoo.py is found, that’s a match.

These matches are tried in order, so that if multiple matches are foundin the same directory on the search path(e.g. a package and a Python file, or a stub file and a Python file)the first one in the above list wins.

In particular, if a Python file and a stub file are both present in thesame directory on the search path, only the stub file is used.(However, if the files are in different directories, the one foundin the earlier directory is used.)

Settingmypy_path/MYPYPATH is mostly useful in the casewhere you want to try running mypy against multiple distinctsets of files that happen to share some common dependencies.

For example, if you have multiple projects that happen to beusing the same set of work-in-progress stubs, it could beconvenient to just have yourMYPYPATH point to a singledirectory containing the stubs.

Following imports

Mypy is designed todoggedly follow all imports,even if the imported module is not a file you explicitly wanted mypy to check.

For example, suppose we have two modulesmycode.foo andmycode.bar:the former has type hints and the latter does not. We runmypy-mmycode.foo and mypy discovers thatmycode.foo importsmycode.bar.

How do we want mypy to type checkmycode.bar? Mypy’s behaviour here isconfigurable – although westrongly recommend using the default –by using the--follow-imports flag. This flagaccepts one of four string values:

  • normal (the default, recommended) follows all imports normally andtype checks all top level code (as well as the bodies of allfunctions and methods with at least one type annotation inthe signature).

  • silent behaves in the same way asnormal but willadditionallysuppress any error messages.

  • skip willnot follow imports and instead will silentlyreplace the module (andanything imported from it) with anobject of typeAny.

  • error behaves in the same way asskip but is not quite assilent – it will flag the import as an error, like this:

    main.py:1:note:Importof"mycode.bar"ignoredmain.py:1:note:(Using--follow-imports=error,modulenotpassedoncommandline)

If you are starting a new codebase and plan on using type hints fromthe start, werecommend you use either--follow-imports=normal(the default) or--follow-imports=error. Either option will helpmake sure you are not skipping checking any part of your codebase byaccident.

If you are planning on adding type hints to a large, existing code base,we recommend you start by trying to make your entire codebase (includingfiles that do not use type hints) pass under--follow-imports=normal.This is usually not too difficult to do: mypy is designed to report asfew error messages as possible when it is looking at unannotated code.

Only if doing this is intractable, try passing mypy just the filesyou want to type check and using--follow-imports=silent.Even if mypy is unable to perfectly type check a file, it can still glean someuseful information by parsing it (for example, understanding what methodsa given object has). SeeUsing mypy with an existing codebase for more recommendations.

Adjusting import following behaviour is often most useful when restricted tospecific modules. This can be accomplished by setting a per-modulefollow_imports config option.

Warning

We do not recommend usingfollow_imports=skip unless you’re really sureyou know what you are doing. This option greatly restricts the analysis mypycan perform and you will lose a lot of the benefits of type checking.

This is especially true at the global level. Setting a per-modulefollow_imports=skip for a specific problematic module can beuseful without causing too much harm.

Note

If you’re looking to resolve import errors related to libraries, try followingthe advice inMissing imports before messing withfollow_imports.

On this page

[8]ページ先頭

©2009-2025 Movatter.jp