You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
But there are two invariants about how __exit__ works in practice that this doesn't capture:
The arguments are either all None, or none of them are
If they are not None, then the typ argument is the type of the exception passed to the exc argument
I believe these invariants are always true in 3.11 thanks to Irit's work, but previously there could be rare circumstances where they didn't hold. You probably know the details better than I do.
We could support the first invariant by using two overloads, one where the arguments are all None and one where they aren't. I don't think that's generally worth doing though: it's a lot of verbose code and doesn't fix many real problems.
Your suggested signature looks like it's trying to support the second invariant, but it doesn't quite: if the types don't match, the type checker will just set T to the common base type of the two arguments.
Your suggested signature looks like it's trying to support
the second invariant, but it doesn't quite: if the types
don't match, the type checker will just set T to the
common base type of the two arguments.
Is there a way to write the second invariant correctly?
Activity
rhettinger commentedon Feb 6, 2022
Typeshed now has a nice self-describing type variable to annotate context managers:
It would be nice to have that in the standard library types module as well.
JelleZijlstra commentedon Feb 6, 2022
PEP-673 (which was accepted) adds typing.Self already. bpo-46534 tracks implementing it.
rhettinger commentedon Feb 7, 2022
On a related note, is this the correct way to annotate __exit__?
JelleZijlstra commentedon Feb 7, 2022
The conventional way is to write
But there are two invariants about how __exit__ works in practice that this doesn't capture:
I believe these invariants are always true in 3.11 thanks to Irit's work, but previously there could be rare circumstances where they didn't hold. You probably know the details better than I do.
We could support the first invariant by using two overloads, one where the arguments are all None and one where they aren't. I don't think that's generally worth doing though: it's a lot of verbose code and doesn't fix many real problems.
Your suggested signature looks like it's trying to support the second invariant, but it doesn't quite: if the types don't match, the type checker will just set T to the common base type of the two arguments.
rhettinger commentedon Feb 8, 2022
Is there a way to write the second invariant correctly?