Python откатил архитектуру сборщика мусора прямо в патч-релизе
Python 3.14.0 в октябре сменил сборщик мусора — с generational на incremental, обещали паузы на больших кучах короче на порядок. В 3.14.5 в мае это просто откатили назад. Патч-релиз отменяет архитектурное решение целого мажора — в CPython такое почти не бывает.
Что пошло не так: на долгоживущих процессах (веб-серверы, пайплайны) резидентная память росла без остановки. По разбору pydevtools, счётчик инкрементальной работы мог уходить в минус — и полный проход сборщика попросту не запускался: в одном из кейсов первый full collection случился только на 20 000-й итерации, а в устойчивом состоянии в памяти висело больше 90 тысяч непрочищенных циклов.
Core team не стала ждать плановый 3.14.6 — ускорили релиз и откатили incremental GC сразу в 3.14 и 3.15, вернув generational из 3.13.
Смущает не сам баг — memory-менеджмент штука тонкая. Смущает то, что фичу пять месяцев гоняли через альфы, беты и rc — и всё равно поймали только когда реальный прод начал жаловаться на RSS. Если вы успели обновиться до 3.14.0–3.14.4 и мониторили память — вы только что бесплатно побетатестили GC для всего коммьюнити.
🔗 discuss.python.org, pydevtools.com
Python 3.14.0 в октябре сменил сборщик мусора — с generational на incremental, обещали паузы на больших кучах короче на порядок. В 3.14.5 в мае это просто откатили назад. Патч-релиз отменяет архитектурное решение целого мажора — в CPython такое почти не бывает.
Что пошло не так: на долгоживущих процессах (веб-серверы, пайплайны) резидентная память росла без остановки. По разбору pydevtools, счётчик инкрементальной работы мог уходить в минус — и полный проход сборщика попросту не запускался: в одном из кейсов первый full collection случился только на 20 000-й итерации, а в устойчивом состоянии в памяти висело больше 90 тысяч непрочищенных циклов.
Core team не стала ждать плановый 3.14.6 — ускорили релиз и откатили incremental GC сразу в 3.14 и 3.15, вернув generational из 3.13.
Смущает не сам баг — memory-менеджмент штука тонкая. Смущает то, что фичу пять месяцев гоняли через альфы, беты и rc — и всё равно поймали только когда реальный прод начал жаловаться на RSS. Если вы успели обновиться до 3.14.0–3.14.4 и мониторили память — вы только что бесплатно побетатестили GC для всего коммьюнити.
🔗 discuss.python.org, pydevtools.com
Discussions on Python.org
Reverting the incremental GC in Python 3.14 and 3.15
Python 3.14 shipped with a new incremental garbage collector. However, we’ve had a number of reports of significant memory pressure in production environments. We’ve decided to revert it in both 3.14 and 3.15, and go back to the generational GC from 3.13.…
Гитхаб был чистый. Пакет — нет
В mrmustard 0.7.4 — квантовой библиотеке Xanadu на PyPI — три дня назад нашли стилер. Тащит с диска SSH-ключи, AWS- и Kubernetes-креды и ставит три способа зацепиться в системе на будущее.
Но бесит не сам стилер, а то, как его спрятали.
У версии 0.7.4 нет ни тега, ни релиза, ни коммита в GitHub-репозитории. Открываешь исходники на гитхабе — там всё чисто, ревью ничего не найдёт. Вредонос добавили только в артефакт, который улетает через
Отдельная деталь для тех, кто вообще думает про такие атаки: пейлоад сначала проверяет, что он не в CI и не в контейнере, и только потом стартует. Целились именно в ноутбуки разрабов и исследователей, а не в одноразовые раннеры.
После такого фраза «да я гитхаб пролистал, там нормально» перестаёт что-либо значить. Гитхаб и то, что реально прилетает по
Нашёл всё не Xanadu, а сторонний исследователь из Aikido Security. PyPI пакет после этого отправил в карантин.
🔗 stepsecurity.io, safedep.io
В mrmustard 0.7.4 — квантовой библиотеке Xanadu на PyPI — три дня назад нашли стилер. Тащит с диска SSH-ключи, AWS- и Kubernetes-креды и ставит три способа зацепиться в системе на будущее.
Но бесит не сам стилер, а то, как его спрятали.
У версии 0.7.4 нет ни тега, ни релиза, ни коммита в GitHub-репозитории. Открываешь исходники на гитхабе — там всё чисто, ревью ничего не найдёт. Вредонос добавили только в артефакт, который улетает через
pip install: угнали токен CI из аккаунта мейнтейнера (это был ziofil, автор проекта) и залили пакет в PyPI напрямую, мимо обычного пайплайна.Отдельная деталь для тех, кто вообще думает про такие атаки: пейлоад сначала проверяет, что он не в CI и не в контейнере, и только потом стартует. Целились именно в ноутбуки разрабов и исследователей, а не в одноразовые раннеры.
После такого фраза «да я гитхаб пролистал, там нормально» перестаёт что-либо значить. Гитхаб и то, что реально прилетает по
pip install, — два разных артефакта, и связывает их только честность мейнтейнера в момент публикации. Если пиньте пакеты по хэшу wheel — вот ровно тот случай, когда это спасает, а не паранойя.Нашёл всё не Xanadu, а сторонний исследователь из Aikido Security. PyPI пакет после этого отправил в карантин.
🔗 stepsecurity.io, safedep.io
www.stepsecurity.io
Compromised PyPI Package: mrmustard 0.7.4 Steals SSH, Cloud, and Kubernetes Credentials - StepSecurity
mrmustard 0.7.4 on PyPI was a credential stealer that ran on import, exfiltrating SSH keys, AWS, and Kubernetes credentials. Here is the analysis, IOCs, and how to respond.
PyPI перестал пускать в старые релизы
Запушил докрутку — забытое wheel под 3.14, например — в релиз, которому две недели? С 22 июля PyPI такое просто не примет.
Правило простое: через 14 дней после публикации релиз закрывается для новых файлов насовсем, без исключений. Тема всплывала ещё в PEP 740 в 2024-м, но реально завелась в марте — после того как через скомпрометированные токены и воркфлоу закинули мусор в LiteLLM и Telnyx. Старые доверенные релизы — идеальная мишень: их качают привычно, без опаски.
Перед тем как включать, проверили, насколько больно это ударит по обычным майнтейнерам: из топ-15k пакетов только 56 хоть раз добавляли cp314-колесо релизу старше двух недель. Почти никто так не работает — а вот атакующему такая лазейка была подарком.
Шероховатость: официального способа проверить статус релиза («закрыт/не закрыт») пока нет — узнаёшь только по 403 при аплоаде. Мелочь, но для CI, который доливает артефакт постфактум, это неприятный сюрприз.
🔗 blog.pypi.org
Запушил докрутку — забытое wheel под 3.14, например — в релиз, которому две недели? С 22 июля PyPI такое просто не примет.
Правило простое: через 14 дней после публикации релиз закрывается для новых файлов насовсем, без исключений. Тема всплывала ещё в PEP 740 в 2024-м, но реально завелась в марте — после того как через скомпрометированные токены и воркфлоу закинули мусор в LiteLLM и Telnyx. Старые доверенные релизы — идеальная мишень: их качают привычно, без опаски.
Перед тем как включать, проверили, насколько больно это ударит по обычным майнтейнерам: из топ-15k пакетов только 56 хоть раз добавляли cp314-колесо релизу старше двух недель. Почти никто так не работает — а вот атакующему такая лазейка была подарком.
Шероховатость: официального способа проверить статус релиза («закрыт/не закрыт») пока нет — узнаёшь только по 403 при аплоаде. Мелочь, но для CI, который доливает артефакт постфактум, это неприятный сюрприз.
🔗 blog.pypi.org
blog.pypi.org
Releases now reject new files after 14 days - The Python Package Index Blog
PyPI no longer allows publishing new files to releases older than 14 days.
uv наконец умеет проверять типы точечно, а не всей монорепой разом
Пока весь техтвиттер спорит про JIT и Rust в CPython, Astral тихо прокачивает uv в сторону монорепо.
23 июля вышел uv 0.11.32 — добавили
До этого патча
Флаг мелкий, но по нему хорошо видно курс: после покупки Astral в марте OpenAI явно не делает из uv просто быстрый pip — это заявка на единый вход в lint/format/typecheck. Направление мне нравится: меньше
Минус один:
🔗 github.com, github.com
Пока весь техтвиттер спорит про JIT и Rust в CPython, Astral тихо прокачивает uv в сторону монорепо.
23 июля вышел uv 0.11.32 — добавили
--package и --all-packages для uv check. Сама команда check появилась только в июне: она гоняет ty, тайп-чекер Astral, прямо из uv, без отдельного pip install ty.До этого патча
uv check в воркспейсе с десятком пакетов проверял всё разом — падает один сервис, и непонятно, на что смотреть в первую очередь. Теперь можно натравить проверку на конкретный пакет флагом --package, а --all-packages явно просит пройтись по всем.Флаг мелкий, но по нему хорошо видно курс: после покупки Astral в марте OpenAI явно не делает из uv просто быстрый pip — это заявка на единый вход в lint/format/typecheck. Направление мне нравится: меньше
pip install ruff mypy black в каждом новом проекте.Минус один:
check всё ещё за preview-флагом, синтаксис может поменяться до стабильного релиза — тащить в CI прямо сейчас я бы не спешил.🔗 github.com, github.com
GitHub
Release 0.11.32 · astral-sh/uv
Release Notes
Released on 2026-07-23.
Preview features
Add --package and --all-packages selection to uv check (#20628)
Allow uv upgrade to update multiple marker-specific declarations of the same ...
Released on 2026-07-23.
Preview features
Add --package and --all-packages selection to uv check (#20628)
Allow uv upgrade to update multiple marker-specific declarations of the same ...
object() как сентинел годами тихо ломался в pickle — и почти никто не замечал
Сколько раз ты писал
В Python 3.15 завезли builtin
Мелочь, а сколько самодельных
🔗 peps.python.org
Сколько раз ты писал
MISSING = object() для дефолта, который надо отличить от None? Я — постоянно. И не знал, что если такой сентинел уедет через pickle (сессии, кэш, multiprocessing, Celery) — на другом конце restored is MISSING вернёт False. Тихий баг, всплывающий только в проде, когда объект пересекает границу процесса.В Python 3.15 завезли builtin
sentinel() (PEP 661). Он запоминает модуль и имя, поэтому pickle и copy.deepcopy восстанавливают тот же объект, а не подделку. Плюс вменяемый repr из коробки — никаких <object object at 0x7f...> в логах.Мелочь, а сколько самодельных
class _Missing: pass теперь можно выкинуть.🔗 peps.python.org
В Python 3.15 завезли нормальный сэмплирующий профайлер
Полгода таскал
Новый модуль
Частота по умолчанию 1кГц, можно гнать хоть до 1МГц. На выходе — flamegraph, pstats или html, на выбор. Профайлер и целевой процесс должны быть на одной минорной версии — из 3.14 к процессу на 3.15 не приаттачиться.
Заодно
🔗 peps.python.org, docs.python.org
Полгода таскал
py-spy в докер-образ, потому что сэмплирующего профайлера в stdlib не было — только cProfile, который считает каждый вызов и заметно тормозит прод. В 3.15 это закрыли.Новый модуль
profiling.sampling (кодовое имя Tachyon, PEP 799) цепляется к живому процессу по PID и читает стек снаружи — без инструментирования кода и без рестарта:python -m profiling.sampling attach 12345Частота по умолчанию 1кГц, можно гнать хоть до 1МГц. На выходе — flamegraph, pstats или html, на выбор. Профайлер и целевой процесс должны быть на одной минорной версии — из 3.14 к процессу на 3.15 не приаттачиться.
Заодно
cProfile переехал в profiling.tracing (алиас остался жить), а древний модуль profile объявили deprecated — выпилят в 3.17.py-spy из докерфайла выкидываю на следующем спринте: не вижу смысла тащить внешний бинарник, когда то же самое теперь есть из коробки.🔗 peps.python.org, docs.python.org
Python Enhancement Proposals (PEPs)
PEP 799 – A dedicated profiling package for organizing Python profiling tools | peps.python.org
This PEP proposes the creation of a new standard library module named profiling to organize Python’s built-in profiling tools under a single, coherent namespace.
До Python 3.15 осталось 66 дней
Открыл вчера changelog beta 4 — и это последняя бета. Дальше только релиз-кандидаты.
7 мая зафиксировали фичи (PEP 790) — с тех пор в 3.15 можно только чинить баги, нового уже не прилетит. 18 июля вышла b4: ~298 фиксов с прошлой беты, и всё, бета-цикл закрыт.
Сегодня мы ровно между b4 и rc1 — до октябрьского релиза 66 дней. Если у вас в проекте есть код под
🔗 blog.python.org, peps.python.org
Открыл вчера changelog beta 4 — и это последняя бета. Дальше только релиз-кандидаты.
7 мая зафиксировали фичи (PEP 790) — с тех пор в 3.15 можно только чинить баги, нового уже не прилетит. 18 июля вышла b4: ~298 фиксов с прошлой беты, и всё, бета-цикл закрыт.
Сегодня мы ровно между b4 и rc1 — до октябрьского релиза 66 дней. Если у вас в проекте есть код под
sys.version_info >= (3, 15) — самое время гонять его на бете, а не ждать октября: после rc1 (4 августа) ABI и API стараются больше не трогать.🔗 blog.python.org, peps.python.org
Последние дни ковырял тестирование AI-генерации в Vaulto Cards.
Само расширение довольно простое: выделяешь слово или фразу в браузере, и оно превращается в учебную карточку. Недавно я добавил библиотеку карточек и режим обучения, поэтому генератор стал заметно сложнее.
И появилась проблема: после каждой правки нужно было вручную открывать расширение, создавать карточки и смотреть, не стало ли хуже.
В итоге я вынес генерацию в отдельный Node.js-скрипт. Он запускает тот же пайплайн, что используется в расширении, только без интерфейса, а результат сохраняет в JSON и картинки.
Так довольно быстро нашлись странные ошибки. Например, целое предложение иногда обрабатывалось как одно случайное слово, а фраза
Пришлось явно разделить режимы
Ещё отдельно описал весь запуск в
Теперь, когда я открываю новую сессию Claude Code, мне не нужно каждый раз объяснять, как про
Само расширение довольно простое: выделяешь слово или фразу в браузере, и оно превращается в учебную карточку. Недавно я добавил библиотеку карточек и режим обучения, поэтому генератор стал заметно сложнее.
И появилась проблема: после каждой правки нужно было вручную открывать расширение, создавать карточки и смотреть, не стало ли хуже.
В итоге я вынес генерацию в отдельный Node.js-скрипт. Он запускает тот же пайплайн, что используется в расширении, только без интерфейса, а результат сохраняет в JSON и картинки.
Так довольно быстро нашлись странные ошибки. Например, целое предложение иногда обрабатывалось как одно случайное слово, а фраза
el gato определялась просто как артикль.Пришлось явно разделить режимы
WORD и SENTENCE и добавить очистку входных данных.Ещё отдельно описал весь запуск в
TESTING_AI_CARDS.md и добавил ссылку в CLAUDE.md.Теперь, когда я открываю новую сессию Claude Code, мне не нужно каждый раз объяснять, как про
У pip, uv и Poetry впервые будет общий выборный начальник
У pip, uv, Poetry и вообще всего Python-пакеджинга до сегодняшнего дня не было ни одного выборного органа — решения по интероп-спекам (wheel, PEP 440 и остальные) принимала неформальная PyPA, группа мейнтейнеров без единого мандата от комьюнити.
Как объявили в blog.python.org, сегодня в 14:00 UTC стартовали номинации сразу в новый Packaging Council (PEP 772, утверждён в апреле) и в PSF Board — окно до 11 августа, голосование 1–15 сентября.
Мест пять: топ-2 по голосам — два года (когорта A), следующие три — год (когорта B). Дальше когорты ротируются по очереди, чтобы совет не менялся весь разом.
Спорный PEP уровня будущего wheel v2 теперь будет решать голосование пятерых выборных, а не один решительный мейнтейнер, который раньше просто брал и делал. Медленнее, зато без личных вето — для стандартов, на которых держится весь пакеджинг, по-моему разумный обмен.
🔗 blog.python.org, blog.python.org, peps.python.org
У pip, uv, Poetry и вообще всего Python-пакеджинга до сегодняшнего дня не было ни одного выборного органа — решения по интероп-спекам (wheel, PEP 440 и остальные) принимала неформальная PyPA, группа мейнтейнеров без единого мандата от комьюнити.
Как объявили в blog.python.org, сегодня в 14:00 UTC стартовали номинации сразу в новый Packaging Council (PEP 772, утверждён в апреле) и в PSF Board — окно до 11 августа, голосование 1–15 сентября.
Мест пять: топ-2 по голосам — два года (когорта A), следующие три — год (когорта B). Дальше когорты ротируются по очереди, чтобы совет не менялся весь разом.
Спорный PEP уровня будущего wheel v2 теперь будет решать голосование пятерых выборных, а не один решительный мейнтейнер, который раньше просто брал и делал. Медленнее, зато без личных вето — для стандартов, на которых держится весь пакеджинг, по-моему разумный обмен.
🔗 blog.python.org, blog.python.org, peps.python.org
GIL уходит поэтапно — и по цифрам это заметно
Три фазы у free-threaded CPython, и по цифрам видно, что вторая — не косметика.
Phase I (3.13, октябрь 2024): экспериментальный билд, adaptive-интерпретатор выключен ради безопасности — минус 40% на single-thread коде. Многие тогда попробовали, увидели просадку и закрыли тему для себя.
Phase II (3.14, сейчас): PEP 779 приняли 16 июня 2025-го, статус — официально поддерживается, но не по умолчанию. Adaptive-интерпретатор вернули, просадка упала до 1% на macOS aarch64 и максимум 8% на x86-64 Linux.
Phase III — билд без GIL по умолчанию — пока просто пустая графа в PEP 779: критериев для неё авторы сознательно не написали. Ни PEP, ни даты — Steering Council решила сперва пожить с двумя билдами и посмотреть, что покажет прод.
🔗 peps.python.org, docs.python.org
Три фазы у free-threaded CPython, и по цифрам видно, что вторая — не косметика.
Phase I (3.13, октябрь 2024): экспериментальный билд, adaptive-интерпретатор выключен ради безопасности — минус 40% на single-thread коде. Многие тогда попробовали, увидели просадку и закрыли тему для себя.
Phase II (3.14, сейчас): PEP 779 приняли 16 июня 2025-го, статус — официально поддерживается, но не по умолчанию. Adaptive-интерпретатор вернули, просадка упала до 1% на macOS aarch64 и максимум 8% на x86-64 Linux.
Phase III — билд без GIL по умолчанию — пока просто пустая графа в PEP 779: критериев для неё авторы сознательно не написали. Ни PEP, ни даты — Steering Council решила сперва пожить с двумя билдами и посмотреть, что покажет прод.
🔗 peps.python.org, docs.python.org
Один Host-заголовок обходил защиту в каждом FastAPI
Пересчитал даты в advisory — между «нашли дыру» и «патч в релизе» прошло почти четыре месяца.
27 января X41 D-Sec наткнулись на баг, когда по заказу OSTIF гоняли аудит vLLM. Причина глубже: в Starlette
Мейнтейнеров уведомили 4 февраля, патч предложили 1 марта, а зашили в релиз только 21 мая — Starlette 1.0.1. Раскрыли на следующий день.
Starlette — подложка под FastAPI, vLLM, LiteLLM, 325 млн скачиваний в неделю. CVSS у мейнтейнера 6.5, у X41 — 7.0, и это не формальность: чем чаще access-контроль держится на пути запроса, а не на честной аутентификации, тем больнее такая дыра.
Если у вас FastAPI и Starlette не трогали с весны — гляньте версию.
🔗 github.com, ostif.org, badhost.org
Пересчитал даты в advisory — между «нашли дыру» и «патч в релизе» прошло почти четыре месяца.
27 января X41 D-Sec наткнулись на баг, когда по заказу OSTIF гоняли аудит vLLM. Причина глубже: в Starlette
request.url собирали из заголовка Host без проверки, а роутинг при этом смотрел на сырой путь из scope. Подсунул кривой Host — и request.url.path, на который завязаны миддлвари с проверками доступа, начинает врать.Мейнтейнеров уведомили 4 февраля, патч предложили 1 марта, а зашили в релиз только 21 мая — Starlette 1.0.1. Раскрыли на следующий день.
Starlette — подложка под FastAPI, vLLM, LiteLLM, 325 млн скачиваний в неделю. CVSS у мейнтейнера 6.5, у X41 — 7.0, и это не формальность: чем чаще access-контроль держится на пути запроса, а не на честной аутентификации, тем больнее такая дыра.
Если у вас FastAPI и Starlette не трогали с весны — гляньте версию.
🔗 github.com, ostif.org, badhost.org
Один релиз Pillow закрыл четыре дыры разом
Проверил
12.3.0 вышла ещё 1 июля, но CVE на самый неприятный баг из четырёх — EPS-парсер уходит в бесконечный цикл на отрицательном byte count в
В том же релизе тихо закрыли ещё три штуки: PDF без лимита на декомпрессию (классический zip bomb), shell-инъекцию через
Если Pillow где-то в проекте парсит файлы от пользователей — это апдейт на сегодня, а не «когда-нибудь занесу в спринт».
🔗 github.com, github.com
Проверил
pip show pillow в паре своих проектов — из них не все жили на актуальной версии.12.3.0 вышла ещё 1 июля, но CVE на самый неприятный баг из четырёх — EPS-парсер уходит в бесконечный цикл на отрицательном byte count в
%%BeginBinary — раскрыли только 14-го, и это до сих пор мало где обсуждали.В том же релизе тихо закрыли ещё три штуки: PDF без лимита на декомпрессию (классический zip bomb), shell-инъекцию через
ImageShow.WindowsViewer, если путь к файлу не свой, и утечку памяти на специально собранном JPEG2000.Если Pillow где-то в проекте парсит файлы от пользователей — это апдейт на сегодня, а не «когда-нибудь занесу в спринт».
🔗 github.com, github.com
Ruff одним патчем увеличил число правил в 7 раз
59 → 413. Именно так вырос дефолтный набор правил в Ruff 0.16.0, который вышел 23 июля.
С версии 0.1.0 в линтере накопилось 260+ новых правил — но по умолчанию их не включали, боялись сломать людям CI. Тут решились: заодно выпилили 18 самых холиварных pycodestyle/pyflakes-правил вроде E731 и F403 — слишком спорные, чтобы навязывать их всем.
Саймон Уиллисон прогнал релиз по своим проектам — и в sqlite-utils нашлось 1618 новых замечаний на коде, который днём раньше проходил линт чисто.
Откатить старое поведение:
🔗 astral.sh, simonwillison.net, github.com
59 → 413. Именно так вырос дефолтный набор правил в Ruff 0.16.0, который вышел 23 июля.
С версии 0.1.0 в линтере накопилось 260+ новых правил — но по умолчанию их не включали, боялись сломать людям CI. Тут решились: заодно выпилили 18 самых холиварных pycodestyle/pyflakes-правил вроде E731 и F403 — слишком спорные, чтобы навязывать их всем.
Саймон Уиллисон прогнал релиз по своим проектам — и в sqlite-utils нашлось 1618 новых замечаний на коде, который днём раньше проходил линт чисто.
Откатить старое поведение:
select = ["E4", "E7", "E9", "F"] в конфиге.🔗 astral.sh, simonwillison.net, github.com
Django 6.1 отрезает Python 3.10, 3.11 и Postgres 14
У меня в трёх сервисах на проде до сих пор Python 3.10 — и до 5 августа с этим лучше определиться.
Django 6.1 rc1 вышел 22 июля, финальный релиз — на днях. И это не косметический минор: под капотом подняли нижнюю планку сразу по всей матрице окружений.
PostgreSQL 14 выкидывают — не потому что кто-то поленился тестировать, а потому что апстрим сам хоронит эту версию в ноябре. SQLite подняли с 3.31 до 3.37 — это уже не «Ubuntu 20.04 из коробки», такое придётся доставлять руками. MariaDB и MySQL тоже сдвинули на пару минорных версий вверх.
Если в докерфайле годами лежит
🔗 djangoproject.com, docs.djangoproject.com
У меня в трёх сервисах на проде до сих пор Python 3.10 — и до 5 августа с этим лучше определиться.
Django 6.1 rc1 вышел 22 июля, финальный релиз — на днях. И это не косметический минор: под капотом подняли нижнюю планку сразу по всей матрице окружений.
PostgreSQL 14 выкидывают — не потому что кто-то поленился тестировать, а потому что апстрим сам хоронит эту версию в ноябре. SQLite подняли с 3.31 до 3.37 — это уже не «Ubuntu 20.04 из коробки», такое придётся доставлять руками. MariaDB и MySQL тоже сдвинули на пару минорных версий вверх.
Если в докерфайле годами лежит
python:3.10-slim и старый postgres:14 — это тот редкий апгрейд, где pip install -U django сам по себе не сработает, пока не поднимете инфру под ним.🔗 djangoproject.com, docs.djangoproject.com
uv 0.12 решил, что вам нужен пакет, а не скрипт
uv init с 28 июля стал строже: вместо голого
С версии 0.12.0
Заодно ужесточили
Голый layout никуда не делся —
🔗 github.com, github.com
uv init с 28 июля стал строже: вместо голого
main.py в корне — сразу пакет.С версии 0.12.0
uv init кладёт код в src/имя/_init_.py, подключает [build-system] с собственным бэкендом uv_build и сразу даёт uv build собрать wheel и tar.gz. Такой layout был дефолтом ещё в v0.3, но в v0.4 его убрали — как объяснили в issue #20185, начинающих путал hatchling. Теперь astral сделали свой билд-бэкенд и вернули пакет по умолчанию.Заодно ужесточили
--project: раньше несуществующий путь давал warning и uv тихо продолжал работать в текущей директории, теперь сразу падает с ошибкой. Отключить нельзя.Голый layout никуда не делся —
uv init --no-package name. Но по умолчанию теперь именно так: инструмент решил, что раз вы его открыли, скрипта вам мало, нужен пакет.🔗 github.com, github.com
Дважды в 2026-м патч CPython сам оказался дырявым
16 марта в security-announce@python.org ушло письмо: CVE-2026-3644 закрывает дыру в
Тогда, в CVE-2026-0672, дырявыми были control-символы в куки (header injection). Патч выправил
Это уже второй раз в 2026-м: с
Если пишете регресс-тест на CVE — гоняйте его не только на PoC из адвизори, а на соседних методах того же класса:
🔗 mail.python.org, mail.python.org, github.com
16 марта в security-announce@python.org ушло письмо: CVE-2026-3644 закрывает дыру в
http.cookies.Morsel, вроде бы починенную в феврале.Тогда, в CVE-2026-0672, дырявыми были control-символы в куки (header injection). Патч выправил
.output(), но .update(), оператор |= и unpickle остались непроверенными — это исправили только в марте, судя по коммиту в cpython.Это уже второй раз в 2026-м: с
webbrowser.open() та же схема, только месяцем позже. CVE-2026-4519 (CVSS 7.0) запрещал URL с ведущим дефисом — часть браузеров читает его как CLI-флаг, командная инъекция. Мейнтейнеры отсекли дефис, но не все пути к нему — обход остался рабочим, и через месяц вышла CVE-2026-4786 с пометкой «incomplete mitigation» в security-announce.Если пишете регресс-тест на CVE — гоняйте его не только на PoC из адвизори, а на соседних методах того же класса:
.update(), |=, unpickle.🔗 mail.python.org, mail.python.org, github.com
$90 000 — весь бюджет PSF на гранты в этом году
Питон-митап у вас в городе получит от PSF максимум $2000 на всю конференцию. Раньше так не было.
Год назад фонд просто кончил деньги: 1 августа 2025-го грантовую программу приостановили, бюджет съели раньше срока. В октябрьском заявлении фонда — отказ от гранта NSF на $1.5M, условием было подписать отказ от любых DEI-программ фонда целиком, не только в этом проекте. В январе дыру частично закрыл донат Anthropic на $1.5M.
Как написали в блоге PSF в июле, программу перезапустили — но не ту, что была. Потолок на конференцию срезали до $2000, воркшопы остались на $1500. Заявки берут 4–25 августа, и только на мероприятия с декабря 2026 по апрель 2027.
Весь этот новый раунд целиком — $90 000 на всех сразу за год.
🔗 pyfound.blogspot.com, pyfound.blogspot.com, pyfound.blogspot.com
Питон-митап у вас в городе получит от PSF максимум $2000 на всю конференцию. Раньше так не было.
Год назад фонд просто кончил деньги: 1 августа 2025-го грантовую программу приостановили, бюджет съели раньше срока. В октябрьском заявлении фонда — отказ от гранта NSF на $1.5M, условием было подписать отказ от любых DEI-программ фонда целиком, не только в этом проекте. В январе дыру частично закрыл донат Anthropic на $1.5M.
Как написали в блоге PSF в июле, программу перезапустили — но не ту, что была. Потолок на конференцию срезали до $2000, воркшопы остались на $1500. Заявки берут 4–25 августа, и только на мероприятия с декабря 2026 по апрель 2027.
Весь этот новый раунд целиком — $90 000 на всех сразу за год.
🔗 pyfound.blogspot.com, pyfound.blogspot.com, pyfound.blogspot.com
mypy — 45 секунд. ty — 2.
Полез проверять цифры Astral, ожидая маркетингового преувеличения — не подтвердилось. Бенчмарк честный: home-assistant, холодный запуск, без кэша. И тесты не спрятаны — в репозитории ty на GitHub бенчмарки лежат открыто, можно прогнать на своём проекте, а не верить графику на слово.
У той же команды за плечами uv и ruff, где «в разы быстрее» оказалось правдой, а не слоганом — доверия это добавляет.
Stable ещё не вышел, Astral сейчас чинят поддержку Pydantic и Django, а не гонятся за цифрами. У меня mypy в проекте фоном не бесит, переезжать сегодня не буду — но как выкатят stable, погоняю на отдельной ветке, не сразу в CI.
🔗 astral.sh, github.com
Полез проверять цифры Astral, ожидая маркетингового преувеличения — не подтвердилось. Бенчмарк честный: home-assistant, холодный запуск, без кэша. И тесты не спрятаны — в репозитории ty на GitHub бенчмарки лежат открыто, можно прогнать на своём проекте, а не верить графику на слово.
У той же команды за плечами uv и ruff, где «в разы быстрее» оказалось правдой, а не слоганом — доверия это добавляет.
Stable ещё не вышел, Astral сейчас чинят поддержку Pydantic и Django, а не гонятся за цифрами. У меня mypy в проекте фоном не бесит, переезжать сегодня не буду — но как выкатят stable, погоняю на отдельной ветке, не сразу в CI.
🔗 astral.sh, github.com
frozendict — новый builtin в Python 3.15
Питон 30+ лет жил без built-in неизменяемого dict — в 3.15 это наконец исправили.
PEP 814 приняли в феврале,
Специфичного кода в патче — всего ~560 строк (7%), остальное общий движок с dict. Из коробки работают json, pickle, pprint, marshal, xml.etree.
Финал 3.15 — в октябре.
🔗 peps.python.org, vstinner.github.io
Питон 30+ лет жил без built-in неизменяемого dict — в 3.15 это наконец исправили.
PEP 814 приняли в феврале,
frozendict уже в бета-сборках. Не путайте с types.MappingProxyType — это просто read-only обёртка над dict, hash() от неё как не было, так и нет. frozendict — отдельный тип, хешируемый, если хешируемы все значения: можно класть конфиг прямо в ключ словаря или в set, без tuple(sorted(d.items())).Специфичного кода в патче — всего ~560 строк (7%), остальное общий движок с dict. Из коробки работают json, pickle, pprint, marshal, xml.etree.
Финал 3.15 — в октябре.
🔗 peps.python.org, vstinner.github.io
На PyPI кража секретов начинается раньше, чем на npm — прямо на import
17 пакетов с одинаковым 1.0.0 — и это само по себе должно было насторожить раньше, чем название.
Socket 7 июля раскрыл кампанию: на PyPI и npm одновременно выложили фейковые SDK для Paysafe, Skrill и Neteller. Методы внутри выглядят рабочими, отвечают «успех» — и молча сливают секреты на C2 в AWS.
На PyPI кража стартует прямо при
Перед тем как что-то украсть, скрипт смотрит на hostname и число ядер. Меньше двух CPU или слово sandbox в имени машины — и он просто ничего не делает.
🔗 socket.dev
17 пакетов с одинаковым 1.0.0 — и это само по себе должно было насторожить раньше, чем название.
Socket 7 июля раскрыл кампанию: на PyPI и npm одновременно выложили фейковые SDK для Paysafe, Skrill и Neteller. Методы внутри выглядят рабочими, отвечают «успех» — и молча сливают секреты на C2 в AWS.
На PyPI кража стартует прямо при
import, без единого вызова функции. В npm-версии для этого нужен настоящий Paysafe API-ключ — там разработчики малвари решили не размениваться по мелочам.Перед тем как что-то украсть, скрипт смотрит на hostname и число ядер. Меньше двух CPU или слово sandbox в имени машины — и он просто ничего не делает.
🔗 socket.dev