MyPy vs. Pyright
MyPy and Pyright are the two most powerful static type checkers currently used in the Python ecosystem. While both aim to enforce type hints and catch errors before runtime, they differ significantly in their implementation, philosophy, speed, and feature set.
Choosing between them-or deciding how to use them together-depends heavily on your priorities: speed, strictness, or integration with development environments.
This article is a logical continuation of the previous discussion on MyPy configuration for strict typing. [/blog/what-is-pyright#pyright-vs-mypy](What is pyright, light comparison with mypy)
1. Core Differences and Philosophy
| Feature | MyPy | Pyright |
|---|---|---|
| Implementation | Pure Python. | TypeScript, often run using Node.js or embedded in VS Code (Pylance). |
| Philosophy | Reference Checker. Aims to align closely with the evolving Python standard (PEPs). | Language Server. Designed to be fast and provide a richer, real-time developer experience. |
| Speed | Can be slow on large codebases due to Python runtime overhead. | Extremely fast due to its design and implementation language. |
| Configuration | Uses mypy.ini or pyproject.toml. Highly granular configuration options. | Uses pyrightconfig.json or pyproject.toml. Often managed via VS Code settings. |
| Ecosystem | The original static checker; strong community support and adoption in CI/CD pipelines. | Powers Pylance (the official Microsoft language server for VS Code). Deep IDE integration. |
2. Feature Comparison and Strengths
Both tools support all major typing features (Generics, Protocols, Any, etc.), but they shine in different areas.
MyPy Strengths (Rigorous Checking)
- Custom Plugins: MyPy allows users to write custom Python plugins to understand dynamic code patterns (e.g., ORM query builders, metaclasses) that confuse standard checkers. This is crucial for libraries like SQLAlchemy.
- Targeted Checking: MyPy often adheres more strictly to the official PEPs, sometimes flagging edge cases that Pyright might treat as acceptable.
- Built-in Stubs: Handles the built-in library type stubs (
typeshed) very well, providing reliable checks for standard library usage.
Pyright/Pylance Strengths (Speed and UX)
- Instant Feedback: Because it's so fast, Pyright (via Pylance) provides near-instantaneous feedback directly in the editor while you type, leading to a much smoother developer experience.
- Command Line Speed: For large monorepos or fast CI/CD builds, Pyright's runtime speed is a massive advantage over MyPy.
- Smart Type Inference: Pyright is known for its aggressive and effective type inference, often figuring out complex types without needing explicit annotations.
3. Key Behavioral Differences (Code Examples)
The difference often boils down to how they handle dynamic or incomplete information.
| Scenario | MyPy Behavior | Pyright Behavior |
|---|---|---|
| Untyped Function Call | If strict is enabled, MyPy often flags the call to the untyped function as unsafe. | Pyright is often more forgiving, inferring Any and allowing the call to proceed without error. |
| Recursive Types | Can be complex to set up and might require specific configurations. | Generally handles recursive and complex structural types more intuitively. |
| Protocol Checking | Strong, often requiring explicit runtime checks to satisfy the checker. | Excellent structural subtyping; checks based on methods present, not nominal inheritance. |
4. Integration and Strategy: Using Both
For high-level teams, the best strategy is often to use both tools to get the best of both worlds:
| Tool | Role | Benefit |
|---|---|---|
| Pyright (via Pylance) | Developer Tool (IDE/Local) | Instant, real-time feedback and excellent navigation/autocomplete. |
| MyPy | Gatekeeper Tool (CI/CD) | Provides the official, most rigorous final check, often with custom project-specific plugins. |
Practical Workflow:
- Develop Locally: Use Pylance (powered by Pyright) in VS Code to get instant error squiggles and quick fixes. This maximizes development speed.
- Commit/Merge: Run MyPy in your Continuous Integration (CI) pipeline. This serves as the final, authoritative gate to prevent merging code that fails the strictest set of rules.
