Skip to content

Optional key to itertools.groupby #2788

Closed

Description

@achampion

Redirect from: python/mypy#6377

itertools.groupby has an @overload type signature but this seems makes Optional[Callable[[T], S]] not match, e.g.:

def fn(iterable: Iterable[T], key: Optional[Callable[[T], S]] = None):
    iterator: Iterator[Tuple[S, Iterator[T]]] = itertools.groupby(iterable, key)
    ...

Fails with:

error: Argument 2 to "groupby" has incompatible type "Optional[Callable[[T], S]]"; expected "Callable[[T], S]"

The revealed type of itertools.groupby:

Overload(def [_T] (iterable: typing.Iterable[_T`-1]) -> typing.Iterator[Tuple[_T`-1, typing.Iterator[_T`-1]]], def [_T, _S] (iterable: typing.Iterable[_T`-1], key: def (_T`-1) -> _S`-2) -> typing.Iterator[Tuple[_S`-2, typing.Iterator[_T`-1]]])

It is legitimate to explicitly pass None as key, so is this expected behaviour?
You can do a similar @overload for myfunc to overcome the error.

If you use if key is not None: the problem becomes you can't effectively describe the type of iterator, e.g.:

iterator: Iterator[Tuple[S, Iterator[T]]]
if key is not None:
    iterator = itertools.groupby(iterable, key) # Ok
else:
    iterator = itertools.groupby(iterable)  # Fail

You get the error:

error: Incompatible types in assignment (expression has type "Iterator[Tuple[T, Iterator[T]]]", variable has type "Iterator[Tuple[S, Iterator[T]]]")

And you can't declare the types in each branch because you will get a redeclaration error Name 'iterator' already defined on line ...

Versions:
Python 3.7.2
MyPy 0.670

Activity

  1. srittau commented on Feb 11, 2019

    @srittau
    Collaborator

    It seems that the seconds overload to groupby() is missing an Optional annotation. Patches welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions