[SOLVED] TypeError: iter() returned non-iterator of type 'RevertableList'

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
Tess
Newbie
Posts: 23
Joined: Thu Aug 04, 2022 3:43 pm
Projects: The Songbird Guild
Organization: Yurisoft
Github: wainwt2
Discord: Tess#7782
Contact:

[SOLVED] TypeError: iter() returned non-iterator of type 'RevertableList'

#1 Post by Tess » Thu Oct 27, 2022 8:37 pm

I'm trying to make a class that can be iterated over like a list, but I'm not sure how to properly implement __iter__ and __next__.

Code: Select all

class Party():
        """A group of units that fight on the same team, either friend or foe."""

        def __init__(self,*units):
            """Takes Unit instances and makes a list of them in the team variable"""
            self.team = units if isinstance(units,list) else [units]
            self.index = 0
        
        def __call__(self):
            """Lets instances of this class be called directly to get the list of party members"""
            return self.team

        def __iter__(self):
            """Makes this class iterable"""
            return self.team

        def __next__(self):
            """Handles how the iterator moves through the class's party members"""
            if self.index >= len(self.team):
                raise StopIteration
            else:
                self.index += 1
                return self.team[index-1]

        ###Class continues###
However, when I try to run it, I get the error message in the title.

From my understanding, RevertableList is a special Ren'Py list that works with rollback, but still has the properties of a normal list. If that's the case though, I'm not sure why python wouldn't see it as an iterable.
Last edited by Tess on Fri Oct 28, 2022 8:14 pm, edited 2 times in total.

User avatar
_ticlock_
Veteran
Posts: 391
Joined: Mon Oct 26, 2020 5:41 pm
Contact:

Re: TypeError: iter() returned non-iterator of type 'RevertableList'

#2 Post by _ticlock_ » Thu Oct 27, 2022 11:57 pm

Tess wrote:
Thu Oct 27, 2022 8:37 pm
I'm trying to make a class that can be iterated over like a list, but I'm not sure how to properly implement __iter__ and __next__.
However, when I try to run it, I get the error message in the title.

From my understanding, RevertableList is a special Ren'Py list that works with rollback, but still has the properties of a normal list. If that's the case though, I'm not sure why python wouldn't see it as an iterable.
You need to return self:

Code: Select all

        def __iter__(self):
            return self
Same for __call__ method

These lines are likely wrong

Code: Select all

 def __init__(self,*units):
         self.team = units if isinstance(units,list) else [units]
1) You either don't use *unit but unit.

Code: Select all

 def __init__(self,units):
         self.team = units if isinstance(units,list) else [units]

Code: Select all

$ party_1 = Party(unit)
$ party_2 = Party([unit,unit])
2) Or other logic

Code: Select all

 def __init__(self,*units):
         self.team = [unit for unit in units]

Code: Select all

$ party_1 = Party(unit)
$ party_2 = Party(unit,unit)

Warning: Note that renpy can't save iterator objects.

User avatar
Tess
Newbie
Posts: 23
Joined: Thu Aug 04, 2022 3:43 pm
Projects: The Songbird Guild
Organization: Yurisoft
Github: wainwt2
Discord: Tess#7782
Contact:

Re: TypeError: iter() returned non-iterator of type 'RevertableList'

#3 Post by Tess » Fri Oct 28, 2022 11:35 am

I've been a bit confused on what *args actually creates. Using

Code: Select all

[unit for unit in units]
is working great so far though!

However, when I change __iter__ and __call__ to return self rather than self.team, the error updates to "iter() returned non-iterator type Party"

User avatar
_ticlock_
Veteran
Posts: 391
Joined: Mon Oct 26, 2020 5:41 pm
Contact:

Re: TypeError: iter() returned non-iterator of type 'RevertableList'

#4 Post by _ticlock_ » Fri Oct 28, 2022 4:18 pm

Tess wrote:
Fri Oct 28, 2022 11:35 am
However, when I change __iter__ and __call__ to return self rather than self.team, the error updates to "iter() returned non-iterator type Party"
1) Not sure why. It seems like it does not see the __next__ method in the class Party. Check the indentation.

Works for this little test:

Code: Select all

init python:
    class Party():
        def __init__(self,*units):
            self.team = [unit for unit in units]
            self.index = 0
        def __iter__(self):
            self.index = 0
            return self
        def __next__(self):
            if self.index >= len(self.team):
                raise StopIteration
            else:
                self.index += 1
                return self.team[self.index-1]

screen party_menu:
    vbox:
        for i in myclass:
            add i
            
label start:
    python:
        a = [TextButton(f"Unit - {i}", action=Return(i)) for i in range(0,10)]
        myclass = Party(*a)
    call screen party_menu
    "Selected : [_return]"

User avatar
Ocelot
Eileen-Class Veteran
Posts: 1882
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: TypeError: iter() returned non-iterator of type 'RevertableList'

#5 Post by Ocelot » Fri Oct 28, 2022 4:40 pm

A question: which RenPy version do you use? Pyhon 2 and 3 define iterators differently.
< < insert Rick Cook quote here > >

User avatar
Tess
Newbie
Posts: 23
Joined: Thu Aug 04, 2022 3:43 pm
Projects: The Songbird Guild
Organization: Yurisoft
Github: wainwt2
Discord: Tess#7782
Contact:

Re: TypeError: iter() returned non-iterator of type 'RevertableList'

#6 Post by Tess » Fri Oct 28, 2022 8:14 pm

Oh yeah, I'm on Ren'Py 7.5. I haven't been able to use the game with 8 so far because pydub doesn't seem to mesh with it for some reason: viewtopic.php?f=8&t=65523

I looked into it though, and realized I have to use next instead of __next__ in Python 2. Changed it to this and it worked perfectly:

Code: Select all

class Party():
        """A group of units that fight on the same team, either friend or foe."""
                
        def __init__(self,*units):
            """Takes Unit instances and makes a list of them in the team variable"""
            self.team = [unit for unit in units]
            self.index = 0
            
	def __iter__(self):
            """Makes this class iterable"""
            self.index = 0
            return self

        def next(self):
            """Handles how the iterator moves through the class's party members"""
            if self.index >= len(self.team):
                raise StopIteration
            else:
                self.index += 1
                return self.team[self.index-1]
Thank you so much for your help guys!

Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot]