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

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

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

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

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

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

При структуре, где пакет лежит в корне репозитория, Python может импортировать его прямо из рабочей директории. Тесты проходят, хотя установленный пакет может оказаться неполным.

В разборе структуры проекта предлагают для библиотек рассмотреть каталог src/:

project/
├── pyproject.toml
├── src/
│ └── mypkg/
│ └── __init__.py
└── tests/


Теперь пакет обычно нужно установить, прежде чем импортировать. Это помогает заметить зависимость от файлов, случайно доступных в корне проекта.

Но установка для разработки и установка собранного wheel — разные проверки. Чтобы найти пропущенный шаблон или файл данных, соберите wheel и запустите тесты с ним в чистом окружении вне репозитория.

#python #тестирование
Что проверить при обновлении до Pydantic 2.14

Библиотека добавила поддержку Python 3.15 и прекратила поддержку 3.9. Поэтому обновление стоит начать с версий интерпретатора в CI и рабочих окружениях.

В анонсе Pydantic 2.14 есть улучшение для функций, принимающих выражения типов. TypeAdapter теперь использует TypeForm, благодаря чему совместимый анализатор может вывести результат TypeAdapter(int | str) как int | str, а не неизвестный тип.

Это улучшает статическую проверку, но не заменяет выполнение валидации. Само указание аннотации ещё не проверяет внешние данные.

Для TypeForm нужны достаточно свежие анализаторы: авторы указывают Pyright 1.1.412 или Mypy 2.2 и новее. Перед обновлением проверьте также свои валидаторы, сериализацию и генерацию схем: в выпуск вошли небольшие изменения поведения.

#python #pydantic
Одинаковые файлы, разные ZIP: почему меняется хеш

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

В разборе воспроизводимых архивов используют поддержку SOURCE_DATE_EPOCH в Python 3.14. При записи через writestr() с именем файла переменная позволяет задать стабильную дату вместо текущей.

Дату лучше брать из неизменяемого события сборки, например коммита. Отдельно нужно сортировать имена, фиксировать содержимое и параметры сжатия. Явно переданный ZipInfo требует своей политики метаданных.

Проверка должна сравнивать байты двух сборок, а не только распакованные файлы. Для строгой воспроизводимости закрепите и версии инструментов: одинаковые исходники не гарантируют одинаковое сжатие в любой среде.

#python #сборка
🔥1
Ленивый импорт откладывает не только загрузку модуля

В Python 3.15 импорт можно отложить до первого обращения к имени. Это полезно для консольной утилиты, которая ради --help загружает тяжёлые зависимости.

# Python 3.15+
lazy import json

def parse(text):
return json.loads(text)


Но выполнение модуля тоже переносится. Если импорт регистрировал плагин, а к имени никто не обратился, регистрация не произойдёт. Ошибка загрузки также может возникнуть позже привычного места импорта.

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

Новый синтаксис не разбирается старыми версиями Python. Для совместимого кода есть __lazy_modules__: старые интерпретаторы игнорируют этот список и выполняют обычный импорт.

#python #производительность
✍1
Готовый сокет ещё не содержит всё сообщение

Selector сообщил, что сокет доступен для чтения. Это означает, что можно попробовать прочитать данные, а не что весь запрос уже пришёл.

В разборе модуля selectors показывают небольшой цикл обработки соединений. Сокеты переводят в неблокирующий режим, а данные накапливают в буфере конкретного соединения.

У TCP нет границ сообщений: один recv может вернуть часть запроса или несколько сообщений вместе. Нужен свой способ выделения сообщения — длина, разделитель или формат протокола.

Запись тоже бывает частичной. Неотправленный остаток сохраняют, а ожидание записи включают только при наличии данных. Иначе постоянно готовый к записи сокет может заставить цикл расходовать CPU впустую.

DefaultSelector выбирает доступный механизм платформы, но правила протокола и очистка соединений остаются задачей приложения.

#python #сети
👍1
Таблицы из PDF: локальная библиотека или облачный API

Текст из PDF извлечён, а столбцы таблицы перемешались. Для отчёта важны не только слова, но и связи между строками, заголовками и ячейками.

В сравнении Docling и LlamaParse один документ обрабатывают двумя способами. Docling работает локально, LlamaParse отправляет PDF в облачный сервис. Отличаются установка, стоимость, форматы результата и возможности настройки.

Docling умеет отдавать таблицы в pandas DataFrame. Для облачного варианта нужно отдельно учитывать отправку документов и условия обработки данных.

Скорость авторы измеряют на одном десятистраничном PDF. Это пример эксперимента, а не универсальный рейтинг парсеров.

Для своего набора проверьте объединённые ячейки, многострочные заголовки, переносы таблиц между страницами и точность чисел после извлечения.

