python/cpython · error · RuntimeError

generator ignored GeneratorExit

Error message

generator ignored GeneratorExit

What it means

Raised by collections.abc.Generator.close() (Lib/_collections_abc.py) when throw(GeneratorExit) into a generator does not end with GeneratorExit or StopIteration. A generator that catches GeneratorExit and yields again violates the iterator protocol; the standard close() machinery detects this and raises RuntimeError instead of silently losing the generator.

Source

Thrown at Lib/_collections_abc.py:388

        Return next yielded value or raise StopIteration.
        """
        if val is None:
            if tb is None:
                raise typ
            val = typ()
        if tb is not None:
            val = val.with_traceback(tb)
        raise val

    def close(self):
        """Raise GeneratorExit inside generator.
        """
        try:
            self.throw(GeneratorExit)
        except (GeneratorExit, StopIteration):
            pass
        else:
            raise RuntimeError("generator ignored GeneratorExit")

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Generator:
            return _check_methods(C, '__iter__', '__next__',
                                  'send', 'throw', 'close')
        return NotImplemented


Generator.register(generator)


class Sized(metaclass=ABCMeta):

    __slots__ = ()

    @abstractmethod
    def __len__(self):

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Delete any yield from the finally/except path of the generator; do cleanup work without suspending.
  2. Catch GeneratorExit explicitly, run cleanup, then re-raise it (bare 'raise').
  3. Avoid 'except BaseException'/'except:' inside generators; catch Exception or narrower.
  4. If a consumer needs a closing signal, use try/finally around next() on the caller side or return a status object instead of a final yield.

Example fix

# before
def gen():
    try:
        yield 1
    finally:
        yield 'done'  # RuntimeError: generator ignored GeneratorExit on close()

# after
def gen():
    try:
        yield 1
    finally:
        release_resources()  # no yield
Defensive patterns

Strategy: try-catch

Try / catch

try:
    gen.close()
except RuntimeError as e:
    if 'generator ignored GeneratorExit' in str(e):
        log.warning('generator %r yielded during close', gen)
    else:
        raise

Prevention

When it happens

Trigger: A generator's try/finally or except BaseException block performs another yield after GeneratorExit arrives; calling .close() directly, breaking out of a for loop and letting GC finalize the generator, or delegating with 'yield from' to a misbehaving subgenerator all reach this code.

Common situations: Generators that emit a sentinel value during cleanup; context-manager-in-generator patterns where finally yields; 'coroutine ignored/yield ignored GeneratorExit' messages during interpreter shutdown; custom Generator subclasses whose throw() returns instead of raising.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/5f89e83b5c36fc7e. Report an issue: GitHub.