Как выполнять CPU-задачи в отдельных интерпретаторах Python
В Python 3.14 InterpreterPoolExecutor запускает потоки с отдельными интерпретаторами. У каждого свой GIL, поэтому вычисления на Python могут одновременно занимать несколько ядер в одном процессе.
У этой модели есть цена: между интерпретаторами передаются сериализованные функции, аргументы и результаты. Импорты и глобальные переменные изолированы. Кеш на уровне модуля станет кешем каждого работника; большая таблица данных может занять память несколько раз.
Подход подходит для достаточно крупных вычислительных задач с простыми входами и выходами. На мелких операциях передачу данных легко сделать дороже вычислений. Перед переносом проверьте совместимость C-расширений и сравните время и память с ProcessPoolExecutor на реальной нагрузке.
#python #производительность
В Python 3.14 InterpreterPoolExecutor запускает потоки с отдельными интерпретаторами. У каждого свой GIL, поэтому вычисления на Python могут одновременно занимать несколько ядер в одном процессе.
У этой модели есть цена: между интерпретаторами передаются сериализованные функции, аргументы и результаты. Импорты и глобальные переменные изолированы. Кеш на уровне модуля станет кешем каждого работника; большая таблица данных может занять память несколько раз.
Подход подходит для достаточно крупных вычислительных задач с простыми входами и выходами. На мелких операциях передачу данных легко сделать дороже вычислений. Перед переносом проверьте совместимость C-расширений и сравните время и память с ProcessPoolExecutor на реальной нагрузке.
#python #производительность
Почему цикл внутри теста скрывает часть ошибок
Тест перебирает десять входов и проверяет результат через assert. Если третий случай падает, оставшиеся семь до проверки не доходят. В отчёте появляется одна ошибка, а состояние остальных случаев неизвестно.
pytest.mark.parametrize превращает каждую пару «вход — ожидаемый результат» в отдельный тест. Без режима остановки на первой ошибке pytest проверит все случаи и покажет, какие именно сломались. Через ids им можно дать понятные имена.
Подготовку ресурсов удобно вынести в fixture с yield: код после yield выполнит очистку. Для ожидаемой ошибки используйте pytest.raises с конкретным типом и match, если важен текст сообщения. Иначе случайный ValueError из другой части функции может сделать тест зелёным.
#python #тестирование
Тест перебирает десять входов и проверяет результат через assert. Если третий случай падает, оставшиеся семь до проверки не доходят. В отчёте появляется одна ошибка, а состояние остальных случаев неизвестно.
pytest.mark.parametrize превращает каждую пару «вход — ожидаемый результат» в отдельный тест. Без режима остановки на первой ошибке pytest проверит все случаи и покажет, какие именно сломались. Через ids им можно дать понятные имена.
Подготовку ресурсов удобно вынести в fixture с yield: код после yield выполнит очистку. Для ожидаемой ошибки используйте pytest.raises с конкретным типом и match, если важен текст сообщения. Иначе случайный ValueError из другой части функции может сделать тест зелёным.
#python #тестирование
Почему frozendict не замораживает вложенные объекты
В Python 3.15 появляется встроенный frozendict. В нём нельзя заменить значение по ключу или удалить запись. Но если значением служит список, сам список по-прежнему можно изменить через append.
Заморозка действует только на отображение. Поэтому frozendict с вложенным списком создаётся без ошибки, а вызов hash завершится TypeError. Для использования в ключе словаря или элементе множества все ключи и значения должны быть хешируемыми.
Есть ещё нюанс совместимости: frozendict не наследуется от dict. Проверка isinstance(value, dict) его отвергнет. Если функции достаточно чтения по ключам, контракт через collections.abc.Mapping принимает оба типа. Для вложенной структуры отдельно выбирайте подходящие контейнеры на каждом уровне.
#python #типизация
В Python 3.15 появляется встроенный frozendict. В нём нельзя заменить значение по ключу или удалить запись. Но если значением служит список, сам список по-прежнему можно изменить через append.
Заморозка действует только на отображение. Поэтому frozendict с вложенным списком создаётся без ошибки, а вызов hash завершится TypeError. Для использования в ключе словаря или элементе множества все ключи и значения должны быть хешируемыми.
Есть ещё нюанс совместимости: frozendict не наследуется от dict. Проверка isinstance(value, dict) его отвергнет. Если функции достаточно чтения по ключам, контракт через collections.abc.Mapping принимает оба типа. Для вложенной структуры отдельно выбирайте подходящие контейнеры на каждом уровне.
#python #типизация
Как дождаться обработки очереди asyncio
Пустая очередь ещё не означает, что работа закончена: потребитель мог забрать элемент и продолжать его обработку. asyncio.Queue.join() ориентируется на число неподтверждённых задач, а не на количество элементов внутри очереди.
В схеме producer/consumer каждому успешному get() соответствует один task_done(). Подтверждение ставят после обработки, обычно в finally. Если подтверждать и неудачные задачи, join означает завершение учёта, а успех и повторную обработку нужно отслеживать отдельно.
maxsize ограничивает накопление: await put() ждёт, пока появится место. Для остановки потребителя можно отправить отдельный маркер, который тоже требует task_done(). Сам join работников не останавливает — после него нужно дождаться завершения их задач.
#python #asyncio
Пустая очередь ещё не означает, что работа закончена: потребитель мог забрать элемент и продолжать его обработку. asyncio.Queue.join() ориентируется на число неподтверждённых задач, а не на количество элементов внутри очереди.
В схеме producer/consumer каждому успешному get() соответствует один task_done(). Подтверждение ставят после обработки, обычно в finally. Если подтверждать и неудачные задачи, join означает завершение учёта, а успех и повторную обработку нужно отслеживать отдельно.
maxsize ограничивает накопление: await put() ждёт, пока появится место. Для остановки потребителя можно отправить отдельный маркер, который тоже требует task_done(). Сам join работников не останавливает — после него нужно дождаться завершения их задач.
#python #asyncio
Как добавить MCP-сервер в Django-проект
django-mcpz позволяет зарегистрировать Python-функцию как MCP-инструмент и подключить сервер в urls.py как обычное представление. Функция получает HttpRequest, поэтому может использовать request.user и ORM проекта.
В примере Адама Джонсона инструмент считает заказы с необязательным фильтром статуса. Параметры и результат описаны через msgspec.Struct: библиотека строит JSON Schema и проверяет аргументы до вызова функции. Реализация рассчитана на обычное синхронное WSGI-развёртывание.
Аутентификация задаётся явно. Для клиентских инструментов есть отзываемые bearer-токены, для OAuth-клиентов — отдельное приложение авторизации. Аннотация read_only описывает инструмент для клиента; реальные права доступа к данным всё равно должен проверять сервер.
#python #django
django-mcpz позволяет зарегистрировать Python-функцию как MCP-инструмент и подключить сервер в urls.py как обычное представление. Функция получает HttpRequest, поэтому может использовать request.user и ORM проекта.
В примере Адама Джонсона инструмент считает заказы с необязательным фильтром статуса. Параметры и результат описаны через msgspec.Struct: библиотека строит JSON Schema и проверяет аргументы до вызова функции. Реализация рассчитана на обычное синхронное WSGI-развёртывание.
Аутентификация задаётся явно. Для клиентских инструментов есть отзываемые bearer-токены, для OAuth-клиентов — отдельное приложение авторизации. Аннотация read_only описывает инструмент для клиента; реальные права доступа к данным всё равно должен проверять сервер.
#python #django
Чего не проверяет runtime_checkable Protocol
Protocol позволяет описать небольшой интерфейс: например, метод send(destination, message). Класс может удовлетворять ему без наследования — статический анализатор проверяет совместимость структуры и сигнатур.
Декоратор runtime_checkable добавляет возможность isinstance, но такая проверка не валидирует сигнатуры методов. Наличие атрибута send не доказывает, что он принимает нужные аргументы или выполняет обещанное действие.
Поэтому проверка плагина требует нескольких уровней: типизация помогает проверить код, тест контракта — поведение адаптера, схема — внешние данные. Аннотация quantity: int сама по себе не отвергает отрицательное число, а корректная схема заказа не доказывает, что товар есть на складе.
#python #типизация
Protocol позволяет описать небольшой интерфейс: например, метод send(destination, message). Класс может удовлетворять ему без наследования — статический анализатор проверяет совместимость структуры и сигнатур.
Декоратор runtime_checkable добавляет возможность isinstance, но такая проверка не валидирует сигнатуры методов. Наличие атрибута send не доказывает, что он принимает нужные аргументы или выполняет обещанное действие.
Поэтому проверка плагина требует нескольких уровней: типизация помогает проверить код, тест контракта — поведение адаптера, схема — внешние данные. Аннотация quantity: int сама по себе не отвергает отрицательное число, а корректная схема заказа не доказывает, что товар есть на складе.
#python #типизация
Как измерять время async-функции через декоратор
Обычная обёртка может вызвать async-функцию и получить объект корутины за микросекунды. Это ещё не время запроса: выполнение корутины начнётся позже, а исключение возникнет уже за пределами обёртки.
В разборе async-декораторов обёртка сама объявлена через async def. Она сохраняет время старта, выполняет return await fn(*args, **kwargs), а запись длительности помещает в finally.
Так измерение охватывает выполнение и очистку при ошибке или отмене. functools.wraps сохраняет метаданные и связь wrapped для интроспекции. Сам сборщик метрик тоже должен быть аккуратным: его ошибка в finally способна перекрыть исходное исключение, а блокирующий ввод-вывод задержит весь event loop.
#python #asyncio
Обычная обёртка может вызвать async-функцию и получить объект корутины за микросекунды. Это ещё не время запроса: выполнение корутины начнётся позже, а исключение возникнет уже за пределами обёртки.
В разборе async-декораторов обёртка сама объявлена через async def. Она сохраняет время старта, выполняет return await fn(*args, **kwargs), а запись длительности помещает в finally.
Так измерение охватывает выполнение и очистку при ошибке или отмене. functools.wraps сохраняет метаданные и связь wrapped для интроспекции. Сам сборщик метрик тоже должен быть аккуратным: его ошибка в finally способна перекрыть исходное исключение, а блокирующий ввод-вывод задержит весь event loop.
#python #asyncio
Почему max_workers не ограничивает очередь задач
ThreadPoolExecutor(max_workers=8) разрешает одновременно выполнять восемь вызовов. Если сразу вызвать submit для миллиона записей, остальные будут ждать, удерживая Future, аргументы и связанные объекты в памяти.
Окно незавершённой работы ограничивает и подачу: отправить, например, 32 задачи, дождаться завершений через wait(..., FIRST_COMPLETED), забрать результаты и только затем добавить новые. Производитель перестаёт бесконечно убегать вперёд.
В Python 3.14 для обработки с сохранением входного порядка есть executor.map(..., buffersize=32). Ручная схема удобнее, когда результаты нужны по готовности. Ни одна из этих границ не задаёт число запросов в секунду: для внешнего API ограничение частоты рассчитывают отдельно.
#python #производительность
ThreadPoolExecutor(max_workers=8) разрешает одновременно выполнять восемь вызовов. Если сразу вызвать submit для миллиона записей, остальные будут ждать, удерживая Future, аргументы и связанные объекты в памяти.
Окно незавершённой работы ограничивает и подачу: отправить, например, 32 задачи, дождаться завершений через wait(..., FIRST_COMPLETED), забрать результаты и только затем добавить новые. Производитель перестаёт бесконечно убегать вперёд.
В Python 3.14 для обработки с сохранением входного порядка есть executor.map(..., buffersize=32). Ручная схема удобнее, когда результаты нужны по готовности. Ни одна из этих границ не задаёт число запросов в секунду: для внешнего API ограничение частоты рассчитывают отдельно.
#python #производительность
Как проверить, что мок заменил нужную зависимость
Если service.py делает from client import fetch, функция использует имя service.fetch. Патч client.fetch не заменит уже импортированную ссылку: тест может продолжить обращаться к настоящему клиенту.
Правило patch — заменять имя там, где тестируемый код его ищет. Для этого примера нужен patch("service.fetch", autospec=True). autospec проверяет совместимость вызова с сигнатурой зависимости и помогает поймать лишний аргумент.
Для async-зависимости важно проверить await: assert_called_once_with доказывает только вызов, а assert_awaited_once_with — ожидание корутины. Дополнительно проверяйте возвращённое значение или эффект работы сервиса. Один счётчик вызовов не показывает, что результат зависимости был использован правильно.
#python #тестирование
Если service.py делает from client import fetch, функция использует имя service.fetch. Патч client.fetch не заменит уже импортированную ссылку: тест может продолжить обращаться к настоящему клиенту.
Правило patch — заменять имя там, где тестируемый код его ищет. Для этого примера нужен patch("service.fetch", autospec=True). autospec проверяет совместимость вызова с сигнатурой зависимости и помогает поймать лишний аргумент.
Для async-зависимости важно проверить await: assert_called_once_with доказывает только вызов, а assert_awaited_once_with — ожидание корутины. Дополнительно проверяйте возвращённое значение или эффект работы сервиса. Один счётчик вызовов не показывает, что результат зависимости был использован правильно.
#python #тестирование
👍2
Почему короткие паузы сборщика мусора обходятся памятью
В CPython подсчёт ссылок освобождает многие объекты сразу, а циклический GC ищет недостижимые циклы. Сокращение пауз этого дополнительного механизма важно для серверов и интерфейсов, но может изменить расход памяти.
В отчёте Language Summit Марк Шеннон разбирает откат инкрементального сборщика Python 3.14 после проблем с памятью на реальных нагрузках. Разделение обхода на небольшие части уменьшало длинные остановки, но дольше сохраняло часть объектов.
Обсуждаемое направление — совместить поколения с инкрементальным обходом молодых и старых объектов. Это предложение, а не настройка, которую уже можно включить. Для оценки изменений нужны одновременно длительность пауз, память и реальные сценарии приложения: улучшение одного показателя может ухудшить другой.
#python #cpython
В CPython подсчёт ссылок освобождает многие объекты сразу, а циклический GC ищет недостижимые циклы. Сокращение пауз этого дополнительного механизма важно для серверов и интерфейсов, но может изменить расход памяти.
В отчёте Language Summit Марк Шеннон разбирает откат инкрементального сборщика Python 3.14 после проблем с памятью на реальных нагрузках. Разделение обхода на небольшие части уменьшало длинные остановки, но дольше сохраняло часть объектов.
Обсуждаемое направление — совместить поколения с инкрементальным обходом молодых и старых объектов. Это предложение, а не настройка, которую уже можно включить. Для оценки изменений нужны одновременно длительность пауз, память и реальные сценарии приложения: улучшение одного показателя может ухудшить другой.
#python #cpython
👍2
Почему копия контекста не делает словарь отдельным
contextvars помогает хранить request ID для задач, которые выполняются на одном потоке event loop. При обычном создании asyncio.Task контекст копируется, поэтому новая задача получает текущую привязку переменной.
Но копия контекста поверхностная. Если ContextVar содержит словарь, родитель и дочерняя задача могут видеть один объект. Изменение его содержимого будет общим; set с новым значением меняет привязку в текущем контексте.
Для метаданных запроса удобнее неизменяемые значения. После set сохраняйте токен и восстанавливайте предыдущую привязку через reset в finally. Дочерняя задача может сохранить захваченный контекст и после завершения запроса, поэтому долгоживущей фоновой работе передавайте только необходимые данные.
#python #asyncio
contextvars помогает хранить request ID для задач, которые выполняются на одном потоке event loop. При обычном создании asyncio.Task контекст копируется, поэтому новая задача получает текущую привязку переменной.
Но копия контекста поверхностная. Если ContextVar содержит словарь, родитель и дочерняя задача могут видеть один объект. Изменение его содержимого будет общим; set с новым значением меняет привязку в текущем контексте.
Для метаданных запроса удобнее неизменяемые значения. После set сохраняйте токен и восстанавливайте предыдущую привязку через reset в finally. Дочерняя задача может сохранить захваченный контекст и после завершения запроса, поэтому долгоживущей фоновой работе передавайте только необходимые данные.
#python #asyncio
Почему тайм-аут не всегда заканчивается ровно по часам
asyncio.TaskGroup владеет созданными в нём задачами и ждёт их завершения. Если одна падает с обычным исключением, группа запрашивает отмену остальных, дожидается очистки и собирает ошибки в ExceptionGroup.
В разборе отмены и тайм-аутов важна граница: cancel() отправляет запрос, а задача должна получить CancelledError и выполнить finally. Если она подавляет отмену или долго очищает ресурсы, завершение затянется.
wait_for() ждёт окончания отмены, поэтому фактическое время может превысить заданный timeout. Контекст asyncio.timeout() отменяет текущую задачу и преобразует свою отмену в TimeoutError снаружи блока. Для связанных операций помещайте TaskGroup внутрь timeout, чтобы дочерняя работа имела явного владельца.
#python #asyncio
asyncio.TaskGroup владеет созданными в нём задачами и ждёт их завершения. Если одна падает с обычным исключением, группа запрашивает отмену остальных, дожидается очистки и собирает ошибки в ExceptionGroup.
В разборе отмены и тайм-аутов важна граница: cancel() отправляет запрос, а задача должна получить CancelledError и выполнить finally. Если она подавляет отмену или долго очищает ресурсы, завершение затянется.
wait_for() ждёт окончания отмены, поэтому фактическое время может превысить заданный timeout. Контекст asyncio.timeout() отменяет текущую задачу и преобразует свою отмену в TimeoutError снаружи блока. Для связанных операций помещайте TaskGroup внутрь timeout, чтобы дочерняя работа имела явного владельца.
#python #asyncio
Что мешает запускать Python из снимка памяти
Импорты и инициализация повторяются при каждом старте интерпретатора. Снимок уже подготовленного процесса мог бы пропускать эту работу — особенно в WebAssembly и сервисах, которые часто запускают короткие задачи.
В обсуждении снимков CPython есть неожиданный барьер: случайное начальное значение для хеширования. Python выбирает его при запуске, чтобы затруднить атаки через коллизии. Снимок зафиксирует значение, и восстановленные процессы начнут использовать одно и то же.
Худ Чатем предлагает отдельную фазу инициализации с повторной настройкой состояния после восстановления. Потребуется учитывать и библиотеки, рассчитывающие на новый запуск. Это пока обсуждаемая архитектура; просто сохранить память процесса недостаточно для безопасного ускорения старта.
#python #cpython
Импорты и инициализация повторяются при каждом старте интерпретатора. Снимок уже подготовленного процесса мог бы пропускать эту работу — особенно в WebAssembly и сервисах, которые часто запускают короткие задачи.
В обсуждении снимков CPython есть неожиданный барьер: случайное начальное значение для хеширования. Python выбирает его при запуске, чтобы затруднить атаки через коллизии. Снимок зафиксирует значение, и восстановленные процессы начнут использовать одно и то же.
Худ Чатем предлагает отдельную фазу инициализации с повторной настройкой состояния после восстановления. Потребуется учитывать и библиотеки, рассчитывающие на новый запуск. Это пока обсуждаемая архитектура; просто сохранить память процесса недостаточно для безопасного ускорения старта.
#python #cpython
Как PEP 827 предлагает выводить тип выбранных полей
ORM-запрос выбирает name и email, но статический анализатор часто видит заранее заданную модель. Для отдельных операций приходится вручную поддерживать похожие типы: публичный ответ, создание записи и частичное обновление.
PEP 827 предлагает преобразования типов: условные выражения, перебор типов и доступ к членам модели. Библиотека могла бы вывести тип результата из выбранных полей или построить Update-модель с необязательными свойствами.
На Language Summit обсуждали и хранение аннотаций: Pydantic и FastAPI используют их во время выполнения, поэтому одного результата статической проверки недостаточно. Сохранение исходных выражений требует компромисса между памятью, скоростью и сложностью. Это предложение с прототипом, а не доступный синтаксис стабильного Python.
#python #типизация
ORM-запрос выбирает name и email, но статический анализатор часто видит заранее заданную модель. Для отдельных операций приходится вручную поддерживать похожие типы: публичный ответ, создание записи и частичное обновление.
PEP 827 предлагает преобразования типов: условные выражения, перебор типов и доступ к членам модели. Библиотека могла бы вывести тип результата из выбранных полей или построить Update-модель с необязательными свойствами.
На Language Summit обсуждали и хранение аннотаций: Pydantic и FastAPI используют их во время выполнения, поэтому одного результата статической проверки недостаточно. Сохранение исходных выражений требует компромисса между памятью, скоростью и сложностью. Это предложение с прототипом, а не доступный синтаксис стабильного Python.
#python #типизация
👍1
Python 3.10 больше не получает исправления безопасности
Версия 3.10.22 стала последней в своей ветке. После пяти лет поддержки Python 3.10 достиг end of life: новых security updates для него не будет.
В объявлении команды Python есть и другие изменения: 3.13.16 — последний полный maintenance-релиз ветки 3.13. Дальше она будет получать только исправления безопасности.
Перед миграцией проверьте интерпретатор в контейнерах, CI, виртуальных окружениях и заданиях по расписанию. Затем убедитесь, что для выбранной версии доступны совместимые зависимости и wheels, и прогоните тесты приложения.
Обновление пакетов внутри окружения само по себе не обновляет Python. Версию runtime нужно менять отдельно.
#python #обновления
Версия 3.10.22 стала последней в своей ветке. После пяти лет поддержки Python 3.10 достиг end of life: новых security updates для него не будет.
В объявлении команды Python есть и другие изменения: 3.13.16 — последний полный maintenance-релиз ветки 3.13. Дальше она будет получать только исправления безопасности.
Перед миграцией проверьте интерпретатор в контейнерах, CI, виртуальных окружениях и заданиях по расписанию. Затем убедитесь, что для выбранной версии доступны совместимые зависимости и wheels, и прогоните тесты приложения.
Обновление пакетов внутри окружения само по себе не обновляет Python. Версию runtime нужно менять отдельно.
#python #обновления
Почему lru_cache удерживает объекты в памяти
Декоратор
Есть и другие ловушки мемоизации. Каждый cache hit возвращает сохранённый объект: изменение закешированного списка увидят следующие вызовы. А
Для результатов выбирайте неизменяемые структуры, для внешних данных продумайте инвалидирование. Через
Потокобезопасность кеша тоже не гарантирует один запуск функции: при одновременных промахах вычисление может повториться.
#python #производительность
Декоратор
lru_cache хранит аргументы и результат функции. Если поставить его на метод экземпляра, self станет частью ключа — кеш может удерживать объект после того, как остальной код перестал им пользоваться.Есть и другие ловушки мемоизации. Каждый cache hit возвращает сохранённый объект: изменение закешированного списка увидят следующие вызовы. А
maxsize ограничивает число записей, но не задаёт срок их жизни.Для результатов выбирайте неизменяемые структуры, для внешних данных продумайте инвалидирование. Через
cache_info() проверьте, сколько попаданий кеш вообще даёт.Потокобезопасность кеша тоже не гарантирует один запуск функции: при одновременных промахах вычисление может повториться.
#python #производительность
👍2
Как менеджер паролей найдёт вашу форму Django
Менеджер паролей обнаружил утечку и предлагает заменить пароль. Чтобы открыть нужную страницу, он может обратиться к
В Django достаточно добавить RedirectView с pattern_name, указывающим на публичную форму смены пароля. URL стандарта не содержит завершающего слеша, а редирект должен быть временным.
Проверьте имя целевого маршрута тестом: Django разрешает его при запросе, поэтому опечатка может остаться незаметной до первого обращения.
Ещё одна проверка — неизвестный URL должен возвращать 404. Если catch-all выдаёт 200 на любой путь, менеджер паролей может проигнорировать этот механизм.
#python #django
Менеджер паролей обнаружил утечку и предлагает заменить пароль. Чтобы открыть нужную страницу, он может обратиться к
/.well-known/change-password.В Django достаточно добавить RedirectView с pattern_name, указывающим на публичную форму смены пароля. URL стандарта не содержит завершающего слеша, а редирект должен быть временным.
Проверьте имя целевого маршрута тестом: Django разрешает его при запросе, поэтому опечатка может остаться незаметной до первого обращения.
Ещё одна проверка — неизвестный URL должен возвращать 404. Если catch-all выдаёт 200 на любой путь, менеджер паролей может проигнорировать этот механизм.
#python #django
Когда Path.info экономит обращения к файловой системе
При обходе большого каталога проверки
У объектов, полученных через
Цена — актуальность. Если другой процесс заменил файл после обхода,
Кеш нельзя очистить на месте; новый
#python #файлы
При обходе большого каталога проверки
is_file() и is_dir() могут создавать множество запросов метаданных. В Python 3.14 появился кеш типов файлов Path.info.У объектов, полученных через
Path.iterdir(), он может уже содержать информацию из сканирования каталога. Несколько проверок типа используют эти данные повторно.Цена — актуальность. Если другой процесс заменил файл после обхода,
path.info может описывать прежнее состояние. Для свежей проверки используйте прямые методы Path.is_file() и Path.is_dir().Кеш нельзя очистить на месте; новый
Path(path) начинает с пустым кешем. Но даже свежая проверка не устраняет гонку между проверкой и открытием файла — ошибки операции всё равно нужно обрабатывать.#python #файлы
Почему mmap не всегда избавляет от копирования
Чтобы работать с данными через заимствованное представление, используйте
Отображение не означает, что весь файл сразу загружен в RAM, и не делает его неизменяемым снимком. Другой процесс всё ещё может менять исходный файл.
Для одного последовательного прохода обычное буферизованное чтение часто проще. Выбирайте mmap под характер доступа и измеряйте результат.
#python #память
mmap позволяет обращаться к содержимому файла по смещениям. Это удобно для бинарных форматов и повторного поиска, но срез mapped[start:end] всё равно создаёт новый объект bytes.Чтобы работать с данными через заимствованное представление, используйте
memoryview. Тогда нужно следить за временем жизни: пока представления существуют, закрытие mapping может вызвать BufferError. Освободите их до выхода из контекстного менеджера.Отображение не означает, что весь файл сразу загружен в RAM, и не делает его неизменяемым снимком. Другой процесс всё ещё может менять исходный файл.
Для одного последовательного прохода обычное буферизованное чтение часто проще. Выбирайте mmap под характер доступа и измеряйте результат.
#python #память
Почему Rust внутри CPython предлагают начать с zlib
На Python Language Summit обсудили постепенное внедрение Rust в CPython. Первый кандидат — модуль
Предлагается использовать
Перед расширением проекта нужно проверить поддержку платформ, влияние на производительность, сборку и сопровождение зависимостей.
Rust помогает исключить некоторые ошибки работы с памятью, но корректность алгоритмов по-прежнему требует тестирования. Поэтому в плане есть fuzzing и property-based tests.
#python #cpython
На Python Language Summit обсудили постепенное внедрение Rust в CPython. Первый кандидат — модуль
zlib: небольшой участок с заметным применением, в том числе при работе с пакетами.Предлагается использовать
zlib-rs, а существующую реализацию сохранить как fallback. В обсуждаемом плане Rust-бэкенд мог бы стать опциональным в Python 3.16. Это предложение, а не уже принятая возможность релиза.Перед расширением проекта нужно проверить поддержку платформ, влияние на производительность, сборку и сопровождение зависимостей.
Rust помогает исключить некоторые ошибки работы с памятью, но корректность алгоритмов по-прежнему требует тестирования. Поэтому в плане есть fuzzing и property-based tests.
#python #cpython
❤1