Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Monkey patch traceback.TracebackException to support MultiError #347
This monkey patches
Documentation is included detailing some examples where this would be useful e.g. logging.
@@ Coverage Diff @@ ## master #347 +/- ## ========================================== - Coverage 99.24% 99.24% -0.01% ========================================== Files 87 87 Lines 10397 10436 +39 Branches 729 728 -1 ========================================== + Hits 10319 10357 +38 Misses 61 61 - Partials 17 18 +1
how important is it that a duplicate exception (
exc.__cause__ == exc) be printed as a duplicate instead of just omitted?
The current code is really careful about duplicate exceptions, because when I was first writing the
MultiError code I had tons of bugs that caused weird reference loops, so I had to make the pretty-printer bulletproof just to figure out what was going on :-). This is probably less important now. It is probably still more important for us than for the stdlib version, because for them the only way you can get a duplicate is if you have something like
A.__context__ is A, which is a weird bug and arbitrarily cutting off the display seems ok? For us we can have things like
MultiError([A, B]) where
A.__context__ is B.__context__, and I feel like here it's a little more confusing if
B is just randomly missing its context without any clue that something has happened (especially if
B are in different parts of the tree).
I guess one approach would be to have the capture code only skip loops, but not throw away "horizontal" duplicates. (Something like, when we recurse we pass through a
seen set, but we make a separate copy of it for each entry in a
MultiError.) And then on output we can filter more? Or we could define a special placeholder object for "duplicate" that we use when capturing? Can you give some estimate of how hard it would be to keep this?
Just putting down some thoughts to make sure I understand what each part of the multierror actually represents.
MultiError traceback: This is the stack from where the MultiError was created to where it was handled.
MultiError context or cause: This is any exception that was being handled when the MultiError was created (like if there was a nursery in an except block).
By using the stdlib traceback formatting code, this will work as desired and there should be no duplicates that need to be explicitly printed.
MultiError sub-exceptions: Each want to be printed separately. If there are duplicates, especially in different parts of the "tree", we probably want to mention that instead of silently omitting them.
This matches with what you said about "horizontal" duplicates and using a copy of our
In this way, all sub-exceptions will be printed with a reasonable stack of causes, and there may be duplicates in those stacks. In order to re-use the existing
@njsmith The only open question left is whether it is important to explicitly mention that we have printed a duplicate exception or if simply printing it is sufficient.
If we want to be explicit that it is a duplicate, we'll need to copy the code from