collections.abc.Callable 在 Python 3.9.1 中有问题吗?
Is collections.abc.Callable bugged in Python 3.9.1?
Python 3.9 includes PEP 585 and deprecates many of the types in the typing
module in favor of the ones in collections.abc
, now that they support __class_getitem__
. This is the case with for example Callable
。在我看来,typing.Callable
和 collections.abc.Callable
的行为应该总是相似的,但事实并非如此。
这个简单的例子导致错误:
>>> from typing import Optional
>>> from collections.abc import Callable
>>> def foo(arg: Optional[Callable[[int], int]]) -> None:
... pass
...
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/usr/local/lib/python3.9/typing.py", line 262, in inner
return func(*args, **kwds)
File "/usr/local/lib/python3.9/typing.py", line 339, in __getitem__
return self._getitem(self, parameters)
File "/usr/local/lib/python3.9/typing.py", line 463, in Optional
return Union[arg, type(None)]
File "/usr/local/lib/python3.9/typing.py", line 262, in inner
return func(*args, **kwds)
File "/usr/local/lib/python3.9/typing.py", line 339, in __getitem__
return self._getitem(self, parameters)
File "/usr/local/lib/python3.9/typing.py", line 451, in Union
parameters = _remove_dups_flatten(parameters)
File "/usr/local/lib/python3.9/typing.py", line 231, in _remove_dups_flatten
return tuple(_deduplicate(params))
File "/usr/local/lib/python3.9/typing.py", line 205, in _deduplicate
all_params = set(params)
TypeError: unhashable type: 'list'
但是 typing.Callable
不会发生同样的错误:
>>> from typing import Callable
>>> def foo(arg: Optional[Callable[[int], int]]) -> None:
... pass
...
>>> # no error
签名稍微简化一点也不会出现这个错误:
>>> from collections.abc import Callable
>>> def foo(arg: Optional[Callable[..., int]]) -> None:
... pass
...
>>> # no error
>>> def foo(arg: Callable[[int], int]) -> None:
... pass
...
>>> # no error
这是 Python 3.9 和 3.9.1 中的错误吗?
Python 3.9 includes PEP 585 and deprecates many of the types in the typing
module in favor of the ones in collections.abc
, now that they support __class_getitem__
. This is the case with for example Callable
。在我看来,typing.Callable
和 collections.abc.Callable
的行为应该总是相似的,但事实并非如此。
这个简单的例子导致错误:
>>> from typing import Optional
>>> from collections.abc import Callable
>>> def foo(arg: Optional[Callable[[int], int]]) -> None:
... pass
...
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/usr/local/lib/python3.9/typing.py", line 262, in inner
return func(*args, **kwds)
File "/usr/local/lib/python3.9/typing.py", line 339, in __getitem__
return self._getitem(self, parameters)
File "/usr/local/lib/python3.9/typing.py", line 463, in Optional
return Union[arg, type(None)]
File "/usr/local/lib/python3.9/typing.py", line 262, in inner
return func(*args, **kwds)
File "/usr/local/lib/python3.9/typing.py", line 339, in __getitem__
return self._getitem(self, parameters)
File "/usr/local/lib/python3.9/typing.py", line 451, in Union
parameters = _remove_dups_flatten(parameters)
File "/usr/local/lib/python3.9/typing.py", line 231, in _remove_dups_flatten
return tuple(_deduplicate(params))
File "/usr/local/lib/python3.9/typing.py", line 205, in _deduplicate
all_params = set(params)
TypeError: unhashable type: 'list'
但是 typing.Callable
不会发生同样的错误:
>>> from typing import Callable
>>> def foo(arg: Optional[Callable[[int], int]]) -> None:
... pass
...
>>> # no error
签名稍微简化一点也不会出现这个错误:
>>> from collections.abc import Callable
>>> def foo(arg: Optional[Callable[..., int]]) -> None:
... pass
...
>>> # no error
>>> def foo(arg: Callable[[int], int]) -> None:
... pass
...
>>> # no error
这是 Python 3.9 和 3.9.1 中的错误吗?