Можно ли использовать typing.Mapping с functools.singledispatch в версии 3.7 и выше? - PullRequest
0 голосов
/ 18 октября 2019

У меня была функция, использующая functools.singledispatch с generics break после обновления до версии 3.7. То, что раньше работало в 3.6:

>>> from functools import singledispatch                             
>>> from typing import Mapping                                   
>>> @singledispatch                                 
... def f(_):                               
...  raise NotImplementedError
... 
>>> @f.register(Mapping)
... def _(x):
...  return x
... 

, теперь повышает

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/cpython/Lib/functools.py", line 831, in register
    raise TypeError(
TypeError: Invalid first argument to `register()`: typing.Mapping. Use either `@register(some_class)` or plain `@register` on an annotated function.

Регистрация тарифов с аннотированной версией не лучше:

>>> @f.register
... def _(x: Mapping):
...  return x
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/home/user/cpython/Lib/functools.py", line 842, in register
    raise TypeError(
TypeError: Invalid annotation for 'x'. typing.Mapping is not a class.

Я неправильно использовал одну отправкуи дженерики раньше, и есть ли способ добиться эквивалентного поведения в версии 3.7 и выше?

1 Ответ

3 голосов
/ 18 октября 2019

Вам нужно collections.abc.Mapping. Общие классы в основном несовместимы с любыми видами проверок во время выполнения.

То, что существует мало совместимости, в основном недокументировано и часто меняется. Например, typing.Mapping когда-то был классом, а документы по-прежнему говорят , что это класс, но сейчас он просто притворяется, что он один. functools.singledispatch нужен настоящий класс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...