mypy

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

mypy - Static Type Checking for Python

mypy - Python静态类型检查

Overview

概述

mypy is the standard static type checker for Python, enabling gradual typing with type hints (PEP 484) and comprehensive type safety. It catches type errors before runtime, improves code documentation, and enhances IDE support while maintaining Python's dynamic nature through incremental adoption.
Key Features:
  • Gradual typing: Add types incrementally to existing code
  • Strict mode: Maximum type safety with --strict flag
  • Type inference: Automatically infer types from context
  • Protocol support: Structural typing (duck typing with types)
  • Generic types: TypeVar, Generic, and advanced type patterns
  • Framework integration: FastAPI, Django, Pydantic compatibility
  • Plugin system: Extend type checking for libraries
  • Incremental checking: Fast type checking on large codebases
Installation:
bash
undefined
mypy是Python的标准静态类型检查工具,通过类型提示(PEP 484)实现渐进式类型检查,提供全面的类型安全保障。它能在运行前捕获类型错误,改进代码文档,增强IDE支持,同时通过增量式采用保留Python的动态特性。
核心特性:
  • 渐进式类型:为现有代码逐步添加类型提示
  • 严格模式:通过--strict标志实现最高级别类型安全
  • 类型推断:从上下文自动推断类型
  • Protocol支持:结构化类型(带类型的鸭子类型)
  • 泛型类型:TypeVar、Generic及高级类型模式
  • 框架集成:兼容FastAPI、Django、Pydantic
  • 插件系统:扩展库的类型检查能力
  • 增量检查:对大型代码库快速进行类型检查
安装:
bash
undefined

Basic mypy

Basic mypy

pip install mypy
pip install mypy

With common type stubs

With common type stubs

pip install mypy types-requests types-PyYAML types-redis
pip install mypy types-requests types-PyYAML types-redis

For FastAPI projects

For FastAPI projects

pip install mypy pydantic
pip install mypy pydantic

For Django projects

For Django projects

pip install mypy django-stubs
pip install mypy django-stubs

Development setup

Development setup

pip install mypy pre-commit
undefined
pip install mypy pre-commit
undefined

Type Annotation Basics

类型注解基础

1. Variable Type Hints

1. 变量类型提示

python
undefined
python
undefined

Basic types

Basic types

name: str = "Alice" age: int = 30 height: float = 5.9 is_active: bool = True
name: str = "Alice" age: int = 30 height: float = 5.9 is_active: bool = True

Type inference (mypy infers types)

Type inference (mypy infers types)

count = 10 # mypy infers: int message = "Hello" # mypy infers: str
count = 10 # mypy infers: int message = "Hello" # mypy infers: str

Multiple types with Union

Multiple types with Union

from typing import Union
user_id: Union[int, str] = 123 # Can be int OR str result: Union[int, None] = None # Nullable int
from typing import Union
user_id: Union[int, str] = 123 # Can be int OR str result: Union[int, None] = None # Nullable int

Optional (shorthand for Union[T, None])

Optional (shorthand for Union[T, None])

from typing import Optional
user_email: Optional[str] = None # Can be str or None
undefined
from typing import Optional
user_email: Optional[str] = None # Can be str or None
undefined

2. Function Type Hints

2. 函数类型提示

python
undefined
python
undefined

Basic function typing

Basic function typing

def greet(name: str) -> str: return f"Hello, {name}"
def greet(name: str) -> str: return f"Hello, {name}"

Multiple parameters

Multiple parameters

def add(a: int, b: int) -> int: return a + b
def add(a: int, b: int) -> int: return a + b

Optional parameters with defaults

Optional parameters with defaults

def create_user(name: str, age: int = 18) -> dict: return {"name": name, "age": age}
def create_user(name: str, age: int = 18) -> dict: return {"name": name, "age": age}

No return value

No return value

def log_message(message: str) -> None: print(message)
def log_message(message: str) -> None: print(message)

Functions that never return

Functions that never return

from typing import NoReturn
def raise_error() -> NoReturn: raise ValueError("Always raises")
undefined
from typing import NoReturn
def raise_error() -> NoReturn: raise ValueError("Always raises")
undefined

3. Collection Type Hints

3. 集合类型提示

python
from typing import List, Dict, Set, Tuple
python
from typing import List, Dict, Set, Tuple

List with element type

List with element type

numbers: List[int] = [1, 2, 3, 4] names: List[str] = ["Alice", "Bob", "Charlie"]
numbers: List[int] = [1, 2, 3, 4] names: List[str] = ["Alice", "Bob", "Charlie"]

Dict with key and value types

Dict with key and value types

user_ages: Dict[str, int] = {"Alice": 30, "Bob": 25} config: Dict[str, Union[str, int]] = {"host": "localhost", "port": 8000}
user_ages: Dict[str, int] = {"Alice": 30, "Bob": 25} config: Dict[str, Union[str, int]] = {"host": "localhost", "port": 8000}

Set with element type

Set with element type

unique_ids: Set[int] = {1, 2, 3}
unique_ids: Set[int] = {1, 2, 3}

Tuple with fixed types

Tuple with fixed types

coordinate: Tuple[float, float] = (10.5, 20.3) user_record: Tuple[int, str, bool] = (1, "Alice", True)
coordinate: Tuple[float, float] = (10.5, 20.3) user_record: Tuple[int, str, bool] = (1, "Alice", True)

Variable-length tuple

Variable-length tuple

numbers: Tuple[int, ...] = (1, 2, 3, 4, 5)
numbers: Tuple[int, ...] = (1, 2, 3, 4, 5)

Modern syntax (Python 3.9+)

Modern syntax (Python 3.9+)

numbers: list[int] = [1, 2, 3] user_ages: dict[str, int] = {"Alice": 30}
undefined
numbers: list[int] = [1, 2, 3] user_ages: dict[str, int] = {"Alice": 30}
undefined

4. Class Type Hints

4. 类类型提示

python
class User:
    # Class attributes
    name: str
    age: int
    email: Optional[str]

    def __init__(self, name: str, age: int, email: Optional[str] = None) -> None:
        self.name = name
        self.age = age
        self.email = email

    def get_info(self) -> Dict[str, Union[str, int]]:
        return {
            "name": self.name,
            "age": self.age,
            "email": self.email or "N/A"
        }

    @classmethod
    def from_dict(cls, data: Dict[str, any]) -> "User":
        return cls(
            name=data["name"],
            age=data["age"],
            email=data.get("email")
        )
