тип безопасности (mypy) для параметров функции при использовании * args

1

Введите контрольный код с помощью mypy:

def foo(a: str, b: float, c: int):
    print(a, b, c + 1)

foo('ok', 2.2, 'bad')

показывает неверный вызов слишком foo:

error: Argument 3 to "foo" has incompatible type "str"; expected "int"

Теперь предположим, что у нас есть оберточная функция, такая как:

from typing import Callable, Any

def say_hi_and_call(func: Callable[..., Any], *args):
    print('Hi.')
    func(*args)

и используйте недействительный вызов

say_hi_and_call(foo, 'ok', 2.2, 'bad')

mypy не сообщит о каких-либо ошибках, вместо этого мы узнаем об этой ошибке во время выполнения:

TypeError: must be str, not int

Я хотел бы поймать эту ошибку раньше. Есть ли возможность уточнить аннотации типа таким образом, чтобы mypy мог сообщить о проблеме?

Теги:
types
python-3.6
typechecking
mypy

1 ответ

0
Лучший ответ

ОК, единственное решение, которое я придумал, делает ясность функции явной, т.е.

from typing import Any, Callable, TypeVar

A = TypeVar('A')
B = TypeVar('B')
C = TypeVar('C')

def say_hi_and_call_ternary(func: Callable[[A, B, C], Any], a: A, b: B, c: C):
    print('Hi.')
    func(a, b, c)

def foo(a: str, b: float, c: int):
    print(a, b, c + 1)

say_hi_and_call_ternary(foo, 'ok', 2.2, 'bad')

Конечно, нужно было бы использовать аналогичные say_hi_and_call_unary и say_hi_and_call_binary и т.д.

Но поскольку я ценю мое приложение, которое не взрывается в PROD по сравнению с некоторыми LOC, я счастлив, когда mypy может сообщить об ошибке, что теперь, безусловно, имеет место:

error: Argument 1 to "say_hi_and_call_ternary" has incompatible type "Callable[[str, float, int], Any]"; expected "Callable[[str, float, str], Any]"

Ещё вопросы

Сообщество Overcoder
Наверх
Меню