This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Print an indication if traceback exceeds sys.tracebacklimit
Type: enhancement Stage:
Components: Interpreter Core Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: JelleZijlstra, eric.smith, gvanrossum, iritkatriel
Priority: normal Keywords:

Created on 2022-03-07 16:52 by JelleZijlstra, last changed 2022-04-11 14:59 by admin.

Messages (5)
msg414674 - (view) Author: Jelle Zijlstra (JelleZijlstra) * (Python committer) Date: 2022-03-07 16:52
If the number of frames in a traceback exceeds sys.tracebacklimit (which defaults to 1000), any remaining frames are silently dropped. See https://docs.python.org/3.10/library/sys.html#sys.tracebacklimit.

This is confusing to users. We should print some indication like "N additional stack frames not shown".

Here are some specific ideas:
- tracebacklimit <= 0 is documented as dropping the whole traceback. In that case, we don't need too print any message.
- It may be expensive to compute a complete count. Perhaps we can count frames up to 2 * tracebacklimit, and just say "Many additional stack frames not shown".
- The C implementation is in tb_print_internal() in traceback.c, and the Python one in _extract_from_extended_frame_gen in traceback.py.
msg414675 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2022-03-07 17:00
There is general confusion as to which part of the traceback is truncated. If I have main() -> f() -> g() -> error(), and the limit is 2, does it print main() -> f(), or does it print g() -> error()? (I'm not even sure which would be more useful.)

FWIW the reason I suggested printing "many" is a worry that somehow a bug could cause counting the length of the list to take forever (e.g. if it ends in a cycle). It would seem more robust to limit the count.
msg414677 - (view) Author: Jelle Zijlstra (JelleZijlstra) * (Python committer) Date: 2022-03-07 17:05
It skips the least recent frames:

>>> def error(): 1 / 0
... 
>>> def g(): error()
... 
>>> def f(): g()
... 
>>> sys.tracebacklimit = 2
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in g
  File "<stdin>", line 1, in error
ZeroDivisionError: division by zero
>>> sys.tracebacklimit = 5
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in f
  File "<stdin>", line 1, in g
  File "<stdin>", line 1, in error
ZeroDivisionError: division by zero

(tried on current main)

I think that's the right behavior because it tells you the function that actually throws the error, which is much harder to figure out from scratch than where the call started.
msg414680 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2022-03-07 17:16
If you go with the second idea, I'd say something like f"More than {2 * tracebacklimit} additional stack frames not shown". It seems handy to know the magnitude of the problem.
msg414684 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-03-07 17:27
Re what the limit means, it’s a bit messier than that, see issue38197.
History
Date User Action Args
2022-04-11 14:59:57adminsetgithub: 91105
2022-03-07 17:27:47iritkatrielsetmessages: + msg414684
2022-03-07 17:16:59eric.smithsetnosy: + eric.smith
messages: + msg414680
2022-03-07 17:05:33JelleZijlstrasetmessages: + msg414677
2022-03-07 17:00:43gvanrossumsetmessages: + msg414675
2022-03-07 16:52:16JelleZijlstracreate