Currently builtin (C) functions (both in the stdlib and third-party libraries) form an important part of many Python applications, but they are invisible in stack traces.
The same applies to classes, whether Python or builtin.
Some sampling profilers show builtin functions, but they need to use platform specific unwinding information, making them non-portable. CProfile also shows calls to builtin functions, but cProfile is so slow as to be useless.
We can add builtin functions to the stack trace at very little cost, so let’s do it.
Example:
class C:
def __init__(self):
math.sqrt(-1)
Calling C()
gives this traceback:
File "example.py", line 7, in <module>
C()
File "example.py", line 5, in __init__
math.sqrt(-1)
ValueError: math domain error
What would like is something like:
File "example.py", line 7, in <module>
C()
File "example.py", line 4, in <module>
class C:
File "example.py", line 5, in __init__
math.sqrt(-1)
File "mathmodule.c", in math.sqrt
ValueError: math domain error
Compatibility issues
Currently all traceback objects have an attached frame, and that frame has a code object.
Traceback objects for builtin functions, would not have frames, or if they did, those frames would not have code objects.
This would break existing code.
One possibility would be to change the traceback from a single linked lists, to a pair of interleaved linked lists, the first accessible by ex.__traceback__
containing the current traceback, and another accessible by ex.__traceback_full__
containing the full traceback with classes and builtin functions.
Estimated costs
Always on – Builtin functions are visible in all stack traces
About 0.5% of current performance. This fraction may increase as we add new optimizations, but not by much and might even decrease.
Only for exception tracebacks
This has essentially zero cost. It makes raising an exception slightly more expensive, but has no cost otherwise
Limitations
Only builtin functions called from Python, or through the Python C-API would show up in stack traces.
Builtin functions and other C functions called directly from C code would need to explicitly add themselves to the stack trace if they wanted to be visible.