diff --git a/src/utils/python.py b/src/utils/python.py index 41fd004ad..bf898299d 100644 --- a/src/utils/python.py +++ b/src/utils/python.py @@ -159,10 +159,12 @@ def collect_extra_debug_data(): frame_locals = frame.f_locals for inspected in ('self', 'cls'): if inspected in frame_locals: - if hasattr(frame_locals[inspected], '__dict__') and \ - frame_locals[inspected].__dict__: - for (key, value) in frame_locals[inspected].__dict__.items(): - frame_locals['%s.%s' % (inspected, key)] = value + for attr_name in dir(frame_locals[inspected]): + try: + v = getattr(frame_locals[inspected], attr_name) + except Exception: + v = '' + frame_locals['%s.%s' % (inspected, attr_name)] = v for key, value in frame_locals.items(): if key == '__builtins__': # This is flooding @@ -173,7 +175,7 @@ def collect_extra_debug_data(): #error we don't want. try: data += repr(value) + '\n' - except: + except Exception: data += '\n' data += '\n' data += '+-----------------------+\n' diff --git a/test/test_utils.py b/test/test_utils.py index bf4d28c2c..48cb02d51 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -1175,6 +1175,45 @@ class TestTruncatableSet(SupyTestCase): s.truncate(3) self.assertEqual(s, set(['foo', 'baz', 'qux'])) +class UtilsPythonTest(SupyTestCase): + def test_dict(self): + class Foo: + def __hasattr__(self, n): + raise Exception() + def __getattr__(self, n): + raise Exception() + + def f(): + self = Foo() + self.bar = 'baz' + raise Exception('f') + + try: + f() + except: + res = utils.python.collect_extra_debug_data() + + self.assertTrue(re.search('self.bar.*=.*baz', res), res) + + def test_slots(self): + class Foo: + __slots__ = ('bar',) + def __hasattr__(self, n): + raise Exception() + def __getattr__(self, n): + raise Exception(n) + + def f(): + self = Foo() + self.bar = 'baz' + raise Exception('f') + + try: + f() + except: + res = utils.python.collect_extra_debug_data() + + self.assertTrue(re.search('self.bar.*=.*baz', res), res) # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: