Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print the type annotations of a function in Python?

So let's say I defined the following function with type annotations:

from typing import List
def my_function(input_1: str, input_2: int) -> List[int]:
    pass

Is there a way to show the annotated types of this function? Maybe a function types_of or something similar? So that it can be used like this:

>> types_of(my_function)
[str, int] -> [List[int]]
like image 994
winklerrr Avatar asked Jul 19 '19 09:07

winklerrr


1 Answers

You can use __annotations__

from typing import List
def my_function(input_1: str, input_2: int) -> List[int]:
    pass


In [2]: my_function.__annotations__
Out[2]: {'input_1': str, 'input_2': int, 'return': typing.List[int]}

Or you can use get_type_hints function from typing module. Actually I think this is more appropriate solution.

According to the docs get_type_hints returns a dictionary containing type hints for a function, method, module or class object.

Function example:

from typing import get_type_hints, List

def my_function(input_1: str, input_2: int) -> List[int]:
    pass

In [2]: get_type_hints(my_function)
Out[2]: {'input_1': str, 'input_2': int, 'return': typing.List[int]}

Class example:

For a classes get_type_hints returns a dictionary constructed by merging all the __annotations__ along Foo.__mro__ in reverse order.

class Bar:
    BAR_C: bool = True

class Foo(Bar):
    FOO_STR: str = 'foo'
    FOO_INT: int = 42

    def __init__(a: str, b: int) -> None:
        self._a = a
        self._b = b

    def some_method(self, foo: List, bar: bool) -> bool:
        pass

In [7]: get_type_hints(Foo)
Out[7]: {'BAR_C': bool, 'FOO_STR': str, 'FOO_INT': int}

Out[8]: get_type_hints(Foo.__init__)
Out[8]: {'a': str, 'b': int, 'return': NoneType}

In [9]: get_type_hints(Foo.some_method)
Out[9]: {'foo': typing.List, 'bar': bool, 'return': bool}

Module example

Our module test_module.py

from typing import Dict

SOME_CONSTANT: Dict[str, str] = {
    '1': 1,
    '2': 2
}


class A:
    b: str = 'b'
    c: int = 'c'


def main() -> None:
    pass

if __name__ == '__main__':
    main()

Then let's open python shell:

In [1]: from typing import get_type_hints
In [2]: import test_module

In [3]: get_type_hints(test_module)
Out[3]: {'SOME_CONSTANT': typing.Dict[str, str]}

In [4]: get_type_hints(test_module.A)
Out[4]: {'b': str, 'c': int}

In [5]: get_type_hints(test_module.main)
Out[5]: {'return': NoneType}
like image 197
Jonhy Beebop Avatar answered Nov 05 '22 14:11

Jonhy Beebop