python
class User:
    # Class attributes
    name: str
    age: int
    email: Optional[str]

    def __init__(self, name: str, age: int, email: Optional[str] = None) -> None:
        self.name = name
        self.age = age
        self.email = email

    def get_info(self) -> Dict[str, Union[str, int]]:
        return {
            "name": self.name,
            "age": self.age,
            "email": self.email or "N/A"
        }

    @classmethod
    def from_dict(cls, data: Dict[str, any]) -> "User":
        return cls(
            name=data["name"],
            age=data["age"],
            email=data.get("email")
        )

Advanced Type Hints

高级类型提示

1. Literal Types

1. 字面量类型

python
from typing import Literal
python
from typing import Literal

Restrict to specific values

Restrict to specific values

def set_log_level(level: Literal["debug", "info", "warning", "error"]) -> None: print(f"Log level: {level}")
def set_log_level(level: Literal["debug", "info", "warning", "error"]) -> None: print(f"Log level: {level}")

Valid

Valid

set_log_level("debug") set_log_level("error")
set_log_level("debug") set_log_level("error")

Type error: Argument 1 has incompatible type "verbose"

Type error: Argument 1 has incompatible type "verbose"

set_log_level("verbose")
set_log_level("verbose")

Multiple literals

Multiple literals

Status = Literal["pending", "approved", "rejected"]
def update_status(status: Status) -> None: pass
undefined
Status = Literal["pending", "approved", "rejected"]
def update_status(status: Status) -> None: pass
undefined

2. Type Aliases

2. 类型别名

python
from typing import Dict, List, Union
python
from typing import Dict, List, Union

Simple alias

Simple alias

UserId = int UserName = str
def get_user(user_id: UserId) -> UserName: return f"User {user_id}"
UserId = int UserName = str
def get_user(user_id: UserId) -> UserName: return f"User {user_id}"

Complex aliases

Complex aliases

JSON = Union[Dict[str, "JSON"], List["JSON"], str, int, float, bool, None] Headers = Dict[str, str] QueryParams = Dict[str, Union[str, int, List[str]]]
def make_request( url: str, headers: Headers, params: QueryParams ) -> JSON: pass
JSON = Union[Dict[str, "JSON"], List["JSON"], str, int, float, bool, None] Headers = Dict[str, str] QueryParams = Dict[str, Union[str, int, List[str]]]
def make_request( url: str, headers: Headers, params: QueryParams ) -> JSON: pass

NewType for distinct types

NewType for distinct types

from typing import NewType
UserId = NewType("UserId", int) ProductId = NewType("ProductId", int)
def get_user(user_id: UserId) -> str: return f"User {user_id}"
user = UserId(123) # Valid product = ProductId(456)
get_user(user) # Valid get_user(product) # Type error: ProductId not compatible with UserId
undefined
from typing import NewType
UserId = NewType("UserId", int) ProductId = NewType("ProductId", int)
def get_user(user_id: UserId) -> str: return f"User {user_id}"
user = UserId(123) # Valid product = ProductId(456)
get_user(user) # Valid get_user(product) # Type error: ProductId not compatible with UserId
undefined

3. Generics and TypeVar

3. 泛型与TypeVar

python
from typing import TypeVar, Generic, List
python
from typing import TypeVar, Generic, List

TypeVar for generic functions

TypeVar for generic functions

T = TypeVar("T")
def first_element(items: List[T]) -> T: return items[0]
T = TypeVar("T")
def first_element(items: List[T]) -> T: return items[0]

Type inference

Type inference

num = first_element([1, 2, 3]) # mypy infers: int name = first_element(["Alice", "Bob"]) # mypy infers: str
num = first_element([1, 2, 3]) # mypy infers: int name = first_element(["Alice", "Bob"]) # mypy infers: str

Bounded TypeVar

Bounded TypeVar

from typing import Union
NumericType = TypeVar("NumericType", int, float)
def add_numbers(a: NumericType, b: NumericType) -> NumericType: return a + b
from typing import Union
NumericType = TypeVar("NumericType", int, float)
def add_numbers(a: NumericType, b: NumericType) -> NumericType: return a + b

Generic classes

Generic classes

class Stack(Generic[T]): def init(self) -> None: self._items: List[T] = []
def push(self, item: T) -> None:
    self._items.append(item)

def pop(self) -> T:
    return self._items.pop()

def is_empty(self) -> bool:
    return len(self._items) == 0
class Stack(Generic[T]): def init(self) -> None: self._items: List[T] = []
def push(self, item: T) -> None:
    self._items.append(item)

def pop(self) -> T:
    return self._items.pop()

def is_empty(self) -> bool:
    return len(self._items) == 0

Usage with type inference

Usage with type inference

int_stack: Stack[int] = Stack() int_stack.push(42) int_stack.push("hello") # Type error: Expected int, got str
str_stack: Stack[str] = Stack() str_stack.push("hello") # Valid
undefined
int_stack: Stack[int] = Stack() int_stack.push(42) int_stack.push("hello") # Type error: Expected int, got str
str_stack: Stack[str] = Stack() str_stack.push("hello") # Valid
undefined

4. Protocol (Structural Typing)

4. Protocol(结构化类型)

python
from typing import Protocol
python
from typing import Protocol

Define protocol (interface)

Define protocol (interface)

class Drawable(Protocol): def draw(self) -> str: ...
class Drawable(Protocol): def draw(self) -> str: ...

Any class with draw() method matches

Any class with draw() method matches

class Circle: def draw(self) -> str: return "Drawing circle"
class Square: def draw(self) -> str: return "Drawing square"
class Circle: def draw(self) -> str: return "Drawing circle"
class Square: def draw(self) -> str: return "Drawing square"

Function accepts any Drawable

Function accepts any Drawable

def render(obj: Drawable) -> str: return obj.draw()
def render(obj: Drawable) -> str: return obj.draw()

Both work (duck typing with types)

Both work (duck typing with types)

circle = Circle() square = Square() render(circle) # Valid render(square) # Valid
circle = Circle() square = Square() render(circle) # Valid render(square) # Valid

Runtime checkable protocols

Runtime checkable protocols

from typing import runtime_checkable
@runtime_checkable class Closeable(Protocol): def close(self) -> None: ...
class File: def close(self) -> None: pass
from typing import runtime_checkable
@runtime_checkable class Closeable(Protocol): def close(self) -> None: ...
class File: def close(self) -> None: pass

Runtime check

Runtime check

f = File() isinstance(f, Closeable) # True
undefined
f = File() isinstance(f, Closeable) # True
undefined

5. Callable Types

5. 可调用类型

python
from typing import Callable
python
from typing import Callable

