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

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

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

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

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

Регистрация в перечне РКН: https://tprg.ru/xZOL
Download Telegram
Counter вычисляет разницу между количествами

Два набора деталей содержат одни и те же названия, но в разных количествах. Если превратить их в множества, различие пропадёт. Для такой сверки в Python 3.15 добавили симметрическую разность Counter, оператор ^.

Для каждого ключа операция берёт максимум минус минимум из двух счётчиков. Поэтому разница между тремя и одной деталью сохраняется как две единицы. Равные количества дают ноль, и такого ключа в результате не будет. Направление расхождения теряется: по результату нельзя сказать, в каком наборе деталей больше.

Операция принимает и отрицательные значения счётчиков. Максимум и минимум берутся из исходных значений, без предварительного обнуления отрицательных. Как и другие операции мультимножеств Counter, она оставляет в результате только положительные количества.
👍1
Одинаковое имя XMP-тега ещё не означает одно поле

В метаданных изображения могут встретиться XML-теги с одинаковым локальным именем из разных пространств имён. Если убрать URI пространства, различить такие свойства по одному имени уже не получится.

В Pillow 13.0.0 метод Image.getxmp получил аргумент strip_namespaces. По умолчанию он равен True, и библиотека по-прежнему убирает URI. Значение False сохраняет полное имя тега в форме {namespace-uri}local-name.

Если вам нужно различать свойства из разных пространств имён, выбирайте False и учитывайте полные ключи при чтении результата. Опция меняет только представление имён XMP-тегов.
Фильтры предупреждений в CLI научились понимать регулярки

В CI бывает нужно превратить в ошибку конкретное семейство предупреждений и оставить остальные видимыми. Настройку для дочернего процесса удобно передать через -W или PYTHONWARNINGS, без правок приложения.

Начиная с Python 3.15 поля сообщения и модуля поддерживают регулярные выражения, если поле начинается и заканчивается косой чертой. Без этих разделителей сохраняется буквальное сопоставление. Это дополнение к синтаксису фильтра, его действия и категории остаются прежними.

У полей разные правила. Сообщение сопоставляется с начала без учёта регистра. Имя модуля учитывает регистр: буквальная строка должна совпасть целиком, а регулярное выражение проверяет начало полного имени. Поэтому одинаковый шаблон в этих двух полях может охватить разные предупреждения.
wxPython 4.3.2 добавил wheels для Python 3.15 и проверку типов обработчиков Bind

При переходе Python-приложения с нативным GUI на новый интерпретатор нужны и подходящие бинарные сборки GUI-библиотеки. В wxPython 4.3.2 заявлены официальная поддержка Python 3.15 и сборка wheels для него. Релиз использует wxWidgets 3.3.4. Выпуск Windows wheels для 32-битной архитектуры прекращён.

Сгенерированные .pyi теперь позволяют проверять типы обработчиков, передаваемых в Bind. Среди других правок в stubs — представление enum в виде классов и более полное описание методов и типов.

Типизатор сможет найти часть ошибок при подключении событий до запуска окна. Работу виджетов в вашей ОС нужно проверять отдельно. Перед миграцией проверьте наличие подходящего wheel и поведение GUI на целевой платформе.
Decimal в тайм-ауте не делает ожидание точнее

Тайм-аут может прийти в программу как Decimal из конфигурации или как Fraction после вычисления. В Python 3.15 функции с аргументами timestamp и timeout принимают любые вещественные числа, а не только int и float.

В описании изменения отдельно оговорено: точность от этого не повышается. Изменение позволяет передавать уже вычисленное значение без преобразования на стороне вызывающего кода.

Что именно ограничивает тайм-аут и когда функция возвращает управление, по-прежнему зависит от её контракта. Допустимый числовой тип этих правил не меняет.
❤1
Стартовый код пакета переезжает из .pth в .start

Файл .pth может не только расширять sys.path. При запуске Python модуль site исполняет найденные в нём строки, начинающиеся с import. Этот код выполняется ещё до первой строки приложения.

В Python 3.15 PEP 829 вводит файлы .start с явными точками входа в форме pkg.mod:callable. Функция вызывается без аргументов, возвращённое значение отбрасывается. У PEP статус Final.

Если рядом есть одноимённый .start, строки import из соответствующего .pth игнорируются. Добавление путей из .pth сохраняется. Это позволяет переносить стартовую инициализацию отдельно от настройки путей, сохраняя старый файл для прежних интерпретаторов.
Обновление Python не обновляет pip в старых venv

В Python 3.15.1 обновили комплектный pip до 26.2.2. В его состав входит certifi 2026.10.19 с изменениями после инцидента с центрами сертификации eMudhra / emSign. Но установка нового интерпретатора сама по себе не обновляет инструменты внутри уже созданных виртуальных окружений.

На странице релиза отдельно просят обновить pip и uv в существующих venv до последних версий. Там же приведены ссылка на wheel pip с SHA-256 и отдельная инструкция по обновлению сертификатов для установки на macOS.

Проверяйте версию pip внутри нужного окружения. Версия системного Python этого не показывает. Для обновления сертификатов выбирайте инструкции релиза, относящиеся к вашему способу установки.
❤2
Unicode-идентификатор начинается и продолжается по разным правилам

Если вы пишете токенизатор или подсветку для языка с Unicode-именами, проверки «это буква или цифра» может оказаться недостаточно. У Unicode есть отдельные свойства для начальной и последующих позиций идентификатора.

В Python 3.15 эти проверки добавили в unicodedata. Функция isxidstart проверяет свойство XID_Start, а isxidcontinue — XID_Continue по UAX #31. Каждая принимает один символ. Модуль использует базу Unicode 17.0.0.

Так можно проверять свойства символов без собственного списка диапазонов, который придётся обновлять вместе с Unicode. Для проверки целого имени нужны ещё правила конкретного языка. Например, эти функции не проверяют, является ли имя зарезервированным словом.
Установщик Python 3.15 для macOS ставит обе сборки по умолчанию

В установщике Python 3.15 с python.org для macOS free-threaded сборка отмечена по умолчанию. Она ставится рядом с обычной, в отдельный PythonT.framework, и запускается командой python3.15t. Отключить этот компонент можно через Customize.

У сборок отдельные каталоги site-packages и собственные экземпляры pip. Наличие пакета в обычном Python поэтому не означает, что он установлен и во free-threaded варианте. В инструкции для macOS рекомендуют использовать виртуальные окружения, чтобы не путать интерпретаторы.

Эта настройка относится к официальному установщику, а не ко всем дистрибутивам Python для Mac. Нативные расширения могут ещё не поддерживать работу без GIL и включать его обратно. Перед запуском приложения во второй сборке проверьте совместимость его зависимостей.
abi3t сокращает число сборок нативного расширения

Нативному расширению обычно нужны отдельные сборки под версии CPython, а free-threaded варианты ещё увеличивают их число. Начиная с CPython 3.15, Stable ABI для free threading, или abi3t, позволяет одной сборке на платформу поддерживать несколько версий. Она совместима и с обычными сборками CPython 3.15+.

Для этого придётся ограничиться доступной частью C API и, возможно, пожертвовать скоростью. Руководство рекомендует сначала подготовить расширение к free threading. Если оно использует генератор кода или биндинги, стоит дождаться поддержки abi3t в соответствующем инструменте.

Расширения с собственными типами переменного размера нельзя перенести на abi3t 3.15. А совместимость ABI не исключает изменений поведения между версиями: тесты нужно запускать на каждой поддерживаемой версии, в обычной и free-threaded сборках Python.
Как посмотреть локальные переменные после ошибки в REPL

Вызов в интерактивном Python завершился исключением, а по traceback непонятно, какое значение привело к ошибке. Пока эта сессия открыта, можно посмотреть локальные переменные в месте ошибки без повторного запуска вызова.

Импортируйте pdb и выполните pdb.pm(). Функция берёт последнее необработанное исключение из sys.last_exc и открывает отладчик на кадре, где оно возникло. Команда p x покажет значение x в этом кадре. На карточке — выполненный пример: после f(0) виден локальный x = 0. Такой сценарий есть и в документации pdb.

Это просмотр сохранённого traceback в том же живом REPL. Продолжить исходный вызов, завершившийся исключением, нельзя. После выхода из интерпретатора этот приём уже не поможет.
ZIP с Zstandard может не открыться у получателя

Архив успешно собрался и распаковался вашим Python, но это ещё не проверка совместимости с утилитой получателя. Для ZIP с Zstandard важны и поддержка алгоритма, и его числовой идентификатор в архиве.

В Python 3.14 появился zipfile.ZIP_ZSTANDARD. По документации zipfile, модуль читает Zstandard с ID 20 и 93, а записывает только 93. Старый ID 20 заменили в спецификации, чтение сохранили ради совместимости. Локальный пример на CPython 3.14.4 подтвердил запись 93 и восстановление исходных байтов.

Нужна сборка Python с необязательным модулем compression.zstd. Если архив уйдёт за пределы вашей среды, проверьте распаковку именно инструментом получателя: часть утилит, включая старые версии Python, Zstandard в ZIP не поддерживает.
🎉1