-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
typing_extensions.Annotated not supported #120
Comments
Hey @hodgespodge! :) I think the problem is as follows: >>> from typing_extensions import Annotated
>>> from beartype.vale import Is
>>> from beartype.door import TypeHint, is_bearable
>>> is_bearable("hello", Annotated[object, Is[lambda value: hasattr(value, 'special_attr')]])
True I've opened an issue at @beartype to get the bear master's (@leycec's) thoughts. |
leycec
added a commit
to beartype/beartype
that referenced
this issue
Oct 12, 2023
This commit resolves an edge case with respect to beartype validators in which @beartype unconditionally (and thus erroneously) ignored *all* type hints 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 issue #290 kindly submitted by Plum maestro @wesselb (Wessel) *and* beartype/plum#120 kindly submitted by professional hodge-podger @hodgespodge. Specifically, this commit: * Improves our private `beartype._util.hint.pep.proposal.utilpep593.is_hint_pep593_ignorable()` tester to avoid ignoring PEP 593-compliant type hints annotated by one or more beartype validators, even if those same hints annotate an ignorable type hint (e.g., the root `object` superclass). * Exhaustively unit tests this edge case. (*Ineluctable defection of delectable perfection!*)
Resolved by beartype/beartype@76e609dd484339ae. I'm willing to pretend this didn't happen if everyone else is. 🥲 |
@hodgespodge if this isn’t top-notch super quick bug solving, then I don’t know what is. Hats off to @leycec! |
Thanks a ton both of y'all! |
leycec
added a commit
to beartype/beartype
that referenced
this issue
Oct 14, 2023
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!*)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Howdy,
For the time being, I'm unfortunately stuck targeting python 3.8. As such, I am using the typing_extensions package to get Annotated.
My goal is to create a custom type checker using beartype.vale.Is. The code is confirmed to work with the new python typing, but fails for typing_extensions. I think it would be great to support typing_extensions.Annotated since beartype.beartype recommends using typing_extensions for python < 3.9 in its documentation.
Thanks!
The text was updated successfully, but these errors were encountered: