pytest-dev/pytest · error · ValueError

Expected {expected}, but got {exc.__name__!r}

Error message

Expected {expected}, but got {exc.__name__!r}

What it means

Raised when the expected_exception argument is a type object but that type is not a subclass of BaseException. raises/RaisesExc require exception classes.

Source

Thrown at src/_pytest/raises.py:451

            ) or (
                issubclass(origin_exc, BaseExceptionGroup)
                and exc_type in (BaseException, Any)
            ):
                if not issubclass(origin_exc, ExceptionGroup):
                    self.is_baseexception = True
                return cast(type[BaseExcT_1], origin_exc)
            else:
                raise ValueError(
                    f"Only `ExceptionGroup[Exception]` or `BaseExceptionGroup[BaseException]` "
                    f"are accepted as generic types but got `{exc}`. "
                    f"As `raises` will catch all instances of the specified group regardless of the "
                    f"generic argument specific nested exceptions has to be checked "
                    f"with `RaisesGroup`."
                )
        # unclear if the Type/ValueError distinction is even helpful here
        msg = f"Expected {expected}, but got "
        if isinstance(exc, type):  # type: ignore[unreachable]
            raise ValueError(msg + f"{exc.__name__!r}")
        if isinstance(exc, BaseException):  # type: ignore[unreachable]
            raise TypeError(msg + f"an exception instance: {type(exc).__name__}")
        raise TypeError(msg + repr(type(exc).__name__))

    @property
    def fail_reason(self) -> str | None:
        """Set after a call to :meth:`matches` to give a human-readable reason for why the match failed.
        When used as a context manager the string will be printed as the reason for the
        test failing."""
        return self._fail_reason

    def _check_check(
        self: AbstractRaises[BaseExcT_1],
        exception: BaseExcT_1,
    ) -> bool:
        if self.check is None:
            return True

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Pass an actual exception class (subclass of BaseException), e.g. ValueError.
  2. If the value is dynamic, validate issubclass(exc, BaseException) before passing.
  3. Check for typos or stale references if a refactor altered the symbol.

Example fix

// before
pytest.raises(int)
// after
pytest.raises(ValueError)
Defensive patterns

Strategy: type-guard

Validate before calling

if not (isinstance(exc, type) and issubclass(exc, BaseException)):
    raise TypeError(f'{exc!r} is not a BaseException subclass')
pytest.raises(exc)

Type guard

def is_exception_type(exc) -> TypeGuard[type[BaseException]]:
    return isinstance(exc, type) and issubclass(exc, BaseException)

Prevention

When it happens

Trigger: Calling pytest.raises(int), pytest.raises(str), RaisesExc(list), or any non-exception type. Hits raises.py:451 when isinstance(exc, type) is True but issubclass(exc, BaseException) was False earlier.

Common situations: Typo in the exception name; a refactor changed a variable to point at a non-exception type; passing a dataclass or model class by mistake.

Related errors


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