-
-
Notifications
You must be signed in to change notification settings - Fork 32k
pdb "args" crashes when an arg is not printable #65052
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The "args" command in pdb crashes when an argument cannot be printed. For version 3.3.3: |
Why is the object not printable? Can you provide a reproducer? Also, the bare except is buggy, it would catch things like KeyboardInterrupt that should not be caught there. 'except Exception' would be appropriate in this case. |
Thanks for your reaction. |
Oops. Here the correct example:
>>> class foo:
... def __init__(self):
... foo.bar = "hello"
... def __repr__(self): return foo.bar
...
>>> pdb.runcall(foo)
> <stdin>(3)__init__()
(Pdb) a
Traceback (most recent call last):
File ".\pdb.py", line 1132, in do_args
self.message('%s = %r' % (name, dict[name]))
File "<stdin>", line 4, in __repr__
AttributeError: type object 'foo' has no attribute 'bar'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".\pdb.py", line 1580, in runcall
return Pdb().runcall(*args, **kwds)
File "C:\Python33\lib\bdb.py", line 439, in runcall
res = func(*args, **kwds)
File "<stdin>", line 3, in __init__
File "<stdin>", line 3, in __init__
File "C:\Python33\lib\bdb.py", line 47, in trace_dispatch
return self.dispatch_line(frame)
File "C:\Python33\lib\bdb.py", line 65, in dispatch_line
self.user_line(frame)
File ".\pdb.py", line 266, in user_line
self.interaction(frame, None)
File ".\pdb.py", line 345, in interaction
self._cmdloop()
File ".\pdb.py", line 318, in _cmdloop
self.cmdloop()
File "C:\Python33\lib\cmd.py", line 138, in cmdloop
stop = self.onecmd(line)
File ".\pdb.py", line 411, in onecmd
return cmd.Cmd.onecmd(self, line)
File "C:\Python33\lib\cmd.py", line 217, in onecmd
return func(arg)
File ".\pdb.py", line 1134, in do_args
self.message('%s = *** repr failed: %s ***' % (name,))
TypeError: not enough arguments for format string At least, I expect pdb to not crash, but a clearer error (as in the patch) is nice to have. |
I am not good at this. Sorry for the mess.
Here is a good example, and a good patch:
>>> class foo:
... def __init__(self):
... foo.bar = "hello"
... def __repr__(self): return foo.bar
...
>>> pdb.runcall(foo)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'pdb' is not defined
>>> import pdb
>>> pdb.runcall(foo)
> <stdin>(3)__init__()
(Pdb) a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python33\lib\pdb.py", line 1577, in runcall
return Pdb().runcall(*args, **kwds)
File "C:\Python33\lib\bdb.py", line 439, in runcall
res = func(*args, **kwds)
File "<stdin>", line 3, in __init__
File "<stdin>", line 3, in __init__
File "C:\Python33\lib\bdb.py", line 47, in trace_dispatch
return self.dispatch_line(frame)
File "C:\Python33\lib\bdb.py", line 65, in dispatch_line
self.user_line(frame)
File "C:\Python33\lib\pdb.py", line 266, in user_line
self.interaction(frame, None)
File "C:\Python33\lib\pdb.py", line 345, in interaction
self._cmdloop()
File "C:\Python33\lib\pdb.py", line 318, in _cmdloop
self.cmdloop()
File "C:\Python33\lib\cmd.py", line 138, in cmdloop
stop = self.onecmd(line)
File "C:\Python33\lib\pdb.py", line 411, in onecmd
return cmd.Cmd.onecmd(self, line)
File "C:\Python33\lib\cmd.py", line 217, in onecmd
return func(arg)
File "C:\Python33\lib\pdb.py", line 1131, in do_args
self.message('%s = %r' % (name, dict[name]))
File "<stdin>", line 4, in __repr__
AttributeError: type object 'foo' has no attribute 'bar' |
There is at least one other place (do_break) where this same problem could crop up. Unittest handles this by having a 'safe_repr' function. pdb doesn't need the same function unittest does, but it could do something similar, and then use %s and this function in the places where it currently uses repr to print an arbitrary object: def safe_repr(obj):
try:
return repr(obj)
except Exception:
return object.__repr__(obj) |
Maybe we could use Pdb._getval_except(arg, frame=None) in the routine do_args. |
I did figure it out. At it works perfectly, except for this little surprise:
>>> bar = "BAR"
>>> def foo(bar):
... del bar
... return 5
>>> pdb.runcall(f, 10)
> <stdin>(2)f()
-> del bar
(Pdb) a
bar = 5
(Pdb) n
> <stdin>(3)f()
-> return 5
(Pdb) a
bar = 'BAR' ##### Huh? Expected undefined I'll leave it to the experts to patch this in proper Python coding style. I did not find a good supporting routine for that elsewhere in pdb. |
Also in do_retval. And the exception is silently ignored in do_p and do_pp when repr() fails, which is not correct. A solution could be to have a message_safe method to be used in such cases. For example, substitute in do_args: self.message('%s = %r' % (name, dict[name]))
with:
self.message_safe('%s = %r', name, dict[name])
def message_safe(self, fmt, *args):
try:
print(fmt % args, file=self.stdout)
except Exception:
exc_info = sys.exc_info()[:2]
self.error(traceback.format_exception_only(*exc_info)[-1].strip()) |
Commands that silently fail when an object is not printable: p, pp The attached script illustrates all these cases. |
p/pp commands were fixed in this commit: |
args, retval and display fixed in #110578, close issue. |
…cts (pythonGH-110578) (cherry picked from commit c523ce0) Co-authored-by: Tian Gao <gaogaotiantian@hotmail.com>
…ay objects (pythonGH-110578) (cherry picked from commit c523ce0) Co-authored-by: Tian Gao <gaogaotiantian@hotmail.com>
Uh oh!
There was an error while loading. Please reload this page.
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
Linked PRs
The text was updated successfully, but these errors were encountered: