15

My function foo accepts an argument things which is turned into a list internally.

def foo(things):
    things = list(things)
    # more code

The list constructor accepts any iterable.

However, annotating things with typing.Iterable does not give the user a clue that the iterable must be finite, not something like itertools.count().

What's the correct type hint to use in this case?

Giorgos Myrianthous
  • 36,235
  • 20
  • 134
  • 156
actual_panda
  • 1,178
  • 9
  • 27
  • 2
    That's not something you can express in a type hint. (How would such a hint even be checked? mypy can't solve the halting problem to figure out whether a generator is finite.) – user2357112 Apr 11 '20 at 10:39
  • 2
    @user2357112supportsMonica I'm more concerned about good documentation than static type checking. How would you let the user know what `things` can be? In the docstring? – actual_panda Apr 11 '20 at 10:41
  • I think the answer may be given here: https://stackoverflow.com/questions/49427944/typehints-for-sized-iterable-in-python . There is also mention of the 'new type called Collection' (as given in the answer to your question from @Giorgos) – Lydia van Dyke Apr 11 '20 at 10:42
  • 3
    @actual_panda: Documentation goes in the documentation. Type hints are not intended to specify all possible restrictions on allowed argument values; "finite iterable", "positive integer", "uppercase string", etc. are all not hintable. – user2357112 Apr 11 '20 at 10:45
  • 3
    @user2357112supportsMonica I get your point but I don't think your examples are good. I can write an `UnsignedInteger` class or an `UppercaseString` class and hint it, but I can't write `FiniteIterable`. – actual_panda Apr 11 '20 at 10:56

1 Answers1

17

I am not aware of any possible way to achieve this in Python as you cannot provide such constraints in type hints.


However, probably the Collection type might be useful in your context as a workaround:

class collections.abc.Collection

ABC for sized iterable container classes.

This requires objects to have a __len__, which is a more strict requirement than being finite. For example, finite generators don't count as Collection.

Giorgos Myrianthous
  • 36,235
  • 20
  • 134
  • 156