opensource_findings channel digest for August 2024

Hello!

Under the cut are many complex technical topics within Python: from generating hypothesis strategies to the structure of the MyPy type checker.

As a test format, I decided to make a selection of complex technical topics that I wrote about in August on my TG channel: https://t.me/opensource_findings with links to full posts.

Let's see how this format works, write your thoughts in the comments! I would appreciate feedback, let's go!


The link contains full posts with all the technical details, for those interested in learning more.

ReadOnly Support in MyPy

The link explains how it works. ReadOnly in runtime and during type checking: https://t.me/opensource_findings/843

Some time ago I added ReadOnly type to CPython. Now added support to MyPy. Soon (from version mypy@1.12.0) we will be able to write and use code like this:

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

Generating data from annotations using hypothesis

The link contains additional examples of data generation and API devices: https://t.me/opensource_findings/841

We all use and love (don't we?) property-based testing. Hypothesis – the leader in this direction in the world of python. It is even used inside CPython.

In August I added support for two new types: LiteralString And ReadOnly

Now you can do this:

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

New issue of “The Best Python Course” about the bytes type

The link contains a lot of additional materials for the issue: https://t.me/opensource_findings/844

Let's see how the protocol works PyBufferwe study magical methods __buffer__ And __release_buffer__let's dive into 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 in MyPy: overload + TypeGuard

The link contains a bunch of examples of type narrowing usage and a general explanation of the concept: https://t.me/opensource_findings/845

Some time ago we found out empirically that type narrowing with TypeIs And TypeGuard in MyPy does not work if the function is defined as a set @overload 'ov.

Which is sad, of course. I did. PR that fixes this problem. Soon you will be able to write code like this (with confidence and without problems!):

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 with @overload And TypeIs will work!

inspect: obsolete and broken parts

Link: Sample Interview Questions (If You Don't Like People), Lots of Broken Code Examples in inspect: https://t.me/opensource_findings/846

One example of broken code:

>>> 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)'

note that / is simply ignored. And the signature is obtained another.

And a small list of what's broken:

The post shows how to fix everything!

Conclusion

Here is a short list of improvements (or deteriorations, depending on how you look at it) to Python that I prepared in August.

I hope that this format is interesting for people: to briefly look at the list and delve into what is needed for work / their curiosity.

I hope for feedback, thank you 🙂

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *