Многие знают, что я почти не добавляю новые фичи в CPython, я стараюсь выпилить существующие и править баге в тех, что у меня не получается убирать. Новые если и добавляю, то без масштабных обсуждений.
Некоторые новые фичи встречают у меня сильный оптимизм: как новый встроенный sampling profiler. Вот тут видео про него кстати с прошедшего PyCon.
Некоторые фичи встречают у меня понимание: как например
typing.disjoint_base. Простая штука, решает понятную проблему. Некоторые фичи встречают у меня лютое подгорание: как например lazy imports. Вот доклад с пайкона и про них, кстати.
Я думаю, что мое понимание хорошей фичи очень сильно расходится с таким пониманием у других питонистов, мое понимание "хорошего питона" можно найти в моем wemake-python-styleguide.
Зная такую вводную, я решил сделать "большую" новую фичу. На один символ в грамматике.
Иммутабельному питону - быть!
У нас была довольно большая проблема: создавать мутабельные словари и множества - можно довольно легко.
{1: 2} и {1, 2, 3}Чтобы создать
frozendict и frozenset нам уже нужен вызов функции: frozendict({1: 2}) и frozenset({1, ,2, 3}). Почему так делать не очень?1. Потому что писать долго, мало людей будут заморачиваться. Зачем, когда проще создать мутабельную структуру?
2. Потому что
frozendict и frozenset тупо медленнее. frozendict пока вообще имеет 0 оптимизаций для работы и просто в тупую копирует всю память из dict, который мы отправляем. Получая буквально O(n * 2) по памяти и времени работы. Делает лишний CALL. А frozenset({1, 2, 3}) немного оптимизирован через INTRINSIC_BUILD_FROZENSET опкод, который генерируется только для set в качестве входного аргумента3. Неудобно писать comprehensions. Они получается сильно менее читаемые, чем их мутабельные версии
Мое предложение (пока только в формате обсуждения): https://discuss.python.org/t/frozenset-and-frozendict-comprehensions/101584/9
Мой PR с добавлением данной фичи в CPython: https://github.com/python/cpython/pull/152820 (он нужен для написания ПЕПа)
Как оно выглядит?
>>> ${1: 2}
frozendict({1: 2})
>>> ${1, 2, 3}
frozenset({1, 2, 3})
>>> ${x: x for x in range(3)}
frozendict({0: 0, 1: 1, 2: 2})
>>> ${x for x in range(2)}
frozenset({0, 1})
Что важно? Оно уже умеет все то, что умеют привычные нам конструкции без
$:-
${} - пустой frozendict, как {} - пустой dict-
${1, *other} - распаковка внутри frozenset-
${**d for d in list_of_dicts} - распаковка внутри frozendict comprehension + PEP-798-
${x async for x in async_iterable if x >0} - async frozenset comprehension с условиемПочему
$? - Потому что
$ - is the real deal 😎💸- Потому что
$ не имеет смысла сейчас: но будет значить "иммутабельность"- Потому что
$ может легко в дальнейшем использовать для других иммутабельных штуках: $(x for x in range(1)) для нативного tuple comprehension, для PEP-805 с __freeze__ и тдИ другие новости моих опенсорс проектов одной строкой
- Новый релиз django-modern-rest с новыми DX фичами
- Добавляем Token auth в следующий релиз DMR
- msgspec готов к релизу новой версии с поддержкой frozendict
- Улучшаем поддержку
match/case в wemake-python-stylguide- Предлагаю улучшенное C-API для создания frozendict
- Выпустил релиз
punq с поддежкой типизацииЕсли вы хотите поддержать мою работу в опенсорсе:
- https://boosty.to/sobolevn
- https://github.com/sponsors/wemake-services
Обсуждение: Что вы думаете, нужен ли такой синтаксис? Удобнее ли будет пользоваться иммутабельными структурами после добавления такого синтаксиса?







