Zen of Python
19.2K subscribers
1.35K photos
202 videos
38 files
3.46K links
Полный Дзен Пайтона в одном канале

Разместить рекламу: @tproger_sales_bot

Правила общения: https://tprg.ru/rules

Другие каналы: @tproger_channels

Сайт: https://tprg.ru/site

Регистрация в перечне РКН: https://tprg.ru/xZOL
Download Telegram
Виктор Стиннер, один из ключевых разработчиков CPython, разобрал в блоге, как устроен PyMutex, замок размером в один байт, на котором держится free-threaded Python.

Зачем такой маленький? В режиме без GIL блокировка нужна на каждый объект отдельно: свой замок у каждого dict, list, set. Старый замок через py_recursivelock_t занимает 72 байта. Для сравнения, пустой список в Python 3.13 весит 56 байт, пустой словарь 64. Вешать по 72 байта на каждый объект невозможно. PyMutex решает это: один байт, из которого реально используются два бита под состояния (свободен, занят, занят с ожидающими потоками).

Что показали замеры. Дизайн взят из WebKit, у их движка есть WTF::Lock, а под капотом лежит _PyParkingLot, кроссплатформенный аналог futex. На захвате и освобождении без конкуренции:
🔘Linux x86-64: PyMutex 11 нс против 44 нс у старого замка, в 4 раза быстрее;
🔘macOS arm64: 13 нс против 18 нс, в 1,4 раза;
🔘Windows x86-64: 13 нс против 38 нс, в 2,9 раза.

Оговорка для авторов C-расширений: напрямую PyMutex использовать не стоит, легко словить взаимоблокировку. Для защиты доступа к объектам есть critical section API, Py_BEGIN_CRITICAL_SECTION(obj).

@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
👍43
time.sleep() — не везде правильный способ подождать

В синхронном скрипте time.sleep(2.5) идиоматичен: пауза в текущем потоке, никаких сюрпризов. Но в отдельном потоке ту же паузу не прервать по сигналу: лучше threading.Event().wait(), который просыпается по event.set().

В асинхронном коде time.sleep() заморозит весь event loop, потому что корутина не уступает управление. Правильный инструмент: await asyncio.sleep(), он приостанавливает только текущую задачу.

В гайде
ещё про декоратор retry, rate limit и паузы в GUI через root.after().
👍10
Forwarded from IT Юмор
😭4😁1🫡1
Отправка почты из Python: stdlib, локальный SMTP и сторонние библиотеки

В стандартной библиотеке Python для работы с почтой есть пакет email и модуль для SMTP-соединений: формируете сообщение, добавляете вложения и адресатов, подключаетесь к серверу и отправляете. Для отладки удобно поднять локальный SMTP-сервер — письма не уйдут в интернет, но вы увидите, как они собираются.

Явное лучше неявного, но ручная сборка писем со временем утомляет. Статья разбирает сторонние инструменты вроде Yagmail и transactional email-сервисов, чтобы вы могли выбрать между «всё под контролем» и готовым решением.

Кому полезно: тем, кто отправляет уведомления, рассылки или отчёты из Python и хочет сравнить подходы.
👌31
Pathway — Python-фреймворк для потоковой обработки данных на Rust-движке

Pathway даёт писать на Python пайплайны реального времени: чтение из источника, преобразования, запись в приёмник, а тяжёлая часть считается Rust-движком. Тот же код работает и на пакетных данных, и на бесконечном потоке. Релиз v0.31.1 вышел 12 июня, на GitHub больше 62 тысяч звёзд.

