Питонические атаки
1.3K subscribers
172 photos
3 videos
1 file
452 links
Всяческие заметки про программирование на Python и другие весёлые истории.
Download Telegram
Пару дней назад опубликовали черновик PEP 671.

Предлагается добавить синтаксис для значений по умолчанию, вычисляемых прямо перед выполнением функции (late-bound function argument defaults). Грубо говоря, можно будет в качестве дефолтного значения указать лямбда-функцию из одного выражения, в которой будут доступны все предыдущие аргументы. Это позволит более компактно выражать зависимости между аргументами.

Например, вместо вот такого:

# Very common: Use None and replace it in the function
def bisect_right(a, x, lo=0, hi=None, *, key=None):
if hi is None:
hi = len(a)

...

Можно будет написать вот такое:

def bisect_right(a, x, lo=0, hi=>len(a), *, key=None):
...


Если при вызове аргумент hi передан, то дефолтное значение не нужно, ничего не происходит. Если же аргумент не передан, то дефолтное значение будет вычислено прямо перед выполнением функции на основе другого аргумента. Вычисление дефолтного значения происходит в пространстве имён функции, поэтому другие аргументы уже должны быть определены и доступны для использования.

Можно указывать несколько аргументов с такими динамическими дефолтными значениями. Они будут выполнены в порядке определения слева направо. Каждый аргумент может ссылаться на любые предыдущие аргументы, но не на следующие после него.

Это пока что всего-лишь черновик на ранней стадии, и далеко не факт, что это изменение будет принято в язык.

#pep
В Python 3.11 стандартная библиотека пополнится модулем tomllib — как можно догадаться по названию, это про работу с TOML файлами. TOML уже стал популярным форматом для описания конфигурации, но до сих пор работа с ним в питоне возможна только через сторонние модули.

Отсутствие в стандартной библиотеке модуля для работы с этим форматом создаёт сложности для разного тулинга, который хочет читать оттуда свои настройки — форматтеры, линтеры, утилиты, связанные с управлением зависимостями и пакетированием. Особенно страдают именно утилиты из последней категории, например, pip или pipenv — они не могут позволить себе зависеть от сторонних пакетов. Им приходится просто вендорить стороннюю библиотеку к себе в код (Ctrl+C, Ctrl+V🗿).

Пока что tomllib будет уметь только читать формат. Интерфейс, по традиции, похож на json (load и loads). Запись решили не делать, потому что сложно, много нюансов, и мало кому нужно.

Сейчас есть тенденция на вынос разного старого ненужного из разросшейся стандартной библиотеки языка (те самые подтекающие батарейки 🪫), да и новые модули без большой нужды стараются не добавлять. Но TOML обещает стать новым стандартом для конфигурации в экосистеме Python (как уже стал в некоторых других экосистемах), так что добавление такой библиотеки точно оправдано.

https://peps.python.org/pep-0680/

#pep #toml
Вы же знаете, что по умолчанию для работы с текстовыми файлами Python использует кодировку UTF-8 на Unix, но не на Windows? Там он возьмёт системную кодировку, типа Win-1251, в зависимости от локали.

Это значит, что если не указать кодировку, то программа будет вести себя по-разному на разных платформах, и текстовые файлики с эмодзями, кириллицей и прочими загадочными иероглифами, записанные на macOS, не будут нормально читаться на Windows. Или даже ещё забавнее — файлики, созданные в русифицированной Windows, не будут нормально читаться в какой-нибудь арабской Windows.

Это поведение было выбрано, чтобы Python вёл себя привычным для платформы образом и не было проблем с другими программами. Например, можно через Python создать текстовый файл, а затем открыть его в Блокноте, и увидеть там правильные буквы, а не "кракозябры" — в старых версиях Windows это было очень актуально. С другой стороны, это усложняет переносимость программ — нужно специально везде указывать кодировки явно, чтобы получить одинаковое поведение на разных платформах.

Сегодня уже ясно, что пластмассовый мир победил и юникод оказался сильней. Практически повсеместно используется UTF-8. Одна универсальная (пусть и не всегда компактная) кодировка куда практичнее, чем множество узкоспециализированных.

И в Python тоже обсуждается переход на UTF-8 везде по умолчанию. Даже на Windows. Пока что это лишь черновик, но идея годная, и я не удивлюсь, если предложение примут. В любом случае, произойдёт это не раньше версии 3.13.

Кстати, в 3.10 при помощи флажка уже можно включить ворнинги, и поймать все места, где у вас при работе с текстовым вводом-выводом не указана кодировка явно. Это подготовка к всеобщему переходу на UTF-8.

#pep #unicode
Радостно видеть, что тайп-чекинг в питоне развивается каждый год, и решает всё больше различных проблем. Вот сейчас дошли и до безопасности.

