In Python 3.5 or above, type hints are supported (see here for more information). However, the proper usage for common types are not well documented.
For instance, from the official site, I could gather the following (proper) usages:
String
# The function signature of greeting is: Callable[[str], str]
def greeting(name: str) -> str:
return 'Hello ' + name
Integer
# The function signature of add is: Callable[[int, int], int]
def add(a: int, b: int) -> int:
return a + b
Floating Point Number
# The default value of x is 1.0
def reciprocal(x: float = 1.0) -> float:
from math import nan
if x == 0:
return nan
return 1 / x
List
from typing import List, TypeVar
T = TypeVar('T')
def repeat(x: T, n: int) -> List[T]:
return [x] * n
Tuple
from typing import Tuple, TypeVar
T = TypeVar('T')
def double(x: T) -> Tuple[T, T]:
return (x, x)
My questions are:
1. What is the return type of map
?
from typing import Iterable
# Is this correct?
x: Iterable[float] = map(int.__float__, [1, 2, 3])
I am not sure if this is the correct type hint for x
above.
2. In a broader sense, what is the 'function signature' of map
?
from typing import Callable, Iterable, TypeVar
T = TypeVar('T')
U = TypeVar('U')
# In the above usage, the type of the map function seems to be:
Function1 = Callable[[T], U]
typeOfMap = Callable[[Function1, Iterable[T]], Iterable[U]]
# Or in one line:
typeOfMap = Callable[[Callable[[T], U], Iterable[T]], Iterable[U]]
But in fact, the map function can accept multiple iterables. It is documented as:
map(function, iterable, ...)
It could be used like this:
# The result is: [['A'], ['B', 'B'], ['C', 'C', 'C']]
result = list(map(repeat, ['A', 'B', 'C'], [1, 2, 3]))
T1 = TypeVar('T1')
T2 = TypeVar('T2')
R = TypeVar('R')
# So, the type of map function in this usage seems to be:
Function2 = Callable[[T1, T2], R]
typeOfMap = Callable[[Function2, Iterable[T1], Iterable[T2]], Iterable[R]]
In general, I guess it should be something like below, but this is not the correct way to write it:
FunctionN = Callable[[T1, T2, ..., Tn], R]
typeOfMap = Callable[[FunctionN, Iterable[T1], Iterable[T2], ..., Iterable[Tn]], Iterable[R]]
So, what is the correct way to write it?
3. In general, where can I find the correct type hint of a Python function / method, including the built-in ones, those in the core libraries?
I need them mainly for learning purpose.
4. Is there any way to output the type inference result computed by the compiler / interpreter, as in Haskell or Erlang?
I know Haskell and Erlang are functional programming languages and variables are immutable, so it would be much easier to make this possible, but just in case if Python also has similar functionalities, I would like to know.
5. Is there any way to check that my type hint is correct?
Or at least let it show me some warning / error at compile time / runtime so that I am aware that something is wrong.
At the time of this writing, the latest stable version is 3.8.0.
From the Python typing documentation, you may use typing. get_type_hints() . Return a dictionary containing type hints for a function, method, module or class object. This is often the same as obj.
In a type hint, if we specify a type (class), then we mark the variable as containing an instance of that type. To specify that a variable instead contains a type, we need to use type[Cls] (or the old syntax typing. Type ).
typing.Mapping is an object which defines the __getitem__,__len__,__iter__ magic methods. typing. MutableMapping is an object which defines same as Mapping but with __setitem__,__delitem__ magic methods as well. typing.Mapping et al. are based on the abc types in this table.
Python's type hints provide you with optional static typing to leverage the best of both static and dynamic typing. Besides the str type, you can use other built-in types such as int , float , bool , and bytes for type hintings. To check the syntax for type hints, you need to use a static type checker tool.
This can be achieved in two ways – We can get function Signature with the help of signature () Function. It takes callable as a parameter and returns the annotation. It raises a value Error if no signature is provided. If the Invalid type object is given then it throws a Type Error. To do this the functions in Python certain attributes.
Type hints are available for all the packages in the Python standard library. However, if you are using third-party packages you’ve already seen that the situation can be different. The following example uses the Parse package to do simple text parsing. To follow along you should first install Parse: Parse can be used to recognize simple patterns.
For that purpose, use the typing.Callable type (see here ): 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 Show activity on this post.
The __code__ attributes also have certain attributes that will help us in performing our tasks. We will be using the co_varnames attribute that returns the tuple of names of arguments and local variables and co_argcount that returns the number of arguments (not including keyword-only arguments, * or ** args).
1. What is the return type of
map
?
map
’s return value is currently typed as an Iterator[T]
. Since iterators are iterables, your annotation of x: Iterable[float] = map(int.__float__, [1, 2, 3])
is valid. (Also, just write map(float, [1, 2, 3])
.)
2. In a broader sense, what is the 'function signature' of map?
It’s currently impossible to represent, which is why typeshed has overloads for up to 6 generic parameters. (one related issue)
3. In general, where can I find the correct type hint of a Python function / method, including the built-in ones, those in the core libraries?
I need them mainly for learning purpose.
Python’s typeshed repository. Note that for non-learning purposes – practice – you should generally either let the type be inferred or use whatever type makes sense rather than the most exact type possible.
You can also use reveal_type
– see below.
4. Is there any way to output the type inference result computed by the compiler / interpreter, as in Haskell or Erlang?
I know Haskell and Erlang are functional programming languages and variables are immutable, so it would be much easier to make this possible, but just in case if Python also has similar functionalities, I would like to know.
This is up to your typechecker. Mypy has reveal_type
.
x = map(float, [1, 2, 3])
reveal_type(x) # note: Revealed type is 'typing.Iterator[builtins.float*]'
5. Is there any way to check that my type hint is correct?
Or at least let it show me some warning / error at compile time / runtime so that I am aware that something is wrong.
Statically, that’s what typechecking is. (For example, Mypy would have told you if your x
hint were wrong.) It can’t catch everything, especially in a language as dynamic as Python, but that’s the nature of programming.
There are a few projects that do some level of runtime assertions based on type annotations, but none I’ve used or would really bother with.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With