Movatterモバイル変換


[0]ホーム

URL:


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

First steps

Type system reference

Configuring and running mypy

Miscellaneous

Project Links

Back to top

Using mypy with an existing codebase

This section explains how to get started using mypy with an existing,significant codebase that has little or no type annotations. If you area beginner, you can skip this section.

Start small

If your codebase is large, pick a subset of your codebase (say, 5,000 to 50,000lines) and get mypy to run successfully only on this subset at first,beforeadding annotations. This should be doable in a day or two. The sooner you getsome form of mypy passing on your codebase, the sooner you benefit.

You’ll likely need to fix some mypy errors, either by insertingannotations requested by mypy or by adding#type:ignorecomments to silence errors you don’t want to fix now.

We’ll mention some tips for getting mypy passing on your codebase in varioussections below.

Run mypy consistently and prevent regressions

Make sure all developers on your codebase run mypy the same way.One way to ensure this is adding a small script with your mypyinvocation to your codebase, or adding your mypy invocation toexisting tools you use to run tests, liketox.

  • Make sure everyone runs mypy with the same options. Checking a mypyconfiguration file into your codebase is theeasiest way to do this.

  • Make sure everyone type checks the same set of files. SeeSpecifying code to be checked for details.

  • Make sure everyone runs mypy with the same version of mypy, for instanceby pinning mypy with the rest of your dev requirements.

In particular, you’ll want to make sure to run mypy as part of yourContinuous Integration (CI) system as soon as possible. This willprevent new type errors from being introduced into your codebase.

A simple CI script could look something like this:

python3 -m pip install mypy==1.8# Run your standardised mypy invocation, e.g.mypy my_project# This could also look like `scripts/run_mypy.sh`, `tox run -e mypy`, `make mypy`, etc

Ignoring errors from certain modules

By default mypy will follow imports in your code and try to check everything.This means even if you only pass in a few files to mypy, it may still process alarge number of imported files. This could potentially result in lots of errorsyou don’t want to deal with at the moment.

One way to deal with this is to ignore errors in modules you aren’t yet ready totype check. Theignore_errors option is useful for this, for instance,if you aren’t yet ready to deal with errors frompackage_to_fix_later:

[mypy-package_to_fix_later.*]ignore_errors = True

You could even invert this, by settingignore_errors=True in your globalconfig section and only enabling error reporting withignore_errors=Falsefor the set of modules you are ready to type check.

The per-module configuration that mypy’s configuration file allows can beextremely useful. Many configuration options can be enabled or disabledonly for specific modules. In particular, you can also enable or disablevarious error codes on a per-module basis, seeError codes.

Fixing errors related to imports

A common class of error you will encounter is errors from mypy about modulesthat it can’t find, that don’t have types, or don’t have stub files:

core/config.py:7: error: Cannot find implementation or library stub for module named 'frobnicate'core/model.py:9: error: Cannot find implementation or library stub for module named 'acme'...

Sometimes these can be fixed by installing the relevant packages orstub libraries in the environment you’re runningmypy in.

SeeMissing imports for a complete reference on these errorsand the ways in which you can fix them.

You’ll likely find that you want to suppress all errors from importinga given module that doesn’t have types. If you only import that modulein one or two places, you can use#type:ignore comments. For example,here we ignore an error about a third-party modulefrobnicate thatdoesn’t have stubs using#type:ignore:

importfrobnicate# type: ignore...frobnicate.initialize()# OK (but not checked)

But if you import the module in many places, this becomes unwieldy. In thiscase, we recommend using aconfiguration file. For example,to disable errors about importingfrobnicate andacme everywhere in yourcodebase, use a config like this:

[mypy-frobnicate.*]ignore_missing_imports = True[mypy-acme.*]ignore_missing_imports = True

If you get a large number of errors, you may want to ignore all errorsabout missing imports, for instance by setting--disable-error-code=import-untyped.or settingignore_missing_imports to true globally.This can hide errors later on, so we recommend avoiding thisif possible.

Finally, mypy allows fine-grained control over specific import followingbehaviour. It’s very easy to silently shoot yourself in the foot when playingaround with these, so this should be a last resort. For moredetails, lookhere.

Prioritise annotating widely imported modules

Most projects have some widely imported modules, such as utilities ormodel classes. It’s a good idea to annotate these pretty early on,since this allows code using these modules to be type checked moreeffectively.

Mypy is designed to support gradual typing, i.e. letting you add annotations atyour own pace, so it’s okay to leave some of these modules unannotated. The moreyou annotate, the more useful mypy will be, but even a little annotationcoverage is useful.

Write annotations as you go

Consider adding something like these in your code styleconventions:

  1. Developers should add annotations for any new code.

  2. It’s also encouraged to write annotations when you modify existing code.

This way you’ll gradually increase annotation coverage in yourcodebase without much effort.

Automate annotation of legacy code

There are tools for automatically adding draft annotations based on simplestatic analysis or on type profiles collected at runtime. Tools includeMonkeyType,autotyping andPyAnnotate.

A simple approach is to collect types from test runs. This may workwell if your test coverage is good (and if your tests aren’t veryslow).

Another approach is to enable type collection for a small, randomfraction of production network requests. This clearly requires morecare, as type collection could impact the reliability or theperformance of your service.

Introduce stricter options

Mypy is very configurable. Once you get started with static typing, you may wantto explore the various strictness options mypy provides to catch more bugs. Forexample, you can ask mypy to require annotations for all functions in certainmodules to avoid accidentally introducing code that won’t be type checked usingdisallow_untyped_defs. Refer toThe mypy configuration file for the details.

An excellent goal to aim for is to have your codebase pass when run againstmypy--strict.This basically ensures that you will never have a type related error without an explicitcircumvention somewhere (such as a#type:ignore comment).

The following config is equivalent to--strict (as of mypy 1.0):

# Start off with thesewarn_unused_configs = Truewarn_redundant_casts = Truewarn_unused_ignores = True# Getting this passing should be easystrict_equality = True# Strongly recommend enabling this one as soon as you cancheck_untyped_defs = True# These shouldn't be too much additional work, but may be tricky to# get passing if you use a lot of untyped librariesdisallow_subclassing_any = Truedisallow_untyped_decorators = Truedisallow_any_generics = True# These next few are various gradations of forcing use of type annotationsdisallow_untyped_calls = Truedisallow_incomplete_defs = Truedisallow_untyped_defs = True# This one isn't too hard to get passing, but return on investment is lowerno_implicit_reexport = True# This one can be tricky to get passing if you use a lot of untyped librarieswarn_return_any = True# This one is a catch-all flag for the rest of strict checks that are technically# correct but may not be practicalextra_checks = True

Note that you can also start with--strict and subtract, for instance:

strict = Truewarn_return_any = False

Remember that many of these options can be enabled on a per-module basis. For instance,you may want to enabledisallow_untyped_defs for modules which you’ve completedannotations for, in order to prevent new code from being added without annotations.

And if you want, it doesn’t stop at--strict. Mypy has additional checksthat are not part of--strict that can be useful. See the completeThe mypy command line reference andError codes for optional checks.

Speed up mypy runs

You can usemypy daemon to get much fasterincremental mypy runs. The larger your project is, the more usefulthis will be. If your project has at least 100,000 lines of code orso, you may also want to set upremote cachingfor further speedups.

On this page

[8]ページ先頭

©2009-2025 Movatter.jp