2

I want to raise a StopIteration exception when the number I send is larger than 999999999.

When I sent to print(check_id_valid(1234567980)) function parameters directly or to IDIterator class (the iterator class) and from there the number pass to check_id_valid() function, the exception is catched at the main() as it should. The error string is printed:

Reached max number, 1234567980 is over 9 digits

But when I send the number to id_generator() function (thanks for the previous help its working good),

The StopIteration exception wont be raised at the main()

def check_id_valid(id_number):

     if len(str(id_number)) < 9:
         raise illigalException(id_number)        
     if int(id_number) > 999999999:
         raise StopIteration(id_number)
def id_generator(Id_number):
   while True:
       Id_number += 1
       if check_id_valid(Id_number):
           yield Id_number
def main():
 
    id_gen = id_generator(1234567800)
    try:
        for item in range(10):   
            print(next(id_gen))

    except StopIteration as e:
        print("Reached max number, " + str(e)  + " is over 9 digits")
    except (illigalException) as e:
        print(e)

if __name__ == "__main__":
    main()

And the error message is -

raise StopIteration(id_number) StopIteration: 1234567801 The above exception was the direct cause of the following exception:

print(next(id_gen)) RuntimeError: generator raised StopIteration

How can I fix it ?

P.S

I need to use the built StopIteration exception, not to override it.

Pynchia
  • 10,996
  • 5
  • 34
  • 43

1 Answers1

2

Python generator will automatically raise StopIteration when it returns. So you shouldn't raise StopIteration inside an generator function yourself.

The StopIteration is used in iterator to stop the iteration, for example inside a for loop.

def check_id_valid(id_number):

     if len(str(id_number)) < 9:
         raise illigalException(id_number)        
     if int(id_number) > 999999999:
         return False

     # you need to return True if is valid.
     return True


def id_generator(Id_number):
   while True:
       Id_number += 1
       if check_id_valid(Id_number):
           yield Id_number
       
       else:
           # this return here will raise the StopIteration error with message id_number for you.
           return id_number
          

Update

# assuming your check_id_valid is still the same.
def id_generator(Id_number):
    while True:
        Id_number += 1
        try:
            check_id_valid(Id_number)
        except StopIteration:
            # this return will raise StopIteration when you call next() on id_generator
            return Id_number
        except Exception as e:
            # raise the other illigalException 
            raise e
        
        yield Id_number
fusion
  • 1,327
  • 6
  • 12
  • I can't return `False`, I need to raise the StopIteration exception. I'm using the `check_id_valid()` with an Iterator class and at the `main()` too. –  Aug 30 '20 at 06:19
  • 1
    @Ileh Then you need to catch the `StopIteration` inside the `id_generator`. – fusion Aug 30 '20 at 06:22