Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Don't crash PuDB when viewing an object with a buggy str() or repr(). #36

Merged
merged 1 commit into from

3 participants

@pvaret

Hi,

Currently PuDB can crash when using the str or repr stringifiers, if the object being stringified is buggy. When attempting to debug code, it's very much a pain.

This patch works around the issue by falling back to the type stringifier in case the str or repr one fails.

@inducer
Owner

@asmeurer, can you take a quick a look at this, please?

@asmeurer
Collaborator

It works for me. I created a file

class Test(object):
    def __str__(self):
        raise Exception

a = Test()

In master, it fails with

Traceback (most recent call last):
  File "/sw/lib/python2.7/runpy.py", line 162, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/sw/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/Users/aaronmeurer/Documents/pudb/pudb/run.py", line 36, in <module>
    main()
  File "/Users/aaronmeurer/Documents/pudb/pudb/run.py", line 30, in main
    steal_output=options.steal_output)
  File "/Users/aaronmeurer/Documents/pudb/pudb/__init__.py", line 67, in runscript
    dbg.interaction(None, sys.exc_info())
  File "/Users/aaronmeurer/Documents/pudb/pudb/debugger.py", line 206, in interaction
    self.set_frame_index(index)
  File "/Users/aaronmeurer/Documents/pudb/pudb/debugger.py", line 157, in set_frame_index
    self.ui.update_var_view()
  File "/Users/aaronmeurer/Documents/pudb/pudb/debugger.py", line 1433, in update_var_view
    locals, globals)
  File "/Users/aaronmeurer/Documents/pudb/pudb/var_view.py", line 461, in make_var_view
    tmv_walker.walk_value("", var, locals[var])
  File "/Users/aaronmeurer/Documents/pudb/pudb/var_view.py", line 257, in walk_value
    displayed_value = get_stringifier(iinfo)(value)
  File "/Users/aaronmeurer/Documents/pudb/pudb/var_view.py", line 235, in <lambda>
    str(custom_stringifier_dict["pudb_stringifier"](value)))
  File "/Users/aaronmeurer/Documents/pudb/example-stringifier.py", line 81, in pudb_stringifier
    return run_with_timeout("str(obj)", 0.5, {'obj':obj})
  File "/Users/aaronmeurer/Documents/pudb/example-stringifier.py", line 69, in run_with_timeout
    r = eval(code, globals)
  File "<string>", line 1, in <module>

but in this branch, the string form gives a: Test (!! ~/Documents/pudb/example-stringifier.py error !!).

@inducer inducer merged commit 8c6fe86 into from
@inducer
Owner

Sounds good. Thanks, both of you!

@asmeurer
Collaborator

By the way, another option would be to catch the exception with pudb itself. I've never had __str__ raise an exception while debugging, so I don't know if this would be more desirable.

@inducer
Owner

On the one hand, that would be neat--on the other, at that point, there'd be half of pudb on the stack, which might or might not confuse people...

@pvaret
@inducer
Owner

Meh, too much effort. :)

@asmeurer
Collaborator

Yeah I agree. And anyway, the str bug may be unrelated to what you're doing. This patch let's you ignore it. It's easy to debug it separately by adding a str call to your code of you want to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 16 additions and 9 deletions.
  1. +16 −9 pudb/var_view.py
View
25 pudb/var_view.py
@@ -198,16 +198,17 @@ def keypress(self, size, key):
custom_stringifier_dict = {}
+def type_stringifier(value):
+ if HAVE_NUMPY and isinstance(value, numpy.ndarray):
+ return "ndarray %s %s" % (value.dtype, value.shape)
+ elif isinstance(value, STR_SAFE_TYPES):
+ return str(value)
+ else:
+ return type(value).__name__
+
def get_stringifier(iinfo):
if iinfo.display_type == "type":
- def _stringifier(value):
- if HAVE_NUMPY and isinstance(value, numpy.ndarray):
- return "ndarray %s %s" % (value.dtype, value.shape)
- elif isinstance(value, STR_SAFE_TYPES):
- return str(value)
- else:
- return type(value).__name__
- return _stringifier
+ return type_stringifier
elif iinfo.display_type == "repr":
return repr
elif iinfo.display_type == "str":
@@ -254,7 +255,13 @@ def walk_value(self, prefix, label, value, id_path=None, attr_prefix=None):
elif isinstance(value, (str, unicode)):
self.add_item(prefix, label, repr(value), id_path, attr_prefix)
else:
- displayed_value = get_stringifier(iinfo)(value)
+ try:
+ displayed_value = get_stringifier(iinfo)(value)
+ except Exception:
+ ## Unfortunately, anything can happen when calling str() or
+ ## repr() on a random object.
+ displayed_value = type_stringifier(value) \
+ + " (!! %s error !!)" % iinfo.display_type
self.add_item(prefix, label,
displayed_value, id_path, attr_prefix)
Something went wrong with that request. Please try again.