3

There seems to be no straight-forward way to print the full stack-trace of the exception occurred when using Python context manager.

For example:

class SomeContext():

    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_value, exc_traceback):
        print(exc_type)
        print(exc_value)
        print(exc_traceback)


with SomeContext():
    raise Exception('Oh no')

While the exc_type and exc_value are returned as expected, exc_traceback only gives a vague value (e.g: <traceback object at 0x7ff05251d840>).

When I try printing exc_traceback.__dict__, it gives: AttributeError: 'traceback' object has no attribute '__dict__'

I know for sure, that I can wrap everything called within the created context with a try ... except ... to print the stack-trace, but it wastes time and I don't want to do it every time I use this context manager. Besides, why Python even gives the exception value and type with __exit__ in the first place, but omits the real stack trace?

This question is not a duplicate of How to catch and print the full exception traceback without halting/exiting the program?, my question regards how to "bubble the traceback" within a created context.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Nikolas
  • 141
  • 1
  • 2
  • 6
  • 1
    It's not a bot, I closed it. What exactly does "bubble the traceback" mean? Your current code is trying to _print_ it, which both the linked posts _do_ cover (please read the _answers_, not just the title). _"why Python... omits the real stack trace"_ - it doesn't, the traceback object _is_ the "real stack trace". – jonrsharpe Jan 16 '23 at 10:34
  • 2
    @jonrsharpe it’s not a duplicate because it’s asking about using a context manager which none of the answers on that post mention. – Dadsdy Jun 18 '23 at 03:21
  • @Dadsdy so what? It's not clear why you or the OP think that matters at all; the same approaches shown in the linked duplicates work just fine in `__exit__`. In fact, as the OP's `__exit__` implementation doesn't return a truth-y value, the full traceback is _already_ shown. – jonrsharpe Jun 18 '23 at 08:40
  • @jonrsharpe Because I am trying to make a context manager that intercepts each of stdin, stdout, and stderr and writes everything writen to them to a file (for stdout and stderr) and reads everything read from them from a file (for stdin), and my prior approach (setting sys.stderr equal to something didn't work (it worked for stdin and stdout)), so using the ```__exit__``` params seemed my only choice. However, I wasn't able to get the text of the traceback. – Dadsdy Jun 18 '23 at 18:11
  • @Dadsdy the linked duplicates **do** show how to get the formatted traceback text from exactly the values that `__exit__` receives, at which point you can send it wherever you like, so it's not clear what the problem is. – jonrsharpe Jun 18 '23 at 20:21
  • @jonrsharpe I thought that there would be something using the trace back object. However, traceback.format_exe() does manage to work. – Dadsdy Jun 18 '23 at 22:33
  • This is not a duplicate of the questions linked above. IMO this should be re-opened because this was my exact question and even though I have a really relevant and useful post, it also does not answer this question: https://stackoverflow.com/a/16993115/7059681 my suggestion is to create a context manager that patches and unpatches `sys.excepthook`. I would post my code as an answer if this question wasn't closed. – ringo Jun 26 '23 at 20:34

0 Answers0