Zen of Python
Полный Дзен Пайтона в одном канале Разместить рекламу: @tproger_sales_bot Правила общения: https://tprg.ru/rules Другие каналы: @tproger_channels Сайт: https://tprg.ru/site Регистрация в перечне РКН: https://tprg.ru/xZOL
Ko'proq ko'rsatish📈 Telegram kanali Zen of Python analitikasi
Zen of Python (@zen_of_python) Rus til segmentidagi kanali faol ishtirokchi. Hozirda hamjamiyat 19 241 obunachidan iborat bo'lib, Texnologiyalar & Aralashmalar toifasida 6 971-o'rinni va Rossiya mintaqasida 34 978-o'rinni egallagan.
📊 Auditoriya ko‘rsatkichlari va dinamika
невідомо sanasidan buyon loyiha tez o‘sib, 19 241 obunachiga ega bo‘ldi.
23 Iyun, 2026 dagi oxirgi ma’lumotlarga ko‘ra kanal barqaror faollikka ega. Oxirgi 30 kunda obunachilar soni -12 ga, so‘nggi 24 soatda esa -9 ga o‘zgardi va umumiy qamrov yuqori darajada qolmoqda.
- Tasdiqlash holati: Tasdiqlanmagan
- Jalb etish (ER): Auditoriya o‘rtacha 11.48% darajada jalb etiladi. Nashrdan keyingi dastlabki 24 soatda kontent odatda umumiy obunachilar sonining 5.16% ini tashkil etuvchi reaksiyalarni to‘playdi.
- Post qamrovi: Har bir post o‘rtacha 2 209 marta ko‘riladi; birinchi sutkada odatda 993 ta ko‘rish yig‘iladi.
- Reaksiyalar va o‘zaro ta’sir: Auditoriya faol: har bir postga o‘rtacha 15 ta reaksiya keladi.
- Tematik yo‘nalishlar: Kontent github, rust, pip, api, install kabi asosiy mavzularga jamlangan.
📝 Tavsif va kontent siyosati
Muallif resursni shaxsiy fikrni ifoda etish maydoni sifatida ta’riflaydi:
“Полный Дзен Пайтона в одном канале
Разместить рекламу: @tproger_sales_bot
Правила общения: https://tprg.ru/rules
Другие каналы: @tproger_channels
Сайт: https://tprg.ru/site
Регистрация в перечне РКН: https://tprg.ru/xZOL”
Yuqori yangilanish chastotasi (oxirgi ma’lumot 24 Iyun, 2026 da olingan) sababli kanal doimo dolzarb va katta qamrovli bo‘lib qoladi. Analitika auditoriya kontent bilan faol hamkorlik qilishini, uni Texnologiyalar & Aralashmalar toifasidagi muhim ta’sir nuqtasiga aylantirishini ko‘rsatadi.
app.frontend().
Теперь собранный фронтенд раздаётся прямо из FastAPI, без отдельного nginx или статик-сервера:
app.frontend("/", directory="dist")
Кладёте билд SPA в dist, одна строка, и приложение само отдаёт его на корне. Есть и router.frontend() для поддерева.
Под капотом в 0.137.0 переписали то, как роутеры включаются друг в друга:
🔘раньше include_router() клонировал каждый путь в один плоский список, и в итоге на всё приложение оставался один роутер;
🔘теперь исходные объекты APIRouter и APIRoute сохраняются, а router.routes стал деревом промежуточных объектов;
🔘из-за этого маршруты можно добавлять в подроутер уже после include_router(), изменения подхватятся, потому что роуты не копируются;
🔘в части случаев это ещё и экономит память.
Здесь же спрятан ломающий момент: если ваш код ходил по router.routes как по плоскому списку APIRoute, он сломается, теперь это дерево. Для таких сценариев в 0.137.2 добавили iter_route_contexts().
@zen_of_pythonAnnotated. Если пишете на Pydantic, FastAPI, Typer или SQLModel, вы видели это каждый день:
id: Annotated[int, Field(gt=0)] name: Annotated[str, Field(min_length=3)]PEP предлагает оператор
@ для метаданных типа:
id: int @ Field(gt=0) name: str @ Field(min_length=3)Та же
Annotated, просто запись короче.
Детали из предложения:
🔘@ связывает сильнее, чем |: запись int | str @ Meta читается как int | Annotated[str, Meta], а для объединения с метаданными нужны скобки (int | str) @ Meta;
🔘цепочка T @ m1 @ m2 разворачивается в плоскую Annotated[T, m1, m2], без вложенности;
🔘под капотом появляется встроенный тип types.AnnotatedType на C, а typing.Annotated станет ссылкой на него;
🔘старая форма Annotated[X, Y] никуда не денется, остаётся для совместимости.
Сокращение нацелено на Python 3.16, до этого его можно будет пробовать через typing_extensions.
@zen_of_pythonRequestKey и ResponseKey вместо строковых ключей в request[...] — промах по типу теперь ловит чекер, а не прод;
🔘 работа с JSON прямо в байтах: json_bytes_response и send_json_bytes отдают уже сериализованные байты, без лишнего прохода через строку;
🔘 в WebSocket появился decode_text — получить TEXT-фрейм сразу как bytes и скормить его, например, orjson;
🔘 encode_basic_auth для аккуратной сборки заголовка Basic-аутентификации;
🔘 cleanup-контексты приложения теперь умеют асинхронные менеджеры контекста.
Если держите сервисы на aiohttp, апгрейд бесплатно даёт и более строгие типы, и меньше накладных расходов на JSON под нагрузкой.
@zen_of_pythongrouped_bar() — группированные столбчатые диаграммы из коробки, без ручной возни со смещениями;
🔘 размеры фигуры можно задавать в px и cm, а не только в дюймах;
🔘 pie_label для подписей на круговых диаграммах;
🔘 отдельный hatchcolor — цвет штриховки независимо от цвета контура;
🔘 встроенные палитры Okabe-Ito и Petroff, дружелюбные к дальтоникам;
🔘 улучшения 3D-графиков и интерактивности.
Группированные бар-чарты и нормальная интернационализация подписей — то, вокруг чего годами городили костыли. А вы что чаще рисуете в Matplotlib?
@zen_of_pythonfit был чёрным ящиком: запустил и ждёшь. Теперь на estimator можно повесить колбэки через set_callbacks():
🔘 ProgressBar рисует прогресс обучения прямо в Jupyter или терминале;
🔘 ScoringMonitor следит за метрикой по ходу обучения, а не только в самом конце.
Что ещё в релизе:
🔘 metric_at_thresholds сразу считает метрики бинарной классификации по сетке порогов, без ручного перебора;
🔘 конфиг sparse_interface переводит трансформеры на sparse arrays вместо устаревших sparse matrices;
🔘 HTML-репр обученной модели теперь показывает не только параметры, но и fitted-атрибуты;
🔘 под капотом перешли на narwhals — библиотека лучше дружит с разными датафреймами, не только с pandas.
Колбэки — та фича, которой не хватало годами: видеть, что многочасовой fit реально движется, а не завис. Уже обновились или пока сидите на проверенной версии?
@zen_of_pythonLiteral["a", "b"], редактор предложит ровно эти значения;
🔘 рефакторинги «вынести функцию или класс в новый модуль» и «перенести символ в другой файл» с автоматическим переписыванием импортов;
🔘 навигация по pytest-фикстурам: от использования фикстуры можно прыгнуть к её определению;
🔘 новый LSP-endpoint getExpectedType: редактор спрашивает у чекера, какой тип ожидается в текущей позиции, и подсказывает точнее;
🔘 команда pyrefly coverage check показывает, насколько код покрыт аннотациями типов.
А вы уже пробуете быстрые чекеры на Rust или пока остаётесь на mypy?
@zen_of_pythonCounter не только считает, но и сразу выдаёт топ: Counter(words).most_common(3);
🔘defaultdict(list) избавляет от проверок if key in dict при группировке;
🔘itertools.groupby работает только на отсортированных данных — классическая ловушка;
🔘functools.partial замораживает аргументы: basetwo = partial(int, base=2);
🔘ChainMap собирает конфиг по приоритету: ChainMap(user_settings, defaults);
🔘@dataclass(frozen=True) даёт неизменяемый объект с __eq__ и __hash__ из коробки.
@zen_of_pythonruff format --check споткнулся о нарушение форматирования в _hooks.py;
🔘потом ruff check нашёл E402 (импорт не в начале файла) и I001 (несортированные импорты) в __init__.py.
Пайплайн красный, релиз не собрался, стилер до пользователей не доехал. Атакующий получил полный доступ на запись в репозиторий и споткнулся о проверку сортировки импортов.
Разбор инцидента опубликовала StepSecurity, и вывод из него шире смешного заголовка. Строгий линтинг в CI — это не только про красоту кода. Вредоносные инъекции почти всегда выглядят чужеродно: обфусцированные блобы, импорты посреди файла, нетипичное форматирование. Линтер с жёсткими правилами превращается в дешёвый детектор аномалий, который не обойти, не понимая кодстайл проекта.
Так что когда в следующий раз будете ворчать на красный пайплайн из-за несортированных импортов — вспомните, что ровно эта проверка спасла проект на 33 тысячи звёзд.
@zen_of_pythonuv audit. Сканирует зависимости проекта по базе OSV на известные уязвимости и заброшенный статус пакетов. Работает в 4-10 раз быстрее pip-audit — фирменный стиль Astral на месте.
Вторая интереснее: проверка на малварь прямо при установке. С переменной окружения UV_MALWARE_CHECK=1 команды uv add и uv sync сверяют залоченные зависимости с MAL-записями OSV и блокируют установку известной малвари до того, как её код вообще запустится. Учитывая, что свежие PyPI-кампании прячут стилеры в .pth-хуки, которые срабатывают при каждом старте интерпретатора даже без импорта пакета, проверка до установки — единственный момент, когда ещё не поздно.
В планах у Astral резолвер, который сам избегает уязвимых версий при разрешении зависимостей, и режим предупреждений только для новых зависимостей, чтобы не тонуть в алертах по старым.
Обе фичи в preview, но включить UV_MALWARE_CHECK в CI можно уже сейчас — бесплатная страховка. Кто на uv, попробуйте uv audit на своём проекте и расскажите, сколько насыпало.
@zen_of_python.remote(ctx) к своему LazyFrame, и запрос уходит считаться на кластер. Хоть петабайтный join, запущенный с ноутбука.
Распределённые движки обычно ощущаются как боль: куча микросервисов, тяжёлый JVM-рантайм, кластер поднимается минуты, а то и десятки минут. У Polars один бинарник и helm-чарт, кластер стартует за секунды. То есть реально можно поднимать отдельный кластер под каждый ETL-джоб и гасить после.
Плюс завезли две приятные штуки:
🔘Профайлинг запросов. Раньше движок был чёрным ящиком: пока запрос не закончился, ты не знал, что он делает. Теперь есть фронтенд и API, которые в реальном времени показывают, какая операция выполняется, сколько строк прошло через каждый узел и сколько данных шаффлится между воркерами. Причём работает и для одного узла, редкий шанс заглянуть внутрь движка на рантайме.
🔘 Data lineage через OpenLineage. Движок умеет слать события в любой коллектор (например, Marquez), так что видно, как и когда таблица создавалась и обновлялась.
@zen_of_pythonrequest.url он пересобирает строкой http://{host}{path}, где host берётся из заголовка Host. А Host контролирует клиент. И если приложение в middleware проверяет доступ так:
if request.url.path.startswith("/admin"):
return PlainTextResponse("Forbidden", status_code=403)
то достаточно дёрнуть /admin/potato с заголовком Host: example.com/? — роутер всё равно отдаст endpoint /admin/potato (он-то смотрит на сырой путь), а вот request.url станет http://example.com/?/admin/potato, и request.url.path схлопнется в просто /. Проверка не срабатывает, секрет утекает.
Что говорит сам мейнтейнер, и это самое интересное:
🔘баг живёт не во фреймворке самом по себе, а в паттерне приложения. Авторизацию вообще нельзя строить на пути, хосте или query — её ломают и трейлинг-слеши, и регистр, и percent-encoding. Host тут просто ещё один способ;
🔘если нужен реальный путь, бери request.scope["path"] — его никто из Host не пересобирает;
🔘чинится апгрейдом на Starlette 1.0.1, там Host наконец валидируется.
Но человеческая часть зашла даже сильнее технической. Исследователи сначала выкатили срок раскрытия в месяц и предложили созвон «через 2 или 5 дней», как будто у опенсорсника есть дежурная security-команда, а не вечера после основной работы. Под конец и вовсе предложили опубликовать advisory до того, как выйдет патч. Мейнтейнер прямо называет это ужасной практикой: открытое описание дыры без фикса оставляет всех уязвимыми, зато атакующие получают ровно ту же инструкцию.
Отдельно его задело, что под уязвимость подняли брендированный лендинг badhost.org с логотипом, именем и интернет-сканером. Маркетинг уязвимости: пока базы CVE не разъехались и Dependabot не прокликал алерты, человек узнаёт о дыре в своём проде из заголовка новости.
@zen_of_pythonlazy import json
lazy from pathlib import Path
print("старт") # json и pathlib ещё не загружены
data = json.loads('{"ok": true}') # здесь json наконец подгружается
Раньше ради быстрого старта тяжёлые импорты прятали внутрь функций. Теперь их можно держать наверху файла, как и положено, без платы за импорт при запуске. Есть и глобальные переключатели: флаг -X lazy_imports и переменная окружения, если хочется включить лень разом. И это не воскрешение отклонённого когда-то PEP 690, механизм тут другой и явный.
Второе приятное: встроенный frozendict (PEP 814). Неизменяемый и хешируемый словарь прямо в языке, без импортов. То же, чем frozenset является для set.
config = frozendict({"debug": True, "retries": 3})
# поменять значение уже нельзя, будет TypeError
Ещё одно: PEP 661 даёт штатный способ делать sentinel-значения вместо самодельных MISSING = object(). Теперь это нормальный механизм с человеческим repr и поддержкой в аннотациях типов.
Под капотом тоже движение: переработанный JIT даёт около 8-9% на Linux x86-64, интерпретатор с tail-call приехал и на Windows (там плюс 15-20%), появился стабильный ABI для free-threaded сборок.
Финальный 3.15 ждём осенью, но облик версии уже ясен. Лично я больше всего жду lazy import: сколько раз приходилось прятать импорты в функции ради быстрого CLI.
А вы ждёте 3.15 или пока сидите на чём-то постарше?
@zen_of_pythonsrc, тесты с print вместо pytest (хотя в CONTRIBUTING всё расписано), импорты вида from mylib import Foo, Bar, которых в коде и документации никогда не было. Сверху сабклассы от этих галлюцинированных типов, разобрать невозможно.
Отдельная деталь: у автора такого PR обычно куча форков других репозиториев, и везде он охотится за меткой good first issue. Похоже на сбор очков на GitHub, а не на желание реально закрыть задачу. Отсюда вопрос: стоит ли тратить силы на честное ревью и как закрыть PR, не отпугнув нормальных будущих контрибьюторов.
Что советуют бывалые мейнтейнеры:
🔘Просто закрыть и заблокировать. Самый частый ответ. К остальным это не враждебно: либо человек игнорит правила проекта, либо приносит код без ценности. И то и другое повод закрыть.
🔘 Завести метку вроде «doesn't follow contribution rules» и объяснить её в гайдлайнах. Тогда на закрытие уходит три клика, а если вернётся живой человек и поправит PR, это уже сигнал, что стоит посмотреть.
🔘 Поднять минимальный порог через CI. ruff, mypy или basedpyright, pytest с требованием покрытия, проверка докстрингов. Линтеры отсекают мусор автоматически, ещё до человеческого ревью.
🔘 Не закрывать вслепую каждый случай. Люди с неродным английским всё чаще прогоняют описание и доки через ИИ. Если контрибьюция небольшая, есть смысл быстро глянуть сам код.
Был и спор про AGENTS.md. Одни считают, что инструкции для агента поднимают качество PR. Другие, что само наличие файла как бы говорит «здесь рады ИИ-коду» и только притягивает слоп.
А вы как с этим справляетесь, если ведёте свои репозитории?
@zen_of_pythoncr_frame;
🔘починили множественное наследование для смешанных Python/C-extension типов, включая сценарии вокруг pybind11 и cpyext;
🔘PyPy3.11 теперь идёт со стандартной библиотекой CPython 3.11.15;
🔘дизассемблер стал ближе к CPython: интерпретатор перешёл на exception tables вместо отдельных opcodes. На скорость это пока не влияет.
Если вы уже используете PyPy, то обновление стоит поставить, API совместим с линейкой 7.3. Если только думаете попробовать — начните с прогона тестов на PyPy3.11 и проверки зависимостей.
PyPy лучше всего раскрывается на чистом Python-коде. В проектах, где основная нагрузка уходит в NumPy, pandas, torch или другие C-расширения, прирост может быть совсем другим.
@zen_of_pythonuv init
uv add fastapi
uv run app.py
uv sync --frozen
Риск с OpenAI тут скорее управленческий, а не технический. Важно смотреть на лицензию, телеметрию, темп релизов и то, останется ли core-разработка открытой. На практике же зависимости живут в стандартном pyproject.toml, а Python уже движется к стандартному lockfile через PEP 751 / pylock.toml, так что миграция с uv должна быть проще, чем с более закрытых форматов.
То есть вопрос скорее не про то, использовать ли uv, а о том как использовать его без религии и без лишней привязки к одному владельцу.
А вы как думаете? Продолжаем жить на uv, всё норм?TypedDict, ParamSpec, оператор type и прочее. Его аргумент: пора признать это формально и выбирать приоритеты по реальной боли пользователей. Опирался на Python Typing Survey 2025.
Дуглас Креагер из Astral (его слайд гласил «an OpenAI joint») показал девятистрочный пример, на котором все продакшен-чекеры (mypy, pyright, pyre, Pyrefly, ty) дают неверный ответ:
def choose[A](a1: A, a2: A) -> A:
return random.choice([a1, a2])
def partial[X, Y, Z](fn: Callable[[X, Y], Z], x: X) -> Callable[[Y], Z]: ...
p = partial(choose, None)
p(2) # все говорят: ошибка, 2 не None
p("hello") # то же самое
Прямой вызов choose(None, 2) работает корректно: A решается в None | Literal[2]. После применения partial система ломается. Креагер предлагает другую стратегию: тянуть весь набор констрейнтов как отложенный обобщённый тип, без преждевременной подстановки. ty переезжает на этот подход, внутри используется тернарная структура BDD (двоичные решающие диаграммы с третьим «неопределённым» ребром).
Коннер Нильсен из команды Pyrefly доложил результаты экспериментов с ИИ-агентами. Если код хорошо типизирован и type checker подключён к агенту через обёртку с циклом «думай, действуй, наблюдай»:
— Доля успешных решений на внутренних бенчмарках команды поднялась с 79,6 до 83,9 процента.
— На 21 процент меньше шагов до решения.
— На 14 процентов быстрее по полному времени работы.
На слабо типизированном коде из SWE-bench Verified эффекта почти нет. Type checker ловит ошибки в соседних с задачей файлах, и агент уходит чинить их вместо основной задачи. Наблюдение по моделям: Claude Sonnet 4.5 чинит каждую ошибку, GPT-5 codex игнорирует типы, пока обёртка насильно их не подсунет.
Ещё были доклады про intersection types (Jelle Zijlstra), PEP 827 от Vercel про conditional и mapped types по образцу TypeScript, tensor-shape типы в Pyrefly, и формализация подмножества Python в Lean 4. Полный обзор здесь: https://bernat.tech/posts/pycon-us-2026-typing-summit-recap/
@zen_of_python (теперь в VK и Max)concurrent.interpreters: публичный API для запуска нескольких полноценных интерпретаторов внутри одного процесса.
Это финал длинной истории. PEP 554 в 2017 году описал идею, PEP 684 в 2023 дал каждому интерпретатору собственный GIL, и PEP 734, принятый в июне 2025, превратил всё это в стандартный Python-модуль. До 3.14 функционал был доступен только через C API.
API ровно такой, какой ожидаешь:
import concurrent.interpreters as interpreters
interp = interpreters.create()
interp.exec('print("Hello from subinterp")')
interp.close()
Каждый интерпретатор изолирован: своя память, свой GIL, свой импорт-кеш. Простые типы передаются через специальный канал без копирования, сложные идут через сериализацию вроде pickle.
Что это даёт:
— Настоящая многозадачность в одном процессе без multiprocessing. Каждый интерпретатор едет на своём GIL и параллельно работает на отдельном ядре.
— Совместимость с asyncio. CPU-bound подзадачи можно гонять в субинтерпретаторах, а сетевой ввод-вывод оставить в основном цикле событий.
— Один процесс. Общие файловые дескрипторы, единое управление, без накладных расходов на fork и spawn.
У подхода одно главное ограничение: C-расширения. Стабильность под per-interpreter GIL не гарантирована, и многим библиотекам ещё предстоит дозревать. Чистый Python и библиотеки с поддержкой PEP 684 работают, остальные могут падать.
PEP 734 и free-threading решают одну задачу разными способами. Free-threading убирает GIL вообще: больше совместимости, меньше изоляции. Sub-interpreters сохраняют GIL на интерпретатор: меньше совместимости, больше изоляции. Похоже, в долгую Python поддержит оба пути.
Свежий разбор с примерами и архитектурой: https://alexeev-dev.bearblog.dev/running-multiple-interpreters-in-python-code-incredible-speed/
@zen_of_python (теперь в VK и Max)
Endi mavjud! Telegram Tadqiqoti 2025 — yilning asosiy insaytlari 
