Skip to content

Make 2-arg iter() return type match passed callable's return type #3326

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 9, 2019
Merged

Make 2-arg iter() return type match passed callable's return type #3326

merged 1 commit into from
Oct 9, 2019

Conversation

wbolster
Copy link
Contributor

@wbolster wbolster commented Oct 8, 2019

This is a continuation of #3291, which was the initial fix for #3201.

The 2-arg version of iter() turns a callable into an iterator. The
changes made in #3291 introduce an Any return type for both the
callable's return type and the iterator's type, while in reality the
return type of the function is always the same as the iterator's type.

This is a continuation of #3291, which was the initial fix for #3201.

The 2-arg version of iter() turns a callable into an iterator. The
changes made in #3291 introduce an Any return type for both the
callable's return type and the iterator's type, while in reality the
return type of the function is always the same as the iterator's type.
@wbolster
Copy link
Contributor Author

wbolster commented Oct 8, 2019

ping @srittau @utkarsh2102 who worked on and reviewed #3201/#3291.

@wbolster
Copy link
Contributor Author

wbolster commented Oct 8, 2019

example:

def a() -> Union[str, int]:
    return ""


n: Union[str, int] = 1

reveal_type(iter(a, n))
# Revealed type is 'typing.Iterator[Union[builtins.str, builtins.int]]' (python-mypy)

reveal_type(iter(a, 1))
# Revealed type is 'typing.Iterator[Union[builtins.str, builtins.int]]' (python-mypy)

reveal_type(iter(a, "foo"))
# Revealed type is 'typing.Iterator[Union[builtins.str, builtins.int]]' (python-mypy)

reveal_type(iter(a, b"foo"))
# Revealed type is 'typing.Iterator[Union[builtins.str, builtins.int]]' (python-mypy)


def b() -> Optional[str]:
    return ""


reveal_type(iter(b, None))
# Revealed type is 'typing.Iterator[builtins.str*]' (python-mypy)

the only thing that seems ‘not strict enough’ seems the example above that passes a bytestring as a sentinel, which doesn't necessarily make sense since the function will never return a bytestring. however, the sentinel may still compare equal (2-arg iter() does equality comparisons) to the values returned by the callable (which is invoked repeatedly), so Any actually seems the correct type to use here.

@wbolster wbolster changed the title Make 2-arg iter() retrun type match passed callable's return type Make 2-arg iter() return type match passed callable's return type Oct 8, 2019
Copy link
Collaborator

@srittau srittau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks fine. I was wrong in my comment #3291 about needing Any.

@srittau srittau merged commit 824e94a into python:master Oct 9, 2019
@wbolster
Copy link
Contributor Author

wbolster commented Oct 9, 2019

thanks for the quick review, @srittau!

as you can see, it took me some experiments to figure out the right approach. 🤯 i wasted some time trying to get rid of the Any sentinel... until i realised it is actually the right type (since the only relation it has to the other types is that it needs to support __eq__()) 🤦‍♀️

@wbolster wbolster deleted the 2-arg-iter-return-type branch October 9, 2019 07:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants