Питонические атаки
1.19K subscribers
183 photos
4 videos
1 file
459 links
Всяческие заметки про программирование на Python и другие весёлые истории.
Download Telegram
А вы заценили красивую картинку, которую Pablo подготовил для этого релиза? Уже второй релиз с красивой картинкой. Прям хоть на футболку печатай.

Есть уже первые обновившиеся до 3.11? Делитесь впечатлениями!
👍23
Чем дольше смотрю, тем больше нравится. Символично, что два острова связывает лишь небольшой мост. Кажется, что культура и обычаи на северном и южном островах совсем разные. Только что говорят на одном языке, да и то с разными акцентами. Редко вылажу из своего асинхронного леса, но иногда заносит на юг, и каждый раз я такой: "ёшкин кот, о чём вообще говорят эти волшебники, чем они тут занимаются?".

А вы где на карте обычно обитаете?

Утащено отсюда, автор @Enchantner. Люблю красивые картинки.
20👏4🐳4🥰2
Всем доброго понедельника!

Если кто-то, как и я, ждал новой версии pyenv, чтобы поставить свежих питонов, то идите обновляйтесь. Несколько дней назад там наконец появился стабильный 3.11.0.
15
Вышел релиз 🔤🔤🔤🔤==0.990.

Релиз получился объемный: там добавили базовую поддержку Python 3.11, рекурсивные типы, категории ошибок в вывод, и ещё на сдачу наложили разные ломающие изменения. Готовьтесь, при обновлении наверняка будут новые проблемы в коде, который раньше тайп-чекался без ошибок. Ниже выпишу самые важные, на мой взгляд, пункты, а за полным списком изменений идите в блог mypy.

Теперь по умолчанию отключены неявные Optional типы. Придётся либо явно указывать в тайп хинте, что переменная/аргумент может принимать None, либо переключать настройку, чтобы вернуть старое неявное поведение:

def foo(s: str = None) -> int: ...  # Error!
def foo(s: str | None = None) -> int: ... # OK

Также тайп-чекер теперь перестал игнорировать пустые функции/методы. Раньше они не проверялись, а теперь проверяются и вызывают ошибки:

# Error: Missing return statement (no error before 0.990)
def some_func(arg: str) -> int:
pass

Через forward reference'ы теперь можно определять рекурсивные типы. Для применения рекурсивных типов нужно обязательно явно указывать тип, потому что если не указать, то mypy выведет какой-то многоэтажный нерекурсивный тип. Вот как это выглядит:

NaiveJSON = str | list["NaiveJSON"] | dict[str, "NaiveJSON"]
test_data: NaiveJSON = {"foo": {"bar": "baz"}} # OK

Тайп чекер постепенно становится умнее и строже. Гаечки затягиваются — остаётся всё меньше неявного и игнорируемого. И это хорошо.
Please open Telegram to view this post
VIEW IN TELEGRAM
20👍3
Почти одновременно со стабильным релизом 3.11.0 вышел первый альфа-релиз следующей версии — 3.12.0a1! И начали появляться первые сообщения о том, что нас там ждёт.

Например, питон научили работать с профилировщиком perf из линукса. Можно будет отлаживать код на питоне, и видеть как вызовы функций внутри библиотек на C/Rust, так и вызовы функций внутри самого интерпретатора, и даже то, что происходит в это время в ядре ОС, включая даже всякие счётчики и кэши процессора. Это, конечно, можно было делать и раньше, но теперь, начиная с 3.12, профилировщик будет понимать код на питоне, так что станет куда проще соотносить результаты анализа с конкретными кусками кода в вашей программе.

Стоит отметить, что это будет работать только на Linux, потому что perf — чисто линуксовый инструмент, который зашит прямо в ядро ОС.

Думаю, это изменение — это побочный результат работы Pablo над профилировщиком memray.

В треде в твиттере больше подробностей и есть ссылка на черновик документации.
👍17🔥1
Разные либы 🚀 продолжают релизить версии с поддержкой Python 3.11.

Напоминаю, что есть такой классный сервис, который отслеживает поддержку конкретной версии популярными библиотеками — https://pyreadiness.org/3.11/.

Сейчас поддержка 3.11 находится на уровне всего 19.4%, но цифра каждый день увеличивается. Это, конечно, не означает, что остальные 80% пакетов не заработают с 3.11. Это лишь значит, что они не задекларировали у себя эту поддержку явно.

Для сравнения, уровень поддержки Python 3.10 сейчас равен 63%, а 3.9 — 75%.
👍7
А ещё в 3.12 в очередной раз улучшат сообщения об ошибках. Интерпретатор научится догадываться о забытых импортах модулей из стандартной библиотеки, а также подсказывать про забытый self.

Взял отсюда и отсюда.
👍17🤔2
О, кстати, прикол. Не задумывался, что лямбда-функции тоже можно аннотировать. Делать я так, конечно, всё равно не буду.

Твит здесь.
❤‍🔥131🥰1
Свежие драмы из интернета.

На днях flake8 переехал на GitHub. Они довольно долго были чуть ли не единственным известным мне проектом, который принципиально хостился на GitLab.

Точнее, переехали они уже полтора года назад, а на днях они удалили свой старый репо на GitLab, который в последнее время был лишь зеркалом. И тут все внезапно заметили этот переезд, потому что у кучи народа отвалились pre-commit хуки локально и начали падать проверки в CI. Напомню, что pre-commit устанавливает свои тулзы именно из git-репозитория по адресу, а не из PyPI по имени пакета. И хоть исправление этой проблемы — это всего лишь поправить 2 символа в ямле, и автор заранее везде, где только можно, анонсировал этот переезд, и даже написал скрипты, которые всё пофиксят автоматически, всё равно мало кто узнал об этом событии заранее. Неприятно получилось, и народ начал роптать.

Мейнтейнер обеих утилит — flake8 и pre-commit (да, их обе поддерживает один человек, и он же поддерживает ещё кучу всего) — рассказал в комментах на реддите, чем был мотивирован этот переезд. Оказывается, причиной послужил неприятный инцидент с криптомайнером, который каким-то необъяснимым образом был запушен каким-то левым чуваком в репо flake8 на гитлабе. Поддержка гитлаба ушла в отрицание и помогла примерно никак: "мы ничего не знаем, вы сами виноваты". Вот 🤷‍♂️

Если используете pre-commit, то проверьте у себя адрес к репо flake8. Запуск pre-commit autoupdate должен по идее всё автоматически обновить правильным образом.
👍20🤔4👏2🖕1
Forwarded from Python etc
I often find myself writing a context manager to temporarily change the current working directory:

import os
from contexlib import contextmanager

@contextmanager
def enter_dir(path):
old_path = os.getcwd()
os.chdir(path)
try:
yield
finally:
os.chdir(old_path)


Since Python 3.11, a context manager with the same behavior is available as contextlib.chdir:

import os
from contextlib import chdir

print('before:', os.getcwd())
# before: /home/gram
with chdir('/'):
print('inside:', os.getcwd())
# inside: /
print('after:', os.getcwd())
# after: /home/gram
👍20😱32🎉1🖕1
Большое интервью Гвидо ван Россума час назад вышло у Лекса Фридмана

https://www.youtube.com/watch?v=-DVyjdw4t9I

0:00 - Introduction
0:48 - CPython
6:01 - Code readability
10:22 - Indentation
26:58 - Bugs
38:26 - Programming fads
53:37 - Speed of Python 3.11
1:18:31 - Type hinting
1:23:49 - mypy
1:29:05 - TypeScript vs JavaScript
1:45:05 - Best IDE for Python
1:55:05 - Parallelism
2:12:58 - Global Interpreter Lock (GIL)
2:22:36 - Python 4.0
2:34:53 - Machine learning
2:44:35 - Benevolent Dictator for Life (BDFL)
2:56:11 - Advice for beginners
3:02:43 - GitHub Copilot
3:06:10 - Future of Python

#IT #Python
🔥19👍3
В Golang 👣 есть такая инструкция defer, которая планирует отложенное действие при выходе из текущей функции. Часто этим пользуются как контекстным менеджером, типа, открываешь файл и тут же при помощи defer планируешь его закрытие:

f := createFile("/tmp/defer.txt")
defer closeFile(f)

Причём закрытие файла выполнится даже если где-то дальше в этой функции произойдёт ошибка — это предотвращает утечку ресурсов. Ещё при помощи defer можно, собственно, перехватывать и обрабатывать разные ошибки. Короче, да, примерно как контекстные менеджеры или блоки try-finally, но не создают дополнительный уровень вложенности в коде, а ещё открытие и закрытие ресурса обычно находятся в коде рядом друг с другом, а не на разных концах файла. Можно выполнить несколько defer — они складываются в стэк, а при завершении функции по очереди снимаются со стэка и выполняются (получается, в обратном порядке).

