This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author JelleZijlstra
Recipients JelleZijlstra, gvanrossum, rhettinger
Date 2022-02-07.19:42:03
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1644262923.67.0.331833321358.issue46669@roundup.psfhosted.org>
In-reply-to
Content
The conventional way is to write

def __exit__(
    self,
    __typ: type[BaseException] | None,
    __exc: BaseException | None,
    __tb: types.TracebackType | None,
) -> None: ...

But there are two invariants about how __exit__ works in practice that this doesn't capture:
1. The arguments are either all None, or none of them are
2. 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.
History
Date User Action Args
2022-02-07 19:42:03JelleZijlstrasetrecipients: + JelleZijlstra, gvanrossum, rhettinger
2022-02-07 19:42:03JelleZijlstrasetmessageid: <1644262923.67.0.331833321358.issue46669@roundup.psfhosted.org>
2022-02-07 19:42:03JelleZijlstralinkissue46669 messages
2022-02-07 19:42:03JelleZijlstracreate