Learning Platform
Глоссарий Troubleshooting
Урок 08.07 · 15 мин
Средний
Module summarymypypyrightRun-on-Your-Machinemypy.iniStrict modeCI integrationForward-link Phase 69

M07 summary + bridge к mypy — Run-on-Your-Machine

Этот финальный урок Module 07 — bridge между in-browser learning environment (Pyodide-driven challenges) и production toolchain на вашей local machine. Type hints сами по себе ничего не enforce’ят — нужен type checker (mypy / pyright / ty), запускаемый на вашем коде. В этом уроке: M07 recap + Run-on-Your-Machine instructions для mypy.

В этом уроке:

  1. M07 recap — 6 уроков, ключевые концепции.
  2. Why mypy — браузер не может type-check.
  3. Run-on-Your-Machinepip install mypy + mypy --strict file.py + sample mypy.ini.
  4. Brief mypy alternatives — pyright, ty (deferred к v2).
  5. Forward-link Phase 69 — mypy в pre-commit hook / CI workflow.

M07 recap — 6 уроков, 6 концепций

#УрокКлючевая концепцияCite
1basic-syntaxPEP 585 built-in generics + PEP 604 unionsPEP 585, PEP 604, Lib/types.py UnionType
2genericsPEP 695 inline syntax + ParamSpecPEP 695, PEP 612, Lib/typing.py TypeVar
3protocol-typeddictProtocol structural subtyping + TypedDictPEP 544, PEP 589, PEP 655 Required
4runtime-introspectionget_type_hints + inspect.signature + dataclasses.fieldsLib/typing.py, Lib/inspect.py, Lib/dataclasses.py
5narrowing-and-type-guardsisinstance / TypeGuard / TypeIs (Python 3.13)PEP 647, PEP 742 forward note
6typed-exceptionsCustom Exception + try/except/else/finally + chainingPEP 654, PEP 3134, Lib/builtins.py

