visidata
visidata copied to clipboard
[bug Python3.9] "AttributeError: 'LazyChainMap' object has no attribute 'get'" when entering pdb++ breakpoint.
Small description
Entering a breakpoint (space breakpoint
) throws AttributeError: 'LazyChainMap' object has no attribute 'get'
.
Expected result Enter the debugger / pdb.
Actual result with screenshot
error_LazyChainMap_has_no_attribute_get.txt
Traceback (most recent call last):
File "/Users/jasonwirth/code/visidata/visidata/basesheet.py", line 170, in execCommand
escaped = super().execCommand2(cmd, vdglobals=vdglobals)
File "/Users/jasonwirth/code/visidata/visidata/basesheet.py", line 72, in execCommand2
exec(code, vdglobals, LazyChainMap(vd, self))
File "breakpoint", line 1, in <module>
File "/Users/jasonwirth/code/visidata/visidata/editor.py", line 88, in _breakpoint
VisiDataPdb(nosigint=True).set_trace()
File "/Users/jasonwirth/miniconda3/envs/visidata/lib/python3.9/bdb.py", line 92, in trace_dispatch
return self.dispatch_return(frame, arg)
File "/Users/jasonwirth/miniconda3/envs/visidata/lib/python3.9/bdb.py", line 151, in dispatch_return
self.user_return(frame, arg)
File "/Users/jasonwirth/miniconda3/envs/visidata/lib/python3.9/pdb.py", line 294, in user_return
self.interaction(frame, None)
File "/Users/jasonwirth/miniconda3/envs/visidata/lib/python3.9/site-packages/pdb.py", line 216, in interaction
ret = self.setup(frame, traceback)
File "/Users/jasonwirth/miniconda3/envs/visidata/lib/python3.9/site-packages/pdb.py", line 259, in setup
ret = super(Pdb, self).setup(frame, tb)
File "/Users/jasonwirth/miniconda3/envs/visidata/lib/python3.9/pdb.py", line 209, in setup
self.stack, self.curindex = self.get_stack(f, tb)
File "/Users/jasonwirth/miniconda3/envs/visidata/lib/python3.9/site-packages/pdb.py", line 290, in get_stack
return self.compute_stack(fullstack, idx)
File "/Users/jasonwirth/miniconda3/envs/visidata/lib/python3.9/site-packages/pdb.py", line 301, in compute_stack
if self._is_hidden(frame):
File "/Users/jasonwirth/miniconda3/envs/visidata/lib/python3.9/site-packages/pdb.py", line 282, in _is_hidden
if frame.f_locals.get('__tracebackhide__') \
AttributeError: 'LazyChainMap' object has no attribute 'get'
Steps to reproduce with sample data and a . enter-breakpoint.vd.txt vd
sheet col row longname input keystrokes comment
open-file sample_data/countries o
countries 0 breakpoint drop into pdb
Additional context
saul.pw/VisiData v2.9dev
The fix seems somewhat trivial, add LazyChainMap.get
method.
def get(self, key, default=None, /):
return self.objs.get(key, default=default)
However the object also maintains a locals
dictionary. I'm not sure if there is a particular order, e.g. check objs
first then check locals
?
def get(self, key, default=None, /):
if key in self.objs:
return self.objs[key]
return self.locals.get(key, default=default)
@jasonwirth, I actually cannot reproduce this on the develop
branch. Are you able to enter the debugger at all? Do you type something into it that triggers this exception?
Oh, this might be a Python version thing! I see you are using Python 3.9, which I am not!
Update I still cannot reproduce this with Python3.9. Waiting on more information or until I take the time to ensure my 3.9 environment is isolated.
I ran into this a while back too. It depended on my config and/or what I was doing in though debugger though - one reliable way to reproduce it was pip installing pdb++ and then triggering a breakpoint()
. pdb++ checked local variables right away where pdb on its own didn't.
I started working on a fix in #589 but it was wrong in a few ways (handy comments from @saulpw in there!). It was fairly low priority for me and didn't seem to affect anyone else so I kinda left it hanging :grimacing: . @jasonwirth's approach sounds simpler though - fix the immediate ouch :).
I did some quick adhoc testing using py3.8. I think the bug is in pdb++, as @ajkerrigan suggested. Dropping into a regular pdb debugger works, but pdb++ gets the error with both 3.8 and 3.9.
Edit: I've tried a variety of things, manually setting breakpoints, using VS Code debugger, etc. I came across this #558 issue on how to debug VD which links to @ajkerrigan page on debugging. Those docs and and CTRL+E
to get the stacktrace has been very helpful.
Thanks everyone for investigating this! @jasonwirth's solution is good, though I think the locals
should be used before objs
, if the key is available, because any locals in e.g. a generator expression should be "more local" than the column values. Can you put together a PR?