You can pass an arbitrary function to eg.split() and eg.subgroup(), and
that function can have a side effect. Suppose you want to log and ignore
OSError with errno==ENOENT but re-raise the rest, you can do this:
```
def log_and_ignore(err):
if err.errno == ENOENT:
log(err)
return False
else:
return True
try:
. . .
except *OSError as eg:
eg = eg.subgroup(log_and_ignore)
if eg is not None:
raise eg
```
On Sun, Feb 28, 2021 at 10:35 AM Jim J. Jewett <[email protected]> wrote:
> Looking at the following PEP example, I'm still not sure what he should do
> to handle some but not all OSError instances:
>
> ... raise ExceptionGroup(
> ... "eg",
> ... [
> ... ValueError(1),
> ... TypeError(2),
> ... OSError(3),
> ... ExceptionGroup(
> ... "nested",
> ... [OSError(4), TypeError(5), ValueError(6)])
> ... ]
>
> except *OSError seems to get him an ExceptionGroup that he still has to
> manually tree-walk to handle the OSErrors that he can actually handle.
>
> Once he has manually tree-walked, he has to manually re-raise the other
> OSErrors that he hasn't filtered out, and they become a sibling of the
> original ExceptionGroup, because they're (now) being raised at a different
> location. (Or, not *really* the original ExceptionGroup, but one that
> looks like it without any OSErrors.) This new sibling relationship is
> there to show that a failed or incomplete attempt was made at resolving the
> OSErrors, but no such attempt was made at the ValueErrors or TypeErrors.
>
> Alternatively, he *might* be able to just grab Exception, then use a
> complicated callback to subgroup only the OSErrors that he will be able to
> handle, and raise the complement of that. It will still add another layer
> of ExceptionGroup, but won't split the remainders.
>
> This seems like an awful lot of work to preserve and elaborate structural
> relations between different exceptions that were originally accidental. (I
> am assuming that the original relation was "these all happened, probably in
> different execution threads" and the new relations are just accidents of
> what got partially handled along the way, or maybe the order in which
> different execution threads got merged.)
>
> I can't imagine ever needing to care about the full tree structure unless
> I'm re-implementing asycio/trio/curio. Even if that structural information
> is important to my own framework, that just means I should create more
> intermediate tasks to handle it more quickly, before the next level of
> aggregation.
>
> I would much prefer an API that let me pattern-match (even just by class
> of the exception instances, though preferably also by attributes), process
> each exception (as though it were the only one) within the code block that
> match selects, and indicate whether that one exception should be raised
> further or not.
>
> -jJ
> _______________________________________________
> Python-Dev mailing list -- [email protected]
> To unsubscribe send an email to [email protected]
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/[email protected]/message/WTZUGBFWFXMGAFHNTTBMUYFGMQCPV5N6/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
--
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/BJYWU6VZNYTTV43T5ZL5CFXLXEOCBDEQ/
Code of Conduct: http://python.org/psf/codeofconduct/