Function that takes another function

Function that takes another function

def apply_twice(func: Callable[[int], int], value: int) -> int: return func(func(value))
def double(x: int) -> int: return x * 2
result = apply_twice(double, 5) # Returns 20
def apply_twice(func: Callable[[int], int], value: int) -> int: return func(func(value))
def double(x: int) -> int: return x * 2
result = apply_twice(double, 5) # Returns 20

Generic callable

Generic callable

from typing import TypeVar
T = TypeVar("T") R = TypeVar("R")
def map_values( func: Callable[[T], R], values: List[T] ) -> List[R]: return [func(v) for v in values]
from typing import TypeVar
T = TypeVar("T") R = TypeVar("R")
def map_values( func: Callable[[T], R], values: List[T] ) -> List[R]: return [func(v) for v in values]

Callable with multiple arguments

Callable with multiple arguments

Validator = Callable[[str, int], bool]
def validate_user(name: str, age: int) -> bool: return len(name) > 0 and age >= 0
validator: Validator = validate_user
undefined
Validator = Callable[[str, int], bool]
def validate_user(name: str, age: int) -> bool: return len(name) > 0 and age >= 0
validator: Validator = validate_user
undefined

mypy Configuration

mypy配置

1. mypy.ini Configuration

1. mypy.ini配置

ini
undefined
ini
undefined

mypy.ini

mypy.ini

[mypy]
[mypy]

Python version

Python version

python_version = 3.11
python_version = 3.11

Import discovery

Import discovery

files = src,tests exclude = build,dist,venv
files = src,tests exclude = build,dist,venv

Type checking strictness

Type checking strictness

disallow_untyped_defs = True disallow_any_unimported = False no_implicit_optional = True warn_return_any = True warn_unused_ignores = True warn_redundant_casts = True
disallow_untyped_defs = True disallow_any_unimported = False no_implicit_optional = True warn_return_any = True warn_unused_ignores = True warn_redundant_casts = True

Error reporting

Error reporting

show_error_codes = True show_column_numbers = True pretty = True
show_error_codes = True show_column_numbers = True pretty = True

Incremental type checking

Incremental type checking

incremental = True cache_dir = .mypy_cache
incremental = True cache_dir = .mypy_cache

Per-module configuration

Per-module configuration

[mypy-tests.*] disallow_untyped_defs = False
[mypy-migrations.*] ignore_errors = True
[mypy-tests.*] disallow_untyped_defs = False
[mypy-migrations.*] ignore_errors = True

Third-party libraries without stubs

Third-party libraries without stubs

[mypy-redis.*] ignore_missing_imports = True
[mypy-celery.*] ignore_missing_imports = True
undefined
[mypy-redis.*] ignore_missing_imports = True
[mypy-celery.*] ignore_missing_imports = True
undefined

2. pyproject.toml Configuration

2. pyproject.toml配置

toml
undefined
toml
undefined

pyproject.toml

pyproject.toml

[tool.mypy] python_version = "3.11" files = ["src", "tests"] exclude = ["build", "dist", "venv"]
[tool.mypy] python_version = "3.11" files = ["src", "tests"] exclude = ["build", "dist", "venv"]

Strictness

Strictness

disallow_untyped_defs = true disallow_any_unimported = false no_implicit_optional = true warn_return_any = true warn_unused_ignores = true warn_redundant_casts = true strict_equality = true strict_concatenate = true
disallow_untyped_defs = true disallow_any_unimported = false no_implicit_optional = true warn_return_any = true warn_unused_ignores = true warn_redundant_casts = true strict_equality = true strict_concatenate = true

Error reporting

Error reporting

show_error_codes = true show_column_numbers = true pretty = true color_output = true
show_error_codes = true show_column_numbers = true pretty = true color_output = true

Incremental

Incremental

incremental = true cache_dir = ".mypy_cache"
incremental = true cache_dir = ".mypy_cache"

Per-module overrides

Per-module overrides

[[tool.mypy.overrides]] module = "tests.*" disallow_untyped_defs = false
[[tool.mypy.overrides]] module = ["redis.", "celery."] ignore_missing_imports = true
undefined
[[tool.mypy.overrides]] module = "tests.*" disallow_untyped_defs = false
[[tool.mypy.overrides]] module = ["redis.", "celery."] ignore_missing_imports = true
undefined

3. Strict Mode

3. 严格模式

bash
undefined
bash
undefined

Enable all strict checks

Enable all strict checks

mypy --strict src/
mypy --strict src/

Strict mode equivalent flags

Strict mode equivalent flags

mypy
--disallow-any-unimported
--disallow-any-expr
--disallow-any-decorated
--disallow-any-explicit
--disallow-any-generics
--disallow-subclassing-any
--disallow-untyped-calls
--disallow-untyped-defs
--disallow-incomplete-defs
--check-untyped-defs
--disallow-untyped-decorators
--no-implicit-optional
--warn-redundant-casts
--warn-unused-ignores
--warn-return-any
--warn-unreachable
--strict-equality
src/

```ini
mypy
--disallow-any-unimported
--disallow-any-expr
--disallow-any-decorated
--disallow-any-explicit
--disallow-any-generics
--disallow-subclassing-any
--disallow-untyped-calls
--disallow-untyped-defs
--disallow-incomplete-defs
--check-untyped-defs
--disallow-untyped-decorators
--no-implicit-optional
--warn-redundant-casts
--warn-unused-ignores
--warn-return-any
--warn-unreachable
--strict-equality
src/

```ini

mypy.ini strict configuration

mypy.ini strict configuration

[mypy] strict = True
[mypy] strict = True

Relax specific checks if needed

Relax specific checks if needed

disallow_any_expr = False # Too strict for most projects disallow_any_explicit = False # Allow explicit Any
undefined
disallow_any_expr = False # Too strict for most projects disallow_any_explicit = False # Allow explicit Any
undefined

Incremental Adoption Strategies

增量式采用策略

1. Start with Entry Points

1. 从入口文件开始

python
undefined
python
undefined

Start typing from main.py (top-level)

Start typing from main.py (top-level)

main.py

main.py

from typing import Optional from app.services import UserService
def main(config_path: Optional[str] = None) -> None: """Application entry point.""" service = UserService() service.run()
if name == "main": main()

```bash
from typing import Optional from app.services import UserService
def main(config_path: Optional[str] = None) -> None: """Application entry point.""" service = UserService() service.run()
if name == "main": main()

```bash

Check only main.py initially

Check only main.py initially

mypy main.py
mypy main.py

Gradually expand scope

