#prog #rust #python #article
The easiest way to speed up Python with Rust
Статья про rustimport — библиотеку для лёгкой интеграции Rust-кода в код на Python, позволяющая импортировать отдельные rs-файлы как расширения. Со стороны Python требует лишь установить import hook.
Отдельно отмечается, что применение у этого метода скорее для прототипирования — по мере роста объёма кода на Rust преимущества rustimport становятся менее полезными.
The easiest way to speed up Python with Rust
Статья про rustimport — библиотеку для лёгкой интеграции Rust-кода в код на Python, позволяющая импортировать отдельные rs-файлы как расширения. Со стороны Python требует лишь установить import hook.
Отдельно отмечается, что применение у этого метода скорее для прототипирования — по мере роста объёма кода на Rust преимущества rustimport становятся менее полезными.
Python⇒Speed
The easiest way to speed up Python with Rust
Rust can make your Python code much faster; here’s how to start using it as quickly as possible.
#prog #python #amazingopensource
Ruff
An extremely fast Python linter, written in Rust.
⚡️ 10-100x faster than existing linters
🐍 Installable via pip
🛠 pyproject.toml support
🤝 Python 3.11 compatibility
📦 Built-in caching, to avoid re-analyzing unchanged files
🔧 Autofix support, for automatic error correction (e.g., automatically remove unused imports)
📏 Over 500 built-in rules
⚖️ Near-parity with the built-in Flake8 rule set
🔌 Native re-implementations of dozens of Flake8 plugins, like flake8-bugbear
⌨️ First-party editor integrations for VS Code and more
🌎 Monorepo-friendly, with hierarchical and cascading configuration
<...>
> Ruff is so fast that sometimes I add an intentional bug in the code just to confirm it's actually running and checking the code.
Ruff
An extremely fast Python linter, written in Rust.
⚡️ 10-100x faster than existing linters
🐍 Installable via pip
🛠 pyproject.toml support
🤝 Python 3.11 compatibility
📦 Built-in caching, to avoid re-analyzing unchanged files
🔧 Autofix support, for automatic error correction (e.g., automatically remove unused imports)
📏 Over 500 built-in rules
⚖️ Near-parity with the built-in Flake8 rule set
🔌 Native re-implementations of dozens of Flake8 plugins, like flake8-bugbear
⌨️ First-party editor integrations for VS Code and more
🌎 Monorepo-friendly, with hierarchical and cascading configuration
<...>
> Ruff is so fast that sometimes I add an intentional bug in the code just to confirm it's actually running and checking the code.
GitHub
GitHub - astral-sh/ruff: An extremely fast Python linter and code formatter, written in Rust.
An extremely fast Python linter and code formatter, written in Rust. - astral-sh/ruff
#prog #python #c #abnormalprogramming #article
Writing a C compiler in 500 lines of Python
С небольшим нюансом: компиляция в WASM и, понятное дело, только весьма небольшого подмножества C. Ну и для достижения ограничения на количество строк компилятор однопроходной.
Writing a C compiler in 500 lines of Python
С небольшим нюансом: компиляция в WASM и, понятное дело, только весьма небольшого подмножества C. Ну и для достижения ограничения на количество строк компилятор однопроходной.
vgel.me
Writing a C compiler in 500 lines of Python
Blog about linguistics, programming, and my projects
#prog #rust #python #performancetrap #article
Rust-Python FFI
Или о некоторых возможных проблемах при интеропе Rust и Python, включая проблемы производительности и проблемы с эргономикой.
Rust-Python FFI
Или о некоторых возможных проблемах при интеропе Rust и Python, включая проблемы производительности и проблемы с эргономикой.
#prog #rust #python #article #suckassstory #performancetrap
Rust std fs slower than Python!? No, it's hardware!
Редкий случай, когда удалось отследить баг и подтвердить, что он действительно в железе. Ссылки на патчи в glibc прилагаются.
TL;DR: оба варианта кода используют mmap в качестве буфера для считывания из файла, но в Python этот буфер используется с некоторым смещением. На некоторых процессорах — в том числе в том, который используется на машине автора — команда
Rust std fs slower than Python!? No, it's hardware!
Редкий случай, когда удалось отследить баг и подтвердить, что он действительно в железе. Ссылки на патчи в glibc прилагаются.
TL;DR: оба варианта кода используют mmap в качестве буфера для считывания из файла, но в Python этот буфер используется с некоторым смещением. На некоторых процессорах — в том числе в том, который используется на машине автора — команда
rep movsb
— которая использовалась в реализации memcpy — парадоксальным образом работает на порядок более медленно при работе с выровненным буфером.xuanwo.io
Rust std fs slower than Python!? No, it's hardware!
Achieving Data Freedom Through Open Source and Rust
#prog #python #article #suckassstory
node.example.com Is An IP Address
Или про проблему с tipchikami в Python2
node.example.com Is An IP Address
Или про проблему с tipchikami в Python2
tuckersiemens.com
node.example.com Is An IP Address
node.example.com is an IP address.
#prog #python #article
ABI compatibility in Python: How hard could it be?
Нативные расширения для Python могут распространяться в двух формах: в исходниках и в пресобранных бинарях.
В первом варианте сборка нативного кода происходит непосредственно на машине, которая использует расширение. Сильным преимуществом этого варианта является то, что расширение собирается под установленную версию Python, поэтому, если оно собирается, оно точно совместимо с этой версией. Очевидным недостатком является тот факт, что ошибки при сборке сложно диагностировать и исправлять, особенно для большинства пользователей Python, которые не обязательно разбираются в процессе сборки компилируемых языков (не говоря уже о том, что компиляция с оптимизациями может занять приличное время).
Для второго варианта — распространения в заранее собранных бинарях — есть стандартный формат, wheel. Недостатком этого подхода является то, что под каждую комбинацию OS, версии CPython и архитектуры нужно делать свой бинарь, что выливается в дополнительную нагрузку для разработчиков для тестирования под каждую из комбинаций. Вдобавок, если поддерживаемой версии wheel под тройку требований нет, пользователь в пролёте — ему остаётся только собирать самостоятельно. В частности, при релизе новой минорной версии CPython пользователям надо ждать, пока разработчики не соберут wheel под эту новую версию.
Для того, чтобы облегчить жизнь и пользователям, и разработчикам, разработчики CPython предоставили ручки, позволяющие выставлять разработчикам нативных расширений стабильное API со стабильным ABI. С технической точки зрения это выражается в установке макроса
У этого подхода, однако, есть гигантский недостаток: никакой инструмент цепочки упаковки пакета, его распространения и использования — включая сам CPython — не проверяет, что тег
В Trail of bits разработали инструмент, который как раз и проверяет, насколько расширение, заявленное, как поддерживающее abi3, действительно является таковым. Для исследования того, насколько этот инструмент полезен, авторы статьи проверили пакеты, скаченные с PyPI за последние 21 день (на момент написания статьи, т. е. 15 ноября 2022 года). По части результатов процитирую статью дословно:
Of the 357 valid packages, 54 (15 percent) contained wheels with ABI version violations. In other words: roughly one in six packages had wheels that claimed support for a particular Python version, but actually used the ABI of a newer Python version.
More severely: of those same 357 valid packages, 11 (3.1 percent) contained outright ABI violations. In other words: roughly one in thirty packages had wheels that claimed to be stable ABI compatible, but weren’t at all!
In total, 1139 (roughly 3 percent) Python extensions had version violations, and 90 (roughly 0.02 percent) had outright ABI violations. This suggests two things: that the same packages tend to have ABI violations across multiple wheels and extensions, and that multiple extensions within the same wheel tend to have ABI violations at the same time (which makes sense, since they should share the same build).
Советую прочитать статью, которая несколько более подробно рассказывает о проблеме, которую представленный инструмент может диагностировать, а также рассказывает о конкретных некорректных пакетах.
ABI compatibility in Python: How hard could it be?
Нативные расширения для Python могут распространяться в двух формах: в исходниках и в пресобранных бинарях.
В первом варианте сборка нативного кода происходит непосредственно на машине, которая использует расширение. Сильным преимуществом этого варианта является то, что расширение собирается под установленную версию Python, поэтому, если оно собирается, оно точно совместимо с этой версией. Очевидным недостатком является тот факт, что ошибки при сборке сложно диагностировать и исправлять, особенно для большинства пользователей Python, которые не обязательно разбираются в процессе сборки компилируемых языков (не говоря уже о том, что компиляция с оптимизациями может занять приличное время).
Для второго варианта — распространения в заранее собранных бинарях — есть стандартный формат, wheel. Недостатком этого подхода является то, что под каждую комбинацию OS, версии CPython и архитектуры нужно делать свой бинарь, что выливается в дополнительную нагрузку для разработчиков для тестирования под каждую из комбинаций. Вдобавок, если поддерживаемой версии wheel под тройку требований нет, пользователь в пролёте — ему остаётся только собирать самостоятельно. В частности, при релизе новой минорной версии CPython пользователям надо ждать, пока разработчики не соберут wheel под эту новую версию.
Для того, чтобы облегчить жизнь и пользователям, и разработчикам, разработчики CPython предоставили ручки, позволяющие выставлять разработчикам нативных расширений стабильное API со стабильным ABI. С технической точки зрения это выражается в установке макроса
Py_LIMITED_API
в значение конкретной версии API перед включением заголовочных файлов, предоставляющих интерфейс к CPython. Это стабильное ABI называется abi3
, и пакет с нативным расширением может иметь тег, говорящий, что код собран относительно этого ABI конкретной версии.У этого подхода, однако, есть гигантский недостаток: никакой инструмент цепочки упаковки пакета, его распространения и использования — включая сам CPython — не проверяет, что тег
abi3
и конкретная версия выставлены корректно. Иными словами, ничто не останавливает пользователей от того, чтобы подгрузить к интерпретатору расширение с некорректным ABI. Последствия этого также плачевны, как и при любом несовпадении ABI, и могут варьироваться от (при удаче) отсутствия каких-либо проблем до крашей или, что гораздо хуже, порчи памяти.В Trail of bits разработали инструмент, который как раз и проверяет, насколько расширение, заявленное, как поддерживающее abi3, действительно является таковым. Для исследования того, насколько этот инструмент полезен, авторы статьи проверили пакеты, скаченные с PyPI за последние 21 день (на момент написания статьи, т. е. 15 ноября 2022 года). По части результатов процитирую статью дословно:
Of the 357 valid packages, 54 (15 percent) contained wheels with ABI version violations. In other words: roughly one in six packages had wheels that claimed support for a particular Python version, but actually used the ABI of a newer Python version.
More severely: of those same 357 valid packages, 11 (3.1 percent) contained outright ABI violations. In other words: roughly one in thirty packages had wheels that claimed to be stable ABI compatible, but weren’t at all!
In total, 1139 (roughly 3 percent) Python extensions had version violations, and 90 (roughly 0.02 percent) had outright ABI violations. This suggests two things: that the same packages tend to have ABI violations across multiple wheels and extensions, and that multiple extensions within the same wheel tend to have ABI violations at the same time (which makes sense, since they should share the same build).
Советую прочитать статью, которая несколько более подробно рассказывает о проблеме, которую представленный инструмент может диагностировать, а также рассказывает о конкретных некорректных пакетах.
The Trail of Bits Blog
ABI compatibility in Python: How hard could it be?
TL;DR: Trail of Bits has developed abi3audit, a new Python tool for checking Python packages for CPython application binary interface (ABI) violations. We’ve used it to discover hundreds of inconsistently and incorrectly tagged package distributions, each…
Блог*
#prog #python #article ABI compatibility in Python: How hard could it be? Нативные расширения для Python могут распространяться в двух формах: в исходниках и в пресобранных бинарях. В первом варианте сборка нативного кода происходит непосредственно на машине…
В статье мимолётом упоминается, что им не удалось найти кошкодевочек, в отличие от moyix.
#prog (somewhat #python) #menacingopensource #article
Someone’s Been Messing With My Subnormals!
TL;DR: After noticing an annoying warning, I went on an absurd yak shave, and discovered that because of a tiny handful of Python packages built with an appealing-sounding but dangerous compiler option, more than 2,500 Python packages—some with more than a million downloads per month—could end up causing any program that uses them to compute incorrect numerical results.
Или чуть более подробно: в силу каких-то сомнительных решений в GCC (равно как и в clang, который старательно скопировал его поведение) активация флага
#prog (somewhat #python) #menacingopensource #article
Someone’s Been Messing With My Subnormals!
TL;DR: After noticing an annoying warning, I went on an absurd yak shave, and discovered that because of a tiny handful of Python packages built with an appealing-sounding but dangerous compiler option, more than 2,500 Python packages—some with more than a million downloads per month—could end up causing any program that uses them to compute incorrect numerical results.
Или чуть более подробно: в силу каких-то сомнительных решений в GCC (равно как и в clang, который старательно скопировал его поведение) активация флага
-Ofast
подразумевает активацию флага -ffast-math
, который, в свою очередь, при компиляции разделяемой библиотеки генерировал для неё конструктор, который, помимо всего прочего, выставлял в процессоре флаг, регулирующий поведение операций над плавающей точкой — более конкретно, FTZ/DAZ, при активации которого операции, которые выдали бы субнормальные числа с плавающей точкой, вместо этого выдают ноль. Несколько нативных расширений были скомпилированы с флагом -Ofast
, которые в результате стали расширениями, банальный импорт которых менял поведение арифметики чисел с плавающей точкой для всего процесса, включая код из NumPy.X (formerly Twitter)
Brendan Dolan-Gavitt (@moyix) on X
Among many, many other files, my Python packaging misadventures seem to have made me the proud owner of these two pictures, deposited in ~/.local/share/koneko/pics. Thanks, pip!
#prog #python #article #abnormalprogramming
Python's Preprocessor
Python позволяет иметь в первой строке комментарий, который говорит о том, какая кодировка используется для текста файла. Имя кодировщика ищется в специальном месте, и механизм для предоставления этого кодировщика позволяет исполнять произвольный код на Python. Как следствие, это позволяет интерпретировать дальнейший текст как угодно — с синтаксисом, произвольно далёким от Python.
(thanks @itpgchannel)
Python's Preprocessor
Python позволяет иметь в первой строке комментарий, который говорит о том, какая кодировка используется для текста файла. Имя кодировщика ищется в специальном месте, и механизм для предоставления этого кодировщика позволяет исполнять произвольный код на Python. Как следствие, это позволяет интерпретировать дальнейший текст как угодно — с синтаксисом, произвольно далёким от Python.
(thanks @itpgchannel)
Pydong
Python’s Preprocessor
Every now and then you hear outrageous claims such as “Python has no preprocessor”.
#prog #python #article
Проблемы вызова Python кода из C кода
Или про то, как немного странный (но легальный) код на Python может привести к сегфолту интепретатора.
Проблемы вызова Python кода из C кода
Или про то, как немного странный (но легальный) код на Python может привести к сегфолту интепретатора.
Хабр
Проблемы вызова Python кода из C кода
Привет, Хабр! Меня зовут Никита Соболев, я опенсорс разработчик и core-разработчик CPython. Давайте поговорим про одну из самых сложных частей интерпретатора CPython – вызов Python кода из C кода....
Блог*
#prog #article Fast Enough VMs in Fast Enough Time Старая (2012 года) статья про применение RPython (языка реализации PyPy) к реализации VM для ЯП с семантикой слишком необычной, чтобы для него подходили существующие VM. Чем привлекает RPython? Обещанием:…
#prog #python #article
И ещё серия старых (2012 год) статей от разработчика PyPy о том, как можно написать код таким образом, чтобы получить наибольшее преимущество от трассирующего JIT:
Controlling the Tracing of an Interpreter With Hints, Part 1: Controlling the Extent of Tracing
Controlling the Tracing of an Interpreter With Hints, Part 2: Controlling Optimization
Controlling the Tracing of an Interpreter With Hints, Part 3: Putting it All Together — про то, как организовать структуру представления объектов так, чтобы получить выгоду от JIT (ибо наивный подход со словарями методов толком не ускорить)
И ещё серия старых (2012 год) статей от разработчика PyPy о том, как можно написать код таким образом, чтобы получить наибольшее преимущество от трассирующего JIT:
Controlling the Tracing of an Interpreter With Hints, Part 1: Controlling the Extent of Tracing
Controlling the Tracing of an Interpreter With Hints, Part 2: Controlling Optimization
Controlling the Tracing of an Interpreter With Hints, Part 3: Putting it All Together — про то, как организовать структуру представления объектов так, чтобы получить выгоду от JIT (ибо наивный подход со словарями методов толком не ускорить)
Blogspot
Controlling the Tracing of an Interpreter With Hints, Part 1: Controlling the Extent of Tracing
The question I was asked most often during my recent US trip was how exactly the hints work that interpreter authors can use to improve the...
#prog #cpp #python
Что общего у C++ и Python?
Правильно: что в C++, что в Python нельзя распаковывать кортежи в аргументах лямбды.
Что общего у C++ и Python?
Правильно: что в C++, что в Python нельзя распаковывать кортежи в аргументах лямбды.
Stack Overflow
Structured binding in lambda arguments
Why I cannot use C++17 structured binding in this case?
std::map<int, int> m;
std::find_if( m.cbegin(), m.cend(), []( const auto & [x, y] ){ return x == y; } );
std::map<int, int> m;
std::find_if( m.cbegin(), m.cend(), []( const auto & [x, y] ){ return x == y; } );
Блог*
#prog #cpp #python Что общего у C++ и Python? Правильно: что в C++, что в Python нельзя распаковывать кортежи в аргументах лямбды.
#prog #python
Причём в Python 2.x можно было писать код вида
, а в Python 3 это убрали после PEP 3113, причём по причинам, которые, на мой взгляд, можно было бы и исправить.
Причём в Python 2.x можно было писать код вида
lambda (x, y): (y, x)
, а в Python 3 это убрали после PEP 3113, причём по причинам, которые, на мой взгляд, можно было бы и исправить.
Python Enhancement Proposals (PEPs)
PEP 3113 – Removal of Tuple Parameter Unpacking | peps.python.org
Tuple parameter unpacking is the use of a tuple as a parameter in a function signature so as to have a sequence argument automatically unpacked. An example is:
#prog #python #article
Новый лучший способ форматирования строк в Python
t-строки — новый вид строк в Python. Походит на format_args! в Rust в том смысле, что позволяет захватывать переменные по имени и создаёт просто шаблон со значениями переменных вместо уже форматированной строки. Как следствие, это позволяет одновременно ускорить форматирование и отделить собственно образование шаблона от его интерпретации. В статье приводится пример форматировщика SQL-запросов: он может при форматировании автоматически экранировать значения. Аналогично для шаблонизатора HTML.
Новый лучший способ форматирования строк в Python
t-строки — новый вид строк в Python. Походит на format_args! в Rust в том смысле, что позволяет захватывать переменные по имени и создаёт просто шаблон со значениями переменных вместо уже форматированной строки. Как следствие, это позволяет одновременно ускорить форматирование и отделить собственно образование шаблона от его интерпретации. В статье приводится пример форматировщика SQL-запросов: он может при форматировании автоматически экранировать значения. Аналогично для шаблонизатора HTML.