Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type hint for a function that returns only a specific set of values

I have a function that can only return a, b or c, all of them are of type T. I want to include this fact in the signature because of the special meaning they carry in the context of the function. How do I do that?

Currently, I use this

def fun(...) -> "a or b or c":     #briefly explain the meaning of a, b and c in its docstring 

Is that the correct one?

I know that I can do this

def fun(...) -> T:     # briefly explain the meaning of a, b and c in its docstring 

but as I said, I want to express in the signature that the function only returns those specific values.

like image 552
Copperfield Avatar asked Sep 08 '16 18:09

Copperfield


People also ask

What are type hints in Python?

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.

What is the use of type () function in Python?

Python has a lot of built-in functions. The type() function is used to get the type of an object. When a single argument is passed to the type() function, it returns the type of the object. Its value is the same as the object.

What is union type in Python?

Union type; Union[X, Y] is equivalent to X | Y and means either X or Y. To define a union, use e.g. Union[int, str] or the shorthand int | str . Using that shorthand is recommended.

What does Optional mean in Python?

A Python optional argument is an argument with a default value. You can specify a default value for an argument using the assignment operator. There is no need to specify a value for an optional argument when you call a function. This is because the default value will be used if one is not specified.


2 Answers

You can do that with literal types.

from typing_extensions import Literal # from typing import Literal  # Python 3.8 or higher  def fun(b: int) -> Literal["a", "b", "c"]:     if b == 0:         return "a"     if b == 1:         return "b"     return "d" 

mypy is able to detect the return "d" as a invalid statement:

error: Incompatible return value type (got "Literal['d']", expected "Union[Literal['a'], Literal['b'], Literal['c']]") 

Python 3.8

Thanks to the PEP 586, the Literal is already included by default in the Python 3.8 typing module.

like image 174
Cesar Canassa Avatar answered Sep 21 '22 05:09

Cesar Canassa


You can't specify that your function returns only a subset of a type's values using type hinting alone. As the name implies, type hinting is all about types not values.

However, you can create a new enum.Enum subtype that only has the values you're going to return and use it in the function. Then you can type hint that you're returning the enum type.

import enum  class cmp_results(enum.IntEnum):     less = -1     equal = 0     greater = 1  def my_cmp_function(x, y) -> cmp_results:     if x < y: return cmp_results.less     elif x == y: return cmp_results.equal     else: return cmp_results.greater 

This may be overkill. Just hinting int as the return type (and documenting the specific values) is probably good enough.

like image 35
Blckknght Avatar answered Sep 17 '22 05:09

Blckknght