pytest-dev/pytest · error · RuntimeError
Cannot enter twice
Error message
Cannot enter {self!r} twice What it means
Raised by WarningsRecorder.__enter__ when the context manager is entered a second time without an intervening __exit__. The recorder tracks an _entered flag (reset to False on exit) to mirror correct context-manager lifecycle; double-entry would corrupt the recorded list and the warnings filter state. The RuntimeError protects against misuse such as manual re-entry.
Solutions
- Always pair __enter__ with __exit__; use the with statement so Python manages lifecycle.
- Create a fresh WarningsRecorder per use rather than reusing one.
- If reusing programmatically, assert `not recorder._entered` before calling __enter__.
Example fix
// before
recorder = WarningsRecorder(_ispytest=True)
recorder.__enter__()
recorder.__enter__() # RuntimeError
// after
with WarningsRecorder(_ispytest=True) as recorder:
...
// for reuse across tests, create a new instance each time Defensive patterns
Strategy: validation
Validate before calling
assert not recorder._entered, f'cannot re-enter {recorder!r}; create a fresh recorder' Type guard
def recorder_enterable(recorder) -> bool:
return not getattr(recorder, '_entered', False) Prevention
- Always use the with statement for WarningsRecorder so __enter__/__exit__ stay paired.
- Do not cache and re-enter a recorder across tests; create a new instance each time.
- In custom harnesses, assert not _entered before calling __enter__.
When it happens
Trigger: Calling recorder.__enter__() twice; a with-block that re-enters the same recorder via __enter__ inside the body; using a recorder in a custom harness that calls __enter__ explicitly then `with recorder:` again.
Common situations: Wrapping WarningsRecorder in a custom context manager that forwards __enter__ twice; fixtures that cache and re-enter a recorder across tests; misuse by internal tooling.
Related errors
- Cannot exit without entering first
- not found in warning list
- exceptions must be derived from Warning, not
- object (type: ) must be callable
- Unexpected keyword arguments passed to pytest.warns
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/ea0c21a54548e9d0.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/recwarn.py:239
best_idx is None
or not issubclass(w.category, self._list[best_idx].category)
):
best_idx = i
if best_idx is not None:
return self._list.pop(best_idx)
__tracebackhide__ = True
raise AssertionError(f"{cls!r} not found in warning list")
def clear(self) -> None:
"""Clear the list of recorded warnings."""
self._list[:] = []
# Type ignored because we basically want the `catch_warnings` generic type
# parameter to be ourselves but that is not possible(?).
def __enter__(self) -> Self: # type: ignore[override]
if self._entered:
__tracebackhide__ = True
raise RuntimeError(f"Cannot enter {self!r} twice")
_list = super().__enter__()
# record=True means it's None.
assert _list is not None
self._list = _list
warnings.simplefilter("always")
return self
def __exit__(
self,
exc_type: type[BaseException] | None,
exc_val: BaseException | None,
exc_tb: TracebackType | None,
) -> None:
if not self._entered:
__tracebackhide__ = True
raise RuntimeError(f"Cannot exit {self!r} without entering first")
super().__exit__(exc_type, exc_val, exc_tb)View on GitHub (pinned to 0d6fbdeffa)