Gradually expand scope

mypy main.py app/services.py mypy src/
undefined
mypy main.py app/services.py mypy src/
undefined

2. Per-Module Strict Mode

2. 按模块启用严格模式

ini
undefined
ini
undefined

mypy.ini - Gradually enable strict checking

mypy.ini - Gradually enable strict checking

[mypy]
[mypy]

Lenient global defaults

Lenient global defaults

ignore_missing_imports = True disallow_untyped_defs = False
ignore_missing_imports = True disallow_untyped_defs = False

Strict for new modules

Strict for new modules

[mypy-app.services.user_service] disallow_untyped_defs = True warn_return_any = True
[mypy-app.api.*] disallow_untyped_defs = True no_implicit_optional = True
[mypy-app.services.user_service] disallow_untyped_defs = True warn_return_any = True
[mypy-app.api.*] disallow_untyped_defs = True no_implicit_optional = True

Still lenient for legacy code

Still lenient for legacy code

[mypy-app.legacy.*] ignore_errors = True
undefined
[mypy-app.legacy.*] ignore_errors = True
undefined

3. Use # type: ignore Strategically

3. 策略性使用# type: ignore

python
undefined
python
undefined

Suppress specific errors during migration

Suppress specific errors during migration

import legacy_module # type: ignore[import]
def process_data(data): # type: ignore[no-untyped-def] # TODO: Add type hints return data.transform()
import legacy_module # type: ignore[import]
def process_data(data): # type: ignore[no-untyped-def] # TODO: Add type hints return data.transform()

Ignore specific error codes

Ignore specific error codes

user_dict = get_user_dict() user_id = user_dict["id"] # type: ignore[index]
user_dict = get_user_dict() user_id = user_dict["id"] # type: ignore[index]

Ignore entire line (use sparingly)

Ignore entire line (use sparingly)

result = external_api.call() # type: ignore
undefined
result = external_api.call() # type: ignore
undefined

4. Reveal Types During Development

4. 开发期间使用reveal_type

python
from typing import reveal_type

def process_user(user_id: int):
    user = get_user(user_id)
    reveal_type(user)  # mypy will show inferred type

    name = user.name
    reveal_type(name)  # mypy will show: str
python
from typing import reveal_type

def process_user(user_id: int):
    user = get_user(user_id)
    reveal_type(user)  # mypy will show inferred type

    name = user.name
    reveal_type(name)  # mypy will show: str

FastAPI Integration

FastAPI集成

1. FastAPI with Type Hints

1. 带类型提示的FastAPI

python
undefined
python
undefined

main.py

main.py

from fastapi import FastAPI, HTTPException from pydantic import BaseModel from typing import List, Optional
app = FastAPI()
from fastapi import FastAPI, HTTPException from pydantic import BaseModel from typing import List, Optional
app = FastAPI()

Pydantic models (auto-validated)

Pydantic models (auto-validated)

class User(BaseModel): id: int name: str email: str age: Optional[int] = None
class UserCreate(BaseModel): name: str email: str age: Optional[int] = None
class User(BaseModel): id: int name: str email: str age: Optional[int] = None
class UserCreate(BaseModel): name: str email: str age: Optional[int] = None

Type-safe endpoints

Type-safe endpoints

@app.get("/") def read_root() -> dict[str, str]: return {"message": "Hello World"}
@app.get("/users/{user_id}") def read_user(user_id: int) -> User: if user_id == 0: raise HTTPException(status_code=404, detail="User not found") return User(id=user_id, name=f"User {user_id}", email="user@example.com")
@app.get("/users") def list_users(skip: int = 0, limit: int = 10) -> List[User]: users = [ User(id=i, name=f"User {i}", email=f"user{i}@example.com") for i in range(skip, skip + limit) ] return users
@app.post("/users") def create_user(user: UserCreate) -> User: # Pydantic ensures type safety return User(id=1, name=user.name, email=user.email, age=user.age)
undefined
@app.get("/") def read_root() -> dict[str, str]: return {"message": "Hello World"}
@app.get("/users/{user_id}") def read_user(user_id: int) -> User: if user_id == 0: raise HTTPException(status_code=404, detail="User not found") return User(id=user_id, name=f"User {user_id}", email="user@example.com")
@app.get("/users") def list_users(skip: int = 0, limit: int = 10) -> List[User]: users = [ User(id=i, name=f"User {i}", email=f"user{i}@example.com") for i in range(skip, skip + limit) ] return users
@app.post("/users") def create_user(user: UserCreate) -> User: # Pydantic ensures type safety return User(id=1, name=user.name, email=user.email, age=user.age)
undefined

2. Async FastAPI Type Checking

2. 异步FastAPI类型检查

python
from typing import List, Optional
from fastapi import FastAPI, Depends
from sqlalchemy.ext.asyncio import AsyncSession

app = FastAPI()
python
from typing import List, Optional
from fastapi import FastAPI, Depends
from sqlalchemy.ext.asyncio import AsyncSession

app = FastAPI()

Async dependency

Async dependency

async def get_db() -> AsyncSession: async with AsyncSessionLocal() as session: yield session
async def get_db() -> AsyncSession: async with AsyncSessionLocal() as session: yield session

Async endpoints with types

Async endpoints with types

@app.get("/users/{user_id}") async def read_user( user_id: int, db: AsyncSession = Depends(get_db) ) -> User: user = await db.get(User, user_id) if user is None: raise HTTPException(status_code=404, detail="User not found") return user
@app.get("/users") async def list_users( skip: int = 0, limit: int = 10, db: AsyncSession = Depends(get_db) ) -> List[User]: result = await db.execute( select(User).offset(skip).limit(limit) ) return result.scalars().all()
undefined
@app.get("/users/{user_id}") async def read_user( user_id: int, db: AsyncSession = Depends(get_db) ) -> User: user = await db.get(User, user_id) if user is None: raise HTTPException(status_code=404, detail="User not found") return user
@app.get("/users") async def list_users( skip: int = 0, limit: int = 10, db: AsyncSession = Depends(get_db) ) -> List[User]: result = await db.execute( select(User).offset(skip).limit(limit) ) return result.scalars().all()
undefined

3. FastAPI Dependency Injection Types

3. FastAPI依赖注入类型

python
from typing import Annotated, Optional
from fastapi import FastAPI, Depends, Header, HTTPException

app = FastAPI()
python
from typing import Annotated, Optional
from fastapi import FastAPI, Depends, Header, HTTPException

app = FastAPI()

Typed dependencies

Typed dependencies