Этот релиз почти целиком про новые коннекторы к базам:
🔘pw.io.elasticsearch.read читает индекс Elasticsearch: своего механизма отслеживания изменений у него нет, поэтому коннектор опрашивает и сверяет пересечение соседних запросов, чтобы ни одна строка не потерялась и не пришла дважды;
🔘pw.io.clickhouse.write пишет в ClickHouse по нативному протоколу, в двух режимах: поток изменений с колонками time и diff либо снапшот текущего состояния в ReplacingMergeTree;
🔘pw.io.mysql.read делает полноценный захват изменений через бинлог MySQL: сначала снимок таблицы, потом непрерывная доставка вставок, обновлений и удалений;
🔘расширили чтение Iceberg, теперь декодируются все примитивные типы, включая date, time, uuid, fixed и decimal;
🔘у коннекторов Postgres добавили набор проверок на старте, чтобы кривая конфигурация падала понятной ошибкой ещё до молчаливой потери строк.

Пригодится дата-инженерам, которые строят аналитику и ETL реального времени и устали склеивать поток из десятка разных коннекторов вручную.

https://github.com/pathwaycom/pathway

Язык: Python и Rust. Лицензия: BSL-1.1.

@prog_tools
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯1
Где держать Telegram-бота или API, чтобы они не падали под нагрузкой и не съедали бюджет?

Tproger собрал подборку из шести VPS-провайдеров под этот сценарий: от тарифов за пару сотен рублей в месяц до конфигураций с DDR5 и портом 10 Гбит/с. У каждого свой акцент — где-то посуточная оплата и запуск за минуту, где-то API для CI/CD, бэкапы и приватные сети, где-то зарубежные локации.

Внутри по каждому провайдеру: реальные конфигурации, цены, на какой нагрузке тестировали и под какой сценарий брать.

https://tproger.ru/articles/gde-razvernut-bota-ili-api---podborka-vps--kotorye-ne-tormozyat
👍1👏1
Вышла CPython 3.15.0b3 — предпоследняя бета перед заморозкой

23 июня вышла третья из четырёх бета-версий Python 3.15: около 195 правок от 86 контрибьюторов со времён второй беты. Набор фич уже заморожен, дальше только багфиксы и шлифовка. Release candidate назначен на 4 августа, финальный релиз на 1 октября, и команда просит прогнать свой код на бете, чтобы поймать регрессии и поломки ABI заранее.

Что приедет в серии 3.15 по сравнению с 3.14:
🔘PEP 686: UTF-8 становится кодировкой по умолчанию, открытие файлов без явного encoding больше не зависит от локали системы;
🔘PEP 810: явные ленивые импорты, модуль грузится при первом обращении, а не на старте программы, это срезает время запуска тяжёлых утилит;
🔘PEP 814: встроенный тип frozendict, неизменяемый словарь без сторонних библиотек;
🔘PEP 661: встроенный sentinel для значений-маркеров вместо самодельных объектов-заглушек;
🔘PEP 798: распаковка через * и ** прямо внутри list- и dict-comprehension;
🔘PEP 799: отдельный пакет для профилирования и Tachyon, высокочастотный статистический сэмплер.

@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
19👏2🤩1
uv 0.11.26 — резолвер зависимостей ускорили сразу с четырёх сторон

uv — быстрый пакетный менеджер и резолвер зависимостей для Python на Rust, замена pip и pip-tools в одном бинарнике. Версия 0.11.26 вышла 30 июня и целиком посвящена скорости резолвинга.

Что ускорили:
🔘 зависимости в PubGrub теперь передаются как ID вместо полных структур, это снижает накладные расходы на каждой итерации резолвера;
🔘 убрали лишние аллокации в ForkMap::contains, структуре, которая проверяет пересечения версий между форками резолвера;
🔘 резолвер стал переиспользовать уже проделанную работу между итерациями PubGrub вместо пересчёта с нуля;
🔘 ускорили выбор кандидата версии для непересекающихся диапазонов зависимостей.

Заодно поправили мелочь: uv теперь предупреждает, если build cache случайно оказался внутри директории с исходниками проекта.

Резолвер зависимостей редко попадает в заголовки, но именно на нём держится ощущение «uv install мгновенный». Вы уже увидели разницу в скорости на своих проектах, или для небольших requirements.txt она и так была незаметна?

