{"record":{"id":"e559d79f61d38571","repo":"RustPython/RustPython","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":670,"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.showwarning = self._showwarning\n                self._module._showwarnmsg_impl = self._showwarnmsg_impl\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":652,"sourceCodeEnd":688,"githubUrl":"https://github.com/RustPython/RustPython/blob/aaeab4f754b4f40efc0c8ab39cf7c4a3c35a8cfd/Lib/_py_warnings.py#L652-L688","documentation":"warnings.catch_warnings.__exit__ raises RuntimeError when the instance was never entered, because there is no saved filters/showwarning state to restore. It fires when __exit__ is invoked manually or out of order -- i.e. the with-protocol pairing of __enter__/__exit__ was broken by hand-rolled code.","triggerScenarios":"Calling cm.__exit__(None, None, None) without a prior cm.__enter__(); framework or fixture code that pairs enter/exit incorrectly; cleanup paths that call exit a second time unguarded.","commonSituations":"Custom context-manager wrappers or test fixtures that drive __enter__/__exit__ by hand; try/finally blocks imitating the with statement; double-cleanup on exception paths.","solutions":["Use the with statement instead of calling __enter__/__exit__ manually","If manual pairing is unavoidable, set a flag and only call __exit__ after a successful __enter__","Audit custom wrappers so exit runs exactly once per enter, including on exceptions"],"exampleFix":"# before\ncm = warnings.catch_warnings()\ncm.__exit__(None, None, None)  # RuntimeError: Cannot exit ... without entering first\n\n# after\nwith warnings.catch_warnings():\n    ...","handlingStrategy":"validation","validationCode":"if getattr(cm, \"_entered\", False):\n    cm.__exit__(None, None, None)  # only exit what was actually entered","typeGuard":"def is_entered(cm) -> bool:\n    return bool(getattr(cm, \"_entered\", False))","tryCatchPattern":"try:\n    cm.__exit__(None, None, None)\nexcept RuntimeError as e:\n    if \"without entering first\" in str(e):\n        pass  # nothing was saved; nothing to restore\n    else:\n        raise","preventionTips":["Prefer the with statement over manual __enter__/__exit__ pairing","Guard cleanup paths so exit runs exactly once per successful enter","In fixtures, pair enter/exit symmetrically in setup/teardown and skip teardown if setup failed"],"tags":["warnings","catch-warnings","runtimeerror","context-manager","lifecycle"],"backgroundTag":"context-manager-misuse","analyzedSha":"aaeab4f754b4f40efc0c8ab39cf7c4a3c35a8cfd","analyzedAt":"2026-08-17T00:37:52.100Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}