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
. To me it would seem that typing.Callable
and collections.abc.Callable
should always behave similarly, but they do not.
This simple example results in an error:
>>> 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'
but the same error does not happen with typing.Callable
:
>>> from typing import Callable
>>> def foo(arg: Optional[Callable[[int], int]]) -> None:
... pass
...
>>> # no error
The error also doesn't happen if the signature is simplified a bit:
>>> 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
Is this a bug in Python 3.9 and 3.9.1?
question from:
https://stackoverflow.com/questions/65858528/is-collections-abc-callable-bugged-in-python-3-9-1 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…