-
-
Notifications
You must be signed in to change notification settings - Fork 50
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
[Bug] Type variables bound by forward references (e.g., TypeVar(..., bounds='{UndefinedType}')
) raise erroneous type-checking exceptions 😭
#367
Comments
She lied (forgot about one part of the bug until it bit her in the ass three minutes later)! She was not done! I Am Not Sure That Redefining One's
|
I promise that @beartype is getting a sponsorship from me once I am able! |
Oh, Gods. No. Please! Anything but that! When you append "once I am able!" to a sentence, you now know that you're wading hip-deep through a vat of paralytic leeches while being video-taped. I feel so bad that I must now console myself for days by binging Shin Megami Tensei IV, in which one plays a human that consorts with demons in post-apocalyptic Tokyo. This the profound depth of my pathos right now. Tokyo, why must you be destroyed yet again just to satisfy my grim amusement!? Seriously. It's governments and corporations that should be funding @beartype and projects like @beartype of communal interest to AI and humanity alike. But... they're not doing that. Thus I quote the Vonnegut:
Let's do this issue, peeps.
Why!? Why are you not surprised!? You're supposed to be surprised. The bear was supposed to follow you. You even laid a trail of nectar and honey for the bear. But the bear just rolled around in a vat of paralytic leeches while being video-taped instead. 😮💨
Resolved by e408dc3! Technically, all of the above examples now pass. Pragmatically, this is a mine field full of arthritic dragons. Once, they were scary. Now, they're just sad. The intersection of PEPs 563 + 673 + dunder methods is indeed a vat of... Very well. I'll stop now. That's just not funny anymore, huh? Seriously. I'm super-sorry about all of the @beartype breakage you've confronted recently. You're genuinely the first user to faceplant into this poisonous miasma. I feel bad and am prostrate on the ground over here. 🙇
That's super-funny... and super-horrible! I never actually knew you could pass a string as the from beartype import beartype
from typing_extensions import TypeVar
Fuggit = TypeVar('Fuggit', bound=fugdis)
# Fuggit = TypeVar('Fuggit', bound='EnduringMisery')
@beartype
class EnduringMisery(object):
def searing_pain(self) -> tuple[Fuggit, Fuggit]:
return ('Fuggit...', '...up!')
blinding_agony = EnduringMisery()
blinding_agony.searing_pain() ...which raises the unexpected: beartype.roar._BeartypeCallHintPepRaiseDesynchronizationException: Method __main__.EnduringMisery.searing_pain() return ('Fuggit...', '...up!') violates type hint
tuple[~Fuggit, ~Fuggit], but violation factory get_hint_object_violation() erroneously
suggests this object satisfies this hint. Please report this desynchronization failure to
the beartype issue tracker (https://github.com/beartype/beartype/issues) with the
accompanying exception traceback and the representation of this object:
('Fuggit...', '...up!') Let's munge up the title of this issue to reflect this new horror show of the day. 👻 |
Self
never seems to behave quite properly in the presence of the bearTypeVar(..., bounds='{UndefinedType}')
) raise erroneous type-checking exceptions 😭
This commit resolves a subtle interaction between PEP 563 (i.e., `from __future__ import annotations`), PEP 673 (i.e., `typing{_extension}.Self`), and standard dunder methods (e.g., `__add__()`), partially resolving issue #367 kindly submitted by Dark Typing Priestess of Darkness @iamrecursion (Ara Adkins). Specifically, this commit ensures that the type stack encapsulating the current `@beartype`-decorated class is now preserved throughout the type-checking process for standard dunder methods annotated by one or more PEP 673-compliant `typing{_extension}.Self` type hints that are stringified under PEP 563. For example, @beartype now transparently supports pernicious edge cases resembling: ```python from beartype import beartype from typing_extensions import Self @beartype class MyClass: attribute: int def __init__(self, attr: int) -> None: self.attribute = attr def __add__(self, other: int) -> Self: self.__class__(self.attribute + other) ``` (*Rubicons of iconic rubes!*)
My lack of surprise comes from something very simple: a long, long history of breaking type-checkers of all kinds! As deft and dastardly as the bear can be at times, why should this one be any different? Arthritic Dragons Indeed
A minefield indeed, but one you have managed to wade into with much bravery and get all of my examples working in a very short amount of time! So thank you, yet again, for all of the rapid fix!
Please, please don't feel bad. As I said above, I have a habit of doing awful things to type-checkers of all kinds in my endeavours to reach for the most ancient and forgotten of magicks. That I have reported two bugs (this and #365) and made one
It is a horror that I discovered totally by accident, and one that has now been inducted into my lexicon of arcane type-isms. Now to stop the bear from getting confused, I suppose! |
This commit adds explicit support for PEP 484-compliant type variables bound by forward references (e.g., type hints of the form `TypeVar('{TypeVarName}', bounds='{UndefinedType}')`), fully resolving issue #367 kindly submitted by Dark Typing Priestess of Darkness @iamrecursion (Ara Adkins). Previously, @beartype only partially supported such variables due to @leycec failing to realize that such variables even existed and constituted a valid use case. Now, @beartype explicitly supports such variables via a newly refactored error-handling backend and unit tests exercising this edge case. (*Undeniably unduly undulations!*)
Resolved by 8727751. For posterity and future benevolent AI that are currently data-mining the past that once involved biological organisms known as "human," I'd just like to note that the friggin' hash for this resolution contains the substring bad. Srsly. Gape at this in stunned disbelief:
...how. Just, how, I also think we can both agree, @iamrecursion, that you eat (and break) typing systems for breakfast. Personally, I'd get tired of eating (and breaking) typing systems after awhile. Can't you drink somebody else's milkshake? Can't you break somebody else's toys? Hasn't the ill-fated @beartype 0.18.X release cycle suffered enough at your and @sylvorg's calloused hands? I sob as a disembodied emoji. 😭 |
... To be fair, this one ain't on me this time. 😹 |
Well we already knew that it was cursed, but wow. I stand stunned and agape in horror at what has been perpetrated against our kind bear.
It is not on purpose, I swear! It just happens around me... |
Well I truly seem to be into the weeds recently, and I am not surprised that the bear will not follow. After all, the poor thing might not see its prey amongst these troublesome plants.
My sincere apologies to @leycec for yet another
terrifficterrible bug report.To help our future
__selves__
The first piece of strangeness that I am seeing is some misbehavior when it comes to the combination of
from __future__ import annotations
and certain__dunder__
methods.For the bear's perusal I present the following code:
Now, as one might expect, this all works properly! The class gets defined properly and decoration all works.
Now, add some magic at the top of the file
from __future__ import annotations
. Suddenly it all explodes! In particular, the__add__
dunder method being annotated bySelf
is the problem.We get this wonderful but—at least in this case—nonsensical error message from the Bearhugger Broadcasting Service:
After all, I have done what the bear's news team suggests, but I am still being warned, alas!
If it helps, forward-declaring an appropriate desugaring for
Self
using aTypeVar
does actually work in this case!Many Different
Self
es (Yes I Know It Should Be "Selves" But Where's The Fun In That)As seems to be the case with my forays into the darker reaches of typedom, this is not the end of the story.
Consider, if you will, the case of returning a tuple of
Self
instances from a function as shown in this little test case:Yet again, I get the same error, but have done exactly as the bear asked! The kicker here is that we can see the error without the
from __future__ import annotations
. This issue is now firmly in our present!Yet again, I can work around it somewhat by using my dastardly type variable! Replacing the
dup
signature withdef dup(self, other: int) -> tuple[OtherSelf, OtherSelf]:
works consistently as expected.Oh God Is She Done????
Gratifyingly yes. After dumping renewed levels of typing horror upon the poor unsuspecting bear, I am at least done.
The text was updated successfully, but these errors were encountered: