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 PyBuffer
we 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 🙂