I use the --pdb
command with ipython, so when I'm debugging code and an error occurs it shows a stack trace. A lot of these errors come from calling numpy or pandas functions with bad inputs. the stack trace starts at the newest frame, in code from these libraries. 5-10 repetitions of the up
command later I can actually see what I did wrong, which will be immediately obvious 90% of the time (eg, calling with a list instead of an array).
Is there any way to specify which stack frame the debugger initially starts in? Either the oldest stack frame, or the newest stack frame in the python file initially run, or similar. This would be much more productive for debugging.
Here's a simple example
import pandas as pd
def test(df): # (A)
df[:,0] = 4 #Bad indexing on dataframe, will cause error
return df
df = test(pd.DataFrame(range(3))) # (B)
Resulting traceback, (A), (B), (C) added for clarity
In [6]: ---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-6-66730543fac0> in <module>()
----> 1 import codecs, os;__pyfile = codecs.open('''/tmp/py29142W1d''', encoding='''utf-8''');__code = __pyfile.read().encode('''utf-8''');__pyfile.close();os.remove('''/tmp/py29142W1d''');exec(compile(__code, '''/test/stack_frames.py''', 'exec'));
/test/stack_frames.py in <module>()
6
7 if __name__ == '__main__':
(A)----> 8 df = test(pd.DataFrame(range(3)))
/test/stack_frames.py in test(df)
2
3 def test(df):
(B)----> 4 df[:,0] = 4
5 return df
6
/usr/local/lib/python2.7/dist-packages/pandas/core/frame.pyc in __setitem__(self, key, value)
2355 else:
2356 # set column
-> 2357 self._set_item(key, value)
2358
2359 def _setitem_slice(self, key, value):
/usr/local/lib/python2.7/dist-packages/pandas/core/frame.pyc in _set_item(self, key, value)
2421
2422 self._ensure_valid_index(value)
-> 2423 value = self._sanitize_column(key, value)
2424 NDFrame._set_item(self, key, value)
2425
/usr/local/lib/python2.7/dist-packages/pandas/core/frame.pyc in _sanitize_column(self, key, value)
2602
2603 # broadcast across multiple columns if necessary
-> 2604 if key in self.columns and value.ndim == 1:
2605 if (not self.columns.is_unique or
2606 isinstance(self.columns, MultiIndex)):
/usr/local/lib/python2.7/dist-packages/pandas/indexes/base.pyc in __contains__(self, key)
1232
1233 def __contains__(self, key):
-> 1234 hash(key)
1235 # work around some kind of odd cython bug
1236 try:
TypeError: unhashable type
> /usr/local/lib/python2.7/dist-packages/pandas/indexes/base.py(1234)__contains__()
1232
1233 def __contains__(self, key):
(C)-> 1234 hash(key)
1235 # work around some kind of odd cython bug
1236 try:
ipdb>
Now ideally, I would like the debugger to start in the second oldest frame at (B), or even at (A). But definitely not at (C) where it goes by default.