{"id":"330548c3671ec7dd","repo":"pytest-dev/pytest","slug":"expected-expected-but-got-exc-name-r","errorCode":null,"errorMessage":"Expected {expected}, but got {exc.__name__!r}","messagePattern":"Expected (.+?), but got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/_pytest/raises.py","lineNumber":451,"sourceCode":"            ) or (\n                issubclass(origin_exc, BaseExceptionGroup)\n                and exc_type in (BaseException, Any)\n            ):\n                if not issubclass(origin_exc, ExceptionGroup):\n                    self.is_baseexception = True\n                return cast(type[BaseExcT_1], origin_exc)\n            else:\n                raise ValueError(\n                    f\"Only `ExceptionGroup[Exception]` or `BaseExceptionGroup[BaseException]` \"\n                    f\"are accepted as generic types but got `{exc}`. \"\n                    f\"As `raises` will catch all instances of the specified group regardless of the \"\n                    f\"generic argument specific nested exceptions has to be checked \"\n                    f\"with `RaisesGroup`.\"\n                )\n        # unclear if the Type/ValueError distinction is even helpful here\n        msg = f\"Expected {expected}, but got \"\n        if isinstance(exc, type):  # type: ignore[unreachable]\n            raise ValueError(msg + f\"{exc.__name__!r}\")\n        if isinstance(exc, BaseException):  # type: ignore[unreachable]\n            raise TypeError(msg + f\"an exception instance: {type(exc).__name__}\")\n        raise TypeError(msg + repr(type(exc).__name__))\n\n    @property\n    def fail_reason(self) -> str | None:\n        \"\"\"Set after a call to :meth:`matches` to give a human-readable reason for why the match failed.\n        When used as a context manager the string will be printed as the reason for the\n        test failing.\"\"\"\n        return self._fail_reason\n\n    def _check_check(\n        self: AbstractRaises[BaseExcT_1],\n        exception: BaseExcT_1,\n    ) -> bool:\n        if self.check is None:\n            return True\n","sourceCodeStart":433,"sourceCodeEnd":469,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/raises.py#L433-L469","documentation":"Raised when the expected_exception argument is a type object but that type is not a subclass of BaseException. raises/RaisesExc require exception classes.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass an actual exception class (subclass of BaseException), e.g. ValueError.","If the value is dynamic, validate issubclass(exc, BaseException) before passing.","Check for typos or stale references if a refactor altered the symbol."],"exampleFix":"// before\npytest.raises(int)\n// after\npytest.raises(ValueError)","handlingStrategy":"type-guard","validationCode":"if not (isinstance(exc, type) and issubclass(exc, BaseException)):\n    raise TypeError(f'{exc!r} is not a BaseException subclass')\npytest.raises(exc)","typeGuard":"def is_exception_type(exc) -> TypeGuard[type[BaseException]]:\n    return isinstance(exc, type) and issubclass(exc, BaseException)","tryCatchPattern":null,"preventionTips":["Always pass an exception class derived from BaseException.","For dynamic values, gate on issubclass(exc, BaseException) before passing to raises.","Watch for typos and stale references after refactors that rename exception classes."],"tags":["pytest","raises","validation","type-check"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}