Was making some typing conversions to string and noticed a different behavior of collections.abc.Callable and typing.Callable here in 3.9.1. Issues issue42195 and issue40494 can be related.
>>> import collections, typing
>>> repr(collections.abc.Callable[[int], str])
"collections.abc.Callable[[<class 'int'>], str]"
>>> repr(typing.Callable[[int], str])
'typing.Callable[[int], str]'
The variant from collections is wrong, it is not consistent with other GenericAlias reprs like
>>> repr(tuple[list[float], int, str])
'tuple[list[float], int, str]'
The problem is actually in the list usage to denote callable arguments:
>>> repr(tuple[[float], int, str])
"tuple[[<class 'float'>], int, str]"
Here is the same error. This error disallows to use typing in eval/exec statements:
>>> c = collections.abc.Callable[[int], str]
>>> d = eval(repr(c))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
collections.abc.Callable[[<class 'int'>], str]
^
SyntaxError: invalid syntax
Ofc there is no such problem with typing.Callable:
>>> c = typing.Callable[[int], str]
>>> d = eval(repr(c))
>>>
Interesting, if pass a list into typing.Tuple, an exception is raised:
>>> repr(typing.Tuple[[float], int, str])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "f:\software\python3.9\lib\typing.py", line 262, in inner
return func(*args, **kwds)
File "f:\software\python3.9\lib\typing.py", line 896, in __getitem__
params = tuple(_type_check(p, msg) for p in params)
File "f:\software\python3.9\lib\typing.py", line 896, in <genexpr>
params = tuple(_type_check(p, msg) for p in params)
File "f:\software\python3.9\lib\typing.py", line 151, in _type_check
raise TypeError(f"{msg} Got {arg!r:.100}.")
TypeError: Tuple[t0, t1, ...]: each t must be a type. Got [<class 'float'>].
I think it is not correct that tuple accepts lists as generics, i. e. for tuple[[float], int, str] an exception as above should be raised. Bu this is the topic for other issue (maybe even already reported).
|