К чему я это. Чувак с реддита сделал аналог такой инструкции для питона. Работает следующим образом:

@defers
def f():
print(1)
defer: print(3)
print(2)

Вызов f() напечатает 1 2 3. Почти как на Go, только с декоратором над функцией и лишним двоеточием после defer.

Под капотом там происходит разбор и модификация AST тела функции, задекорированной
@defers
. Обратите внимание на строчку
defer: print(3)
. Синтаксически здесь происходит аннотация переменной defer, а в тайп-хинте лежит какой-то вызов функции. Python игнорирует тайп-хинты для переменных в теле функций, то есть функцию вызывать он не будет даже пытаться — можно положить туда что угодно, лишь бы соответствовало синтаксису. Библиотека выполняет код из тайп-хинта на выходе из функции. Интересная эксплуатация особенностей языка!

Автор не рекомендует пользоваться этим в продакшене. Это скорее забавная поделка, чем рабочий инструмент. Но если всё-таки будете, то обязательно применять в комплекте с:

result, err = do_thing()
if err is not None:
return None, err

Иначе не прочувствуете вайб! 🖥

GitHub | Тред на реддите
Please open Telegram to view this post
VIEW IN TELEGRAM
🤡20😁10👍7🔥32👎1🥴1
Я всё чаще и чаще замечаю Rust рядом с Python...

Совершенно недавно я нашел вот такой HTTP сервер на Rust для приложений на Python - Granian.

Разработчики ставят перед собой следующие цели:
+ Поддержка HTTP версий 1, 2 и 3
+ Один пакет для всех платформ
+ Сервер должен заменить Gunicorn/Uvicorn
+ Обеспечение большей производительности по сравнению с конкурентами.

Сейчас оно умеет в:
+ ASGI/3 и RSGI
+ HTTP/1 и HTTP/2
+ Вебсокеты над HTTP/1 и HTTP/2
+ Поддержка SSL

К сожалению проект пока что в супер-бетке, поддерживает Питон 3.7/3.8. Очень надеюсь что с этого что-то вырастет.

#библиотека
👍161👎1🤔1
Forwarded from Python etc
The typing.assert_type function (added in Python 3.11) does nothing in runtime as most of the stuff from the typing module. However, if the type of the first argument doesn't match the type provided as the second argument, the type checker will return an error. It can be useful to write simple "tests" for your library to ensure it is well annotated.

For example, you have a library that defines a lot of decorators, like this:

from typing import Callable, TypeVar

C = TypeVar('C', bound=Callable)

def good_dec(f: C) -> C:
return f

def bad_dec(f) -> Callable:
return f


We want to be 100% sure that all decorators preserve the original type of decorated function. So, let's write a test for it:

from typing import Callable, assert_type

@good_dec
def f1(a: int) -> str: ...

@bad_dec
def f2(a: int) -> str: ...

assert_type(f1, Callable[[int], str]) # ok
assert_type(f2, Callable[[int], str]) # not ok
👍8💩41🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
Смотрите какая штука. Умеет делать hot reloading для многих программ без потери состояния. То есть прям сохраняешь файл на диске, она догружает изменения прямо в работающую программу, что-то там до/перевычисляет до точки останова, и показывает тебе новый результат.

Можно использовать утилиту саму по себе, а можно интегрировать её в редактор. На данный момент есть плагин для PyCharm, а расширение для VSCode в статусе "coming soon". Запилена отдельная поддержка для Django, Flask, SQLAlchemy и Pandas. Вроде можно достаточно гибко управлять поведением reloading'а, чтобы обработать разные краевые случаи.

Выглядит круто!

https://reloadium.io/

P.S. С телефона гифку надо смотреть в оригинале, иначе шакалы.
🔥18👍6
Python 3.11.1 релизнулся — первая багфикс версия.

Есть такое суеверие, что лучше не обновляться на версию с нулевым последним числом, а подождать первого багфикс-релиза. Вот, теперь даже консервативные пользователи могут обновляться. Хотя, по моим ощущениям, и нулевая версия почти никаких проблем не доставляла (кроме отсутствия предсобранных колёс у библиотек).

Кстати, метрика поддержки 3.11 в библиотеках выросла до 25.6%. Месяц назад она была 19.4%.
👍6
FastAPI перегнал Django по количеству скачиваний? 🤔

Твит
🔥41👎3