Reputation: 4047
I have a function that requires parameter to be both Sized and Iterable at the same time.
def foo(items):
print(len(items))
for i in item:
print(i)
I thought that I can use standard typing
module from python3.5+ and write this:
from typing import Collection, Any
def foo(items: Collection[Any]):
print(len(items))
for i in item:
print(i)
foo([1, 2, 3])
# PyCharm warns: Expected type 'Collection', got 'List[int]' instead.
Collection looks like what I need: class typing.Collection(Sized, Iterable[T_co], Container[T_co])
Why it causes warning?
What should i do to hint parameter as both Iterable and Sized?
Upvotes: 2
Views: 586
Reputation: 5876
A dirty fix to make Python 3.5 happy is to use Union[Sized, Iterable[Any]]
.
It is dirty, because using this type annotation says that it should be either sized OR iterable, not sized AND iterable. The current Pycharm (2018.1) accepts this, and it runs.
UPDATE:
I have found a way to use Collections
in Python versions < 3.6.
Before 3.6 Sequence
is basically what Collection
is in 3.6 (See here and here). In 3.6 a Sequence
is basically a reversible Collection
(see here), and this gave me issues, because a python set
is not a sequence (it is not reversible) so I patched it with the following import code:
if sys.version_info >= (3, 6):
from typing import Collection
else:
from typing import Sequence, TypeVar
T = TypeVar('T')
Collection = Sequence[T]
Upvotes: 0
Reputation: 155526
Collection
was only introduced in 3.6; odds are, your version of PyCharm doesn't recognize it yet.
There is no built-in that describes a sized, iterable container in 3.5, so you can't use this annotation in 3.5, at least, not without writing your own typing
type, which PyCharm may or may not recognize.
Upvotes: 4