async def get_current_user( authorization: Annotated[Optional[str], Header()] = None ) -> User: if authorization is None: raise HTTPException(status_code=401, detail="Not authenticated") # Verify token and return user return User(id=1, name="Current User", email="user@example.com")
async def get_current_user( authorization: Annotated[Optional[str], Header()] = None ) -> User: if authorization is None: raise HTTPException(status_code=401, detail="Not authenticated") # Verify token and return user return User(id=1, name="Current User", email="user@example.com")

Use dependency with type annotation

Use dependency with type annotation

@app.get("/me") async def read_current_user( current_user: Annotated[User, Depends(get_current_user)] ) -> User: return current_user
@app.get("/me") async def read_current_user( current_user: Annotated[User, Depends(get_current_user)] ) -> User: return current_user

Complex dependency chain

Complex dependency chain

class UserService: def init(self, db: AsyncSession) -> None: self.db = db
async def get_user(self, user_id: int) -> Optional[User]:
    return await self.db.get(User, user_id)
def get_user_service( db: Annotated[AsyncSession, Depends(get_db)] ) -> UserService: return UserService(db)
@app.get("/users/{user_id}") async def get_user_endpoint( user_id: int, service: Annotated[UserService, Depends(get_user_service)] ) -> User: user = await service.get_user(user_id) if user is None: raise HTTPException(status_code=404, detail="User not found") return user
undefined
class UserService: def init(self, db: AsyncSession) -> None: self.db = db
async def get_user(self, user_id: int) -> Optional[User]:
    return await self.db.get(User, user_id)
def get_user_service( db: Annotated[AsyncSession, Depends(get_db)] ) -> UserService: return UserService(db)
@app.get("/users/{user_id}") async def get_user_endpoint( user_id: int, service: Annotated[UserService, Depends(get_user_service)] ) -> User: user = await service.get_user(user_id) if user is None: raise HTTPException(status_code=404, detail="User not found") return user
undefined

Django Integration

Django集成

1. Django with django-stubs

1. Django与django-stubs

bash
undefined
bash
undefined

Install django-stubs

Install django-stubs

pip install django-stubs mypy
pip install django-stubs mypy

Generate mypy configuration

Generate mypy configuration

python -m mypy --install-types

```ini
python -m mypy --install-types

```ini

mypy.ini

mypy.ini

[mypy] plugins = mypy_django_plugin.main
[mypy.plugins.django-stubs] django_settings_module = "myproject.settings"
undefined
[mypy] plugins = mypy_django_plugin.main
[mypy.plugins.django-stubs] django_settings_module = "myproject.settings"
undefined

2. Django Models with Type Hints

2. 带类型提示的Django模型

python
undefined
python
undefined

models.py

models.py

from django.db import models from typing import Optional
class User(models.Model): email: models.EmailField = models.EmailField(unique=True) name: models.CharField = models.CharField(max_length=100) age: models.IntegerField = models.IntegerField(null=True, blank=True) is_active: models.BooleanField = models.BooleanField(default=True) created_at: models.DateTimeField = models.DateTimeField(auto_now_add=True)
def get_display_name(self) -> str:
    return self.name or self.email

@classmethod
def get_active_users(cls) -> models.QuerySet["User"]:
    return cls.objects.filter(is_active=True)
undefined
from django.db import models from typing import Optional
class User(models.Model): email: models.EmailField = models.EmailField(unique=True) name: models.CharField = models.CharField(max_length=100) age: models.IntegerField = models.IntegerField(null=True, blank=True) is_active: models.BooleanField = models.BooleanField(default=True) created_at: models.DateTimeField = models.DateTimeField(auto_now_add=True)
def get_display_name(self) -> str:
    return self.name or self.email

@classmethod
def get_active_users(cls) -> models.QuerySet["User"]:
    return cls.objects.filter(is_active=True)
undefined

3. Django Views with Type Hints

3. 带类型提示的Django视图

python
undefined
python
undefined

views.py

views.py

from django.http import HttpRequest, HttpResponse, JsonResponse from django.shortcuts import get_object_or_404 from typing import Dict, Any from .models import User
def user_detail(request: HttpRequest, user_id: int) -> JsonResponse: user: User = get_object_or_404(User, pk=user_id) data: Dict[str, Any] = { "id": user.id, "name": user.name, "email": user.email, } return JsonResponse(data)
def user_list(request: HttpRequest) -> JsonResponse: users = User.get_active_users() data = { "users": list(users.values("id", "name", "email")) } return JsonResponse(data)
undefined
from django.http import HttpRequest, HttpResponse, JsonResponse from django.shortcuts import get_object_or_404 from typing import Dict, Any from .models import User
def user_detail(request: HttpRequest, user_id: int) -> JsonResponse: user: User = get_object_or_404(User, pk=user_id) data: Dict[str, Any] = { "id": user.id, "name": user.name, "email": user.email, } return JsonResponse(data)
def user_list(request: HttpRequest) -> JsonResponse: users = User.get_active_users() data = { "users": list(users.values("id", "name", "email")) } return JsonResponse(data)
undefined

Type Stubs and Third-Party Libraries

类型存根与第三方库

1. Installing Type Stubs

1. 安装类型存根

bash
undefined
bash
undefined

Install stubs for popular libraries

Install stubs for popular libraries

pip install types-requests pip install types-PyYAML pip install types-redis pip install types-boto3
pip install types-requests pip install types-PyYAML pip install types-redis pip install types-boto3

Search for available stubs

Search for available stubs

pip search types-
pip search types-

Auto-install missing stubs

Auto-install missing stubs

mypy --install-types
undefined
mypy --install-types
undefined

2. Creating Custom Stubs

2. 创建自定义类型存根

python
undefined
python
undefined

stubs/external_lib.pyi

stubs/external_lib.pyi

from typing import Optional, List
class Client: def init(self, api_key: str) -> None: ...
def get_user(self, user_id: int) -> Optional[dict]: ...

def list_users(self, limit: int = 10) -> List[dict]: ...
def connect(host: str, port: int) -> Client: ...

```ini
from typing import Optional, List
class Client: def init(self, api_key: str) -> None: ...
def get_user(self, user_id: int) -> Optional[dict]: ...

def list_users(self, limit: int = 10) -> List[dict]: ...
def connect(host: str, port: int) -> Client: ...

```ini

mypy.ini

mypy.ini

[mypy] mypy_path = stubs
undefined
[mypy] mypy_path = stubs
undefined

3. Ignoring Missing Imports

3. 忽略缺失的导入

ini
undefined
ini
undefined

mypy.ini

mypy.ini

[mypy-external_lib.*] ignore_missing_imports = True
[mypy-external_lib.*] ignore_missing_imports = True

For multiple libraries

For multiple libraries

[mypy-celery.,redis.,boto3.*] ignore_missing_imports = True
undefined
[mypy-celery.,redis.,boto3.*] ignore_missing_imports = True
undefined

CI/CD Integration

CI/CD集成

1. GitHub Actions

1. GitHub Actions

yaml
undefined
yaml
undefined

.github/workflows/type-check.yml

.github/workflows/type-check.yml

name: Type Check
on: [push, pull_request]
jobs: mypy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3
  - name: Set up Python
    uses: actions/setup-python@v4
    with:
      python-version: '3.11'

  - name: Install dependencies
    run: |
      pip install mypy
      pip install -r requirements.txt
      pip install types-requests types-PyYAML

  - name: Run mypy
    run: mypy src/

  - name: Run mypy strict on new code
    run: mypy --strict src/api/
undefined
name: Type Check
on: [push, pull_request]
jobs: mypy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3
  - name: Set up Python
    uses: actions/setup-python@v4
    with:
      python-version: '3.11'

  - name: Install dependencies
    run: |
      pip install mypy
      pip install -r requirements.txt
      pip install types-requests types-PyYAML

  - name: Run mypy
    run: mypy src/

  - name: Run mypy strict on new code
    run: mypy --strict src/api/
undefined

2. Pre-commit Hook

2. Pre-commit钩子

yaml
undefined
yaml
undefined

.pre-commit-config.yaml

.pre-commit-config.yaml

repos:

```bash
repos:

```bash

Install pre-commit

Install pre-commit

pip install pre-commit pre-commit install
pip install pre-commit pre-commit install

Run manually

Run manually

pre-commit run mypy --all-files
undefined
pre-commit run mypy --all-files
undefined

3. Make Target

3. Make目标

makefile
undefined
makefile
undefined

Makefile

Makefile

.PHONY: typecheck typecheck: mypy src/
.PHONY: typecheck-strict typecheck-strict: mypy --strict src/
.PHONY: typecheck-report typecheck-report: mypy src/ --html-report mypy-report @echo "Report: mypy-report/index.html"
.PHONY: ci ci: typecheck test lint
undefined
.PHONY: typecheck typecheck: mypy src/
.PHONY: typecheck-strict typecheck-strict: mypy --strict src/
.PHONY: typecheck-report typecheck-report: mypy src/ --html-report mypy-report @echo "Report: mypy-report/index.html"
.PHONY: ci ci: typecheck test lint
undefined

Common Patterns and Idioms

常见模式与惯用写法

1. Overload for Multiple Signatures

1. 为多个签名使用Overload

python
from typing import overload, Union

@overload
def process(data: str) -> str: ...

@overload
def process(data: int) -> int: ...

@overload
def process(data: list) -> list: ...

def process(data: Union[str, int, list]) -> Union[str, int, list]:
    """Process different data types."""
    if isinstance(data, str):
        return data.upper()
    elif isinstance(data, int):
        return data * 2
    else:
        return [x * 2 for x in data]
python
from typing import overload, Union

@overload
def process(data: str) -> str: ...

@overload
def process(data: int) -> int: ...

@overload
def process(data: list) -> list: ...

def process(data: Union[str, int, list]) -> Union[str, int, list]:
    """Process different data types."""
    if isinstance(data, str):
        return data.upper()
    elif isinstance(data, int):
        return data * 2
    else:
        return [x * 2 for x in data]

mypy knows return types

mypy knows return types

result1: str = process("hello") # Valid result2: int = process(42) # Valid result3: str = process(42) # Type error
undefined
result1: str = process("hello") # Valid result2: int = process(42) # Valid result3: str = process(42) # Type error
undefined

2. TypedDict for Structured Dicts

2. 为结构化字典使用TypedDict

python
from typing import TypedDict, Optional

class UserDict(TypedDict):
    id: int
    name: str
    email: str
    age: Optional[int]
python
from typing import TypedDict, Optional

class UserDict(TypedDict):
    id: int
    name: str
    email: str
    age: Optional[int]

Type-safe dict usage

Type-safe dict usage

def create_user(data: UserDict) -> UserDict: return { "id": 1, "name": data["name"], "email": data["email"], "age": data.get("age"), }
user: UserDict = { "id": 1, "name": "Alice", "email": "alice@example.com", "age": 30 }
def create_user(data: UserDict) -> UserDict: return { "id": 1, "name": data["name"], "email": data["email"], "age": data.get("age"), }
user: UserDict = { "id": 1, "name": "Alice", "email": "alice@example.com", "age": 30 }

Type error: Missing required key "email"

Type error: Missing required key "email"

invalid_user: UserDict = { "id": 1, "name": "Bob", }
undefined
invalid_user: UserDict = { "id": 1, "name": "Bob", }
undefined

3. Final and Constant Values

3. Final与常量值

python
from typing import Final
python
from typing import Final

Constants that should never change

Constants that should never change

API_VERSION: Final = "v1" MAX_RETRIES: Final[int] = 3
API_VERSION: Final = "v1" MAX_RETRIES: Final[int] = 3

Type error: Cannot assign to final name

Type error: Cannot assign to final name

API_VERSION = "v2"
API_VERSION = "v2"

Final class (cannot be subclassed)

Final class (cannot be subclassed)

from typing import final
@final class BaseConfig: pass
from typing import final
@final class BaseConfig: pass

Type error: Cannot inherit from final class

Type error: Cannot inherit from final class

class AppConfig(BaseConfig): # Error! pass
undefined
class AppConfig(BaseConfig): # Error! pass
undefined

4. Self Type for Method Chaining

4. 方法链式调用的Self类型

python
from typing import Self  # Python 3.11+

class Builder:
    def __init__(self) -> None:
        self._value = 0

    def add(self, value: int) -> Self:
        self._value += value
        return self

    def multiply(self, value: int) -> Self:
        self._value *= value
        return self

    def build(self) -> int:
        return self._value
python
from typing import Self  # Python 3.11+

class Builder:
    def __init__(self) -> None:
        self._value = 0

    def add(self, value: int) -> Self:
        self._value += value
        return self

    def multiply(self, value: int) -> Self:
        self._value *= value
        return self

    def build(self) -> int:
        return self._value

Type-safe method chaining

Type-safe method chaining

result = Builder().add(5).multiply(2).add(3).build()
undefined
result = Builder().add(5).multiply(2).add(3).build()
undefined

mypy vs pyright Comparison

mypy与pyright对比

Feature Comparison

特性对比

Featuremypypyright
Type CheckerOfficial Python type checkerMicrosoft's type checker
SpeedSlower on large codebasesFaster, incremental
StrictnessConfigurable strict modeVery strict by default
IDE IntegrationGood (LSP support)Excellent (Pylance in VS Code)
Plugin SystemYes (mypy plugins)Limited
Error MessagesClear, detailedVery detailed, helpful
CommunityLarge, officialGrowing, Microsoft-backed
Type InferenceGoodExcellent
Configurationmypy.ini, pyproject.tomlpyrightconfig.json, pyproject.toml
特性mypypyright
类型检查器官方Python类型检查器Microsoft开发的类型检查器
速度大型代码库上速度较慢更快,支持增量检查
严格性可配置严格模式默认非常严格
IDE集成良好(支持LSP)优秀(VS Code中的Pylance)
插件系统支持(mypy插件)有限
错误信息清晰、详细非常详细、有帮助
社区庞大、官方支持正在增长,由Microsoft支持
类型推断良好优秀
配置mypy.ini、pyproject.tomlpyrightconfig.json、pyproject.toml

When to Use mypy

何时使用mypy

bash
undefined
bash
undefined

Use mypy for:

Use mypy for:

- Official Python type checking standard

- 官方Python类型检查标准

- Plugin ecosystem (Django, SQLAlchemy, Pydantic)

- 插件生态系统(Django、SQLAlchemy、Pydantic)

- Gradual typing with fine-grained control

- 细粒度控制的渐进式类型检查

- Compatibility with existing mypy configurations

- 与现有mypy配置兼容

- CI/CD pipelines (industry standard)

- CI/CD流水线(行业标准)

undefined
undefined

When to Use pyright

何时使用pyright

bash
undefined
bash
undefined

Use pyright for:

Use pyright for:

- VS Code development (Pylance)

- VS Code开发(Pylance)

- Faster type checking on large codebases

- 大型代码库上更快的类型检查

- Stricter type checking by default

- 默认更严格的类型检查

- Better type inference

- 更优秀的类型推断

- Real-time IDE feedback

- 实时IDE反馈

undefined
undefined

Using Both

同时使用两者

toml
undefined
toml
undefined

pyproject.toml - Configure both

pyproject.toml - Configure both

[tool.mypy] strict = true files = ["src"]
[tool.pyright] include = ["src"] strict = ["src/api"] reportMissingTypeStubs = false

```bash
[tool.mypy] strict = true files = ["src"]
[tool.pyright] include = ["src"] strict = ["src/api"] reportMissingTypeStubs = false

```bash

Run both in CI

Run both in CI

mypy src/ pyright src/
undefined
mypy src/ pyright src/
undefined

Local mypy Profiles (Your Repos)

本地mypy配置文件(你的仓库)

Common patterns from your Python projects:
  • Strict default (edgar, kuzu-memory, mcp-browser):
    disallow_untyped_defs = true
    ,
    check_untyped_defs = true
    ,
    no_implicit_optional = true
    ,
    warn_return_any = true
    ,
    strict_equality = true
    .
  • Relaxed profile (mcp-ticketer): strict flags disabled temporarily with a
    disable_error_code
    list for patch releases.
  • Incremental adoption (mcp-vector-search):
    ignore_errors = true
    while stabilizing types.
  • Missing imports:
    ignore_missing_imports = true
    used in mcp-memory and mcp-ticketer.
Reference: see
pyproject.toml
in
edgar
,
kuzu-memory
,
mcp-vector-search
, and
mcp-ticketer
.
你的Python项目中的常见模式:
  • 严格默认配置(edgar、kuzu-memory、mcp-browser):
    disallow_untyped_defs = true
    ,
    check_untyped_defs = true
    ,
    no_implicit_optional = true
    ,
    warn_return_any = true
    ,
    strict_equality = true
  • 宽松配置(mcp-ticketer):临时禁用严格标志,为补丁版本添加
    disable_error_code
    列表。
  • 增量式采用(mcp-vector-search):稳定类型期间设置
    ignore_errors = true
  • 缺失导入处理:mcp-memory和mcp-ticketer中使用
    ignore_missing_imports = true
参考:查看
edgar
kuzu-memory
mcp-vector-search
mcp-ticketer
中的
pyproject.toml

Best Practices

最佳实践

1. Start with Key Modules

1. 从核心模块开始

python
undefined
python
undefined

✅ GOOD: Type critical business logic first

✅ 推荐:优先为关键业务逻辑添加类型

services/user_service.py

services/user_service.py

from typing import Optional
class UserService: def get_user(self, user_id: int) -> Optional[User]: """Retrieve user by ID.""" return self.db.query(User).get(user_id)
def create_user(self, data: UserCreate) -> User:
    """Create new user."""
    user = User(**data.dict())
    self.db.add(user)
    self.db.commit()
    return user
undefined
from typing import Optional
class UserService: def get_user(self, user_id: int) -> Optional[User]: """根据ID检索用户。""" return self.db.query(User).get(user_id)
def create_user(self, data: UserCreate) -> User:
    """创建新用户。"""
    user = User(**data.dict())
    self.db.add(user)
    self.db.commit()
    return user
undefined

2. Use Type Aliases for Readability

2. 使用类型别名提升可读性

python
undefined
python
undefined

✅ GOOD: Clear, reusable type aliases

✅ 推荐:清晰、可复用的类型别名

from typing import Dict, List, Union
JSON = Union[Dict[str, "JSON"], List["JSON"], str, int, float, bool, None] Headers = Dict[str, str] UserId = int
def parse_response(data: JSON, headers: Headers) -> UserId: pass
from typing import Dict, List, Union
JSON = Union[Dict[str, "JSON"], List["JSON"], str, int, float, bool, None] Headers = Dict[str, str] UserId = int
def parse_response(data: JSON, headers: Headers) -> UserId: pass

❌ BAD: Complex inline types

❌ 不推荐:复杂的内联类型

def parse_response( data: Union[Dict[str, Union[...]], List[...], str, int, float, bool, None], headers: Dict[str, str] ) -> int: pass
undefined
def parse_response( data: Union[Dict[str, Union[...]], List[...], str, int, float, bool, None], headers: Dict[str, str] ) -> int: pass
undefined

3. Prefer Explicit Over Implicit

3. 优先显式类型而非隐式推断

python
undefined
python
undefined

✅ GOOD: Explicit types for public APIs

✅ 推荐:公共API使用显式类型