#python #данные
👍1
Enum ограничивает состояния, но не проверяет переходы

Статус "paied" — допустимая строка. Enum позволяет проверить значение на границе приложения:

from enum import Enum

class Status(Enum):
NEW = "new"
PAID = "paid"

print(Status("paid") is Status.PAID) # True
# Status("paied") вызовет ValueError


В разборе Enum отдельно рассматривают значения для сериализации и имена членов. Status("paid") ищет по значению, а Status["PAID"] — по имени.

Но наличие статусов NEW и PAID не запрещает переход обратно. Разрешённые переходы нужно описать отдельно, например в методе объекта или таблице правил.

Если значения уходят в API или базу, выбирайте их явно. Переименование элемента перечисления и изменение внешнего строкового значения могут иметь разные последствия для совместимости.

#python #архитектура
❤1
После GIL: почему одних потоков недостаточно

Убрать общую блокировку — не значит убрать гонки данных. Если несколько потоков меняют общие объекты, приложению по-прежнему нужны правила доступа.

На Python Language Summit обсуждали модель BOC: задачи заранее объявляют, какие защищённые данные им нужны, а планировщик координирует выполнение. Идея — перенести часть работы с блокировками из прикладного кода в механизм запуска задач.

Прототип bocpy использует отдельные интерпретаторы. Его уже можно исследовать, но полноценное владение объектами потребует изменений среды выполнения. Авторы также отмечают цену обмена данными.

Это исследовательское предложение, а не новая гарантия стандартного Python. Для рабочего приложения пока нужно явно выбирать модель параллельности и проверять совместное использование изменяемых объектов.

#python #параллельность
Как дать помощнику контекст ошибки из Logfire

Помощник видит код репозитория, но не знает, какой запрос завершился ошибкой и сколько времени заняла база. Без телеметрии он может уверенно искать причину не в том месте.

В разборе Logfire MCP показывают, как передать клиенту MCP доступ к трассам, логам и метрикам. Помощник может запросить данные через SQL, сопоставить ошибку с обработчиком и проверить гипотезу на реальном выполнении.

Начать расследование лучше с конкретного сервиса, интервала времени и проблемного запроса. Так проще получить проверяемый ответ и ограничить объём данных.

Права нужно выбирать по задаче: сервер предоставляет инструменты не только для запросов, но и для управления объектами мониторинга. Доступ к просмотру телеметрии сам по себе не требует разрешать изменения алертов или настроек.

#python #отладка
Python 3.16 alpha: что уже может проверить автор библиотеки

Первая альфа Python 3.16 вышла 13 октября. Набор возможностей ещё меняется, но ждать финального выпуска для первой проверки совместимости необязательно.

В анонсе разработчики предлагают запускать библиотеки и приложения на предварительной версии и сообщать об ошибках CPython.

Для библиотеки полезно проверить установку, импорт, тесты и сборку расширений. Если установка не удалась, отделите несовместимость своего кода от отсутствия готовых сборок зависимостей.

Такую проверку можно добавить отдельным заданием CI, сохранив основную матрицу поддерживаемых версий. Сбой предварительной версии нужно разобрать, а не автоматически считать регрессией библиотеки.

Это ранний выпуск для тестирования. Перенос рабочего сервиса на него не требуется; финальный Python 3.16 запланирован на октябрь 2027 года.

#python #тестирование
Как найти медленную функцию новым профилировщиком Tachyon

Приложение тормозит, но непонятно, где оно проводит время. В Python 3.15 появился статистический профилировщик profiling.sampling, известный как Tachyon.

В разборе Astral показывают запуск через uv:

uv run --python 3.15   -m profiling.sampling run   --flamegraph --browser app.py


Профилировщик периодически снимает состояние выполнения. Граф помогает найти участки, которые часто попадают в выборку, и выбрать место для дальнейшего исследования.

Число выборок не равно точному числу вызовов. А изменение короткой функции не обязательно ускорит весь сценарий.

После правки повторите тот же замер с теми же данными и отдельно сравните полное время работы. Авторское ускорение на одном примере нельзя переносить на любое приложение.

#python #производительность
❤1
Почему обновления Django важны даже без SQL-инъекций

Запрос может вредить серверу, просто заставляя его тратить слишком много памяти или процессорного времени на разбор данных.

В обновлении безопасности Django от 6 октября исправили несколько таких сценариев. Один связан с кешированием множества длинных языковых кодов, другой — с квадратичной сложностью разбора параметров HTTP-заголовка.

Исправления вошли в 6.1.2, 6.0.9 и 5.2.18. Обновляться нужно до актуального исправленного выпуска своей поддерживаемой ветки.

После обновления проверьте обработку необычных заголовков: внутри парсера изменился механизм разбора, поэтому некоторые некорректные значения могут обрабатываться иначе.

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

#python #django