'Decoding a python function where what's returned is a Iterator[Tuple] -

Imagine a function with a signature such as this:

def read_something (file_name__path: str) -> Iterator[Tuple[Sequence1, Sequence2]]:

If I am writing the function to basically iterate over a document and return a tuple-type object... Does the Iterator[Tuple[Sequence1, Sequence2]] portion of the line indicate that because I used the Typing modules, the returned item (if properly constructed) will be an iterator consisting of a tuple? Or does that mean that I still must iterate over the document and assign each item that I iterate over into an actual tuple (such as tuple(item, item). In other words, does that Iterator[Tuple[Sequence1, Sequence2]] magically transform something like two lists into the iterator with the lists becoming a tuple? Or is that more for the reader of the function to be familiar with the returned object type?



Solution 1:[1]

  1. -> Do absolutely nothing. It only shows that someone who created the function probably planned to set return value as an Iterator. Also this return type will be used by IDE when popup hint appear.
  2. If you want to check correct typing you may use mypy:
from typing import Iterator, Tuple

def correct_iterator() -> Iterator[Tuple[int, str]]:
  for el in [(1, '1'), (2, '2')]:
    yield el

def correct_tuple() -> Tuple[int, str]:
  return (1, '1')

def bad_iterator() -> Iterator[Tuple[int, str]]:
  # that is line 12 ?
  return (1, '1')
mypy example.py
example.py:12: error: Incompatible return value type (got "Tuple[int, str]", expected "Iterator[Tuple[int, str]]")
example.py:12: note: "tuple" is missing following "Iterator" protocol member:
example.py:12: note:     __next__
Found 1 error in 1 file (checked 1 source file)

As you can see return value for bad_iterator is not Iterator and didn't converted into Iterator. But type error appeared.

Edit: how to check types without mypy

It is able to check returned value type without mypy, but you have to do it outside the defined function:

from typing import Iterator

def the_iterator():
  for el in [1,2,3]:
    yield el

iterator_output = the_iterator()

assert True == isinstance(iterator_output, Iterator)

However it is not able to use generics in this check. isinstance(..., Iterator[int]) will raise error:

TypeError: Subscripted generics cannot be used with class and instance checks

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1