Cross-module bridges уже накоплены:

  • M02 урок 06 → M07 урок 01: tuple[int, ...] immutable hashable handle, теперь typed.
  • M03 урок 04 → M07 урок 02: closure carries *args/**kwargs; ParamSpec — type-system overlay поверх.
  • M04 урок 04 → M07 урок 03: Protocol vs ABC — structural vs nominal subtyping.
  • M04 урок 05 → M07 урок 04: @dataclass(frozen=True, slots=True) + type hints + dataclasses.fields() = framework basis.
  • M06 урок 04 → M07 урок 06: context-manager vs try/finally — when to choose.
  • M07 урок 07 (этот) → Phase 69: mypy в CI workflow.

Type-hints — overlay поверх runtime stack. Существующие primitives (closure, generator, dataclass, context-manager) не меняются — они получают type-system view.


Why mypy — браузер не может type-check

Type hints — аннотации. Python interpreter их хранит в __annotations__, но не enforce’итdef f(x: int) -> int: return x спокойно вызывается с f('hello') и returns 'hello'. Type checking — отдельный инструмент:

  • mypy — оригинальный, reference implementation. Python-based, slower but feature-complete.
  • pyright — Microsoft, TypeScript-based, faster, used VSCode Pylance.
  • ty (“type” — Astral.sh, 2024+) — Rust-based, ultra-fast, early stage. Astral акредитована OpenAI в марте 2026 (deal pending regulatory close); ty / ruff / uv остаются OSS commitment per OpenAI и Astral CEO Charlie Marsh.

Pyodide (browser Python) — interpreter, не type-checker. Чтобы реально проверить ваш typed code — нужно local install и запуск на вашей машине.

Это invariant курса: все type-checking happens locally. Browser challenges — runtime correctness only (does code produce expected output).


Run-on-Your-Machine — mypy installation

TIP

Run-on-Your-Machine: install и запустить mypy locally

Шаги для проверки typed code из M07 на вашей machine:

# 1. Install mypy в virtual environment
python3 -m venv .venv
source .venv/bin/activate            # Linux/macOS
# .venv\Scripts\activate              # Windows
pip install mypy

Проверьте version:

mypy --version
# mypy 1.8.0 (compiled: yes)

2. Создайте файл example.py (любой код из M07):

# example.py
def parse_age(s: str) -> int | None:
    try:
        return int(s)
    except ValueError:
        return None


def use_age(s: str) -> str:
    age = parse_age(s)
    return f'age + 1 = {age + 1}'   # ← BUG: age may be None!

3. Run mypy:

mypy example.py

Expected output:

example.py:9: error: Unsupported operand types for + ("None" and "int")  [operator]
example.py:9: note: Left operand is of type "int | None"
Found 1 error in 1 file (checked 1 source file)

mypy поймал bug до запуска! age может быть None — age + 1 поднимет TypeError в runtime. Лечение: if age is None: ... narrowing (M07 урок 05) → mypy approves.

4. Run в strict mode:

mypy --strict example.py

Strict mode включает все warnings: --disallow-untyped-defs, --warn-return-any, --strict-equality и т.д. Production-grade hygiene.


Run-on-Your-Machine — mypy.ini configuration

TIP

Run-on-Your-Machine: project-wide mypy.ini

Configuration через mypy.ini (или pyproject.toml [tool.mypy]):

1. Создайте mypy.ini в корне проекта:

[mypy]
python_version = 3.13
strict = True
warn_unused_ignores = True
warn_redundant_casts = True
disallow_any_generics = True
implicit_reexport = False
show_error_codes = True
show_column_numbers = True

# Per-module overrides — useful для third-party libraries без stubs
[mypy-some_legacy_lib.*]
ignore_missing_imports = True

2. Run без аргументов — mypy использует mypy.ini:

mypy .

Expected output (если example.py clean):

Success: no issues found in 1 source file

3. Strictness flags — что включает strict = True:

FlagEffect
--disallow-untyped-defsAll functions must have type annotations
--disallow-untyped-callsCannot call untyped functions
--warn-return-anyWarn if function returns Any
--no-implicit-optionaldef f(x: int = None) — error (must write `int
--warn-unused-ignoresWarn on # type: ignore comments больше не nededed
--strict-equality1 == 'hello' — error (incompatible types)
--warn-redundant-castsWarn on cast(int, x) if x уже int

Это — production baseline. Rolling out strict постепенно: start с relaxed, add flags as project matures.


Brief alternatives — pyright и ty

pyright (Microsoft, OSS):

  • TypeScript-based — installed via npm install -g pyright (или pip install pyright).
  • Faster чем mypy (incremental, multi-core).
  • Used by VSCode Pylance extension under the hood.
  • Strict mode default-er чем mypy.
# Run pyright:
pyright example.py

ty (Astral.sh, 2024+):

  • Rust-based — ultra-fast (10-100x mypy).
  • Early stage (0.x version, 2026); production-readiness emerging.
  • Drop-in replacement aspirations для mypy CLI.
  • OpenAI acquired Astral в марте 2026 (OpenAI announcement) — deal pending regulatory review. Astral CEO Charlie Marsh подтвердил продолжение OSS development всех инструментов (uv, ruff, ty); OpenAI committed support. Для DE-команд это означает: ty / ruff / uv остаются open-source — но roadmap может integrate с Codex/AI tooling сильнее.
# Install (when available stable):
# pip install ty
# ty check example.py

Choice rationale для M07 курса: mypy — reference implementation, most mature, official Python.org documentation references. pyright worth knowing для VSCode users. ty — следить, но ещё early. Deferred глубокое лечение alternatives к v2 курса.


mypy + pre-commit hook + CI workflow — production hygiene. Phase 69 (Production Skills) будет cover:

  1. pre-commit hookpip install pre-commit + .pre-commit-config.yaml с mypy entry. Runs before every commit, blocks bad commits locally.
  2. GitHub Actions workflow — .github/workflows/typecheck.yml running mypy --strict src/ on PR.
  3. Strictness ratchet — start strict = False, add per-module strict overrides, ratchet к full strict per milestone.
  4. # type: ignore[error-code] — surgical bypass для third-party limitations.
# .github/workflows/typecheck.yml (Phase 69 preview):
name: Type Check

on: [push, pull_request]

jobs:
  mypy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python_version: '3.13'
      - run: pip install mypy
      - run: mypy --strict src/

Это — carrying Phase 69 forward-link: type hints (M07) → strict mypy (M07 урок 07) → CI integration (Phase 69).


What’s next — Phase 67 продолжается M08

M07 завершает type-system overlay. Phase 67 продолжается M08 (Testing с pytest) — Plan 67-03:

  • pytest taught conceptually (in-browser challenges использует platform test harness — pytest forbidden в Pyodide per SC#4).
  • Run-on-Your-Machine convention (pre-promised M00 урок 03) — этот урок 07 fulfilled first instance; M08 add ≥3 more callouts (pip install pytest + pytest -v + pytest —cov + conftest.py).
  • Type hints + pytest — typed fixtures, parametrize с типами, def test_foo(client: APIClient) -> None: pattern.

M07 self-assessment checklist

Перед переходом к M08 — убедитесь, что можете ответить без подсказки:

  1. Запишите signature функции принимающей list of int or None и возвращающей dict mapping str to list of float. (Solution: def f(items: list[int] | None) -> dict[str, list[float]]:)
  2. Объясните, почему class Stack[T]: (PEP 695) эквивалент class Stack(Generic[T]) с T = TypeVar('T'). Что хранится в __type_params__?
  3. Реализуйте Protocol Comparable с методом __lt__(self, other: object) -> bool. Покажите, что int, str, tuple все structurally compatible (никакого inheritance).
  4. Что вернёт dataclasses.fields(User)[0].type для @dataclass class User: id: int? (Answer: <class 'int'> — real type object). А после from __future__ import annotations? (Answer: 'int' — string. Pitfall 11.)
  5. Реализуйте TypeGuard[list[str]] predicate, который returns True iff list содержит только str. Объясните, почему без TypeGuard mypy не может narrow.
  6. Запишите class ValidationError(Exception) hierarchy с двумя sub-types InvalidFormatError + OutOfRangeError. Show full try/except/else/finally pattern в validate_age функции.
  7. Назовите mypy --strict команду + 5 flags, что она включает. Что такое mypy.ini strict = True?

Если уверенно отвечаете на все 7 — M07 пройдён. Сомневаетесь — re-read соответствующий урок.


Cross-course context

Cross-course → Spark: 03/06 spark-sql-catalog — mypy strict-mode валидация type hints до runtime — параллель Spark SQL Catalog: df.printSchema() показывает schema до execution; analyzer проверяет column types в plan resolution стадии и raises AnalysisException если type mismatch. Оба механизма — pre-execution static checking, отделяющие type-correctness от runtime errors. mypy работает на Python source level; Spark Catalog — на DataFrame plan level; принцип общий.


Ключевые выводы

  1. M07 — type-system overlay поверх runtime stack (closure, generator, dataclass, context-manager). Existing primitives получают typed view.
  2. PEP 585/604/695 + Protocol/TypedDict + runtime introspection + TypeGuard + typed exceptions = full vocabulary M07.
  3. Type checker (mypy / pyright / ty) — отдельный tool. Pyodide не type-check’ит — Run-on-Your-Machine для real validation.
  4. mypy — reference implementation. pip install mypy + mypy --strict file.py — basic workflow. mypy.ini для project-wide config.
  5. strict = True — production baseline strictness. Включает disallow-untyped-defs, warn-return-any, no-implicit-optional, etc.
  6. pyright (Microsoft) — faster alternative, used VSCode. ty (Astral.sh, акредитована OpenAI в марте 2026, OSS commitment сохраняется) — Rust-based, ultra-fast, emerging. Mature treatment alternatives — v2 курса.
  7. Forward-link Phase 69 — mypy в pre-commit hook + GitHub Actions workflow. Production hygiene: type hints meaningful только если CI enforces.
  8. M07 self-assessment — 7-item checklist для verification understanding перед M08.

Поздравляем — вы прошли type-system overlay. Дальше — M08 Testing с pytest.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 4. Зачем нужен **отдельный** type checker (mypy / pyright) — почему Python interpreter сам не enforce'ит type hints?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 7