trepanxpy is a python bytecode debugger. Just like pdb it can step trough the code. With the difference being that trepanxpy steps between bytecode instructions and can view the stack. trepanxpy needs x-python to work, x-python is a bytecode interpreter written in Python. Both can be installed with pip.
# main.py
def foo(a, b, c):
return a[b + c]
# simulate off by 1 error 1 + 2 > len(a) - 1
print(foo([10, 11, 12], 1, 2))
Below i use trepanxpy to debug the code. I have added some comments and removed some output for readability and privacy.
PS > trepan-xpy main.py
Running x-python main.py with ()
(main.py:2): <module>
-> 2 def foo(a, b, c):
(trepan-xpy) stepi
<# ~15 step instructions ommited to the relevant bytecode #>
(trepan-xpy) stepi
(main.py:3 @6): foo
.. 3 return a[b + c]
@ 6: BINARY_ADD (1, 2)
(trepan-xpy) info stack
0: <class 'int'> 2
1: <class 'int'> 1
2: <class 'list'> [10, 11, 12]
(trepan-xpy) stepi
(main.py:3 @8): foo
.. 3 return a[b + c]
@ 8: BINARY_SUBSCR ([10, 11, 12], 3)
(trepan-xpy) info stack
<# note that 3 is the index and the list has only 3 elements #>
0: <class 'int'> 3
1: <class 'list'> [10, 11, 12]
(trepan-xpy) __import__("dis").dis(foo)
<# disassembled bytecode of foo #>
3 0 LOAD_FAST 0 (a)
2 LOAD_FAST 1 (b)
4 LOAD_FAST 2 (c)
6 BINARY_ADD
8 BINARY_SUBSCR
10 RETURN_VALUE
(trepan-xpy) stepi
<# errors ommitted #>
IndexErrorlist index out of range
<# stack trace ommitted #>
trepan-xpy: That's all, folks...
<# note that the debugger shuts down after the IndexError was raised #>
As you can see it is possible to step trough bytecode. But most of the time you can achieve a similar results easier with pdb. for example:
PS > python -m pdb main.py
> main.py(2)<module>()
-> def foo(a, b, c):
(Pdb) continue
<# traceback ommitted #>
IndexError: list index out of range
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> main.py(3)foo()
-> return a[b + c]
(Pdb) p dir()
['a', 'b', 'c']
(Pdb) p (a, b, c)
([10, 11, 12], 1, 2)
(Pdb) p b + c
3
(Pdb) p len(a)
3
(Pdb) exit()
Post mortem debugger finished. The main.py will be restarted
> main.py(2)<module>()
-> def foo(a, b, c):
(Pdb) q
So to answer your question
You can use a bytecode debugger to get access to Python bytecode arguments in runtime.
Sadly trepanxpy does not have a lot of features that make pdb usable. Debugging non trivial pieces of code might be unfeasable. I am missing features such as breakpoints and being able to inspect anything after an exception is trown.
I would recommend using pdb over trepanxpy most of the time. But it can be usefull to use trepanxpy to step trough a very minimal reproducable piece of code.