Is built-in function iter only partially implemented?

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
snake77
Posts: 31
Joined: Thu Jun 24, 2021 11:26 pm

Is built-in function iter only partially implemented?

Post by snake77 » Sun Oct 17, 2021 12:41 pm

Code: Select all

Python 3.9.2 (default, Feb 28 2021, 17:03:44) 
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> iter(int, 1)
<callable_iterator object at 0x7f2623b7c100>
>>> 
vs.

Code: Select all

MicroPython v1.17-80-g4c9e17e0a-dirty on 2021-10-14; linux version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>> iter(int, 1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: function takes 1 positional arguments but 2 were given
>>> 

User avatar
mattyt
Posts: 410
Joined: Mon Jan 23, 2017 6:39 am

Re: Is built-in function iter only partially implemented?

Post by mattyt » Mon Oct 18, 2021 1:08 am

That's correct, the sentinel is not implemented. (The note mentioned next but it's the same reasoning for iter.)

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Is built-in function iter only partially implemented?

Post by stijn » Mon Oct 18, 2021 6:06 am

Second argument for next is implemented in the code depending on compilation flags though, which isn't the case for iter

snake77
Posts: 31
Joined: Thu Jun 24, 2021 11:26 pm

Re: Is built-in function iter only partially implemented?

Post by snake77 » Mon Oct 18, 2021 9:54 pm

Well, for the second argument for next there is a very easy obvious workaround with try ... except StopIteration. Am I overlooking the easy workaround for the missing second argument of iter?

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Is built-in function iter only partially implemented?

Post by stijn » Tue Oct 19, 2021 6:47 am

The 2-argument version does something completely different so indeed no easy workaround. I think it should be possible to implement it yourself, then override the built-in iter to call your version insead.

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Is built-in function iter only partially implemented?

Post by stijn » Tue Oct 19, 2021 7:39 am

I got curious so here's the (briefly tested) exercise:

Code: Select all

import builtins

class IterateCallable:
    def __init__(self, func, sentinel):
        self.func = func
        self.sentinel = sentinel

    def __iter__(self):
        return self

    def __next__(self):
        if (r := self.func()) == self.sentinel:
            raise StopIteration
        return r

orig_iter = builtins.iter

def iter2(obj, *args):
    if not args:
        return orig_iter(obj)
    return IterateCallable(obj, *args)

builtins.iter = iter2

def GetFunc():
    i = 0
    def Func():
        nonlocal i
        i += 1
        return i
    return Func

for p in iter([1, 2]):
    print(p)

for p in iter(GetFunc(), 3):
    print(p)

User avatar
mattyt
Posts: 410
Joined: Mon Jan 23, 2017 6:39 am

Re: Is built-in function iter only partially implemented?

Post by mattyt » Wed Oct 20, 2021 1:14 am

Sorry, there's much better information in issue #5384 (I wasn't aware of this ticket when I first responded).

The summary is that yes, it's not implemented. The two argument form isn't so common and there is a work-around (documented in the issue) so I guess it seemed like a reasonable candidate to omit.

It could be added if there's a strong enough case to do so, though it will probably need to be hidden behind a compile-time option (like next) to reduce the impact on micros with fewer resources.

Please comment in the issue if you have strong opinions!

Post Reply