Search code examples
pythondictionarypycharmenumerate

Why does passing an enumerate function result to the dict constructor yield a type warning?


Consider these two dict declarations:

some_data = [4, 5, 6]
d1 = dict(enumerate(some_data))
d2 = dict((x, y) for x, y in enumerate(some_data))

The return value of enumerate() is an enumerate object, which I understand to be like a generator (if it isn't in fact an actual generator) which yields tuples of int and whatever the type of the elements of the iterable passed into enumerate() is.

So, d1 and d2 will end up with the same value after the above code and I would say the d2 declaration is needlessly setting up another generator, pulling data from the enumerate() function result and yielding it without modification.

However, IDEs like PyCharm will generate a warning for the declaration of d1:

"Unexpected type(s): (enumerate[int]) Possible types: (Mapping) (Iterable[Tuple[Any, Any]])
Inspection info: This inspection detects type errors in function call expressions. Due to dynamic dispatch and duck typing, this is possible in a limited but useful number of cases. Types of function parameters can be specified in docstrings or in Python 3 function annotations."

Why is this? Is this an oversight in the definition of enumerate(), which actually is an Iterable[Tuple[Any, Any]] of sorts? After all it yields tuples of [int, Any] and it's just as iterable as the one created by a call of a generator?

Or am I missing some possible construction where the result of enumerate() cannot be dealt with by the dict((Iterable)) constructor?


Solution

  • It is a known bug, please vote for https://youtrack.jetbrains.com/issue/PY-35037 (thumbs up near the title)