{"record":{"id":"58dd3e919fddbc2e","repo":"python/cpython","slug":"cannot-exit-r-without-entering-first","errorCode":null,"errorMessage":"Cannot exit %r without entering first","messagePattern":"Cannot exit %r without entering first","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Lib/_py_warnings.py","lineNumber":729,"sourceCode":"            self._module._filters_mutated_lock_held()\n            if self._record:\n                if _use_context:\n                    context.log = log = []\n                else:\n                    log = []\n                    self._module._showwarnmsg_impl = log.append\n                # Reset showwarning() to the default implementation to make sure\n                # that _showwarnmsg() calls _showwarnmsg_impl()\n                self._module.showwarning = self._module._showwarning_orig\n            else:\n                log = None\n        if self._filter is not None:\n            self._module.simplefilter(*self._filter)\n        return log\n\n    def __exit__(self, *exc_info):\n        if not self._entered:\n            raise RuntimeError(\"Cannot exit %r without entering first\" % self)\n        with _wm._lock:\n            if _use_context:\n                self._module._warnings_context.set(self._saved_context)\n            else:\n                self._module.filters = self._filters\n                self._module._showwarnmsg_impl = self._showwarnmsg_impl\n            self._module.showwarning = self._showwarning\n            self._module._filters_mutated_lock_held()\n\n\nclass deprecated:\n    \"\"\"Indicate that a class, function or overload is deprecated.\n\n    When this decorator is applied to an object, the type checker\n    will generate a diagnostic on usage of the deprecated object.\n\n    Usage:\n","sourceCodeStart":711,"sourceCodeEnd":747,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_py_warnings.py#L711-L747","documentation":"Raised by warnings.catch_warnings.__exit__ when the context manager's __exit__ is called without a prior __enter__. The object tracks an internal _entered flag set in __enter__ and cleared in __exit__; exiting an un-entered (or already-exited and mutated) instance would corrupt the saved warning-filter state, so CPython guards it with a RuntimeError.","triggerScenarios":"Calling cm = warnings.catch_warnings(); cm.__exit__(None, None, None) directly; manually invoking __enter__/__exit__ (e.g. to emulate a context manager across function boundaries) and calling __exit__ twice; passing a catch_warnings instance to contextlib.ExitStack and popping its callback twice.","commonSituations":"Code that wraps catch_warnings in a custom try/finally instead of a with block; reusing one catch_warnings instance for nested suppression; refactoring away from 'with' while keeping explicit enter/exit calls; test fixtures that conditionally enter the context.","solutions":["Use the context manager form: with warnings.catch_warnings(): ... and let Python call __exit__ exactly once","If manual control is required, call __enter__ first and guarantee __exit__ runs once (try/finally), and never reuse the instance","Check the internal flag defensively before manual exit: if getattr(cm, '_entered', False): cm.__exit__(...)","Use contextlib.ExitStack.enter_context(cm) instead of hand-managing enter/exit pairing"],"exampleFix":"// before\ncm = warnings.catch_warnings()\ncm.__exit__(None, None, None)  # RuntimeError\n\n# after\nwith warnings.catch_warnings():\n    warnings.simplefilter('ignore')\n    do_noisy_thing()","handlingStrategy":"validation","validationCode":"import warnings\ncm = warnings.catch_warnings()\nassert getattr(cm, '_entered', False) is False\ncm.__enter__()\ntry:\n    warnings.simplefilter('ignore')\n    noisy()\nfinally:\n    if getattr(cm, '_entered', False):\n        cm.__exit__(None, None, None)","typeGuard":null,"tryCatchPattern":"try:\n    cm.__exit__(None, None, None)\nexcept RuntimeError:\n    pass  # already exited; state is consistent, safe to ignore","preventionTips":["Always use 'with warnings.catch_warnings():' instead of manual enter/exit","Never reuse one catch_warnings instance for nested or repeated suppression","Prefer contextlib.ExitStack for dynamic nesting"],"tags":["warnings","context-manager","runtimeerror","stdlib"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}