Issue 46981: Empty typing.Tuple - Python tracker (original) (raw)

Created on 2022-03-11 08:21 by serhiy.storchaka, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 31836 merged serhiy.storchaka,2022-03-12 09:37
Messages (5)
msg414892 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2022-03-11 08:21
There are two empty typing.Tuple. They have the same repr but are not equal. >>> from typing import * >>> t1 = Tuple[()] >>> t2 = t1.copy_with(()) >>> t1 typing.Tuple[()] >>> t2 typing.Tuple[()] >>> t1 == t2 False >>> t1.__args__ ((),) >>> t2.__args__ () The only differences is that one has empty __args__, while other has __args__ containing an empty tuple. There is a code purposed to make __args__ containing an empty tuple in this case. What is the purpose? It is not pure theoretical question. This affects unpacked TypeVarTuple substitution. With natural implementation Tuple[Unpack[Ts]][()] is not equal to Tuple[()] and I still have not figured which and where code should be added to handle this special case. It would be easier if such special case did not exist. Built-in tuple does not have a special case: >>> tuple[()].__args__ ()
msg414947 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2022-03-11 23:35
Alas, I have no idea. I don't even recall what copy_with() is for (it was apparently introduced in 3.7). Possibly vopy_with() is wrong here? I imaging some of this has to do with the special casing needed so that repr() of an empty Tuple type doesn't print "Tuple[]" (which IIRC it did, long ago).
msg414986 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2022-03-12 09:40
If for repr(Tuple[()]), it is no longer needed.
msg415391 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2022-03-17 07:52
New changeset 15df8f8d89a0e563bdd15e4cd6734298736a5a1d by Serhiy Storchaka in branch 'main': bpo-46981: Remove typing._TypingEmpty (GH-31836) https://github.com/python/cpython/commit/15df8f8d89a0e563bdd15e4cd6734298736a5a1d
msg416958 - (view) Author: Jelle Zijlstra (JelleZijlstra) * (Python committer) Date: 2022-04-08 05:07
I tried out 3.11 on my pyanalyze type checker and got some failures because of this change, because my previous trick for distinguishing between Tuple and Tuple[()] failed. 3.10: >>> from typing import get_args, Tuple >>> get_args(Tuple[()]) ((),) >>> get_args(Tuple) () 3.11: >>> from typing import get_args, Tuple >>> get_args(Tuple[()]) () >>> get_args(Tuple) () However, the new behavior is more consistent: get_args(tuple[()]) always returned (). It's also easy enough to work around (just check `... is Tuple`). I'll put a note in the What's New for 3.11 about this change.
History
Date User Action Args
2022-04-11 14:59:57 admin set github: 91137
2022-04-08 05:07:15 JelleZijlstra set messages: +
2022-03-17 08:20:59 serhiy.storchaka set status: open -> closedstage: patch review -> resolvedresolution: fixedversions: + Python 3.11
2022-03-17 07:52:39 serhiy.storchaka set messages: +
2022-03-12 09:40:10 serhiy.storchaka set messages: +
2022-03-12 09:37:44 serhiy.storchaka set keywords: + patchstage: patch reviewpull_requests: + <pull%5Frequest29934>
2022-03-11 23:35:09 gvanrossum set messages: +
2022-03-11 19:38:58 JelleZijlstra set nosy: + JelleZijlstra
2022-03-11 08:21:12 serhiy.storchaka create