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] Granular warning messages #73
Comments
You're absolutely right. We'd really love for Interestingly, this exact issue is something my younger self continually complained about in Just Fix This, Please.Interestingly, this is also a common complaint throughout the Python world. Exceptions come bundled with traceback context out-of-the-box, but warnings don't. It is saddening. Until we resolve this on our end, would you mind suffering through one of the following workarounds? You can either:
from beartype import beartype
from beartype.roar import BeartypeDecorHintPep585DeprecationWarning
from warnings import simplefilter
# Coerce all PEP 585 deprecation warnings into fatal exceptions.
simplefilter('error', BeartypeDecorHintPep585DeprecationWarning)
# Under Python ≥ 3.9, this should now raise a fatal exception.
from typing import Callable, List
@beartype
def isfunctions(funcs: List[Callable]) -> bool:
return all(callable(func) for func in funcs)
$ python -W "error::UserWarning::0" muh_script.py
Personally, we favour the test-driven approach. We repeatedly faceplanted into this issue again and again with various third-party frameworks, especially Big Scary Ones (BSOs) like NumPy and SciPy. Globally nipping this in the bud seemed like the sanity-preserving approach. Tschüß, Ami!Thanks yet again for all the incisive suggestions, Anselm. Completely unrelatedly, I loved and adored my brief stay in Germany. What a delightful nation you've all made there! I dabbled in AI research at the Universität Bremen's Technologie-zentrum informatik (TZI). Ahh – to be foolishly young and guzzling buckets of German lager in the summertime tiergartens of Bremen again. 🌞 🍻 🌷 |
Oh, and I hope you don't mind my lightly massaging the issue title. As GitHub stars and issues alike explode in volume, I'm in triage mode sifting the "This would be really great to have!" from the "The stars are burning pits of fission and so is my code because of you." That said, I really want this to happen. NumPy-style contextless warnings are nobody's friend. 😞 |
So, we've investigated where those beartype warnings were coming from. Let me explain a little about the context. In this case, I guess our smartness turned a little against us. Aspectizing our own code worked quite well up until recently when those beartype warnings popped up and had us Now the ironic conclusion: Turns out we were applying beartype to beartype - which was complaining about itself, making us chase our own tails ^_^" PS: AI research in Bremen sounds absolutely lovely! Although, I fear corona is quite the spoilsport these days again - we're on "lockdown for non-immunized people" mode now, about to ruin xmas 3 times in a row now. |
Wow. Because First, I love that you have a public submodule named
heh Second, pinch me I must be dreaming, but did you really just imply that
If true, that's an impressive and (more importantly) immediate solution to the problem of globally applying
But... how exactly should everyone use When you get a spare moment, would you mind replying with a working minimal-length example (MLE) that globally applies We'll still do import hook automation eventually, of course. Because it's cool and scary and therefore attractive to risk-prone code slingers like us. Can't help but meddle with the dark side, can we?
heh ...wait. That's actually superbad. I never thought of going recursive – but now that you've unsealed Pandora's Snuff Box, I can't help but feel that we're hypocritical. We warn everyone else not to use PEP 484 type hints under Python ≥ 3.9... and then we do exactly that. Honestly, I was kinda hoping nobody would notice that. Welp. This is awkward. |
Yes and no. It works well enough for flat modules, but I dropped the ball on deep recursion and transitivity a while back when nobody seemed to care much about aspectizing at all and things got weird on the packaging front. Would you mind opening an issue for the specific cases you're thinking of? I'd love to give it the TLC it deserves :-)
Actually the last few days I've been working on a Showcase, just haven't gotten to the aspectizing part just yet! Maybe it'll be done when you're awake again ;-) |
Yes! You ask. I comply. That's just how we roll here in the bear cave. |
If you care to check out the Showcase, you will find I've added a chapter about aspectizing towards the end. I also asked my companions to help with aspectizing, so I'm optimistic we can come up with something more usable soon(tm). |
Firstly, that's hot. I never knew GitHub-rendered Jupyter notebook cells could look so svelte. 😮 I'm now considering C-C-Can It Be!?Secondly: import use
from beartype import beartype
from use import isfunction
np = use('numpy')
np @ (isfunction, '', beartype) zomg. You just runtime type-checked the entirety of NumPy without its permission. When you wrote "adds extra functionality to that module like You are Anselm. What couldn't you do? Does that terrifying yet aesthetically pleasing magic work under the most recent stable release of Slay All the DragonsThirdly, this actually leads us to a topic that is completely tangential to our normals: PEP 563. I've long suspected that PEP 563 dramatically reduces the decoration-time efficiency of runtime type-checkers. Issue #71 all but confirmed that suspicion. With
NumPy is the perfect type-hinting torture test, because they take type hints to hitherto unimagined heights of insanity. With concrete timings in hand, I'll finally have something tangible to approach the Python Steering Council with. Oh, boy! Python mailing list: prepare for incoming @leycec. |
|
Fun benefits from generous air quotes in this context. 😮💨 Everyone using runtime type-checkers should probably know about PEP 563, so... Here goes the hellshow. This is PEP 563: from __future__ import annotations That's it. Insert that at the very top of any Python module as the first statement of that module and you've now conditionally enabled PEP 563 for that module. Congratulations. You have successfully destroyed runtime performance. Why? Because: # Enabling PEP 563 stringifies all type hints from actual usable objects like this...
def muh_func(muh_arg: list[str]) -> tuple[int, bool]: pass
# ...into unusable string placeholders like this.
def muh_func(muh_arg: 'list[str]') -> 'tuple[int, bool]': pass Nobody can directly use a stringified type hint like PEP 563 is the thing that almost destroyed We'd all like to bury PEP 563 once and for all. If we can extract useful metrics out of |
Ohhh, THAT PEP.. yeah, I heard the screaming and shouting from afar. By that time it sounded like a good idea, having run into problems with forward references etc myself, but yeah.. killing pydantic doesn't sound very smart :( |
Crap. Shouldn't comment on github issues on my mobile. |
ZOMG. Back on topic, I never knew that the standard Of course, it's unclear exactly what Let's cogitate on this while I continue doing nothing. |
This commit is the first in a commit chain improving the granularity of warning messages, en-route to resolving feature request #73 kindly submitted several lifetimes ago by Stuttgart `typing` master @amogorkon (Anselm Kiefner). Specifically, this commit: * Prefixes warning messages with contextual metadata describing the origin of those warnings, typically including fully-qualified module, class, and/or callable names as relevant. * Associates warnings emitted by @beartype with the external user-defined modules to which those warnings apply under Python ≥ 3.12, whose standard `warnings.warn()` function accepts a new `skip_file_prefixes` parameter for exactly this purpose. Thanks so much to @amogorkon for gently prodding us to do this several lifetimes ago. This miracle on Earth is happening because of you. (*Considerable sidereal dirigible!*)
So. The final journey of feature request #73 begins. 🌆 |
This commit is the next in a commit chain improving the granularity of warning messages, en-route to resolving feature request #73 kindly submitted several lifetimes ago by Stuttgart `typing` master @amogorkon (Anselm Kiefner). Specifically, this commit exhaustively debugs and tests our recently defined private `beartype._util.error.utilerrwarn.reissue_warnings_placeholder()` utility function that is key to this special madness.: Thanks so much to @amogorkon for gently prodding us to do this several lifetimes ago. This miracle on Earth is happening because of you. (*Fractious fractions in an insatiate satisfaction!*)
Resolved by 438fe70. At long last, the promised land has arrived. After two years of sullen silence and much video gaming, @beartype 0.18.0 now offers detailed context for all warnings – including the much-feared PEP 585 deprecation warnings: >>> from beartype import beartype
>>> from typing import List
>>> @beartype
... def oh(god: List[str]) -> str: return god[0]
>>> oh(['We are born of the blood', 'made men by the blood', 'undone by the blood.'])
BeartypeDecorHintPep585DeprecationWarning: Function __main__.oh() parameter "god"
PEP 484 type hint typing.List[str] deprecated by PEP 585. This hint is scheduled for
removal in the first Python version released after October 5th, 2025. To resolve this,
import this hint from "beartype.typing" rather than "typing". The bear snickers even as it flexes its biceps. 💪 🐻 |
I would like to apply beartype as an aspect-decorator via justuse
use(thing) @ (isfunction, "", beartype)
but with only
as warning, there's not much to go on..
The text was updated successfully, but these errors were encountered: