Строгая нотация типов в python

Строгая нотация типов в python


Задавал как то вопрос про нотации типов в функциях в python в стиле

def incr(number: int) -> int:
    return number + 10

В таком случае, работая в IDE я буду получать соответствующие подсказки типов, по сути информируя среду о типах данных, с которыми работаю. И мне известно, что в отличии от условного с++, принимаемый на вход тип данных может не соответствовать тому что указан в нотации, IDE может и что-то скажет об этом, но сам интерпретатор никаким образом ругаться не станет. Вопрос вот в чём:

Существуют ли библиотеки с декораторами(?), автоматизирующую проверку типов, и вызывающие исключения, в случае несоответствии проверки?

Выражаясь псевдоязыком, в моей голове это должно выглядеть так:

def incr(number: int) -> int:
    assert isinstance(number, int), TypeError
    result = number + 10
    assert isinstance(result, int), TypeError
    return result

Только разумеется, я имею в виду автоматизацию процедуры проверки всех принимаемых и возвращаемых значений

Ответ:

Есть библиотека typeguard (вроде бы слышал про нее раньше, но сейчас нашел через этот ответ), которая умеет в том числе добавлять проверки типов получаемых и возвращаемых значений функций.

Пример из документации:

from typeguard import typechecked

@typechecked
def some_function(a: int, b: float, c: str, *args: str) -> bool:
    ...
    return retval

@typechecked
class SomeClass:
    # All type annotated methods (including static and class methods and properties)
    # are type checked.
    # Does not apply to inner classes!
    def method(x: int) -> int:
        ...

Мой пример:

from typeguard import typechecked


@typechecked
def test(x: int) -> int:
    return x


print(test(10))  # Выведет 10
print(test("abcd"))  # TypeError: type of argument "x" must be int; got str instead

В том числе умеет проверять, например, что передан список целых чисел, а не произвольных значений:

from typing import List

from typeguard import typechecked


@typechecked
def test(x: List[int]) -> int:
    return sum(x)


print(test([1, 2, 3, "A"]))  # TypeError: type of argument "x"[3] must be int; got str instead

Похожая библиотека: strongtyping, работает похожим образом (правда, не умеет проверять тип возвращаемого значения):

from strongtyping.strong_typing import match_typing


@match_typing
def test(x: int) -> int:
    return x


print(test("abcd"))
# Incorrect parameter: [x] `'abcd'`
#         required: <class 'int'>
from strongtyping.strong_typing import match_typing
from typing import List

@match_typing
def test(x: List[int]) -> int:
    return sum(x)

print(test([1, 2, 3, "A"]))
# Incorrect parameter: [x] `[1, 2, 3, 'A']`
#         required: typing.List[int]



Report Page