Skip to content
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

Two argument form of iter() is not implemented. #5384

Open
hardkrash opened this issue Dec 5, 2019 · 6 comments
Open

Two argument form of iter() is not implemented. #5384

hardkrash opened this issue Dec 5, 2019 · 6 comments

Comments

@hardkrash
Copy link

The builtin iter(callable, sentinel) from pep 234 is not implemented.

The use case is something like this.

with open('file.bin', 'rb') as f:
    for chunk in iter(lambda: f.read(128), b''):
        process_chunk(chunk)

The two parameter form allows an easy way to make a callable into an iterable by using a sentinel.

It allows for replacing the do while workarounds with a simple iterator.

with open('file.bin', 'rb') as f:
    chunk = f.read(128)
    while chunk != b'':
        process_chunk(chunk)
        chunk = f.read(128)

Credit to this stack overflow answer from jfs
https://stackoverflow.com/a/20014805

@mikewadsten
Copy link
Contributor

Sort of related to #4400.

@dpgeorge
Copy link
Member

dpgeorge commented Dec 6, 2019

Yes, this is simply not implemented, mainly because the same thing can be achieved in pure Python. As a workaround the following can be used:

def iter2(c, s):
    while True:
        v = c()
        if v == s:
            raise StopIteration
        yield v

(This would be simpler with the walrus operator!)

@hardkrash
Copy link
Author

While I agree on the fact that this can be worked around in many ways. it is unfortunate that this is not explicitly called out in the documentation as a difference from python's core syntax.

This would be a compatibility wrapper needed to make the two argument form of iter work without changing source code.

from compat import iter

Where compat.py has something like this.

S = some_singleton
_orig_iter = iter
def _compat_iter(c, s=S):
    if s is S:
        for x in _orig_iter(c):
            yield x
    else:
        while True:
            v = c()
            if v == s:
                raise StopIteration
            yield v

iter = _compat_iter

Would adding 2 argument form to the builtin iter function be an acceptable patch?

@dpgeorge
Copy link
Member

it is unfortunate that this is not explicitly called out in the documentation as a difference from python's core syntax.

It's not really a syntax difference, rather the fact that MicroPython implements a subset of the Python builtins. It could be added to the docs via tests/cpydiff (which automatically generates differences for the docs).

Would adding 2 argument form to the builtin iter function be an acceptable patch?

Implemented in C I think it'd be a large patch and therefore unlikely to be made part of default MicroPython builds. It could be made optional like the 2-arg form of next(), but I'm just not sure how generally useful it would be (it hasn't been requested so far).

@dpgeorge
Copy link
Member

This would be a good candidate for #5025.

@hex007
Copy link

hex007 commented Apr 19, 2023

Found this not implemented the hard way. next called with two params can just throw Not implemented exception would be much easier to understand than

TypeError: function takes 1 positional arguments but 2 were given

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

No branches or pull requests

4 participants