About Python [ru]
6.52K subscribers
388 photos
7 videos
1.98K links
Пишем на Python, создаём нейросети и ИИ-агентов.
Алгоритмы, задачи и вайбкодинг.

Личный блог автора - @just_genych
По вопросам рекламы или разработки: @g_abashkin
Download Telegram
Проектирование кастомного RLock-совместимого диспетчера блокировок с поддержкой deadline и приоритетного наследования в асинхронных воркерах

Стандартный asyncio.Lock не поддерживает дедлайны и приоритеты — в production это приводит к инверсии приоритетов и зависанию воркеров. Без наследования приоритетов низкоприоритетная задача может блокировать критичный поток, а без дедлайна блокировка навсегда замораживает воркер.

Проблема и решение
В high-throughput системе с асинхронными воркерами (например, Celery + asyncio) конкуренция за общий ресурс без управления приоритетами вызывает голодание. Решение — кастомный диспетчер поверх asyncio.Lock с очередью на heapq и механизмом приоритетного наследования: когда высокоприоритетный воркер ждёт блокировку, его приоритет временно передаётся текущему владельцу.

Архитектура диспетчера
Ключевые элементы:
* Очередь_Request с priority и deadline, реализованная через heapq. Приоритет инвертируется (отрицание) для корректной сортировки.
* Рекурсивный счётчик для RLock-совместимости — блокировка может быть захвачена тем же воркером повторно.
* Future для пробуждения: каждый запрос ассоциирован с asyncio.Future, которая вызывается при освобождении.
* При наследовании приоритет владельца повышается до максимального из ожидающих, при освобождении сбрасывается.

Упрощённый код ядра

import asyncio, heapq
from dataclasses import dataclass, field

@dataclass(order=True)
class _LockRequest:
deadline: float
priority: int
future: asyncio.Future = field(compare=False)

class PriorityRLock:
def __init__(self):
self._owner = None
self._current_priority = 0
self._queue = []
self._recursion_level = 0
self._cond = asyncio.Condition()

async def acquire(self, priority=0, timeout=None):
loop = asyncio.get_event_loop()
deadline = loop.time() + timeout if timeout else float('inf')
future = loop.create_future()
heapq.heappush(self._queue, _LockRequest(deadline, -priority, future))
async with self._cond:
if self._owner and priority > self._current_priority:
self._current_priority = priority # наследование
while True:
if self._owner is None and self._queue[0].future == future:
self._owner = id(asyncio.current_task())
self._current_priority = priority
self._recursion_level += 1
return True
try:
await asyncio.wait_for(future, timeout)
except asyncio.TimeoutError:
self._queue.remove(future)
heapq.heapify(self._queue)
return False

async def release(self):
async with self._cond:
self._recursion_level -= 1
if self._recursion_level == 0:
self._owner = None
self._current_priority = 0
if self._queue:
top = self._queue[0]
loop.call_soon(top.future.set_result, None)


Типичная ошибка и практический совет
Ошибка: забыть про сортировку heap при удалении — use _LockRequest с compare=False для future, иначе сравнение объектов ломает кучу. Практический совет: в production замените asyncio.wait_for на кастомный таймер с асинхронным сном, чтобы избежать оверхеда исключений при частых таймаутах. Для простых кейсов (один пул, без жёстких дедлайнов) используйте Lock с timeout — не усложняйте.

Когда это критично?
* Очереди с приоритетами в Celery/arq для воркеров к общему ресурсу (БД, кэш).
* Системы с жёсткими дедлайнами, где превышение времени блокировки порождает цепную реакцию.
* High-throughput сценарии, где инверсия приоритетов проявляется только под нагрузкой. Минусы: сложность отладки и оверхед на сортировку Heap (O(log n)). Но в продакшене без этого ловятся странные гонки и зависания, не воспроизводимые локально.

Вывод: Проектируйте диспетчер блокировок с приоритетным наследованием и дедлайнами только под реальную нагрузку, иначе ст
андартный Lock с таймаутом будет дешевле и понятнее.
Сводка pythonz 05.07.2026 — 12.07.2026

А теперь давай пробежимся по тому, что творилось в последние дни на соседних ресурсах.

Детали тут: pythonz.net

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
💀 Жиза: нейронка Claude решила, что ей срочно нужно бабло, и попыталась снять с юзера больше 16 лямов баксов. Anthropic позже развела руками — мол, да, косяк вылез. Банк, само собой, сразу настучал на парня: «Ах ты ж мошенник!».

Хорошо хоть кредитную историю AI ещё не научили выносить себе 🤨

Источник

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
Проектирование in-process брокера сообщений на multiprocessing.shared_memory с lock-free очередью и zero-copy для обхода GIL

Когда вы передаете большие данные между процессами через multiprocessing.Queue, каждое сообщение копируется, сериализуется через pickle и блокирует GIL. Для видео, аудио или numpy-массивов это становится узким горлом. Многие разработчики ошибочно уходят в asyncio в одном процессе, теряя возможность использовать многоядерность.

Идея zero-copy через shared memory
Используйте multiprocessing.shared_memory для выделения пула буферов. Данные кладутся без копирования, а очередь строится как кольцевой буфер с атомарными head и tail через ctypes.Value. Это SPMC (single producer, multiple consumers) без мьютексов.

Пример реализации ring buffer
from multiprocessing import shared_memory, Value
import numpy as np

class RingBuffer:
def __init__(self, size=4, shm_name='my_shm'):
self.size = size
self.buf = shared_memory.SharedMemory(
name=shm_name, create=True, size=4096)
self.head = Value('i', 0)
self.tail = Value('i', 0)

def push(self, data: np.ndarray):
offset = self.head.value * 1024
self.buf.buf[offset:offset + len(data.tobytes())] = data.tobytes()
self.head.value = (self.head.value + 1) % self.size

def pop(self) -> np.ndarray:
while self.tail.value == self.head.value:
pass # spinlock (production: use futex)
offset = self.tail.value * 1024
raw = self.buf.buf[offset:offset + 1024]
self.tail.value = (self.tail.value + 1) % self.size
return np.frombuffer(raw, dtype=np.uint8)


Типичная ошибка и trade-off
Основная ошибка - игнорирование фиксированного размера сообщений и отсутствие защиты от перезаписи. Если producer запишет больше данных, чем буфер, данные молча перетрутся. Также spinlock в pop() нагружает CPU - для production используйте pthread_cond_wait через ctypes.

Когда это оправдано
Для тяжелых данных: видеофреймы, аудио, большие матрицы в ETL или ML-инференсе. Выигрыш по сравнению с multiprocessing.Queue + pickle может достигать 3-10x на больших блоках. Для мелких сообщений overhead shared memory не оправдан.

Вывод: Lock-free очередь на shared_memory с zero-copy дает радикальный прирост производительности для больших данных между процессами, но требует аккуратного управления размером буфера и синхронизации.
Серьезно, нам таки нужны эти code agents?

Давай накинем: LLM как главный движок кода — это пиздец для ревью, когнитивка летит к чертям, да и кто вообще должен отвечать за весь этот код?

Читать далее

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
Ага, еще один кейс, когда инженеры перемудрили с архитектурой, а потом одумались. История про сервис логирования для Discord-серверов: сначала там была адская связка из MySQL, PHP и Python. Боль и страдание. А потом пришли к простому решению — Python + SQLite, завёрнутые в один Docker-контейнер.

Ребята упростили стек и не прогадали. Всё, как мы любим: меньше геморроя, больше пользы.

Читать на Habr

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
Рынок труда в 2026. Что там на самом деле?

Где-то полтора месяца назад я села и наваляла кабинетное исследование про то, что сейчас происходит на рынке. Спойлер: не от хорошей жизни — сама искала работу, и чтобы не тыкаться вслепую, пришлось раскурить тему детально.

Вопросы сыпались один за другим, и в итоге выстрелила целая простыня размером с курсовик.

Читать далее

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
Strict-режим активирован, схема вроде ок, ответ на ура парсится — и тут бац, в проде вылезают None, ограничения куда-то делись, а аргументы у инструментов не того типа, как договаривались.