@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤‍🔥5👻31👍1
Forwarded from Веб-страница
django-scroll-to-top: кнопка «наверх», которая не ломается в проде

Кнопка «наверх» кажется мелочью, пока в проде не всплывают cookie-баннер, чат поддержки, нижняя мобильная навигация и строгий CSP. Автор собрал типовые условия в Django-пакет django-scroll-to-top: один template-тег, Django Admin, настройка цвета и положения через админку без правки шаблонов.

Без jQuery, CDN и обязательной сборки. Если JavaScript выключён, остаётся обычная ссылка в начало страницы. Если в ваших Django-проектах кнопку надоело таскать между шаблонами, я бы заглянул в разбор на Tproger.
У Python появится отдельный совет по паковке — назначили даты первых выборов

После того как Steering Council в апреле утвердил PEP 772, PSF объявила даты первых выборов в новый Python Packaging Council: технический орган, который берёт на себя решения по спецификациям совместимости пакетов.

Совет состоит из пяти мест: два кандидата с наибольшим числом голосов получают двухлетний срок, а три оставшихся получают годовой. Голосование пройдёт параллельно с выборами PSF Board 2026.

Даты, если планируете участвовать:
🔘 28 июля: открытие номинаций;
🔘 11 августа: закрытие номинаций;
🔘 13 августа: публикация списка кандидатов;
🔘 25 августа: дедлайн подтверждения намерения голосовать;
🔘 1–15 сентября: само голосование.

Голосовать смогут члены PSF уровня Contributing, Supporting или Fellow, которые заранее подтвердят намерение участвовать.

Управление пакетным хозяйством Python годами было разбросано между pip, PyPA, отдельными PEP и добровольцами-энтузиастами. Кажется ли вам, что выделенный совет реально наведёт порядок, или это ещё один орган для лишних согласований?

@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
25🙈1
Вышла третья бета Python 3.15 — предпоследняя перед релиз-кандидатом, который намечен на 4 августа. Набор фич зафиксирован, так что уже понятно, что войдёт в релиз:

🔘 ленивые импорты для ускорения старта (PEP 810);
🔘 встроенные типы frozendict (PEP 814) и sentinel (PEP 661);
🔘 сэмплирующий профайлер Tachyon и отдельный пакет для организации инструментов профилирования (PEP 799);
🔘 распаковка в comprehensions (PEP 798) и UTF-8 как кодировка по умолчанию (PEP 686);
🔘 заметно ускоренный JIT: 8–9% среднего прироста на x86-64 Linux относительно обычного интерпретатора, 12–13% на macOS/AArch64;
🔘 стабильный ABI для free-threaded сборок.

В самой бете 195 исправлений от 86 контрибьюторов, последняя бета выйдет 18 июля. Разработчикам библиотек самое время прогнать тесты на 3.15 и собрать пререлизные wheels.

Уже пробовали 3.15 на своих проектах или ждёте стабильного релиза?

@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
3🔥2🥰1
В Python появится встроенный frozendict: Steering Council принял PEP 814, и тип уже доступен в бета-версиях Python 3.15. Виктор Стиннер, соавтор PEP, рассказал историю вопроса: его первую попытку, PEP 416, Гвидо отклонил ещё в 2012 году.

Что внутри:

🔘 неизменяемый словарь: попытка присвоить элемент даёт TypeError;
🔘 хешируемый, если хешируемы все значения, так что его можно класть в set и использовать как ключ словаря;
🔘 сохраняет порядок вставки, но сравнение и хеш от порядка не зависят;
🔘 поддерживает объединение через | и сравнение с обычным dict.

Главное отличие от types.MappingProxyType в том, что прокси остаётся обёрткой над живым словарём, а frozendict — самостоятельный неизменяемый тип со своим хешем.

Ждёте frozendict в 3.15 или вам хватало MappingProxyType?

@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍2