{"record":{"id":"7b7580126be7ec05","repo":"pytest-dev/pytest","slug":"allow-unwrapped-true-has-no-effect-when-expectin","errorCode":null,"errorMessage":"`allow_unwrapped=True` has no effect when expecting a `RaisesGroup`. You might want it in the expected `RaisesGroup`, or `flatten_subgroups=True` if you don't care about the structure.","messagePattern":"`allow_unwrapped=True` has no effect when expecting a `RaisesGroup`\\. You might want it in the expected `RaisesGroup`, or `flatten_subgroups=True` if you don't care about the structure\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/_pytest/raises.py","lineNumber":978,"sourceCode":"        # it to avoid an error when passing it to super().__init__\n        check = cast(\n            \"Callable[[BaseExceptionGroup[ExcT_1|BaseExcT_1|BaseExceptionGroup[BaseExcT_2]]], bool]\",\n            check,\n        )\n        super().__init__(match=match, check=check)\n        self.allow_unwrapped = allow_unwrapped\n        self.flatten_subgroups: bool = flatten_subgroups\n        self.is_baseexception = False\n\n        if allow_unwrapped and other_exceptions:\n            raise ValueError(\n                \"You cannot specify multiple exceptions with `allow_unwrapped=True.`\"\n                \" If you want to match one of multiple possible exceptions you should\"\n                \" use a `RaisesExc`.\"\n                \" E.g. `RaisesExc(check=lambda e: isinstance(e, (...)))`\",\n            )\n        if allow_unwrapped and isinstance(expected_exception, RaisesGroup):\n            raise ValueError(\n                \"`allow_unwrapped=True` has no effect when expecting a `RaisesGroup`.\"\n                \" You might want it in the expected `RaisesGroup`, or\"\n                \" `flatten_subgroups=True` if you don't care about the structure.\",\n            )\n        if allow_unwrapped and (match is not None or check is not None):\n            raise ValueError(\n                \"`allow_unwrapped=True` bypasses the `match` and `check` parameters\"\n                \" if the exception is unwrapped. If you intended to match/check the\"\n                \" exception you should use a `RaisesExc` object. If you want to match/check\"\n                \" the exceptiongroup when the exception *is* wrapped you need to\"\n                \" do e.g. `if isinstance(exc.value, ExceptionGroup):\"\n                \" assert RaisesGroup(...).matches(exc.value)` afterwards.\",\n            )\n\n        self.expected_exceptions: tuple[\n            type[BaseExcT_co] | RaisesExc[BaseExcT_co] | RaisesGroup[BaseException], ...\n        ] = tuple(\n            self._parse_excgroup(e, \"a BaseException type, RaisesExc, or RaisesGroup\")","sourceCodeStart":960,"sourceCodeEnd":996,"githubUrl":"https://github.com/pytest-dev/pytest/blob/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/raises.py#L960-L996","documentation":"Raised by RaisesGroup.__init__ when allow_unwrapped=True is passed to a RaisesGroup whose expected_exception is itself a RaisesGroup (nested). allow_unwrapped only affects the outermost unwrap decision, so setting it on a RaisesGroup that already expects a RaisesGroup is a no-op and signals user confusion. pytest points the user to put allow_unwrapped on the inner RaisesGroup or to use flatten_subgroups.","triggerScenarios":"RaisesGroup(RaisesGroup(ValueError), allow_unwrapped=True); nesting RaisesGroup inside RaisesGroup and setting allow_unwrapped on the outer one. The isinstance(expected_exception, RaisesGroup) check fires.","commonSituations":"Building nested group matchers programmatically and copying allow_unwrapped through every level; misunderstanding which level the unwrap applies to.","solutions":["Move allow_unwrapped=True to the inner RaisesGroup where unwrapping should occur.","Remove allow_unwrapped if you do not need single-exception unwrapping at all.","If you want to ignore subgroup nesting structure, use flatten_subgroups=True on the outer RaisesGroup instead."],"exampleFix":"// before\nwith pytest.raises(RaisesGroup(RaisesGroup(ValueError), allow_unwrapped=True)):\n    ...\n// after\nwith pytest.raises(RaisesGroup(RaisesGroup(ValueError, allow_unwrapped=True))):\n    ...\n// or flatten structure:\nwith pytest.raises(RaisesGroup(ValueError, flatten_subgroups=True)):\n    ...","handlingStrategy":"validation","validationCode":"from _pytest.raises import RaisesGroup\nif allow_unwrapped and isinstance(expected_exception, RaisesGroup):\n    raise SystemExit('move allow_unwrapped to the inner RaisesGroup, or use flatten_subgroups')","typeGuard":"def allow_unwrapped_outer_ok(expected_exception, allow_unwrapped) -> bool:\n    from _pytest.raises import RaisesGroup\n    return (not allow_unwrapped) or not isinstance(expected_exception, RaisesGroup)","tryCatchPattern":null,"preventionTips":["Set allow_unwrapped only on the RaisesGroup whose immediate value may be a bare exception.","Prefer flatten_subgroups=True when you want to ignore subgroup structure.","Document nested RaisesGroup construction in helper code."],"tags":["pytest","raises","raisesgroup","allow-unwrapped","nested-group","validation"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}