monty 0.0.21

A sandboxed, snapshotable Python interpreter written in Rust.
Documentation
# Reference counts stay balanced through the `with` machinery's pushed
# frames: `BeforeWith` pushes the ctx and the `__enter__` frame binds self;
# `WithExit`/`WithExceptStart` bind self plus the exception triple. The
# suppressed exception survives through the attribute written by `__exit__`,
# which we assert by binding it to `survived` at the end.
class CM:
    def __enter__(self):
        return self

    def __exit__(self, typ, val, tb):
        self.last_exc = val
        return True


cm = CM()
with cm as bound:
    pass

with cm:
    raise ValueError('kept alive via cm.last_exc')

# The suppressed exception is held by `cm.last_exc` (refcount 1) plus this
# binding (refcount 2); `cm` and `bound` alias the one instance (refcount 2);
# `CM` is held by the global plus the instance's class slot (refcount 2).
survived = cm.last_exc
# ref-counts={'CM': 2, 'cm': 2, 'bound': 2, 'survived': 2}