Python 3 type hints for function signature

13,272

Solution 1

For that purpose, use the typing.Callable type (see here):

from typing import Callable

def takes_two(f: Callable[[int, int], int]) -> int:
    return f(123, 456)

The first argument to Callable is a list of types for the arguments of the function, while the second argument is the return type.

Of course, python itself does not check types at all. For this, you should use additional tools such as mypy

Solution 2

Short answer: there is no built-in way to enforce type declaration and checking.

As the name suggests, these are type hints, which can help the programmer know what is passed as arguments and what is returned from functions (this can be specially useful when reading/reviewing large code files). However, as can be seen here in this post from Guido, Jukka and Lukasz:

It should also be emphasized that Python will remain a dynamically typed language, and the authors have no desire to ever make type hints mandatory, even by convention.

So if you expect statically-typed arguments which would raise errors if passed objects do not have the required type, then you should not be using python in the first place.

However, you may have some options: e.g. IDEs, like pycharm or Atom, have plug-ins that will check types for you.


However, if your point is to just have a type hint for callable with no enforcing, error-raising or automatic checking, then check @dseuss' answer :)

Share:
13,272
patmanpato
Author by

patmanpato

Updated on June 17, 2022

Comments

  • patmanpato
    patmanpato about 2 years

    Is there a way to declare the signature of a function object with Python (3.5+) type hints? Specifically, is there a way to declare what type of function object a function can accept or a variable can reference.

    I'm sure it could get quite messy (as it can with C++11 lambda types for example), but is there at least some way to check function types?

    For example:

    def func1(x: int) -> int:
        return x
    
    def func2(x: int, y: int) -> int:
        return x + y
    
    # 'TwoArgFn' is a 'function type' that accepts two ints and returns an int
    def takes_two(f: TwoArgFn) -> int:
        return f(123, 456)
    

    Passing func1 as an argument to takes_two should be an error, whereas passing func2 is fine.

  • patmanpato
    patmanpato almost 6 years
    Thanks, good point. I should have clarified I was just after hinting for tools like mypy, not actual run-time type checking too. I've saved tens of hours of debugging already thanks to type hints however.