Beartype 0.16.3
This bug-defying patch release adds official support for hot module reloading, root superclass validators, forward reference issubclass()
proxying, readable forward reference exceptions, and class redecoration eliding as well as documenting a medley of topics and APIs first introduced with the beartype.claw
subpackage under @beartype 0.15.0. Where did the time go? Probably playing vidya games, if I'm being openly honest with myself.
@beartype 0.16.3 almost qualified as a full-blown minor release called @beartype 0.17.0. In the end, however... you failed, @beartype 0.16.3! You weren't quite big enough, dizzyingly stupefying enough, or blatantly broken enough to get upgraded to a minor release. It's for the best.
Look. It was Canadian Thanksgiving. It was all I could do to take the roasted turkey leg out of my mouth. Still, there is awesome sauce. This includes:
-
Hot reloading. @beartype is now robust against hot reloading (i.e., re-importation of previously imported modules containing one or more @beartype-decorated classes), resolving issue #288 kindly submitted by awfully ingenious Cambridge researcher @awf (Andrew Fitzgibbon). The
@beartype
decorator now explicitly (in order):- Detects class redefinition (i.e., redefinition of a previously
@beartype
-decorated class with the same name in the same module, usually but not necessarily due to hot reloading). - On the first redefinition of any class, clears all caches (i.e., @beartype-specific internal caches that could possibly contain the prior definition of that redefined class).
- Detects class redefinition (i.e., redefinition of a previously
-
Root superclass validators. The
@beartype
decorator now supports beartype validators of the formtyping(|_extensions).Annotated[object, beartype.vale.Is*, ...]
(i.e., PEP 593-compliant type hints annotating the otherwise ignorable rootobject
superclass by one or more unignorable beartype validators), resolving both issues #290 kindly submitted by Plum maestro @wesselb (Wessel) and beartype/plum#120 kindly submitted by professional hodge-podger @hodgespodge. With the fearsome power of root superclass validators, validate that arbitrary objects satisfy various constraints regardless of the actual types of those objects. This is now a thing:>>> from beartype.door import is_bearable >>> from beartype.typing import Annotated >>> from beartype.vale import Is >>> ICanHazAttr = Annotated[object, Is[ ... lambda value: hasattr(value, 'i_can_haz_attr')]] >>> is_bearable('hello', ICanHazAttr) False # <-- y u no got that attr, "str" class!? >>> class IHazAttr(object): ... i_can_haz_attr = 'Totally got this one, bro.' >>> is_bearable(IHazAttr, ICanHazAttr) True # <-- kk, you gots that attr
-
Forward reference
issubclass()
proxying. The@beartype
decorator now supports subscripted forward references (e.g.,"type[MuhClass]"
) to proxy bothisinstance()
andissubclass()
type-checks, resolving issue #289 kindly submitted by Google X extraordinaire @patrick-kidger (Patrick Kidger). Previously, subscripted forward references erroneously proxied onlyisinstance()
type-checks; this omission prevented these references from correctly resolving stringified type hints of the formtype[{UndefinedClass}]
(i.e., subscriptions of the PEP 585-complianttype[...]
builtin by a forward reference to a class that has yet to be defined). Now, all is full of QA. Praise be to the Kidger: e.g.,from beartype import beartype # .-- this really hot ASCII art # | arrow means this works now @beartype # v def dance_beartype_dance(i_dont_wanna: 'type[YoullDanceAndLikeIt]'): pass class YoullDanceAndLikeIt(...): ...
-
Readable forward reference exceptions. The
@beartype
decorator now raises human-readable exceptions involving forward references. Previously, forward reference proxies insanely presented themselves as unreadable private @beartype classes likebeartype._check.forward._fwdref._BeartypeForwardRefIndexable
. Now, forward reference proxies quietly pretend they're just the classes they proxy. They're not, but you're no longer supposed to know. Sure... okay. Look. This is a bald-faced lie, but @beartype is okay with lying toyour facegit blame
when doing so is in your best interests. Specifically, forward reference proxies now additionally proxy both:- The fully-qualified names of the modules declaring the classes to which they refer.
- The unqualified basenames of those classes.
-
Class redecoration eliding. The
@beartype
decorator now efficiently protects itself against redecoration. Previously,@beartype
uselessly allowed classes already decorated by@beartype
to be redecorated by@beartype
. Now,@beartype
usefully ignores attempts to redecorate classes: e.g.,@beartype # <-- this now reduces to a noop @beartype # <-- this still does nice stuff class MuhRedecoratedClass(...): ...
-
Documented stuff. Read such risible, readily defensible, and easily digestible documentation as:
- A revised high-level introduction to @beartype, which now promotes our principal
beartype.claw.beartype_this_package()
import hook. Ideally, this is what almost everyone should now be using. - A new
beartype.claw
API page. Every beartype import hook has now been exhaustively documented. Okay, okay. We omitted thebeartype.claw.beartyping()
context manager, because we ran out of time and Cyberpunk 2077 isn't going to hack its own neural link, is it? It might, actually. We were warned! - A new "What does 'pure-Python' mean?" FAQ entry. Reading is fun, even if you learn nothing and squander precious time that could have been better spent breathlessly watching Keanu Reeves do Keanu Reeves things.
- A new "What does 'hybrid runtime-static' mean?" FAQ entry. You will be bored to tears even as you gnash your teeth in mute frustration, which really cannot be good for your teeth.
- A new "What does 'third-generation type-checker' mean?" FAQ entry. Fun with Tedious Historical Facts That Will Bore You and Were Probably Just Made Up By @leycec Anyway: The Reckoning.
- Injects superfluous images illegally culled from Akira into this documentation, just because. If @beartype can do something, @beartype will do something.
- A revised high-level introduction to @beartype, which now promotes our principal
This is @beartype 0.16.3, the patch release best described as...
When you strive for Mount Olympus, yet you're still in Hades.
— @leycec, excerpts from "My Life with Beartype: A Sad Story"
This is how the QA was won. Not with a whimper, but an exploding head emoji. 😑 → 🤯