GeezerVison is showing github.com — Empty typing.Tuple · Issue #91137 · python/cpython
Empty typing.Tuple #91137Description
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee = None
closed_at = <Date 2022-03-17.08:20:59.454>
created_at = <Date 2022-03-11.08:21:12.398>
labels = ['library', '3.11']
title = 'Empty typing.Tuple'
updated_at = <Date 2022-04-08.05:07:15.239>
user = 'https://github.com/serhiy-storchaka'
bugs.python.org fields:
activity = <Date 2022-04-08.05:07:15.239>
actor = 'JelleZijlstra'
assignee = 'none'
closed = True
closed_date = <Date 2022-03-17.08:20:59.454>
closer = 'serhiy.storchaka'
components = ['Library (Lib)']
creation = <Date 2022-03-11.08:21:12.398>
creator = 'serhiy.storchaka'
dependencies = []
files = []
hgrepos = []
issue_num = 46981
keywords = ['patch']
message_count = 5.0
messages = ['414892', '414947', '414986', '415391', '416958']
nosy_count = 4.0
nosy_names = ['gvanrossum', 'serhiy.storchaka', 'JelleZijlstra', 'kj']
pr_nums = ['31836']
priority = 'normal'
resolution = 'fixed'
stage = 'resolved'
status = 'closed'
superseder = None
type = None
url = 'https://bugs.python.org/issue46981'
versions = ['Python 3.11']
Activityserhiy-storchaka commented on Mar 11, 2022 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__
() gvanrossum commented on Mar 11, 2022 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). serhiy-storchaka commented on Mar 12, 2022 If for repr(Tuple[()]), it is no longer needed. serhiy-storchaka commented on Mar 17, 2022 JelleZijlstra commented on Apr 8, 2022 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. serhiy-storchaka commented on Jun 25, 2022 We get a report about broken pickling of empty typing.Tuple #94245. Shallow and deep copying are broken too.
>>> copy.copy(Tuple[()])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/serhiy/py/cpython3.10/Lib/copy.py", line 102, in copy
return _reconstruct(x, None, *rv)
File "/home/serhiy/py/cpython3.10/Lib/copy.py", line 265, in _reconstruct
y = func(*args)
File "/home/serhiy/py/cpython3.10/Lib/typing.py", line 312, in inner
return func(*args, **kwds)
File "/home/serhiy/py/cpython3.10/Lib/typing.py", line 1233, in __getitem__
params = tuple(_type_check(p, msg) for p in params)
File "/home/serhiy/py/cpython3.10/Lib/typing.py", line 1233, in <genexpr>
params = tuple(_type_check(p, msg) for p in params)
File "/home/serhiy/py/cpython3.10/Lib/typing.py", line 176, in _type_check
raise TypeError(f"{msg} Got {arg!r:.100}.")
TypeError: Tuple[t0, t1, ...]: each t must be a type. Got ().
>>> copy.deepcopy(Tuple[()])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/serhiy/py/cpython3.10/Lib/copy.py", line 172, in deepcopy
y = _reconstruct(x, memo, *rv)
File "/home/serhiy/py/cpython3.10/Lib/copy.py", line 265, in _reconstruct
y = func(*args)
File "/home/serhiy/py/cpython3.10/Lib/typing.py", line 312, in inner
return func(*args, **kwds)
File "/home/serhiy/py/cpython3.10/Lib/typing.py", line 1233, in __getitem__
params = tuple(_type_check(p, msg) for p in params)
File "/home/serhiy/py/cpython3.10/Lib/typing.py", line 1233, in <genexpr>
params = tuple(_type_check(p, msg) for p in params)
File "/home/serhiy/py/cpython3.10/Lib/typing.py", line 176, in _type_check
raise TypeError(f"{msg} Got {arg!r:.100}.")
TypeError: Tuple[t0, t1, ...]: each t must be a type. Got ().
All this can be fixed by backporting this change. But it will break pyanalyze. amitbad commented on Feb 20, 2024 I was using python 3.10 and getting the same error while using Gemini-Pro-Vision.
This resolved my issue - pip install pydantic==1.10.13
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|