Jelle Zijlstra <jelle.zijls...@gmail.com> added the comment:

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.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue46669>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to