C.W.K.
Stream
Lesson 04 of 05 · published

ruff and mypy — Lint and Type Check

~18 min · ruff, mypy, lint, type-check

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete

ruff — the modern Python linter

For years, Python linting required pylint, flake8, pycodestyle, isort, and a stack of plugins, each in a separate config. ruff (Rust-written) replaces all of them with a single tool that's 10-100x faster. It does style checks, import sorting, dead code detection, security warnings, and even autofixes. Modern Python projects (Pippa included) use ruff and call it a day.

The two commands

ruff check — show issues. ruff check --fix — autofix what's safely fixable. ruff format — format code (replaces black, in many setups). Configure once in pyproject.toml under [tool.ruff]. The default rules are sensible; tweak only when you have specific reasons.

mypy — static type checking

Type hints exist in your code; mypy reads them and verifies usage. mypy module.py or mypy . for the whole project. Errors are reported with file/line. Run it in CI; fix all errors as you go. Strict mode (--strict or strict = true in config) requires fully-typed code — the right setting for new projects, an aspiration for legacy ones.

pyright — the alternative

pyright (Microsoft) is mypy's main competitor. Faster, slightly different inference. VS Code's Pylance extension uses it. Many teams use pyright in the IDE for speed, mypy in CI for the "official" check. Both work on the same type hints.

pre-commit — running checks before each commit

pre-commit is a framework for Git hooks. Configure once in .pre-commit-config.yaml with the tools you want (ruff, mypy, pytest). Runs them on changed files at git commit time. Catches issues before you push.

Code

ruff — install and run·bash
pip install ruff

# Check your code
ruff check .

# Autofix
ruff check . --fix

# Format (replaces black for many)
ruff format .

# Common output:
# my_module.py:42:5: E711 Comparison to None should be 'x is None'
# Found 1 error.
# [*] 1 fixable with the --fix option.
ruff config in pyproject.toml·toml
[tool.ruff]
line-length = 100
target-version = "py310"

[tool.ruff.lint]
select = [
    "E",    # pycodestyle errors
    "F",    # Pyflakes
    "W",    # pycodestyle warnings
    "I",    # isort
    "UP",   # pyupgrade
    "B",    # flake8-bugbear
    "C4",   # flake8-comprehensions
]
ignore = ["E501"]    # line too long (handled by formatter)

[tool.ruff.format]
quote-style = "double"
# enable preview features
preview = false
mypy — basic usage·bash
pip install mypy

# Check a file
mypy my_module.py

# Check the whole project
mypy .

# Strict mode — recommended for new code
mypy --strict .

# Output:
# my_module.py:42: error: Incompatible return type (got 'int', expected 'str')
# Found 1 error in 1 file (checked 5 files)
mypy config in pyproject.toml·toml
[tool.mypy]
python_version = "3.10"
strict = true

# Override per-module
[[tool.mypy.overrides]]
module = "third_party_lib.*"
ignore_missing_imports = true

[[tool.mypy.overrides]]
module = "my_legacy_module.*"
disallow_untyped_defs = false      # allow untyped during gradual typing
pre-commit — gate commits·yaml
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.4.0
    hooks:
      - id: ruff
        args: [--fix]
      - id: ruff-format

  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.10.0
    hooks:
      - id: mypy

# Install hooks once:
# pip install pre-commit
# pre-commit install
# Now every git commit runs ruff and mypy on changed files

External links

Exercise

In a small project: (a) install ruff and mypy. (b) Configure both in pyproject.toml with strict-ish settings. (c) Write a tiny module with a deliberate type error (e.g., return "abc" from a function annotated -> int). (d) Run mypy and observe the error. Fix it. (e) Run ruff check — write code with a deliberate unused import and confirm ruff flags it.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.