Python code quality: type checking, formatting and project tooling
You check type hints with mypy, keep code consistent with ruff and black, and set up maintainable projects with pre-commit and modern project tooling.
Level 301 · 19 lessons · 18 practice labs
Lessons
The type system
- typing: collections, Optional and unions
- Type checking with mypy
- Generics: TypeVar and Generic
- TypedDict, Literal and NewType
- Adding types to old code step by step
- Short task: bring the mypy errors down to zero
Formatting and static analysis
- Fast linting with ruff
- Consistent formatting with black
- Complexity and code smells
- Security linting with bandit
- Checks on every commit with pre-commit
- Short task: get a messy project through the checks
Project tooling
- One configuration with pyproject.toml
- Environments and lock files with uv
- The src layout and package boundaries
- Versioning and a changelog
- Running tests and checks in continuous integration
- Short task: prepare your own project template
Capstone
- Capstone: take a project through a quality gate
Practice labs
- Typing a plugin interface with Protocol and overload: Describe an untyped plugin interface with Protocol, overload and generics so mypy strict passes cleanly and a wrong plugin is caught at check time.
- Naming magic numbers: Move the unexplained numbers in a shipping fee calculation to named constants and an Enum while tests stay green and ruff stays clean.
- Handling an Optional return correctly: Add the right type hints to a lookup that may return None and clear the callers' mypy errors with checks.
- Describing dictionary payloads with TypedDict: Describe a free-form order dictionary with TypedDict and Literal so mypy catches wrong keys.
- Writing a generic queue class: Make a queue class that uses Any type-safe with TypeVar and Generic so mixed-type use is a mypy error.
- Separating mixed-up ids with NewType: Make a bug that mixes up user and order ids detectable before runtime with NewType.
- Taking an old module to mypy strict: Type an untyped invoicing module step by step and bring mypy --strict errors to zero without type: ignore.
- Clearing ruff findings: Fix a module full of unused imports and shadowed names until ruff reports nothing.
- Reconciling formatter and linter settings: Bring black's and ruff's conflicting line-length and quote settings down to one configuration in pyproject.toml.
- Breaking up a complex function: Split a shipping-fee function with complexity above twenty into small functions so the score drops below ten and tests pass.
- Cleaning up code smells: Refactor a module with duplicated blocks, magic numbers and dead code without changing behaviour.
- Classifying bandit findings: Fix the real ones among five bandit findings and mark the false alarms with a justified nosec.
- Setting up pre-commit hooks: Write a pre-commit configuration with ruff, black and mypy hooks so a faulty commit is blocked.
- Writing a local hook that catches secrets: Write a local pre-commit hook that looks for key patterns in committed files and supports an allow-list file.
- Gathering scattered config into pyproject: Move setup.cfg, pytest.ini and mypy.ini settings into pyproject.toml and confirm the tools behave the same.
- Moving a project to the src layout: Expose and fix a packaging bug hidden by importing from the root by moving to the src layout.
- Reproducing an environment from a lock file: Produce a lock file with uv, rebuild the environment from scratch and show versions match the lock exactly.
- Writing a one-command quality gate: Write a check script that runs format, lint, type and test checks in order and stops with a non-zero code at the first failure.
About this course
You check type hints with mypy, keep code consistent with ruff and black, and set up maintainable projects with pre-commit and modern project tooling.
What you will learn
- The type system
- Formatting and static analysis
- Project tooling
- Capstone
Prerequisites
You should be comfortable with the level 101 and 201 topics of the same path.
Lab environment
Lessons run in your own Kali Linux terminal that opens in the browser. Nothing to install; the lab starts clean in every lesson.
Frequently asked questions
- Is this course right for my level?
- The course is at level 301; it assumes you know the topics of the lower-level courses.
- Is there anything to install?
- No. Every lesson runs in your own lab environment that opens in the browser.
- How do lessons work?
- Each lesson has 8 to 10 steps and a short quiz. Early steps show the command to type, later steps give less help; if two attempts fail, the solution opens.
- Can I try it for free?
- Yes. The first three lessons of every course are free.