Прямой ответ
Миграция на новую минорную версию Python — процедура на день, если делать её по плану и заранее: (1) инвентаризация зависимостей (все ли выпустили колёса/поддержку под 3.13), (2) прогон тестов на новой версии (локально/pyenv + матрица CI), (3) чистка deprecated-поведения (DeprecationWarning в логах теста — чек-лист будущих поломок), (4) переключение рантаймов (requires-python, Docker-базы, раннеры CI) с сохранённым откатным путём. Версия 3.13 интересна не только рутиной: интерактивный REPL с цветами и multiline-редактированием, экспериментальный JIT (PEP 744 — по умолчанию выключен), экспериментальная free-threaded сборка без GIL (PEP 703 — о GIL и параллельности в статье отдельный разбор) и улучшенные трейсбеки ошибок — но для проектов миграция прежде всего про совместимость.
Шаг 1. Зависимости: главный источник проблем
Проверка системно: для каждой зависимости — наличие колёс/заявленная поддержка 3.13 (pip index/страница пакета на PyPI, раздел classifiers); практически — собрать окружение 3.13 и попытаться установить lock: uv pip compile/pip-compile на python3.13 покажет нерезолвимое сразу (пакеты с C-расширениями без колёс полезут в source-сборку или упадут). Типовые отставшие: научный стек сразу после релиза (numpy/scipy догоняют за месяцы — к 2026-му давно готовы), нишевые библиотеки с заброшенной поддержкой (кандидаты на замену), пакеты, пинящие python_requires<3.13 (форк/замена/ждём). Собственный пакет — поднимаете classifiers и requires-python осмысленно: нижняя граница — политика поддержки (упаковка); в матрицу CI добавляете 3.13 до переключения прода (совместимость проверяется неделями параллельно).
Шаг 2. Deprecated и сломанное: читать чек-лист
What's New 3.13 — обязательное чтение на час: удалённые модули/атрибуты (исторически — то, что deprecated с 3.11/3.12: старые псевдонимы typing, элементы unittest-asyncio и т.п. — точный список в секции Removed), изменения поведения (детали CPython API важны авторам расширений, прикладному коду — меньше). Практический приём вместо чтения всего: прогнать тесты с -W error::DeprecationWarning (предупреждения становятся ошибками — код сам покажет, где он устарел) — на предыдущей версии (3.12) этот прогон дешевле, чем разбор на новой. Логи прода/стейджа с включёнными DeprecationWarning за неделю до миграции — вторая половина картины (тесты покрывают не всё).
Шаг 3. Матрица CI и переключение
Матрица CI — гайд по GitHub Actions: 3.13 добавляется в список версий, несколько прогонов — и список красных мест конкретен. Порядок переключения: локальные окружения команды (pyenv/uv/mise — 3.13 рядом с 3.12, не вместо), Docker-базы (python:3.13-slim — отдельная ветка/PR, полный прогон интеграционных тестов), раннеры/серверы — последними, с откатом «сменить тег образа обратно» (не «переустановить python»). Сроки поддержки: минорные версии Python живут ~5 лет (security-фиксы — 2 последних года); EOL текущей версии проекта — дедлайн, после которого миграция становится вынужденной и срочной (а срочные миграции ломаются). Разумная политика — апгрейд через 6–12 месяцев после релиза минора: экосистема догнала, баги первого периода исправлены.
Что 3.13 даёт прикладному коду
Не только галочку «мы на новом»: REPL — цветной, с paste-режимом и multiline-редактированием (отладка в консоли приятнее; pyrepl также в стандартном интерактиве), трейсбеки — точнее указания в сложных выражениях и цепочках исключений, производительность — стандартные «несколько процентов» специализации интерпретатора плюс экспериментальный JIT (--enable-experimental-jit на сборке; выигрыш пока скромный и workload-зависимый — включать по замеру, не по вере). free-threaded сборка (python3.13t) — отдельная установка для экспериментов с многопоточным CPU-параллелизмом без GIL; в прод-2026 нести рано (экосистема C-расширений догоняет), но попробовать на своём горячем коде полезно — возможно, через год это ваш путь. Для большинства проектов 3.13 — «та же программа, чуть быстрее, ошибки понятнее».
Откат и типичные провалы
Откат миграции должен быть операцией, а не проектом: образ/версия интерпретатора — один параметр (Docker-тег, pyenv-версия, setup-python в CI), данные и lock-файлы — версионируемы (откат lock — отдельный реверт). Типовые провалы и лечение: «колесо не собралось на 3.13» — дождаться/заменить пакет/остаться на 3.12 (миграция не гонка); «тесты зелёные, прод лежит» — расхождение зависимостей (prod-окружение собирается не из того lock; лечение — единый lock и установка из него везде); «DeprecationWarning стал SyntaxError» — удалённый синтаксис пропущен (лечение — прогон на 3.12 с -W error заранее); «сломался C-расширение своего производства» — пересобрать под 3.13 (ABI меняется каждый минор — в CI сборка под все поддерживаемые версии).
Практический сценарий: миграция сервиса за неделю
Реалистичный план для продуктового сервиса на 3.11. День первый — разведка: локально ставим 3.13 (pyenv/uv), собираем окружение из lock-файла, фиксируем, что не установилось (обычно один-два пакета с C-расширениями — проверяем статусы, ищем замены или ждём колёс); тесты на 3.13 — список падений (часто пустой или короткий). День второй — чистка: прогон на 3.11 с -W error::DeprecationWarning в тестовом контуре выявляет устаревшие вызовы, правки вносятся в основную ветку и совместимы с обеими версиями (миграция не должна быть «большим взрывом»). День третий — CI: 3.13 добавляется в матрицу рядом с 3.11/3.12, неделя параллельных прогонов накапливает статистику (включая редко выполняемые nightly-задачи). День четвёртый — стейджинг: Docker-база меняется на python:3.13-slim отдельным PR, полный прогон интеграционных тестов и канареечный период на стейдже; метрики сравниваются со стартовой версией (время старта, потребление памяти, латентность — регрессии редки, но проверяются цифрами). День пятый — прод: смена тега образа с сохранением предыдущего (откат — смена тега обратно за минуту) и наблюдение сутки. Команда при этом продолжает работать в обычном темпе: ни одна правка не ждала «окна миграции», потому что миграция шла маленькими совместимыми шагами. Ровно так же через год проходится 3.14 — процедура становится рутиной.
FAQ
Стоит ли мигрировать сразу в день релиза минора? Прикладным проектам — нет (экосистема догоняет 3–6 месяцев); библиотекам — добавить версию в матрицу заранее полезно (пользователи спросят). Золотая середина — релиз+полгода.
Пропустили две версии (3.11 → 3.13)? Нормально и даже проще: читаете два What's New, удалённое копится — но миграция одна. Хуже — затянуть до EOL: тогда добавляется давление и устаревшие зависимости, которые уже никто не чинит.
Free-threaded сборка заменит multiprocessing? В перспективе — частично (потоки вместо процессов для CPU-параллелизма), но в 3.13 это эксперимент: однопоточная производительность ниже, не все расширения готовы. Планируйте — не внедряйте, и следите за статусом в своих зависимостях.
Нужно ли переписывать код под новые фичи? Нет: новые версии обратно совместимы в рамках языка — старый код работает. Фичи (pattern matching из 3.10, JIT из 3.13) внедряются в новом коде по желанию; миграция и модернизация — разные задачи.
Источники: What's New in Python 3.13, PEP 744 (JIT), PEP 703 (free-threading) — ссылки в шапке.