В 3.11 добавят тип LiteralString, который может принимать любые строки, собранные из строковых литералов. Можно взять любые литералы, как угодно их скомпоновать друг с другом, и в итоге всё равно получится тип, совместимый с LiteralString. Но если подмешать туда любую строку, которая не хранится в коде программы, а поступает извне, то это уже не может быть LiteralString.

hello = "Здравствуй"
world = "прекрасная планета"

# совместимо со StringLiteral, потому что строчка составлена целиком из литералов в коде
s1 = f"{hello}, {world}!"

# не совместимо, потому что примешивается что-то извне, не литерал
name = input("name: ")
s2 = f"{hello}, {name}!"

Зачем такой тип нужен? При помощи него можно запретить передавать в "опасные" функции, подверженные различного рода инъекциям, строки, включающие пользовательский ввод. Это просто будет ошибкой на уровне системы типов. Таким образом, написать уязвимый код с SQL, shell, XSS, SSTI или какими-либо ещё инъекциями станет немножко сложнее. Для этого всего лишь нужно, чтобы в библиотеках важные места были помечены этим типом, и, конечно же, чтобы пользователь время от времени запускал тайп-чекер. На выполнение программы это всё никак не влияет.

Пока что это предложение поддерживается только в тайп-чекере pyre.

https://peps.python.org/pep-0675/

#pep #typing
Вижу, что многие пользуются black, isort или как минимум форматируют код в PyCharm. Инструменты хорошие, но они ориентируются на устаревший PEP-8, поэтому в ближайшее время придётся подыскивать им замену.

Опубликован черновик нового стайл-гайда PEP-9001, который через какое-то время станет обязательным для соблюдения, поэтому рекомендую всем ознакомиться уже сейчас и присоединиться к обсуждению:

https://peps.pythondiscord.com/pep-9001/

#pep
Многие пользовались возможностью импортировать синтаксис из будущего (from __future__ import …), но задумывались ли вы когда-нибудь ОТКУДА на самом деле приходит этот синтаксис? Ведь если мы можем получить фичи из будущего, значит кто-то в будущем должен отправлять их в прошлое?

Документ описывает установку для отправки синтаксиса в прошлое на основе наработок по «потоковому накопителю» доктора Эмметта Брауна.

https://peps.pythondiscord.com/pep-2241/

#pep
Появился PEP 723, который предлагает "встраивать" pyproject.toml в однофайловые скрипты.
Предлагается добавить переменную __pyproject__, которая будет содержать в себе валидный TOML, описывающий метадату скрипта, в том числе как скрипт запускать и какие зависимости необходимы для запуска.

К примеру, вот так будет выглядеть скрипт, которому для работы нужна библиотека requests и питон 3.11 или выше:

__pyproject__ = """
[project]
requires-python = ">=3.11"
dependencies = [
"requests<3",
]
"""
import requests
resp = requests.get("https://peps.python.org/api/peps.json")
print(resp.json())

PEP прикольный, что-то такое есть в качестве экспериментального RFC в Rust. Из минусов хотел бы отметить то, что автоматическая установка зависимостей может привести к запуску нежелательного кода. Но решение банальное - перед тем как что-то запускать, проверяйте, что вы запускаете.

#pep
Пока я спал, руководящий совет языка принял PEP 703 (Making the Global Interpreter Lock Optional in CPython).

Кратко о том, о чём говорится в посте:

1. Руководящему совету ясно, что несмотря на все проблемы и недостатки потоков, nogil будет полезен для Python, так как позволит находить более масштабируемые решения.
2. В то же время, они не уверены, получится ли убрать GIL не сломав при этом обратную совместимость - всё же не хотелось бы терять десятилетия развития базы пакетов. Существующая пакетная экосистема - это одна из сильных сторон языка, как и простая интеграция библиотек на C c CPython.
3. Оценить влияние nogil без реализации сложно, поэтому nogil должен выпускаться в составе регулярных релизов и не обязательно он там должен быть по-умолчанию.
4. Это всё ещё не гарантированная история. Если что-то пойдет не так - от изменений откажутся. Развёртывание должно быть постепенным и наиболее плавным.
5. Выкатка будет происходить в 3 фазы, которые возможно изменятся:
- В первой фазе nogil сделают возможным таргетом при сборке, чтобы разработчики могли тестировать свои пакеты.
- Во второй фазе, когда изменения в API и ABI будут сформированы, а поддержка nogil от сообщества будет достаточной, nogil-сборку добавлят как "поддерживаемую, но не по умолчанию".
- В третьей фазе nogil-сборку сделают сборкой "по-умолчанию", а от gil-сборки будут отказываться.
6. При успешной реализации nogil, ожидается падение производительности на 10-15% в худшем случае.

#pep