@beartype 0.20.1
materializes before your astonished keyboard with an explosive fizzy sizzling not unlike that of a flimsy soda can bursting its aluminum seams all over your astonished keyboard:
pip install --upgrade beartype
Because I am a bald middle-aged man, I still use pip
. Someday I will update my priors and switch to uv
. Someday... but not today. 🥹
@beartype 0.20.1
brings a ton of fun stuff! It almost made the cut for a full-fledged minor @beartype 0.21.0
release. In the end, I couldn't bear the thought of another never-ending release candidate cycle. And neither could you. Which is why...
@beartype 0.20.1
is the shark in this metaphor. pretty sure that makes you the diver.
@beartype 0.20.1
is brought to you by...
GitHub Sponsors: When You Befriend the Bear, You've got a Bear for Life
This release comes courtesy these proud GitHub Sponsors, without whom @leycec's cats would currently be eating grasshoppers:
- @sesco-llc (SESCO Enterprises), "The Power of Innovation in Trading": this inspires me to get out of the house and do something
https://sescollc.com - @DylanModesitt (Dylan Modesitt), quantitative strategies energy trading associate: ...wikipedia, don't fail me now!
https://dylanmodesitt.com - @tactile-metrology (Tactile Metrology), "Software and hardware that you can touch." When I want to be touched by software and hardware, I call @tactile-metrology:
https://metrolo.gy imagine if this domain actually worked. how cool would that be!?
Thanks so much, masters of fintech and metrology.
The Masters of Fintech and Metrology. That's who.
Let's start with the good stuff.
Dataclass Type-checking: Everybody Gets What Everybody Wants
In the now-legendary GitHub poll "Tell @leycec What to Do", everybody told @leycec to type-check dataclasses. Thus, @beartype 0.20.1
now type-checks dataclasses... sorta.
Type-checking dataclasses is hard. I am soft-bellied and lazy. After combining these things, you get half-hearted dataclass type-checking. @beartype only conditionally type-checks dataclasses when you explicitly tell @beartype to type-check dataclasses by enabling our newly introduced BeartypeConf(is_check_pep557: bool = False)
configuration option. For safety, this option is disabled by default.
When you want dataclass type-checking, you have to enable dataclass type-checking – like so:
from beartype import beartype, BeartypeConf
from dataclasses import dataclass, InitVar
from typing import ClassVar
@beartype(conf=BeartypeConf(is_check_pep557=True)) # <-- check it like a boss
@dataclass
class MuhDataclass(object):
muh_int: int
muh_classvar: ClassVar[str] = 'This is fine. Srsly. Does @leycec not have Buddha nature?'
muh_initvar: InitVar[bytes] = b'This is fine, too. No joke. No shade. No idea.'
# *GOOD.*
good_data = MuhDataclass(muh_int=42) # <-- this works
good_data.muh_int = 0xCAFEBABE # <------- this works, too
# *BAD.*
bad_data = MuhDataclass(muh_int=42) # <-- still works
bad_data.muh_int = '0xCAFEBABE' # <------ this fails! *YAY*!
...which raises the expected type-checking violation:
beartype.roar.BeartypeDecorHintParamDefaultViolation: Dataclass MuhDataclass(muh_int=42)
attribute 'muh_int' new value '0xCAFEBABE' value '0xCAFEBABE' violates type hint <class 'int'>,
as str '0xCAFEBABE' not instance of int.
As the above example demonstrates, this preliminary functionality supports standard dataclass fields annotated by either:
- Standard PEP-compliant hints – except relative forward references, which are currently unsupported. (See below! It sucks.) 😢
- PEP 526-compliant
typing.ClassVar[...]
type hints. 🥰 - PEP 557-compliant
dataclasses.InitVar[...]
type hints. 😸
who did this to you, @beartype!?! oh, it was just dataclasses.
What's the Catch? What're You not Telling Us!?!?
Thanks to the non-triviality of dataclasses and my own moral failings (read: "I am laziness incarnate"), this functionality currently fails to support all possible dataclass configurations and use cases. Popular edge cases not supported include:
-
Frozen dataclasses (e.g.,
@dataclass(frozen=True)
), which are currently guaranteed to raise exceptions when enablingis_check_pep557=True
. -
Slotted dataclasses (e.g.,
@dataclass(slots=True)
), which are currently guaranteed to raise exceptions when enablingis_check_pep557=True
. -
Dataclass subclasses (i.e., dataclasses subclassing other dataclasses). This is completely untested. No idea what happens. Could blow up everything. Could do nothing, which is better than just blowing up everything.
-
PEP 563 (i.e.,
from __future__ import annotations
), which almost certainly raises exceptions when enablingis_check_pep557=True
. -
Dataclass fields annotated by one or more relative forward references (i.e., strings referring to the names of currently undefined types, subsequently defined in the current submodule), which almost certainly raises exceptions when enabling
is_check_pep557=True
: e.g.,from dataclasses import dataclass @dataclass class UnsupportedDataclass(object): unsupported_field: 'UndefinedType' # <-- BREAKS EVERYTHING, YO class UndefinedType(object): pass
Until @beartype fully supports all of the above edge cases, is_check_pep557
will continue defaulting to False
. Someday, this will surely work for everybody. Until then, let us collectively sob. 😭
teach a dev to crush bugs for a day and he'll crush bugs for a life
The Click Ecosystem: Now Best Friends with Beartype
Previously, @beartype only supported the core Click project for generating Pythonic CLIs and TUIs. Now, @beartype 0.20.1
extensibly supports the full Click ecosystem of Click-based projects – including the new BigBoy™, rich-click. Combine the venerable powers of Click + Rich. Truly, your app will own the terminal:
from beartype import beartype
from rich_click import command
@beartype # <-- actually works now. i know. i'm stunned, too.
@command()
def do_something_for_leycecs_sake() -> int:
return 0xFEEDFACE # Feed that face! Feed it good.
your silky smooth Rich TUI has never felt so good
That's it, folks! That's all we've got. It wasn't much, but it was still more than you wanted on a Friday morning. This has been @beartype 0.20.1
. Thanks so much for having us. If anyone needs us, we'll be playing video games and listening to Finnish viking metal all night. 🤘
Lastly but Beastly (but not Leastly)...
...to financially feed @leycec and his friendly @beartype through our ancient GitHub Sponsors profile that predates the existence of dinosaur-like AI chatbots. Come for the candid insider photos of a sordid and disreputable life in the Canadian interior; stay for the GitHub badge and warm feelings of general goodwill.
Cue hypnagogic rave music that encourages fiscal irresponsibility. 🎵 🎹 🎶
Bear Club: The First Rule of Bear Club Is You Crush Bugs
Bear Club welcomes long-standing users @RomainBrault, @rg936672, and @GithubCamouflaged to bask in the code-warming radiance that is @beartype 0.20.1
.
don't by shy! come on in. the water's warm. there's more than enough QA to go around...