How to Specify Multiple Return Types Using Type-Hints

How to specify multiple return types using type-hints

From the documentation

class typing.Union

Union type; Union[X, Y] means either X or Y.

Hence the proper way to represent more than one return data type is

from typing import Union

def foo(client_id: str) -> Union[list,bool]

But do note that typing is not enforced. Python continues to remain a dynamically-typed language. The annotation syntax has been developed to help during the development of the code prior to being released into production. As PEP 484 states, "no type checking happens at runtime."

>>> def foo(a:str) -> list:
... return("Works")
...
>>> foo(1)
'Works'

As you can see I am passing a int value and returning a str. However the __annotations__ will be set to the respective values.

>>> foo.__annotations__ 
{'return': <class 'list'>, 'a': <class 'str'>}

Please Go through PEP 483 for more about Type hints. Also see What are type hints in Python 3.5??

Kindly note that this is available only for Python 3.5 and upwards. This is mentioned clearly in PEP 484.


From Python 3.10 onwards, there is a new way to represent this union. See Union Type:

A union object holds the value of the | (bitwise or) operation on multiple type objects. These types are intended primarily for type annotations. The union type expression enables cleaner type hinting syntax compared to typing.Union.

As we can see, this is exactly the same as typing.Union in the previous versions. Our previous example can be modified to use this notation:

def foo(client_id: str) -> list | bool:

Correct type hint for multiple return values

You want to use typing.Union to indicate that the function can return either one type of thing or another. For example, if you had a function that could either return an int or a str, then it's return type would be Union[int, str].

So,

def foo(a: int, b: int, flag: bool) -> Union[int, Tuple[int, int]]:

If you're using Python 3.10, there's a better way to write a union: int | Tuple[int, int]

However, I should repeat the warning given in the comments. Having such a return type is an antipattern and you should refactor your code to avoid this.

How to annotate types of multiple return values?

You are always returning one object; using return one, two simply returns a tuple.

So yes, -> Tuple[bool, str] is entirely correct.

Only the Tuple type lets you specify a fixed number of elements, each with a distinct type. You really should be returning a tuple, always, if your function produces a fixed number of return values, especially when those values are specific, distinct types.

Other sequence types are expected to have one type specification for a variable number of elements, so typing.Sequence is not suitable here. Also see What's the difference between lists and tuples?

Tuples are heterogeneous data structures (i.e., their entries have different meanings), while lists are homogeneous sequences. Tuples have structure, lists have order.

Python's type hint system adheres to that philosophy, there is currently no syntax to specify an iterable of fixed length and containing specific types at specific positions.

If you must specify that any iterable will do, then the best you can do is:

-> Iterable[Union[bool, str]]

at which point the caller can expect booleans and strings in any order, and of unknown length (anywhere between 0 and infinity).

Last but not least, as of Python 3.9, you can use

-> tuple[bool, str]

instead of -> Tuple[bool, str]; support for type hinting notation has been added to most standard-library container types (see PEP 585 for the complete list). In fact, you can use this as of Python 3.7 too provided you use the from __future__ import annotations compiler switch for your modules and a type checker that supports the syntax.

Is there a way to make a type hint for multiple returns

From Python 3.5 to 3.8 you want Tuple[dict, int] in order to specify that you will return both as Python will return them as a tuple.

from typing import Tuple

def rework_data(measurement: dict) -> Tuple[dict, int]:
...
return measurement, 0

As of Python 3.9 Tuple is deprecated and you should use the builtin type

def rework_data(measurement: dict) -> tuple[dict, int]:
...
return measurement, 0

Python multiple return type hints best practice

Ok so after a bit of reading I figured out what I think is the best way to handle this:

changed get_config method to below;

    def __init__(self) -> None:
self._service: LocalService = LocalService()
self._config: ConfigModel = self._service.load_json(PATH, DEFAULT_CONFIG)

def get_config(self) -> ConfigModel:
return self._config

I then used typing.TypedDict to add type hints to the entire structure of my config file;

from typing import TypedDict

class CategoryModel(TypedDict, total=False):
# All
enabled: bool
prefix: str | None
# Generics
allowed_ids: list[str]
method: str
enable_prefix: bool
suffix: str | None
# Ratings
absolute_buckets: list[int]
min_votes_required: int
not_enough_votes_treatment: str
relative_count: int
weight_ratings_by_votes: bool

class CategorisationSettingsModel(TypedDict):
perspectives: CategoryModel
ratings: CategoryModel
release_date: CategoryModel
themes: CategoryModel

class SearchSettingsModel(TypedDict):
fallback_to_name_search: bool
filter_words: list[str]
refresh_cache_days: int

class PlatformParsingSettingsModel(TypedDict):
enabled: bool
prefix: str | None
platform_map: dict[str, list[int]] | None

class ConfigModel(TypedDict):
api_auth: dict[str, str]
categorisation_settings: CategorisationSettingsModel
search_settings: SearchSettingsModel
platform_parsing: PlatformParsingSettingsModel
overrides: dict[str, str]

How to specify multiple returns with type hinting?

How about you return a tuple like return (df, dataset) and then set the type hinting to tuple. This should solve your problem. If I am not wrong then performing return df, dataset actually returns a tuple. You can check that by printing the type of the values returned.

Hope this helps :)

How do I specify multiple types for a parameter using type-hints?

You want a type union:

from typing import Union

def post_xml(data: Union[str, ET.Element]):
...

Python type hints for function returning multiple return values

EDIT: Since Python 3.9 and the acceptance of PEP 585, you should use the built-in tuple class to typehint tuples.

You can use a typing.Tuple type hint (to specify the type of the content of the tuple, if it is not necessary, the built-in class tuple can be used instead):

from typing import Tuple

def greeting(name: str) -> Tuple[str, List[float], int]:
# do something
return a, b, c


Related Topics



Leave a reply



Submit