Skip to content

Commit

Permalink
**Beartype 0.16.3** released.
Browse files Browse the repository at this point in the history
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):
  1. 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).
  1. 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).
* **Root superclass validators.** The `@beartype` decorator now supports
  beartype validators of the form
  `typing(|_extensions).Annotated[object, beartype.vale.Is*, ...]`
  (i.e., PEP 593-compliant type hints annotating the otherwise ignorable
  root `object` 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:

  ```python
  >>> 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 both `isinstance()` *and* `issubclass()`
  type-checks, resolving issue #289 kindly submitted by Google X
  extraordinaire @patrick-kidger (Patrick Kidger). Previously,
  subscripted forward references erroneously proxied only `isinstance()`
  type-checks; this omission prevented these references from correctly
  resolving stringified type hints of the form `type[{UndefinedClass}]`
  (i.e., subscriptions of the PEP 585-compliant `type[...]` 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.,

  ```python
  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 like
  `beartype._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 to ~~your face~~ `git 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.,

  ```python
  @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](https://beartype.readthedocs.io)
    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](https://beartype.readthedocs.io/en/latest/api_claw). Every
    beartype import hook has now been exhaustively documented. Okay,
    okay. We omitted the `beartype.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](https://beartype.readthedocs.io/en/latest/faq/#what-does-pure-python-mean).
    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](https://beartype.readthedocs.io/en/latest/faq/#what-does-hybrid-runtime-static-mean-pretty-sure-you-made-that-up-too).
    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](https://beartype.readthedocs.io/en/latest/faq/#third-generation-type-checker-doesn-t-mean-anything-does-it).
    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.

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. (An explosive impulse detonates tons of decidedly pulsating lozenges!*)
  • Loading branch information
leycec committed Oct 14, 2023
1 parent 76e609d commit aa31743
Showing 1 changed file with 1 addition and 0 deletions.
1 change: 1 addition & 0 deletions doc/src/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ The Left-Paw Path
See the left sidebar for links to human-readable API documentation – including:

* :mod:`beartype`, documenting the core :func:`.beartype` decorator API.
* :mod:`beartype.claw`, documenting the beartype import hook API.
* :mod:`beartype.door`, documenting the Decidedly Object-Oriented
Runtime-checker (DOOR) API.
* :mod:`beartype.roar`, documenting the beartype exception and warning API.
Expand Down

0 comments on commit aa31743

Please sign in to comment.