I would like to get your advice on the most pythonic way to express the following function in python with type hints:
I'd like to expose a function as part of a library that accepts an input argument and returns an output. The contract for the input argument should be that:
- my function can iterate over it
- it's ok if my function maintains a reference to the input (e.g. by returning an object that keeps that reference)
- it's ok to iterate over the input more than once
An example could be a function that accepts a sequence of URLs and then issues requests to these URLs, potentially with some retry logic so I'd have to iterate the original sequence more than once. But my question is more generic than just this sample.
At first glance a suitable signature would be:
from typing import Iterable
def do_sth(input: Iterable[str]) -> SomeResult:
...
However this violates the third requirement, because in python there is no guarantee that you can iterate over an Iterable more than once, e.g. because iterators and generators are themselves iterables.
Another attempt might be:
from typing import Sequence
def do_sth(input: Sequence[str]) -> SomeResult:
...
But then the Sequence
contract is more than my function requires, because it includes indexed access and also the knowledge of the length.
A solution that came to my mind is to use the Iterable
signature and then make a copy of the input internally. But this seems to introduce a potential memory problem if the source sequence is large.
Is there a solution to this, i.e. does python know about the concept of an Iterable
that would return a new iterator each time?