pytest-dev/pytest · error · RuntimeError

Cannot enter {self!r} twice

Error message

Cannot enter {self!r} twice

What it means

WarningsRecorder is a non-reentrant context manager; calling __enter__ on an instance that is already entered raises RuntimeError. You must exit before re-entering.

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 98b357f69e)

Solutions

  1. Use a fresh WarningsRecorder instance for each independent with-block.
  2. Ensure __exit__ completes before re-entering the same instance.
  3. Prefer letting the recwarn fixture manage enter/exit; do not enter it manually inside the test.

Example fix

// before
with recwarn:
    ...
with recwarn:  # same instance, RuntimeError
    ...
// after
with WarningsRecorder(_ispytest=True) as w1:
    ...
with WarningsRecorder(_ispytest=True) as w2:
    ...
Defensive patterns

Strategy: validation

Validate before calling

if getattr(recorder, '_entered', False):
    raise RuntimeError('recorder already entered; exit first or use a new instance')
recorder.__enter__()

Prevention

When it happens

Trigger: Entering the same WarningsRecorder instance twice without an intervening exit — e.g. two nested `with recwarn:` blocks on the same fixture instance, or a manual __enter__ after the fixture already entered. Hits recwarn.py:239.

Common situations: Reusing a session/function-scoped recorder fixture across nested with-blocks; manual context-manager misuse; a helper that enters the recorder the caller also entered.

Related errors


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/ea0c21a54548e9d0.json. Report an issue: GitHub.