Skip to content

Commit 8e9bfe0

Browse files
committed
CPython compatible interpretation of sys.traceback limit in the default exception hook
1 parent 2fa728a commit 8e9bfe0

File tree

2 files changed

+23
-4
lines changed
  • graalpython

2 files changed

+23
-4
lines changed

graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_sys.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
*graalpython.lib-python.3.test.test_sys.SysModuleTest.test_sys_getwindowsversion_no_instantiation
3838
*graalpython.lib-python.3.test.test_sys.SysModuleTest.test_c_locale_surrogateescape
3939
*graalpython.lib-python.3.test.test_sys.SysModuleTest.test_posix_locale_surrogateescape
40+
*graalpython.lib-python.3.test.test_sys.SysModuleTest.test_sys_tracebacklimit
4041
*graalpython.lib-python.3.test.test_sys.SysModuleTest.test_sys_version_info_no_instantiation
4142
*graalpython.lib-python.3.test.test_sys.SysModuleTest.test_thread_info
4243
*graalpython.lib-python.3.test.test_sys.UnraisableHookTest.test_custom_unraisablehook

graalpython/lib-graalpython/sys.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,30 @@ def __print_traceback__(typ, value, tb):
200200
print(msg, file=stderr, end="")
201201
return
202202
try:
203+
# CPython's C traceback printer diverges from traceback.print_exception in some details marked as (*)
204+
import sys
203205
import traceback
204-
lines = traceback.format_exception(typ, value, tb)
205-
# CPython's C traceback printer diverges from traceback.print_exception in this small detail.
206-
# We'd like to contribute to CPython to fix the divergence, but for now we do just
207-
# a string substitution to pass the tests
206+
no_traceback = False
207+
limit = getattr(sys, 'tracebacklimit', None)
208+
if isinstance(limit, int):
209+
if limit <= 0:
210+
# (*) the C traceback printer does nothing if the limit is <= 0,
211+
# but the exception message is still printed
212+
limit = 0
213+
no_traceback = True
214+
else:
215+
# (*) in the C printer limit is interpreted as -limit in format_exception
216+
limit = -limit
217+
else:
218+
# (*) non integer values of limit are interpreted as the default limit
219+
limit = None
220+
lines = traceback.format_exception(typ, value, tb, limit=limit)
221+
# (*) if the exception cannot be printed, then the message differs between the C driver and format_exception
222+
# We'd like to contribute to CPython to fix the divergence, but for now we do just a string substitution
223+
# to pass the tests
208224
lines[-1] = lines[-1].replace(f'<unprintable {typ.__name__} object>', f'<exception str() failed>')
225+
if no_traceback:
226+
lines = lines[-1:]
209227
for line in lines:
210228
print(line, file=stderr, end="")
211229
except BaseException as exc:

0 commit comments

Comments
 (0)