fix(deps): update dependency beartype to >=0.22.2,<0.23.0 #21
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
>=0.19.0,<0.20.0
->>=0.22.2,<0.23.0
>=0.19.0,<0.20.0
->>=0.22.2,<0.23.0
Warning
Some dependencies could not be looked up. Check the Dependency Dashboard for more information.
Release Notes
beartype/beartype (beartype)
v0.22.2
: Beartype 0.22.2: Yo Dawg We Heard You Like LLMBeartype
0.22.00.22.10.22.2 portals into the mortal plenum with a disturbing "WHOOOMP!" As you panic, all the oxygen in the room is rapidly vacuumed into an adjacent hyperdimension. It's not @beartype's safest entrance – but it's one we're all sure to remember. This is @beartype0.22.2
: don't ask what happened to0.22.0
. just... don't.pip install --upgrade --pre beartype # beartype casts magic missile on the darkness
The central dogma of @beartype
0.22.2
is LLM compatibility. Do you like LLM? Do you like compatibility? Then your code likes @beartype0.22.2
(even against your better judgement). But before the liking starts...0.22.2
salutes you who are about to code@leycec and his beautiful science wife are eating well. Thanks entirely to...
GitHub Sponsors: Befriend the Bear and Get a Bear for Life
This release comes courtesy these proud GitHub Sponsors, without whom @leycec's cats would currently be eating grasshoppers in the abandoned back lot again:
https://sescollc.com
https://dylanmodesitt.com
Additional financial shout-outs to @ilyapoz (@Ilia Pozhilov), the amazing former Yandex code cosmonaut who graciously donated a pile of Georgian lari to @beartype this go-around. Apparently, the lari is denominated in the ლ Unicode character. What a symbol! It looks like a beautiful hat. If only the Canadian dollar was half as manly. 😭
Thanks so much, masters of fintech and Yandex.
Tidelift: A Rising Tide Lifted @beartype's Not-At-All-Leaky Boat
This release also comes courtesy Tidelift, which very graciously pays out recurring income to security-sensitive open-source projects like @beartype, NumPy, and other stuff you probably care about. @beartype joining Tidelift has super-positive implications for Python's broader QA community – including:
responsibilityQA. Somebody smart said that.If you represent a security-conscious corporate, government, or non-profit, the best way bar none for you to support @beartype and secure your own workflow is by subscribing to Tidelift through SonarQube Advanced Security. Security giant Sonar recently acquired Tidelift, guaranteeing the economic viability of the Tidelift model for billions of future open-source projects that have yet to be born. Join the jargon-laden conversation and pay someone else to think about unreadable acronyms like SAST, SCA, and SBOM for once.
!!STUFF YOU WANNA READ EVEN THOUGH ITS EXHAUSTING!!
You really want to bump the @beartype requirement in your
pyproject.toml
file. Preserve end user sanity tomorrow by explicitly requiring a minimum of @beartype>=0.22.2
today: e.g.,Why? Bear with us. This explanation may bore you. Imagine what typing this out felt like.
Prior versions of @beartype are fundamentally incompatible with Python 3.14. Python packagers like
pip
anduv
do not update packages by default. Unless you bump your @beartype requirement, your existing userbase who already installed your package will be unable to use your package under Python 3.14 – even after manually updating your package, because manually updating your package fails to transitively update all dependencies of your package by default. In other words, Python packaging still kinda sucks.This is why...
!!MORE STUFF YOU WANNA READ EVEN THOUGH ITS EXHAUSTING!!
beartype.claw
import hooks have been supremely revamped. They still work the same, but they're now explicitly compatible with a lot more than they used to be. If you tried enablingbeartype_this_package()
but switched back to manually decorating everything with@beartype
becausebeartype_this_package()
spewed too many errors everywhere, please givebeartype_this_package()
a second chance:Let us know how it goes. If stuff is still busted, we'll immediately fix that stuff. We now have the necessary machinery in our abstract syntax tree (AST) transformer to support all (or most, anyway) compatibility woes previously associated with
beartype.claw
import hooks.beartype.claw
shamelessly dances for anyonetl;dr: Llamas, Bears, & You
@beartype
0.22.2
dramatically improves compatibility across the board with the APIs, packages, and paradigms you care about. Because you care, we care. In fact, we spent whole months caring. We cared so much we're all cared out. The summer went away in a blitz of caring and we didn't even notice. Oh, Gods. The warmth has fled. The snow is coming. And all we have to show for it is massive compatibility gains across the board.This includes:
0.22.2
weeps from pride and accomplishment, but mostly sleep deprivationPython 3.14: Oh, It's Big
Python 3.14. You care about Python 3.14 even if you don't know you care. @beartype now fully supports PEP 649 and 749 – landmark QA standards introduced by Python 3.14 that finally obsolete PEP 563. All these numbers mean something. We swear. Since all horror stories start with two nondescript teens in a Buick, let's start there:
That's PEP 563. And... that's now deprecated. PEP 749 officially deprecated PEP 563 a few months ago:
tl;dr: On October ~15th 2029,
from __future__ import annotations
will be officially deprecated. On October ~15th 2031,from __future__ import annotations
will be removed entirely from the Python language. At that time, any module usingfrom __future__ import annotations
will raise aSyntaxError
at importation time and thus become unimportable. In 2025, nobody should enablefrom __future__ import annotations
voluntarily.Sometime over the next several five years, you and your righteous dev team will require Python ≥ 3.14 as a mandatory dependency. That's just the way of the Python world. Planned obsolesce is the road we walk. When that happens, you'll no longer need
from __future__ import annotations
to declare forward references to undefined types in type hints like this:Unquoted forward references are thus baked into Python 3.14. Order of type hints and types is no longer significant. Define and annotate stuff in any order you like.
@beartype
0.22.2
: because life is too short and code is too long.Large Language Models: Apparently, They're Large
@beartype
0.22.2
now ships with out-of-the-box support for Bad Boy LLM APIs that defy community standards, mental health, and your last hair follicles. This includes:These APIs are awesome, because they changed the world. But they're also hostile to literally every other Python decorator in existence. @beartype is a Python decorator in existence. Thus, these APIs are hostile to @beartype.
Why? Because they all define decorator-hostile decorators: that is, decorators that prevent other decorators from being applied. That's not how decorators are supposed to work. You're supposed to be able to apply decorators in any arbitrary order. That was the deal, LLM APIs! Apparently, LLM APIs hated that deal. Their decorators destructively transform your normal functions and methods (which are decoratable by @beartype) into abnormal instances of API-specific types (which are not decoratable by @beartype).
In the worst case of both LangChain and FastMCP, these abnormal instances of API-specific types aren't even callable! They don't just destroy the types of what they decorate. They destroy the callability of what they decorate. What kind of compatibility-hostile API turns a function or method into an uncallable object that you can't do anything with anymore? LangChain and FastMCP. That's who.
Examples include:
@langchain_core.runnables.chain
decorator function.@fastmcp.FastMCP.tool
decorator method.@celery.Celery.task
decorator method.@beartype
0.22.2
now officially supports decorator-hostile decorators like this. It cost us our summer, but no price is too high. Okay. The price was pretty high. But this is the AI-ML-LLM hype train we're talking about. You either board that train or you prepare to eat everybody else's dust as they point fingers and cruelly guffaw into their monocles at you. @beartype prefers to board that train.@beartype walks its own road, though. @beartype boards that train in its own special way. Specifically, @beartype now maintains two internal databases efficiently structured as trie prefix search trees:
beartype.claw
import hooks then:@beartype
decorator before (rather than after) the last decorator-hostile decorator in existing chains of two or more consecutive decorators decorating your callables and types in your modules.@beartype
decorator now silently ignores attempts to decorate instances of these problematic types. Don't even bother! They're busted, @beartype. At least we no longer are. 😅It's... complicated. Really, really complicated. There's a doctoral PhD thesis somewhere here for somebody who wants one. Me? I just wanna sleep. Blessed sleep! Take me now!
Polars: Cold as Ice, DataFrames Are Nice
Polars is the vibrant Pandas alternative everyone loves. 35k GitHub stars cannot be wrong. Although I feel jealousy when I hear numbers like that, @beartype now officially supports validation of Polars DataFrames vis-a-vis Pandera – the only sane way to validate the integrity of your fragile DataFrames that are probably falling over as we speak. Poor guys.
Previously, @beartype only supported validation of Pandas DataFrames via Pandera. Now, @beartype supports both Pandas and Polars. This can only mean one thing. Our powers are growing at an exponential rate. The QA Singularity is upon us. Check out this terrifying exhibition of runtime validation run amok:
...which helpfully blows up with a human-readable exception that relieves you:
@beartype: Bleeding-edge APIs named after magnetic dipoles? Yeah. We do that, too.
0.22.2
pours one out for the DataFrame that didn't make it.PEP 646: We Don't Understand Variadic Generics Either, But Apparently @beartype Now Supports Them
@beartype
0.22.2
fully supports PEP 646 – Variadic Generics. ...for certain glib definitions of "fully supports."PEP 646 is outrageously huge. It's the longest and cruelest
typing
standard published to date. Synopsizing that standard is a fool's errand. Thus, we now synopsize that standard. PEP 646 brings two things to the QA table. Let's go!Type Variable Tuples: They're Weird and Kinda Suck, But Maybe Somebody Who Is a Good Person Loves Them
PEP 646 introduces type variable tuples (i.e.,
typing.TypeVarTuple(...)
objects). Whereas good ol' PEP 484-compliant type variables (i.e.,typing.TypeVar(...)
objects) match only a single type (likeMuhGeneric[int]
forclass MuhGeneric[T](): ...
), type variable tuples greedily match zero or more types (likeWoahGeneric[int, str, bool]
forclass WoahGeneric[*Ts](): ...
).The use case is tensors, supposedly. I personally press "F" to doubt that any real-world tensor frameworks will actually leverage type variable tuples. Doing so would inhibit forward compatibility with future tensor APIs in those frameworks. Why? Because type variable tuples match types greedily. Once you've exposed a type variable tuple to your end users through a public-facing generic type, you can never add any other type variables to that generic type without breaking backward compatibility. You're now permanently locked in to that generic type API for the rest of all time.
Aren't ordinary type variables like that too, though? No. You can always add additional type variables to normal generic types without breaking backward compatibility. How? PEP 696-compliant type variable defaults (e.g.,
T = TypeVar("T", default=int)
). Press "F" if anyone would like me to babble incoherently more about all this.That said, type variable tuples probably do have practical internal use. I'd never expose them to end users for the aforementioned reasons. They cause compatibility woes. Still, @beartype
0.22.2
now fully supports them. Use them! Reassure us that we didn't waste the entire summer on this! Oh, Gods... the summer... it's... it's gone, everybody. 😩0.22.2
when it realized where the summer wentTuple Type Hint Unpacking: They're Also Weird, But They're Actually Useful!?
PEP 646 also introduces tuple type hint unpacking (e.g.,
tuple[int, *tuple[str, ...]]
). This spec goes really hard really fast. The syntax is also kinda nasty. But the core idea is that you can now deeply type-check the contents of non-trivial tuple data structures. You may now be thinking:Indeed! It's all true! You can use tuples like data structures. @beartype internally does this all the time. Why? Unjustifiable microoptimizations. Because CPython is highly internally optimized for tuple instantiation, access, and garbage-collection, tuples make the ideal read-only data structures for many perfidious purposes. CPython cares a lot about tuples. Tuples are the backbone of CPython's calling convention, because functions and methods returning multiple values implicitly return tuples of those values. This makes tuples the ideal data structures for implementing many pure-Python algorithms – especially recursive algorithms implemented iteratively.
Of course, tuple data structures do promote unreadable and obfuscated code that not even the unpaid intern wants to maintain. But that's not a problem if you're a dodgy codebase like @beartype. Ain't nobody maintaining this code except @leycec – a well-known glutton for punishment-by-dev-hell.
If you are like @leycec, you too can now type-check your shamefully growing heap of tuple data structures from Hell. How? PEP 646, yo. Previously, PEP 484 only let you type-check two simplistic kinds of tuple hints:
tuple[str, int]
, for example, is the fixed tuple hint matching tuples containing one string item followed by an integer item.tuple[str, ...]
, for example, is the variadic tuple hint matching tuples containing zero or more string items.That's great if your tuple data structures are simplistic. But they're probably not, are they? That's why you're still reading this at 4:17AM. Your wife is calling out for you in her fitful sleep, but you don't even care! This is riveting Internet reading right here!
So what if your tuple data structures are as complicated as your marriage? You reach for PEP 646 and @beartype
0.22.2
. You can now unpack at most one child tuple hint inside another parent tuple hint. For reasons that will become clear shortly, most child tuple hints unpacked in this way are variadic. Do that and you've now defined a mixed fixed-variadic tuple hint that matches tuples containing (in order):tuple[str, bytes, *tuple[int, ...], bool, float]
, for example, is the mixed fixed-variadic tuple hint matching tuples containing (in order) a string item, a byte string item, zero or more integer items, a boolean item, and a floating-point number item. Cool, right? But the coolness doesn't stop there. Consider cardinality. Old-school variadic tuple hints (liketuple[str, ...]
) only match tuples containing zero or more items. But what if you want to match a positive number of items? Tuple hint unpacking trivially lets you do that, too.tuple[str, *tuple[str, ...]]
, for example, is the mixed fixed-variadic tuple hint matching tuples containing one or more strings. This example then generalizes to arbitrary cardinality bound only by your patience and openness to syntactic barbarism. Want to match tuples containing a larger number of strings? Just keep prependingstr
child type hints until you're satisfied, exhausted, and dripping with sweat at 4:17AM.tuple[str, str, str, str, str, *tuple[str, ...]]
, for example, is the mixed fixed-variadic tuple hint matching tuples containing five or more strings. It's silly. Yet, it works. Kinda.@beartype
0.22.2
: it's only silly if you admit it's silly.0.22.2
proudly unpacks tuple hints as the wind blows its hair aroundLastly but Beastly (but not Leastly)...
...to financially feed @leycec and his friendly @beartype through either:
Cue hypnagogic rave music that encourages fiscal irresponsibility. 🎵 🎹 🎶
Bear Club: The First Rule of Bear Club Is You Crush Bugs
@beartype high-fives the reclusive secret society of worldwide bear bros who might possibly care about this. You are the select few. The elect enlightened. You are:
@posita, @wesselb, @tusharsadhwani, @JWCS, @patrick-kidger, @EtaoinWu, @iamrecursion, @Moosems, @langfield, @sylvorg, @Glinte, @cclauss, @sean-roelofs-ai, @kultura-luke, @jonathanberthias, @gotmax23, @adamtheturtle, @ilyapoz, @MilesCranmer, @rg936672, @ddorian, @k4ml, @riesentoaster, @LeonHilf, @jeertmans, @mzealey, @thetianshuhuang, @RomainBrault, @alisaifee, @ArneBachmannDLR, @JelleZijlstra, @tactile-metrology, @RobPasMue, @GithubCamouflaged, @kloczek, @uriyasama, @danielgafni, @JWCS, @rbroderi, @AlanCoding, @tvdboom, @crypdick, @jvesely, @komodovaran, @kaparoo, @MaximilienLC, @fleimgruber, @alexoshin, @gabrieldemarmiesse, @James4Ever0, @NLPShenanigans, @rtbs-dev, @yurivict, @st--, @murphyk, @dosisod, @Rogdham, @alisaifee, @denisrosset, @damarro3, @ruancomelli, @jondequinor, @harshita-gupta, @jakebailey, @denballakh, @jaanli, @creatorrr, @msvensson222, @avolchek, @femtomc, @AdrienPensart, @jakelongo, @Artur-Galstyan, @ArneBachmann, @danielward27, @WeepingClown13, @rbnhd, @radomirgr, @rwiegan, @brettc, @spagdoon0411, @helderco, @paulwouters, @jamesbraza, @dcharatan, @kasium, @AdrienPensart, @sunildkumar, @peske, @mentalisttraceur, @awf, @PhilipVinc, @dcharatan, @empyrealapp, @rlkelly, @KyleKing, @skeggse, @RomainBrault, @deepyaman, @minmax, @jedie, @pablovela5620, @thiswillbeyourgithub, @Logan-Pageler, @knyazer, @ilyapoz, @yuzhichang, @Fedezzab, @antonioan, @im-Kitsch, @mthramann, @fbartolic, @rgallardone, @frrad, @jonnyhyman, @jennydaman, @likewei92, @acec2127, @rudimichal, @woutdenolf, @PauloHMTeixeira.
v0.21.0
: Beartype 0.21.0: Curses, It's Recursion!Beartype 0.21.0 consoles your codebase as it shudders under the oppressive tidal wave of bugs. Much like its predecessors, @beartype
0.21.0
is here to help. Unlike its predecessors, @beartype0.21.0
claims it solves more problems than it creates for once. Is @beartype0.21.0
.... lying!? 🫢pip install --upgrade beartype # <-- blast all bugs into the git pit
Let your test suite show the truth – even if @leycec just wants to play obscure French video games with titles like Clair Obscur: Expedition 33 (Because This Couldn't Be More Pretentiously Pseudorandom) the entire weekend and pretend our issue tracker isn't collapsing under its own ponderous weight:
0.21.0
: this can't be what you've waited months for@beartype
0.21.0
is gratefully 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:
https://sescollc.com
https://dylanmodesitt.com
Thanks so much, masters of fintech.
Let's get this pawful party started.
tl;dr: Explosive Recursion Never Felt So Good
@beartype
0.21.0
is obsessed with recursive data structures. They're more common than you might think! Okay. They're totally rare. We all learn about recursive data structures as poverty-stricken undergrads who subsist on years-old cup ramen and then pretend we never learned about them. You'll never need to implement a recursive data structure in pure-Python, because somebody else already did that for you. Graphs, heaps, queues, linked lists, skip lists, trees, and (our personal favourite) tries are all sufficiently awesome that you're already using most of them... because somebody else made them. That's why you're using them! Right? Ain't nobody got spare time or brain space to hack out a pure-Python red-black binary tree in 2025. But somebody did.@beartype
0.21.0
is for that somebody. When you need recursion, you need @beartype0.21.0
.@beartype
0.21.0
also acknowledges that 2025 is Humanity on Hard Mode™. The planet isn't doing well. Humanity isn't doing well. Industrial civilization isn't doing well. The US isn't doing well. Even Canada's looking a bit shaky – and we face literal death just by going outside six months of the year. Let's not even mention the deer flies, black flies, mosquitos, ticks, or rabid raccoons. Gods. Anything but the rabid raccoons. Therefore, wherever you are, whatever you face, whenever the darkness erupts and starts gnawing on your codebase...@beartype
0.21.0
will be there. We got your codebase's back. In fact, we're currently scratching that back. Feels good, right? These paws have claws – but only for bugs. Your code got lucky.0.21.0
: a familiar face you can trustSynopsis: When You're So Verbose Even Your Synopsis Is a White Paper
Let @beartype assuage, massage, and presage ...wat? it's my release party and i'll rhyme if i wanna those issues away. @beartype
0.21.0
promises it delivers first-class best-of-breed hyphenated-jargon-hype-train support for:Recursive type hints! That's right. Now you too can revel in the disgusting power of infinitely deep data structures with [PEP 695][]-compliant recursive
type
aliases. The only catch? This unworldly magic needs Python ≥ 3.12, which is quite the catch indeed. Behold! Unworldly magic:Type hint matching an infinitely recursive list. Look, I don't know. This is for
the extreme sports coders that like to live dangerously and code even harder.
type RecursiveListExplodesYourApp = list[RecursiveListExplodesYourApp]
Generalized hint overrides! That's right. Now you too can replace all
list[str]
type hints with... uhh,list[str] | tuple[str, ...]
. Pretend somebody wants this:Users can now pass tuples of strings to all callables annotated as
accepting only lists of strings. waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaat?
beartype_this_package(conf=BeartypeConf(hint_overrides=FrozenDict({
list[str]: list[str] | tuple[str, ...]}))) # <-- pretend this makes sense
0.21.0
: If you don't feel like a wild animal while coding, can it be called coding?Recursion: Still Destroying Lives after All These Years
@beartype
0.21.0
now officially supports all possible forms of recursion in type hints. This includes directly recursive [PEP 695][]type
aliases, indirectly recursive [PEP 484][] generics, and @beartype-specific hint overrides. Which you prefer depends on which bitter pill you're willing to swallow:If you're willing to require Python ≥ 3.12 as a mandatory dependency, prefer [PEP 695][]
type
aliases. They're concise. They're descriptive. They're elegant. They "just work" intuitively in the exact way you expect them to:Annotate recursive data structures with a "simple" one-liner. \o/
type RecursiveListExplodesYourApp = list[RecursiveListExplodesYourApp]
Let's take this one recursive app destroyer at a time.
0.21.0
: this is the biggest animated gif i have ever seenDirect Recursion via PEP 695 Type Aliases: Because How Much More Broken Could Your App Get?
Directly recursive [PEP 695][] type aliases is what everybody who wants recursive type hints wants. Against all odds, you're actually reading this. You want recursive type hints. Thus, you want:
...which raises the expected output and exception traceback:
Pore one out for the unsuspecting @beartype users that actually tried to run the above example. Their smoking CPUs are no longer with us. What remains of the ruin of their motherboards is now locked into a segfaulting bootloop featuring a cackling ASCII-art bear. It is sad.
0.21.0
: "zomg so cuuuuuute oh my brain hurts nooooooooooooooo"What's the Catch?
What? Catch? Surely you jest! There's no... oh, who am I kidding. There are huge catches associated with [PEP 695][]. For one, @beartype intentionally does not support older PEP-noncompliant variants of recursive type hints that used stringified forward references. You might occasionally see crufty stuff like this floating around StackOverflow, older codebases, or the
mypy
issue tracker:@beartype doesn't support that. Using stringified forward references to induce recursion is non-standard. @beartype probably could support that, but there's not much point in supporting non-standards when standardized alternatives exist. That's why...
@beartype
0.21.0
only supports [PEP 695][]: the only standard for defining recursive type hints. Everything else was just somethingmypy
made up. Recursivetype
aliases now work wonderfully under Python ≥ 3.12 – but that's the gotcha here.0.21.0
: rambo with a sword is something that happened only on an alternate timeline... but it still happenedOh, Gods! Here It Comes!
That's right. You love to hate it. [PEP 695][] is unusable under Python ≤ 3.11. Attempting to define any
type
alias under Python ≤ 3.11 results in CPython raising an unreadable"SyntaxError: invalid syntax"
exception.In a year or two, this will be significantly less of a hard blocker for everyone. Increasingly, nobody cares about Python ≤ 3.11. Do you care about Python ≤ 3.11? Maybe – but you probably shouldn't, unless your huge userbase is obsessed by Python ≤ 3.11. In that case, you're kinda screwed. You have to choose between your love for recursion and your love for having users. Tough choice. I'd choose recursion, personally.
0.21.0
: users who hate recursion are users who make your face contort into a tight rictus of agonyPython ≥ 3.12? Is That Really the Only Catch?
Absolutely! Totally! How could anything else possibly go wrong!
...oh, who am I kidding!?!?!? There is yet another huge catch associated with [PEP 695][]. @beartype does not deeply t
Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about these updates again.
This PR was generated by Mend Renovate. View the repository job log.