def get_user(user_id: int) -> Optional[User]: return db.query(User).get(user_id)
def get_user(user_id: int) -> Optional[User]: return db.query(User).get(user_id)

❌ ACCEPTABLE: Type inference for internal helpers

❌ 可接受:内部辅助函数使用类型推断

def _format_name(first, last): # mypy infers str -> str return f"{first} {last}"
undefined
def _format_name(first, last): # mypy infers str -> str return f"{first} {last}"
undefined

4. Use reveal_type for Debugging

4. 使用reveal_type调试

python
undefined
python
undefined

During development, check inferred types

开发期间,检查推断的类型

from typing import reveal_type
def process_data(data): result = transform(data) reveal_type(result) # mypy: Revealed type is "int" return result * 2
undefined
from typing import reveal_type
def process_data(data): result = transform(data) reveal_type(result) # mypy: Revealed type is "int" return result * 2
undefined

5. Document Type Ignores

5. 为类型忽略添加文档说明

python
undefined
python
undefined

✅ GOOD: Document why type checking is disabled

✅ 推荐:说明禁用类型检查的原因

import legacy_module # type: ignore[import] # TODO: Add type stubs
import legacy_module # type: ignore[import] # TODO: 添加类型存根

❌ BAD: No explanation

❌ 不推荐:无任何说明

import legacy_module # type: ignore
undefined
import legacy_module # type: ignore
undefined

Common Pitfalls

常见陷阱

❌ Anti-Pattern 1: Using Any Everywhere

❌ 反模式1:到处使用Any

python
undefined
python
undefined

WRONG: Defeats purpose of type checking

错误:失去类型检查的意义

from typing import Any
def process(data: Any) -> Any: return data.transform()

**Correct:**
```python
from typing import Union, Protocol

class Transformable(Protocol):
    def transform(self) -> dict: ...

def process(data: Transformable) -> dict:
    return data.transform()
from typing import Any
def process(data: Any) -> Any: return data.transform()

**正确写法:**
```python
from typing import Union, Protocol

class Transformable(Protocol):
    def transform(self) -> dict: ...

def process(data: Transformable) -> dict:
    return data.transform()

❌ Anti-Pattern 2: Ignoring Type Errors Globally

❌ 反模式2:全局忽略类型错误

ini
undefined
ini
undefined

WRONG: Disables type checking

错误:完全禁用类型检查

[mypy] ignore_errors = True

**Correct:**
```ini
[mypy] ignore_errors = True

**正确写法:**
```ini

Ignore specific modules only

仅忽略特定模块

[mypy-legacy.*] ignore_errors = True
[mypy] strict = True
undefined
[mypy-legacy.*] ignore_errors = True
[mypy] strict = True
undefined

❌ Anti-Pattern 3: Not Using Optional

❌ 反模式3:不使用Optional

python
undefined
python
undefined

WRONG: Nullable without Optional

错误:可空值未标记Optional

def get_user(user_id: int) -> User: user = db.get(user_id) # Can be None! return user # Runtime error if None

**Correct:**
```python
from typing import Optional

def get_user(user_id: int) -> Optional[User]:
    return db.get(user_id)
def get_user(user_id: int) -> User: user = db.get(user_id) # 可能为None! return user # 为None时会触发运行时错误

**正确写法:**
```python
from typing import Optional

def get_user(user_id: int) -> Optional[User]:
    return db.get(user_id)

Handle None explicitly

显式处理None情况

user = get_user(123) if user is not None: print(user.name)
undefined
user = get_user(123) if user is not None: print(user.name)
undefined

Quick Reference

快速参考

Common Commands

常用命令

bash
undefined
bash
undefined

Basic type checking

基础类型检查

mypy main.py mypy src/
mypy main.py mypy src/

Strict mode

严格模式

mypy --strict src/
mypy --strict src/

Install missing type stubs

安装缺失的类型存根

mypy --install-types
mypy --install-types

Generate HTML report

生成HTML报告

mypy src/ --html-report mypy-report
mypy src/ --html-report mypy-report

Check specific error codes

显示错误代码

mypy --show-error-codes src/
mypy --show-error-codes src/

Ignore missing imports

忽略缺失的导入

mypy --ignore-missing-imports src/
mypy --ignore-missing-imports src/

Follow imports

跟随导入

mypy --follow-imports=silent src/
mypy --follow-imports=silent src/

Incremental mode (faster)

增量模式(更快)

mypy --incremental src/
mypy --incremental src/

Verbose output

详细输出

mypy --verbose src/
undefined
mypy --verbose src/
undefined

Error Code Reference

错误代码参考

bash
undefined
bash
undefined

Common error codes

常见错误代码

[attr-defined] # Attribute not defined [arg-type] # Argument type mismatch [return-value] # Return type mismatch [assignment] # Assignment type mismatch [call-overload] # No matching overload [index] # Invalid index operation [operator] # Unsupported operand type [import] # Cannot find import [misc] # Miscellaneous type error [no-untyped-def] # Function missing type annotation [var-annotated] # Variable needs type annotation
undefined
[attr-defined] # 属性未定义 [arg-type] # 参数类型不匹配 [return-value] # 返回类型不匹配 [assignment] # 赋值类型不匹配 [call-overload] # 无匹配的重载 [index] # 无效的索引操作 [operator] # 不支持的操作数类型 [import] # 无法找到导入 [misc] # 其他类型错误 [no-untyped-def] # 函数缺少类型注解 [var-annotated] # 变量需要类型注解
undefined

Resources

资源

Related Skills

相关技能

When using mypy, consider these complementary skills (available in the skill library):
  • pytest: Type-safe testing with mypy - integrates type checking into your test suite for comprehensive type coverage
  • fastapi-local-dev: FastAPI with full type safety - combines FastAPI's runtime validation with mypy's static checking
  • pydantic: Runtime type validation with mypy support - validates data at runtime while mypy validates at compile time

mypy Version Compatibility: This skill covers mypy 1.8+ and reflects current best practices for Python type checking in 2025.
使用mypy时,可考虑以下互补技能(技能库中已提供):
  • pytest: 带mypy的类型安全测试 - 将类型检查集成到测试套件中,实现全面的类型覆盖
  • fastapi-local-dev: 全类型安全的FastAPI - 结合FastAPI的运行时验证与mypy的静态检查
  • pydantic: 支持mypy的运行时类型验证 - 运行时验证数据,同时mypy在编译时验证类型

mypy版本兼容性: 本技能覆盖mypy 1.8+,反映了2025年Python类型检查的当前最佳实践。