{"record":{"id":"5f89e83b5c36fc7e","repo":"python/cpython","slug":"generator-ignored-generatorexit","errorCode":null,"errorMessage":"generator ignored GeneratorExit","messagePattern":"generator ignored GeneratorExit","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Lib/_collections_abc.py","lineNumber":388,"sourceCode":"        Return next yielded value or raise StopIteration.\n        \"\"\"\n        if val is None:\n            if tb is None:\n                raise typ\n            val = typ()\n        if tb is not None:\n            val = val.with_traceback(tb)\n        raise val\n\n    def close(self):\n        \"\"\"Raise GeneratorExit inside generator.\n        \"\"\"\n        try:\n            self.throw(GeneratorExit)\n        except (GeneratorExit, StopIteration):\n            pass\n        else:\n            raise RuntimeError(\"generator ignored GeneratorExit\")\n\n    @classmethod\n    def __subclasshook__(cls, C):\n        if cls is Generator:\n            return _check_methods(C, '__iter__', '__next__',\n                                  'send', 'throw', 'close')\n        return NotImplemented\n\n\nGenerator.register(generator)\n\n\nclass Sized(metaclass=ABCMeta):\n\n    __slots__ = ()\n\n    @abstractmethod\n    def __len__(self):","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_collections_abc.py#L370-L406","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Delete any yield from the finally/except path of the generator; do cleanup work without suspending.","Catch GeneratorExit explicitly, run cleanup, then re-raise it (bare 'raise').","Avoid 'except BaseException'/'except:' inside generators; catch Exception or narrower.","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."],"exampleFix":"# before\ndef gen():\n    try:\n        yield 1\n    finally:\n        yield 'done'  # RuntimeError: generator ignored GeneratorExit on close()\n\n# after\ndef gen():\n    try:\n        yield 1\n    finally:\n        release_resources()  # no yield","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    gen.close()\nexcept RuntimeError as e:\n    if 'generator ignored GeneratorExit' in str(e):\n        log.warning('generator %r yielded during close', gen)\n    else:\n        raise","preventionTips":["Remove yields from generator finally/except blocks.","Prefer contextlib.closing or explicit close() at a deterministic point.","Lint for 'yield' inside try/finally (ruff/pylint rules on risky yields)."],"tags":["generator","generator-exit","collections-abc","iterator-protocol"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}