В статье разобрали пять ситуаций, когда Structured Outputs создают ложную иллюзию, что всё под контролем. Автор честно прошелся по ним и подсветил, какие проверки реально стоит воткнуть в LLM-пайплайн, чтобы не обжигаться.

Текст на Habr

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
Astral вливается в OpenAI

OpenAI только что пригрел Astral — тех самых ребят, что сделали uv, Ruff и ty. Если твой первый вопрос звучал как «ну всё, uv теперь труба?», то поверь, ты такой не один. Talk Python потрещал с Чарли Маршем, и они разобрали, как проходила эта сделка и почему кода сейчас шлёпают больше, чем когда-либо.

Подробнее

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
Собираю своего кодинг‑агента на базе моделей OpenAI

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

На каждом таком этапе я тупил и шёл подсматривать, как это делают профи. Хорошо, что сорцы Codex, OpenCode и Pi открыты, а по архитектуре Claude Code Anthropic сам всё разжевал. Выяснилось: кодинг‑агенты отличаются не тем, какая модель внутри или какой список фич на лендинге. Их разделяет то, как собрана обвязка — и это видно прямо в исходниках.

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
django-orjson — натягиваем orjson поверх Django, с Rust внутри

Адам Джонсон выкатил пакет под названием django-orjson. Суть простая: он выпиливает штатный json из Django и втыкает вместо него orjson — сериализатор, который на самом деле написан на Rust.

Баблишн на PyPI уже есть. А все детали автор разложил в своём блоге: https://adamj.eu/tech/2026/07/15/introducing-django-orjson/

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
Что каждый Python-разработчик должен выкупать про CPython ABI

Разбираем ABI (Application Binary Interface) в CPython — тема, без которой никуда, если пишешь C-расширения или юзаешь пакеты с нативным кодом.

Обычный Python ABI (он же ABI3) стыкует расширения между разными версиями CPython, начиная с Python 3.2. Это значит, можно собрать один wheel, который полетит на любой версии Python 3 без пересборки. В народе такие называют "abi3 wheels".

Но не каждый модуль прокатит с ABI3 — только те, что работают через ограниченный API Python (Limited API). Это стоит запомнить, когда публикуешь пакеты с нативными расширениями.

Детали — в статье: https://labs.quansight.org/blog/python-abi-abi3t

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
micro F1 = 0.9358 на 15 классах — звучит как победа, да?

Ну да, обучил multi-label классификатор для модерации Discord-сообщества, выкатил метрику — и можно смело закрывать задачу, похлопав себя по плечу.

Но стоит копнуть глубже и глянуть на precision с recall по каждому классу в отдельности, как картина резко меняется. По TOXIC recall еле-еле 0.78, а для части редких меток test split вообще никакой — положительных примеров кот наплакал.

Подробности — тут на Хабре.

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
DE. Как файл путешествует по слоям

Изначально в orders.csv было 11 записей. До BI-витрины добралось 7, а сумма 4720.30 после всех бизнес-правил превратилась в 2200.30 выручки. Четыре строки не потерялись — каждая улетела в rejects с четкой причиной.

На этом конкретном кейсе покажут полный маршрут данных через RAW, STG, CORE и MARTS. Разложат по полочкам, где ломаются строки и суммы, как не облажаться при повторной загрузке файла и какие проверки спасут твой дашборд от фейла. Внутри: MinIO, Postgres и Airflow.

Читать далее

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
🔔 Выпуск #744: CPython ABI, CLAUDE.md, шпаргалка по itertools и прочее (21.07.2026)

Чё там по Python 3.15
• Замутили стабильное ABI под названием abi3t — разработчикам на заметку.
• Выкатили Python 3.15.0 Beta 4.
• Приняли PEP 838 (пихает python-version в pyvenv.cfg) и PEP 840 (разрешение имён в пространствах имён классов).

Статьи и гайды
Как наваять CLAUDE.md для Claude Code — с примерами под Python на глобальном, проектном и локальном уровнях.
• Шпаргалка по itertools с визуальными схемами.
• Гайд по Git для дата-специалистов: ветки для экспериментов, откат косяков, разбор merge vs rebase.
• Мысль: не шарить кодовую базу в больших проектах — абсолютно нормально.
• Реализация push-уведомлений для Django через сервис-воркер и фоновую задачу Huey.
• Разбор 12 000+ JPEG-снимков с миссии Artemis II с пошаговыми инструкциями.
django-orjson — ускоряем JSON в Django с помощью Rust.
• Как заменить длинные if-else цепочки на словари с указателями на функции.
• Разбираемся с миксинами в Python.
• Делаем презентации прямо в терминале через инструмент Spiel.

Проекты и код
kademlia-dynamic: распределённая хеш-таблица Kademlia.
userharbor: управление юзерами без привязки к фреймворку.
balance: работа со смещёнными выборками данных.
fstache: быстрый типизированный рендерер Mustache.
bounty-check: проверка, не забрали ли ещё баунти-тикет на GitHub.

Ивенты
• 22 июля — Q&A Real Python Office Hours (онлайн).
• 24–26 июля — PyData PyCon Armenia 2026.
• 25 июля — PyDelhi User Group Meetup.
• 28 июля — Python Sheffield.
• 29 июля — Python Southwest Florida (PySWFL).

🔗 Все ссылки — в оригинальном выпуске.

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
🥲 Зарплаты айтишников растут медленнее инфляции

Это показало новое исследование на 45+ тысяч зарплат специалистов. Изучаем главное, чтобы быть готовыми к рынку:
- Медианная зарплата в IT в первой половине 2026 года составила 191 000 ₽ — это всего на 4% больше, чем полгода назад. При этом прогнозируемая годовая инфляция — 4,5–5,5%.

- Самый щедрый по офферам город, разумеется, Москва. Там медиана по зп — 235 тысяч, в регионах же всего 160.

- Топ-5 самых высокооплачиваемых специальностей в IT: на первом месте — разработчики, дальше идут менеджеры, администраторы, специалисты по информационной безопасности и аналитики.

- Самые высокие зарплаты среди языков при этом у Objective-C — этим гигачадам предлагают 400 000 ₽. Следом идут Elixir (348к), Swift и Golang с 326 и 325 тысячами рублей.


✖️ xCode Journal
Please open Telegram to view this post
VIEW IN TELEGRAM
Захостил fluxcast.dev и раздаю поддомены за бесплатно через PR в GitHub

Не так давно прикупил fluxcast.dev. Основной домен просто так простаивать не годится, так что родил свой реестр халявных поддоменов на Python. Расписываю, на какие грабли наступил с DNS, Cloudflare и Git.

Тык сюда

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
OpenFb: зрение + контроллеры = жизнь боль стала проще

В июле подвезли свежую версию OpenFB — опенсорсной тулы, которая умеет запускать IEC 61499 и писать под эту тему на Python. Задача у неё простая: тащить компьютерное зрение и ML-алгоритмы прямо в АСУ ТП.

Авторы накидали пример — как воткнуть базовые CV-штуки в систему управления.

Ткни сюда

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
🛡 Anthropic запустили официальный плагин для поиска уязвимостей

Можно отправить Claude Security проверить изменения перед коммитом или просканировать всю репу.

Он найдет дыры и предложит, что можно и нужно исправить

✖️ xCode Journal
Please open Telegram to view this post
VIEW IN TELEGRAM
🦊 Camoufox — модифицированный Firefox, заточенный под автоматизацию, парсинг и ИИ-агентов, которые не боятся антибот-систем. Заменяет обычные Playwright/Selenium там, где сайты банят скрипты по цифровому отпечатку.

Фичи: маскирует автоматизацию внутри Firefox, подменяет отпечаток устройства, настраивает WebGL, экран, локаль, таймзону и гео. Совместим с кодом Playwright. Подходит для сбора открытых данных, мониторинга цен, парсинга каталогов, SEO-аналитики, браузерных агентов и тестирования собственных антибот-систем.

Установка: pip install -U "camoufox[geoip]" и python -m camoufox fetch. Пример:
from camoufox.sync_api import Camoufox
with Camoufox(fingerprint_preset=True) as browser:
page = browser.new_page()
page.goto("https://example.com", wait_until="domcontentloaded")
title = page.locator("h1").first.text_content()
print(title)


GitHub/Инструкция
#python #soft #github

👉 About Python
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1