Python - Generator case where nothing to return

It is important to know, which iteration causes the error. That is certainly pointed in traceback, but in this case traceback is not necessary (keep reading).

Is iteration over generator an issue?

After you take a look at that, it is obvious, but worth clarifying that:

  • empty generator is not of NoneType, so iterating through it will not cause such issue:

    >>> def test_generator():
        for i in []:
            yield i
    
    
    >>> list(test_generator())  # proof it is empty
    []
    >>> for x in test_generator():
        pass
    
    >>> 
    
  • generator is recognized by Python during definition (I am simplifying) and trying to mix generators and simple functions (eg. by using conditional, as below) will be a syntax error:

    >>> def test_generator_2(sth):
        if sth:
            for i in []:
                yield i
        else:
            return []
    
    SyntaxError: 'return' with argument inside generator (<pyshell#73>, line 6)
    

Is the iteration inside generator an issue?

Based on the above the conclusion is that the error is not about iterating through iterator, but what happens when it is created (the code within generator):

def iterate_my_objects_if_something(self):
    for x in self.my_objects:  # <-- only iteration inside generator
        if x.something:
            yield x

So seemingly in some cases self.my_objects becomes None.

Solution

To fix that issue either:

  • guarantee that self.my_objects is always an iterable (eg. empty list []), or
  • check it before iteration:

    def iterate_my_objects_if_something(self):
        # checks, if value is None, otherwise assumes iterable:
        if self.my_objects is not None:
            for x in self.my_objects:
                if x.something:
                    yield x
    

Just do a simple check:

def iterate_my_objects_if_something(self):
    if self.my_objects:
        for x in self.my_objects:
            if x.something:
                yield x