Cython научился подсказывать компилятору C, какая ветка вероятнее
14 августа вышла бета 3.3.0b1. Релиз для тех, кто собирает расширения: в нём несколько вещей, которые раньше приходилось обходить руками.
🔘 появились
🔘 реализована конструкция
🔘 аннотации типов у глобальных переменных теперь участвуют в выводе типов, а не игнорируются;
🔘 у сеттеров свойств, объявленных на C, появилась возможность явно пробрасывать исключение вместо безусловной проверки
🔘 поддержан синтаксис однородных кортежей вида
🔘 набор возможностей общего модуля теперь настраивается при сборке: команда
Последний пункт стоит читать вместе с предупреждением авторов: возможность экспериментальная, и если при сборке выключить то, что реально используется, импорт упадёт уже во время работы. Отдельно поменялась схема имён при экспорте и импорте слитых функций на C, но старые имена оставлены для совместимости.
Есть и просто ускорения: форматирование чисел в
@zen_of_python
14 августа вышла бета 3.3.0b1. Релиз для тех, кто собирает расширения: в нём несколько вещей, которые раньше приходилось обходить руками.
cython.likely() и cython.unlikely() — подсказки оптимизатору компилятора C о том, какая ветка условия ожидается чаще;except * для групп исключений по PEP 654 на Python 3.11 и новее;PyErr_Occurred() после каждого вызова;tuple[atype, ...];cython generate-shared принимает --only и --exclude, так что в модуль попадает только нужное.Последний пункт стоит читать вместе с предупреждением авторов: возможность экспериментальная, и если при сборке выключить то, что реально используется, импорт упадёт уже во время работы. Отдельно поменялась схема имён при экспорте и импорте слитых функций на C, но старые имена оставлены для совместимости.
Есть и просто ускорения: форматирование чисел в
f-строках, extend у bytearray байтами, проверки одиночного символа, размер асинхронных генераторов и перевод модулей с большим числом строк. Численных замеров в списке изменений нет, только слова «быстрее» и «меньше», так что судить о выигрыше на своём проекте придётся самому.@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥4❤1
Приглашаем Go- и Python-разработчиков, аналитиков и продакт-менеджеров на тревел-тех хакатон от Островка.
Вам предстоит решить одну из двух AI-задач в сфере тревел-теха и побороться за главный приз — 1 000 000 ₽.
Присоединиться к хакатону можно из любой точки мира. Участвуйте командой до пяти человек и выбирайте один из двух треков:
Скорее присоединяйтесь по ссылке!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Двадцать пять минут, которые снимают половину вопросов новичка: доклад Неда Бэтчелдера «Facts and Myths about Python names and values» с PyCon US 2015.
Весь доклад отвечает на один вопрос: что происходит, когда вы пишете
🔘 почему Python нельзя описать ни как передачу по значению, ни как передачу по ссылке;
🔘 почему два имени могут указывать на один объект и менять его вместе;
🔘 почему присваивание никогда не копирует объект;
🔘 почему
🔘 почему изменяемый аргумент по умолчанию живёт между вызовами;
🔘 почему аргументы функции, атрибуты объекта и переменная цикла — это всё одна и та же операция связывания имени.
Бэтчелдер разбирает это на диаграммах с коробочками и стрелками, без единой строчки про внутренности интерпретатора. Именно поэтому доклад одиннадцатилетней давности не устарел ни на строчку: семантика имён и объектов с тех пор не менялась.
@zen_of_python
Весь доклад отвечает на один вопрос: что происходит, когда вы пишете
x = 23. Ответ — не «в переменную кладётся значение», а «имя привязывается к объекту». Из этого простого сдвига вырастает объяснение почти всех классических непоняток:+= для списка и для числа ведут себя по-разному;Бэтчелдер разбирает это на диаграммах с коробочками и стрелками, без единой строчки про внутренности интерпретатора. Именно поэтому доклад одиннадцатилетней давности не устарел ни на строчку: семантика имён и объектов с тех пор не менялась.
@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Numba 0.67.0 научилась работать с NumPy 2.5 и собирает пакеты для Python 3.14 и Windows ARM64.
🔘 у
🔘 добавлена JIT-поддержка
🔘
🔘 анализ живости переменных перевели на топологический порядок, а проверка принадлежности стеку в
🔘 сборки через
Из ломающего:
Отдельно починили тихую ошибку компиляции при повторном присваивании нелокальной переменной во вложенной функции: раньше генерировался неверный код, теперь вылетает
@zen_of_python
np.sum и np.cumsum появился динамический axis, ось теперь можно вычислять во время выполнения;np.insert, пока без аргумента axis;np.random.binomial в RandomState переключается с BINV на BTPE, когда n * min(p, 1 - p) > 30, поток случайных чисел при этом сохраняется;_find_back_edges стала за O(1);pycc теперь могут быть побайтно воспроизводимыми на Linux и macOS.Из ломающего:
np.row_stack и двумерное векторное произведение убраны вслед за NumPy 2.5, cross2d остаётся только для старых версий. Пакеты под Windows ARM64 на старте ограничены Python 3.14, часть тестов там пропущена из-за проблемы в LLVM 22.Отдельно починили тихую ошибку компиляции при повторном присваивании нелокальной переменной во вложенной функции: раньше генерировался неверный код, теперь вылетает
UnsupportedError. Численного бенчмарка ускорения BTPE авторы не приводят.@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
PyPI перестал принимать новые файлы в релизы старше четырнадцати дней
Сет Ларсон описал это изменение 22 июля. Правило простое: если версия пакета опубликована больше двух недель назад, добавить в неё новый файл больше нельзя. Цель — закрыть сценарий, при котором давно стабильную версию тихо дополняют после угона токена или доступа к сборочному процессу. Подтверждённых злоупотреблений на момент публикации не было.
🔘 обсуждение началось ещё вокруг PEP 740 в январе 2024 года и вернулось в марте 2026-го после компрометации двух проектов;
🔘 исправление влили 8 июля 2026 года;
🔘 главное возражение бытовое: проекты иногда докладывают колёса для новой версии Python в уже выпущенный релиз;
🔘 масштаб возражения измерили: среди 15 тысяч самых популярных пакетов так поступили только 56 проектов, добавив совместимое с CPython 3.14 колесо позже чем через две недели;
🔘 на профильной встрече в рамках PyCon US 2026 сочли приемлемым требование выпускать под новый Python новую версию пакета;
🔘 автор просит пока не закладываться на это правило как на гарантию: семантика закрытого релиза и соответствующий интерфейс ещё не определены.
Окончательная модель должна приехать вместе с новым протоколом загрузки и предварительными релизами, после стандартизации PEP 694. Так что практический вывод для авторов пакетов такой: план поддержки нового CPython теперь придётся строить через выпуск новой версии, а не через дозагрузку колеса в старую.
@zen_of_python
Сет Ларсон описал это изменение 22 июля. Правило простое: если версия пакета опубликована больше двух недель назад, добавить в неё новый файл больше нельзя. Цель — закрыть сценарий, при котором давно стабильную версию тихо дополняют после угона токена или доступа к сборочному процессу. Подтверждённых злоупотреблений на момент публикации не было.
Окончательная модель должна приехать вместе с новым протоколом загрузки и предварительными релизами, после стандартизации PEP 694. Так что практический вывод для авторов пакетов такой: план поддержки нового CPython теперь придётся строить через выпуск новой версии, а не через дозагрузку колеса в старую.
@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
✍4
uv 0.12.5 поменял правило выбора интерпретатора: при одинаковом приоритете теперь предпочитается более новая версия и стандартный вариант Python. Если в конфигурации несколько интерпретаторов с равным приоритетом, окружение может собраться уже не тем Python, что вчера.
🔘 подтянуты CPython 3.10.21, 3.11.16 и 3.12.14;
🔘 в preview у
🔘 экспорт SBOM в CycloneDX по умолчанию содержит URL и хеши артефактов;
🔘
🔘 в скриптах по PEP 723 относительные пути к индексам разрешаются относительно каталога скрипта, а не текущего каталога.
Выбор индекса по имени авторы помечают как preview. Численных бенчмарков в заметках к релизу нет.
@zen_of_python
--index и --default-index появился выбор настроенного индекса по имени;cache-physical-space откатывается к логическому размеру файла там, где физический размер файловая система не отдаёт;Выбор индекса по имени авторы помечают как preview. Численных бенчмарков в заметках к релизу нет.
@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Forwarded from Точка входа в программирование
Создаём программу, которая сама умеет выбирать модели в зависимости от задачи
Чем дольше работаешь с ИИ, тем больше убеждаешься, что под разные задачи нужны разные модели. Дя простых задач не нужна дорогая модель, а со сложной дешевая может не справиться. А ещё, используя только одну модель, вы рискуете получить кирпич, если эта модель вдруг станет недоступна.
Выход — разделить запросы по сложности и держать под рукой запасной вариант. Сначала ваш скрипт решает, насколько труден вопрос, потом отправляет простое к дешёвой модели, а сложное — к мощной. При сбое переключается на резервную модель. Туториал разбирает это на Python шаг за шагом.
#python
Чем дольше работаешь с ИИ, тем больше убеждаешься, что под разные задачи нужны разные модели. Дя простых задач не нужна дорогая модель, а со сложной дешевая может не справиться. А ещё, используя только одну модель, вы рискуете получить кирпич, если эта модель вдруг станет недоступна.
Выход — разделить запросы по сложности и держать под рукой запасной вариант. Сначала ваш скрипт решает, насколько труден вопрос, потом отправляет простое к дешёвой модели, а сложное — к мощной. При сбое переключается на резервную модель. Туториал разбирает это на Python шаг за шагом.
#python
👍2
Дэвид Бизли пишет с нуля живьём на сцене, за 46 минут проходя весь путь от простого сокета до собственного цикла событий. Слайдов почти нет, только редактор и терминал.
Последовательность такая. Берётся заведомо тяжёлая функция — рекурсивные числа Фибоначчи — и простой сетевой сервис. Сначала он последовательный, и один клиент блокирует всех остальных. Дальше появляются потоки: они спасают там, где программа ждёт ввод-вывод, но на вычислениях упираются в глобальную блокировку интерпретатора. Затем процессный пул, который блокировку обходит, но платит за это сериализацией и передачей данных.
Самая ценная часть в конце. Бизли показывает, что генератор с
После этого
@zen_of_python
Последовательность такая. Берётся заведомо тяжёлая функция — рекурсивные числа Фибоначчи — и простой сетевой сервис. Сначала он последовательный, и один клиент блокирует всех остальных. Дальше появляются потоки: они спасают там, где программа ждёт ввод-вывод, но на вычислениях упираются в глобальную блокировку интерпретатора. Затем процессный пул, который блокировку обходит, но платит за это сериализацией и передачей данных.
Самая ценная часть в конце. Бизли показывает, что генератор с
yield — это способ задачи добровольно приостановиться, и из этого прямо на глазах собирает планировщик с очередью задач, а потом цикл событий с select, ожиданием и пробуждением через пару сокетов.После этого
asyncio перестаёт быть магией: видно, из каких частей он состоит и почему устроен именно так.@zen_of_python
PEP 842 предлагает ключевое слово
Питер Бирма опубликовал черновик 25 июля, целевая версия — Python 3.16. Идея в том, чтобы у модуля появился явный публичный интерфейс, а не соглашение об именах с подчёркиванием и переменная
🔘 объявление помечается прямо в определении:
🔘 при обращении к скрытому имени поднимается
🔘 переменная
🔘 запись
🔘
🔘 слово мягкое, то есть существующий код с переменной по имени
Автор сам подчёркивает, что это не модификатор доступа: ограничение обходится удалением
В обсуждении сразу поднялся вопрос производительности: эталонная реализация пока не оптимизирована и, вероятно, добавляет накладные расходы на обращение к атрибутам модуля. Открытым остаётся и то, как пакет должен добираться до приватных имён собственных подмодулей. Пока это черновик, и до 3.16 у предложения ещё есть время измениться.
Обсуждение предложения
@zen_of_python
export и прячет из модуля всё, что им не помеченоПитер Бирма опубликовал черновик 25 июля, целевая версия — Python 3.16. Идея в том, чтобы у модуля появился явный публичный интерфейс, а не соглашение об именах с подчёркиванием и переменная
__all__, о которой знает только импорт со звёздочкой.export class Public видно снаружи, а обычный class Private из dir(module) исчезает;ExportError, наследник AttributeError;__export__ со списком строк работает как список экспорта, а имена в ней могут быть ещё не определены, но тогда импорт со звёздочкой упадёт;from module export NAME равносильна импорту имени с последующим его экспортом;export перед def и class разрешён только на уровне модуля, внутри функции это синтаксическая ошибка;export продолжит работать, а модули без __export__ ведут себя как раньше.Автор сам подчёркивает, что это не модификатор доступа: ограничение обходится удалением
__export__, правкой списка или обращением к __dict__ модуля. Смысл не в защите, а в том, чтобы автодополнение, документация и статический анализ видели границу библиотеки так же, как её видит автор.В обсуждении сразу поднялся вопрос производительности: эталонная реализация пока не оптимизирована и, вероятно, добавляет накладные расходы на обращение к атрибутам модуля. Открытым остаётся и то, как пакет должен добираться до приватных имён собственных подмодулей. Пока это черновик, и до 3.16 у предложения ещё есть время измениться.
Обсуждение предложения
@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1🤔1
Марк Шеннон и Даниэле Пармеджани опубликовали PEP 805 «Safe Parallel Python»: параллелизм в CPython без гонок по умолчанию. Целевая версия 3.16, статус Draft.
🔘 Каждый объект получает атрибут
🔘 Классы, функции и модули создаются Local. Замыкание, меняющее
🔘 Добавляются
🔘 Мотив: PEP 703 даёт параллелизм, но допускает гонки, а PEP 734 безопасен, но объекты между интерпретаторами без копирования не передать. Без чего-то подобного, считают авторы, две сборки CPython останутся навсегда.
@zen_of_python
__shareable__ только на чтение, со значением Immutable, Local, Protected или Synchronized. Контролируется доступ к объекту, а не отдельные операции: проверка нужна лишь при создании ссылки потока из ссылки в куче.nonlocal, останется Local, и передача его в чужую группу потоков даст IllegalThreadAccessException.SynchronizedList, SynchronizedDict и SynchronizedSet; sys.modules станет первым, sys.path — вторым. Авторы предупреждают: эти классы защищают объект от порчи, но потокобезопасности не дают.@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
Дескрипторы — та часть объектной модели Python, которую большинство использует каждый день, не зная названия. Официальное руководство Раймонда Хеттингера объясняет её по шагам и остаётся живой документацией, а не архивом.
Протокол состоит из трёх методов:
🔘
🔘 обычная функция становится связанным методом ровно потому, что функция — тоже дескриптор;
🔘
🔘 разница между дескрипторами с записью и без определяет, кто победит: дескриптор или словарь экземпляра;
🔘 на этом же построены
Практическая часть — готовый класс
@zen_of_python
Протокол состоит из трёх методов:
__get__, __set__ и __delete__. Класс, реализующий их, перехватывает доступ к атрибуту. Из этого собрано больше, чем кажется:property, staticmethod, classmethod и super() — всё это дескрипторы, и в руководстве показаны их упрощённые реализации на Python;__set_name__ позволяет дескриптору узнать имя атрибута, под которым его объявили;__slots__ и модели в ORM.Практическая часть — готовый класс
Validator и валидаторы OneOf, Number и String: проверка типов и диапазонов при присваивании, без единой строчки проверок в коде, который этими полями пользуется.@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
Почему
Антонио Куни разобрал по шагам, что происходит при обращении к атрибуту — от байткода до кода CPython. Порядок поиска на картинке.
Из него сразу объясняется несколько загадок. Дескриптор данных, то есть объект с
Там же видно, откуда берётся связанный метод: обычная функция — это дескриптор без записи, и
У классов поиск устроен иначе: сначала дескрипторы данных метакласса, потом полный проход по порядку разрешения методов.
Автор берёт CPython 3.12.11: в 3.13 этот код усложнён оптимизациями.
@zen_of_python
obj.prop вызывает функцию, а C.prop возвращает объект, и откуда метод знает про selfАнтонио Куни разобрал по шагам, что происходит при обращении к атрибуту — от байткода до кода CPython. Порядок поиска на картинке.
Из него сразу объясняется несколько загадок. Дескриптор данных, то есть объект с
__get__ и __set__, проверяется раньше словаря экземпляра — поэтому property не перекрыть, положив одноимённый ключ в obj.__dict__. И property остаётся дескриптором данных, даже когда сеттера нет: он определяет __set__ и сам поднимает AttributeError.Там же видно, откуда берётся связанный метод: обычная функция — это дескриптор без записи, и
obj.meth разворачивается в C.meth.__get__(obj, C).У классов поиск устроен иначе: сначала дескрипторы данных метакласса, потом полный проход по порядку разрешения методов.
Автор берёт CPython 3.12.11: в 3.13 этот код усложнён оптимизациями.
@zen_of_python