You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ExceptionGroup.subgroup() returns a fully matching nested subclass group unchanged instead of calling derive() #9576
subgroup() returns a nested exception group subclass as the same object when all of its leaves match, without calling derive(). split() does call derive(), so eg.split(c)[0] and eg.subgroup(c) disagree. The docs for derive() say: "This method is used by subgroup() and split(), which are used in various contexts to break up an exception group. A subclass needs to override it in order to make subgroup() and split() return instances of the subclass rather than ExceptionGroup."
subgroup() tracks whether anything was dropped and returns zelf when nothing was (if !modified { return Ok(zelf.into()); }), so a group whose leaves all match is never passed to derive() (exception_group.rs#L126-L161). split() right below has no such shortcut. CPython only returns the group itself when the condition matches the group as a whole; otherwise it rebuilds every partially or fully matching nested group with derive(), for split() and subgroup() alike (exceptions.c#L1067-L1100, #L1154-L1157, #L1209-L1233). Dropping the modified shortcut and always calling derive_and_copy_attributes when matching is non-empty would match CPython. PyPy had the same shortcut and just removed it this way (pypy/pypy#5717).
test_exception_group.NestedExceptionGroupSubclassSplitTest.test_split_BaseExceptionGroup_subclass_no_derive_new_override passes because for subgroup() it only checks the leaves.
Drafted with help from Claude Code; I reviewed and checked it before posting.
Activity