[issue17911] Extracting tracebacks does too much work
Björn Sandberg Lynch added the comment: I was trying to stay with the established pattern of the existing methods. There are two unrelated issues to solve here - deferring linecache access, and the extract_exception functionality. When it comes to deferral, we could wrap each line in a different class than tuple, but this constitutes a public API change (and this is a *very* widely used library). Even changing to a namedtuple would cause a lot of grief, since we'd break lots of doctests, and subclassing tuple is a lot of effort for little benefit. If we only do it for the deferred usage, it would only be inconsistent. I suppose we could have a completely separate way of doing things for ExceptionSummary, but again, inconsistent, and I think if one extract_xxx method provides the functionality, users would expect it to be available in the others. For ExceptionSummary, the same summary instance is used more than once if you have a cause set, so object creation had to be separated from the graph population. Either this is done in a constructor function or we would need some obscure tricks with the class kwargs. This way, there's a separation of concerns - the class wraps *one* exception, and the function creates a bunch and links them together as needed. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17911 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17911] Extracting tracebacks does too much work
Changes by Björn Sandberg Lynch adaptivelo...@gmail.com: Added file: http://bugs.python.org/file30901/traceback2.patch ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17911 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17911] Extracting tracebacks does too much work
Björn Sandberg Lynch added the comment: After thinking about it, I decided to defer instead of suppress line fetching. Suppressing would still give a traceback later, but not the same as the original. extract_exception is where the meat is. There's a slight quirk in how context works - if cause is set to something else than the actual exception, context still gets set even though it won't be printed. This is to enable later analysis. However, if you explicitly 'raise Exception from None' neither of them will be set - the formatting code would have issues otherwise. I'm not too happy about the code duplication between the format_exception method and the formatting that works on exceptions directly, but there are plenty of tests to ensure that the output is identical. Feel free to dispute my naming choices. I'm admittedly influenced by twisted. -- keywords: +patch Added file: http://bugs.python.org/file30895/traceback.patch ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17911 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue17911] Extracting tracebacks does too much work
Björn Sandberg Lynch added the comment: I've been looking into this as an easy piece to bite off. If I understand Guido correctly, he'd like to defer or suppress the linecache call when getting the tb summary. The problem with deferring is that you need to access f_globals for the loader to work correctly when the module source is a non-file import source. If we keep a reference to f_globals for each line in the traceback, we can defer this to later (ideally we'd just keep the __loader__ value, but that would require changing the linecache interface as well). My inclination would be to have another keyword argument to _extract_tb_or_stack_iter (terse=False or verbose=True - either style works). In terse mode, no source lines would be available, and the formatted output would be the same as if the source wasn't available at all. This would work, although the traceback module is structured so that I'd need to pass it through quite a few wrapped iterator calls. I'm not sure how free a hand I have when it comes to refactoring the internal implementation. I'm not fond of the extractor callbacks - I'd prefer a generator-based approach on the lines of: def _tb_iter(tb, limit): i = 0 while tb is not None: if limit is not None and limit i: break yield tb.tb_frame, tb.tb_lineno tb = tb.tb_next i += 1 def _extract_frame_iter(frames, terse=False): ... for frame, lineno in frames: ... -- nosy: +adaptivelogic ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue17911 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com