-
-
Notifications
You must be signed in to change notification settings - Fork 49
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
[Feature Request] PEP 362 (i.e., func.__signature__
+ inspect.Signature
) support
#295
Comments
Ah, ha! It is everyone's favourite scuba-diving globe-trotting Google X ML specialist, Dr. Kidger! Okay. So, you caught @beartype out red-pawed here. PEP 362 – Function Signature support is something we've been meaning (but failing) to implement for literally years. Since the road to bugginess is paved with good intentions, we did other stuff instead. This is why cats cry in the autumn. 😿 I will now quote my more idealistic younger self. Thankfully, he already figured out what we need to do here. That's good, because my more cynical older self was clueless. Here's what younger @leycec says about all this:
Sadly, I have yet to finalize Python 3.12 compatibility. A firestorm of bugs erupted on the issue tracker, which @beartype 0.16.4 doused with kerosene. You'd think that would make things worse. Sometimes, you just gotta fight fire with fire. Thankfully, I should finalize Python 3.12 compatibility in a week or two in a new @beartype 0.17.0 release. Assuming I am not lying to everyone yet again, I promise to then resolve this issue by adding PEP 362 support. And I dub thee... @beartype 0.18.0! So much for our reasonable roadmap. Truly, this world is chaos. |
beartype.beartype
+ functools.wraps
does not raisefunc.__signature__
+ inspect.Signature
) support
Haha! FWIW, I've worked around this by creating a string for the function and then |
So. Emoji cat: please weep for us as we implement clever but saddening workarounds. 😿
Thanks Soooooo Much for......recommending @beartype for the Google Open Source Peer Bonus!!!! I'm so eternally grateful. Seriously. An Aspy cannot lie. (It's true, because you read it online.) That is one of the nicest things anyone's ever done for me. It truly means alot. Social recognition isn't something I'm accustomed to. But it feels surprisingly great! Even if @beartype never wins anything beyond the sweet dopamine rush of crushing everyone's bugs, I can't thank you enough for publicly believing in @beartype – the undomesticated QA varmint. Therefore, I have repaid you tonight by... Doing Something That Doesn't Help You at AllYes, it's true! Commit 973a00e now partially resolves this issue. @beartype now supports your first use case that you don't actually care about at all: from beartype import beartype
from functools import wraps
import inspect
def muh_func(muh_arg: int): # <-- wat!? no @beartype? how can this be?
pass
@beartype # <-- oh, okay. here's the @beartype. phew. that was close
@wraps(muh_func) # <-- standard decorator idiom
def muh_wrapper(*args, **kwargs): # <-- isomorphic non-closure wrapper
return muh_func(*args, **kwargs)
muh_wrapper('This is an integer, I swear it!') # <-- now raises an exception: BOOM! Better than nuthin', @beartype. Better than nuthin'. 💪 🐻 Interestingly, @beartype has supported the standard idiom for defining decorators for a few years: e.g., from beartype import beartype
from collections.abc import Callable
from functools import wraps
import inspect
@beartype
def muh_decorator(func: Callable) -> Callable:
@beartype # <-- oh, okay. here's the @beartype. phew. that was close
@wraps(func) # <-- standard decorator idiom
def muh_wrapper(*args, **kwargs): # <-- isomorphic closure wrapper
return func(*args, **kwargs)
return muh_wrapper
@muh_decorator # <-- wat!? no @beartype? how can this be?
def muh_func(muh_arg: int):
pass
muh_func('This is an integer, I swear it!') # <-- still raises an exception: BOOM! I'd assumed that most user-defined decorators would look like that. Clearly, I was wrong. Never thought anyone would actually implement a decorator wrapper outside of a closure context... but they did. @patrick-kidger: If he did what you expected, this world would be a really boring place. |
This commit generalizes the `@beartype` decorator to support *all* **isomorphic wrappers** (i.e., higher-level callables decorated by the standard `@functools.wraps` decorator for wrapping lower-level callables with additional functionality defined by even higher-level decorators such that those wrappers isomorphically preserve both the number and types of all passed parameters and returns by accepting only a variadic positional argument and a variadic keyword argument), partially resolving issue #295 kindly submitted by @patrick-kidger (Patrick Kidger) – the Best Google X Researcher of All Time, Clearly. Previously, @beartype only supported **isomorphic closure wrappers** (i.e., isomorphic wrappers defined as closures rather than non-closure callables). Now, @beartype supports both isomorphic closure wrappers *and* **isomorphic non-closure wrappers** (i.e., isomorphic wrappers defined as non-closure callables rather than closures). Notably, this is now fine: ```python from beartype import beartype from functools import wraps import inspect def muh_func(muh_arg: int): # <-- wat!? no @beartype? how can this be? pass @beartype # <-- oh, okay. here's the @beartype. phew. that was close @wraps(f) # <-- standard decorator idiom def muh_wrapper(*args, **kwargs): # <-- isomorphic non-closure wrapper pass ``` (*Idiomatically immaterial idiocy in a cyclic automata, mate!*)
Haha, you're very welcome, I did it because I really appreciate all of the effort you've put into beartype!
:D |
For what it's worth, the second is my actual use-case: beartyp'ing a dynamically-created function, with a manually-assigned signature and annotations. What's the best way to workaround this with current versions of beartype?
The text was updated successfully, but these errors were encountered: