Дайджест канала opensource_findings за август 2024

dbe7167c6bf0d811261e556ad05faff5

Привет!

Под катом множество сложных технических тем внутри питона: от генерации стратегий hypothesis до устройства тайпчекера MyPy.

В качестве тестового формата решил сделать подборку сложных технических тем, про которые писал в августе у себя в тг канале: https://t.me/opensource_findings со ссылками на полные посты.

Посмотрим, насколько такой формат работает, напишите свои мысли в комментарии! Буду благодарен обратной связи, поехали!

По ссылке полные посты со всеми техническими деталями, для тех кому интересно узнать глубже.

Поддержка ReadOnly в MyPy

По ссылке объяснение, как работает ReadOnly в райнтайме и во время проверки типов: https://t.me/opensource_findings/843

Некоторое время назад я добавил тип ReadOnly в CPython. Теперь добавил поддержку в MyPy. Скоро (с версии mypy@1.12.0) мы сможем писать и использовать такой код:

from typing_extensions import ReadOnly, TypedDict

class User(TypedDict):
    username: ReadOnly[str]  # you cannot change the value of `user['username']`

user: User = {'username': 'sobolevn'}
user['username'] = 'changed'  # type error! username is read-only

Генерация данных из аннотаций при помощи hypothesis

По ссылке дополнительные примеры генерации данных и устройства API: https://t.me/opensource_findings/841

Мы все используем и любим (ведь да?) property-based testing. Hypothesis — лидер в данном направлении в мире питона. Используется даже внутри CPython.

В августе я добавил поддержку двух новых типов: LiteralString и ReadOnly

Теперь можно делать так:

from typing import ReadOnly

from hypothesis import given, strategies as st

# MyPy allows this with: --enable-incomplete-feature=InlineTypedDict
def create_user(user: {'email': ReadOnly[str]}) -> User:
    """It somehow builds a user instance from the email."""

@given(st.builds(create_our_user))
def test_user_login_cannot_be_after_created(user: User) -> None:
    assert user.last_loggined_at >= user.joined_at

Новый выпуск «Лучшего курса по Питону» про тип bytes

По ссылке множество дополнительных материалов к выпуску: https://t.me/opensource_findings/844

Смотрим, как устроен протокол PyBuffer, изучаем магические методы __buffer__ и __release_buffer__, окунаемся в C:

typedef struct {
    PyObject_VAR_HEAD
    Py_DEPRECATED(3.11) Py_hash_t ob_shash;
    char ob_sval[1];

    /* Invariants:
     *     ob_sval contains space for 'ob_size+1' elements.
     *     ob_sval[ob_size] == 0.
     *     ob_shash is the hash of the byte string or -1 if not computed yet.
     */
} PyBytesObject;

Type Narrowing в MyPy: overload + TypeGuard

По ссылке куча примеров использований type narrowing и общее объяснение концепции: https://t.me/opensource_findings/845

Некоторое время назад мы выяснили опытным путем, что type narrowing с TypeIs и TypeGuard в MyPy не работает, если функция определена как набор @overload 'ов.

Что печально, конечно. Я сделал PR, который чинит данную проблему. Скоро можно будет писать вот такой код (смело и без проблем!):

from typing import TypeIs, overload

from my_app.models import User, PaidUser, FreeUser  # User and its subclasses
from my_app.models import Subscription

@overload
def is_paid_user(user: User, subscription: None) -> TypeIs[FreeUser]:
    ...

@overload
def is_paid_user(user: User, subscription: Subscription) -> TypeIs[PaidUser]:
    ...

Type narrowing с @overload и TypeIs будет работать!

inspect: устаревшие и сломанные части

По ссылке: примеры вопросов для собеседований (если вам не нравятся люди), множество примеров сломанного кода в inspect: https://t.me/opensource_findings/846

Один из примеров сломанного кода:

>>> import inspect

>>> def func(a: int = 0, /, b: int = 1, *, c: int = 2):
...     return inspect.currentframe()

>>> frame = func()
>>> # notice that pos-only and kw-only args are not supported properly:
>>> inspect.formatargvalues(*inspect.getargvalues(frame))
'(a=0, b=1, c=2)'

Обратите внимание, что / просто игнорируется. И сигнатура получается другой.

И небольшой список сломанного:

В посте путь — как все починить!

Заключение

Вот такой небольшой список улучшений (или ухудшений, тут уж кто как считает) питона я подготовил в августе.

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

Надеюсь на обратную связь, спасибо :)

© Habrahabr.ru