mypy: Optional Static Typing for Python Projects
Optional static typing for Python
At a glance
- What is it?
- mypy is a static type checker for Python that reads PEP 484 annotations and reports type errors before your code runs. It supports gradual adoption, letting teams annotate one file at a time while unannotated code continues to work unchanged.
- Who is it for?
- mypy suits teams writing Python who want to catch type errors at analysis time rather than at runtime. Projects with large, unannotated codebases can start with a single module and grow coverage incrementally.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What mypy Catches and Who Needs It
mypy answers a specific problem: Python is a dynamic language, which means type errors surface only when the affected line executes. A function that receives the wrong argument type does not fail until that path runs. In a codebase with sparse test coverage, or one with long execution paths before the error occurs, that failure may only appear in production.
The project is aimed at developers who already use PEP 484 type hints or plan to start adding them. Type hints have been valid Python syntax since Python 3.0, and the README describes them as similar to comments in that they do not affect runtime behavior. The interpreter runs annotated code exactly as it runs unannotated code; mypy is a separate analysis tool that reads those annotations and checks them for consistency.
Teams migrating large legacy codebases do not have to annotate everything at once. The design supports mixing typed and untyped modules in a single project. Gradual adoption is the intended workflow, not a workaround.
How mypy Analyzes Types Without Executing Code
mypy builds a type graph by parsing Python source files. It tracks what type each variable holds, what each function expects and returns, and whether the types are compatible at each call site. The README describes this as static checking: the program is never run, and the analysis can catch errors in code paths that a test suite never exercises.
The tool supports several type system features according to the documentation: type inference so you do not annotate every variable manually, generics, callable types, tuple types, union types, and structural subtyping. Structural subtyping lets you check whether a value satisfies an interface without requiring explicit inheritance, which matters for duck-typed Python patterns.
Gradual typing is central to how mypy fits into an existing project. When a function has no type annotations, mypy treats its arguments and return value as the special Any type, which is compatible with everything. This means unannotated code does not cause errors even when it calls annotated code, so you can add types one file at a time. The trade-off is that Any values suppress type checks wherever they flow: annotating a high-level function that calls many unannotated helpers may leave a meaningful gap in coverage even after the high-level function is fully typed.
Installing mypy and Running Your First Check
mypy installs from PyPI with pip:
python3 -m pip install -U mypyTo run a type check on a program, pass the filename:
mypy PROGRAMmypy prints type errors with file and line number. The README gives a short example showing how a program that adds a string to an integer is caught at analysis time:
number = input("What is your favourite number?")
print("It is", number + 1) # error: Unsupported operand types for + ("str" and "int")After seeing errors, you can still run the program with the standard interpreter:
python3 PROGRAMType errors reported by mypy do not prevent Python from executing the program. For large codebases, the README recommends daemon mode, which keeps mypy state in a background process so subsequent checks re-analyze only the files that changed:
dmypy run -- PROGRAMThe documentation states that daemon mode often gives sub-second incremental updates on large projects. To install from the development branch instead of the PyPI release, use:
python3 -m pip install -U git+https://github.com/python/mypy.gitMypyc: How mypy Compiles Itself to Run Faster
The mypy package that pip installs is not pure interpreted Python. The README explains that mypyc, a companion project, takes Python type hints and compiles Python modules into C extensions. mypy itself is compiled this way at release time, which according to the README makes the distributed version approximately four times faster than an interpreted install.
This matters for teams deciding how to integrate mypy into their workflow. The default pip install delivers the compiled binary, so most users benefit from the speedup automatically. The interpreted install is available through the --no-binary flag:
python3 -m pip install --no-binary mypy -U mypyThe interpreted version is useful if you are diagnosing a bug in mypy itself or need to run on a platform where the compiled wheels are not available. mypyc is a separate project with its own issue tracker at github.com/mypyc/mypyc. Contributors who want to work on the compilation layer should check that repository rather than the main mypy repository.
The fact that mypy compiles itself is also an endorsement of mypyc's practical capability: the tool its own authors chose to make faster is the one being compiled.
Editor and Pre-commit Integration
The README lists integrations for several common editors. VS Code provides basic built-in support for mypy. Vim users can connect mypy through Syntastic by adding `let g:syntastic_python_checkers=['mypy']` to their vimrc, or through ALE, which the README says enables mypy automatically when it is installed. Emacs users can use Flycheck. PyCharm has a dedicated mypy plugin maintained by Dropbox, and Sublime Text has SublimeLinter-contrib-mypy.
For automated enforcement, the README recommends pre-commit mirrors-mypy, which runs mypy as a pre-commit hook before each commit. The README notes a concrete limitation here: by default, the pre-commit hook setup limits mypy's ability to analyze third-party dependencies. Teams that need mypy to check calls into installed packages need to configure the hook to give mypy access to the project virtual environment; the default isolated hook environment does not include those packages.
Where mypy Falls Short
Gradual typing is a feature, but it is also the main source of false confidence. When a function accepts Any, mypy stops tracking the type through that function's body. A large, unannotated codebase can show zero errors even when type problems exist, because Any absorbs everything that flows through unannotated code. Teams often discover this when they add --strict or --disallow-untyped-calls to the configuration and find a large number of new errors.
Third-party library coverage depends on stub packages. Libraries that do not ship inline types need a corresponding types-* package in typeshed or on PyPI. When stubs are missing, mypy treats the library as Any and will not catch type errors in calls to it. The README is silent on which libraries have stubs and which do not; you need to check typeshed or the library documentation separately before assuming coverage.
The README does not document a procedure for removing mypy from a project after you have added annotations. The annotations themselves are valid Python and can be left in place; they do not affect runtime behavior. But the team effort to add them is not trivially reversed, and the strictness level you commit to early shapes how much rework awaits if you raise it later.
mypy vs General Python Linters and Runtime Validators
Pyright is the most commonly searched alternative to mypy, based on related search queries, and both tools consume PEP 484 annotations. The mypy README does not document Pyright's internals or compare the two tools directly. Teams choosing between them typically run both on a sample module and compare the output for their specific codebase and third-party dependencies.
Pylint is a general-purpose Python linter that flags style issues, unused variables, and some type-related problems as part of a broader diagnostic pass. It is a different category of tool from mypy: mypy builds a full type graph and infers types across module boundaries, while pylint performs lighter per-file checks. Ruff, listed alongside mypy in related searches, is a fast linter focused on style and correctness rules rather than type inference.
For validation at runtime rather than statically, pydantic is a common companion. pydantic enforces types at the boundaries of a running program when parsing incoming JSON or configuration, while mypy checks type consistency within the static code before execution. The two tools address different failure modes and are commonly used in the same project for that reason.
Editorial conclusion
mypy suits teams writing Python who want to catch type errors at analysis time rather than at runtime. Projects with large, unannotated codebases can start with a single module and grow coverage incrementally. Teams should verify that their main third-party dependencies have stub packages available in typeshed or as separate types-* packages before expecting full coverage; missing stubs leave gaps that mypy cannot see. On any codebase larger than a few hundred files, configure dmypy from the start so that incremental checks stay fast. The compiled binary distributed on PyPI is approximately four times faster than an interpreted install, according to the README, so the default pip install is the right starting point for most users.
Frequently asked questions
What does mypy do in Python?
mypy is a static type checker that reads PEP 484 type annotations in Python source files and reports type errors without running the code. According to the README, it can catch bugs in code paths that tests do not cover, since it analyzes all annotated paths at once.
Should I use mypy or Pyright?
Both tools check Python type annotations against PEP 484, and the mypy documentation does not compare them directly. Teams often run both on a small portion of their codebase to see which produces more relevant output for their specific code patterns and library dependencies before committing to one.
What is better than mypy for Python type checking?
Pyright is frequently compared to mypy as an alternative static type checker for Python. The mypy documentation does not recommend one over the other; the right choice depends on your editor integration, existing toolchain, and how each tool handles the specific libraries your project uses.
How do I use mypy in Python?
Install mypy with pip install mypy, then run mypy followed by your Python filename to see type errors. For ongoing development on large codebases, start the daemon with dmypy run -- PROGRAM so that subsequent checks re-analyze only changed files and stay fast.
How do I use mypy with VS Code?
The README states that VS Code provides basic integration with mypy. For automated enforcement, you can add mypy as a pre-commit hook using pre-commit mirrors-mypy, though the README notes that the default hook configuration limits mypy's ability to analyze third-party dependencies.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/python-mypy)
Community notes