import sys
import traceback
from unittest.mock import patch

def dump_stack(detailed_types=(), file=sys.stdout):
    def detailed_repr(obj, _repr=repr):
        def repr_attributes(obj, indent_level=2):
            if isinstance(obj, detailed_types):
                seen.add(id(obj))
                indent = '    ' * indent_level
                for name, value in sorted(vars(obj).items()):
                    yield f'{indent}.{name} = {value}'
                    if id(value) not in seen:
                        yield from repr_attributes(value, indent_level + 1)
        seen = set()
        return '\n'.join([_repr(obj), *repr_attributes(obj)])

    with patch('builtins.repr', detailed_repr):
        print(
            *traceback.StackSummary.extract(
                traceback.walk_stack(sys._getframe(1)), capture_locals=True
            ).format(), sep='\n', file=file
        )

class Foo:
    def __init__(self, x, y):
        self.bar = Bar(x, y)
        self.foo = self

class Bar:
    def __init__(self, x, y):
        self.x = x
        self.y = y

def foo(c):
    d = c + 1
    dump_stack(detailed_types=(Foo, Bar))

a = 1
b = Foo(2, 3)
foo(a)