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.

classification
Title: Add types.Self
Type: Stage: resolved
Components: Versions: Python 3.11
process
Status: closed Resolution: duplicate
Dependencies: Superseder: Implementing PEP 673 (Self type)
View: 46534
Assigned To: Nosy List: JelleZijlstra, gvanrossum, rhettinger
Priority: normal Keywords:

Created on 2022-02-06 23:12 by rhettinger, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (5)
msg412682 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2022-02-06 23:12
Typeshed now has a nice self-describing type variable to annotate context managers:

Self = TypeVar('Self')

def __enter__(self: Self) -> Self:
    return self

It would be nice to have that in the standard library types module as well.
msg412684 - (view) Author: Jelle Zijlstra (JelleZijlstra) * (Python committer) Date: 2022-02-06 23:14
PEP 673 (which was accepted) adds typing.Self already. bpo-46534 tracks implementing it.
msg412772 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2022-02-07 17:27
On a related note, is this the correct way to annotate __exit__?


Exc = TypeVar('Exc', bound=Exception)

def __exit__(self, exctype: Optional[Type[Exc]], excinst: Optional[Exc], exctb: Any) -> None:
msg412786 - (view) Author: Jelle Zijlstra (JelleZijlstra) * (Python committer) Date: 2022-02-07 19:42
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.
msg412813 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2022-02-08 05:25
> 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?
History
Date User Action Args
2022-04-11 14:59:55adminsetgithub: 90827
2022-02-08 05:25:38rhettingersetmessages: + msg412813
2022-02-07 19:42:03JelleZijlstrasetmessages: + msg412786
2022-02-07 18:09:47rhettingersetstatus: open -> closed
superseder: Implementing PEP 673 (Self type)
resolution: duplicate
stage: resolved
2022-02-07 17:27:50rhettingersetmessages: + msg412772
2022-02-06 23:14:04JelleZijlstrasetmessages: + msg412684
2022-02-06 23:12:51rhettingercreate