import ast


def exec_then_eval(code, namespace=None):
    """Exec a code block & return evaluation of the last line"""
    # TODO: make this less brittle.
    if namespace is None:
        namespace or {}

    block = ast.parse(code, mode='exec')
    last = ast.Expression(block.body.pop().value)

    exec(compile(block, '<string>', mode='exec'), namespace)
    return eval(compile(last, '<string>', mode='eval'), namespace)

@@ -4,156 +4,845 @@
 ort 
-ast%0A%0A%0Adef exec_then_eval(code, namespace=None):%0A    %22%22%22Exec a code block & return evaluation of the last line%22%22%22%0A    # TODO: make this less brittle.
+sys%0Aimport ast%0Afrom contextlib import contextmanager%0A%0A%0Aclass _CatchDisplay(object):%0A    %22%22%22Class to temporarily catch sys.displayhook%22%22%22%0A    def __init__(self):%0A        self.output = None%0A%0A    def __enter__(self):%0A        self.old_hook = sys.displayhook%0A        sys.displayhook = self%0A        return self%0A%0A    def __exit__(self, type, value, traceback):%0A        sys.displayhook = self.old_hook%0A        # Returning False will cause exceptions to propagate%0A        return False%0A%0A    def __call__(self, output):%0A        self.output = output%0A%0A%0Adef exec_then_eval(code, namespace=None, filename='%3Cstring%3E'):%0A    %22%22%22%0A    Execute a multi-line block of code in the given namespace%0A%0A    If the final statement in the code is an expression, return%0A    the result of the expression.%0A    %22%22%22%0A    tree = ast.parse(code, filename='%3Cast%3E', mode='exec')
 %0A   
@@ -886,155 +886,356 @@
 ace 
-or
+=
  %7B%7D%0A
-%0A
     
-block = ast.parse(code, mode='exec')%0A    last = ast.Expression(block.body.pop().value)%0A%0A    exec(compile(block, '%3Cstring%3E', mode='exec')
+catch_display = _CatchDisplay()%0A%0A    if isinstance(tree.body%5B-1%5D, ast.Expr):%0A        to_exec, to_eval = tree.body%5B:-1%5D, tree.body%5B-1:%5D%0A    else:%0A        to_exec, to_eval = tree.body, %5B%5D%0A%0A    for node in to_exec:%0A        compiled = compile(ast.Module(%5Bnode%5D),%0A                           filename=filename, mode='exec')%0A        exec(compiled
 , na
@@ -1247,71 +1247,250 @@
 ce)%0A
+%0A
     
-return eval(compile(last, '%3Cstring%3E', mode='eval'), namespace)
+with catch_display:%0A        for node in to_eval:%0A            compiled = compile(ast.Interactive(%5Bnode%5D),%0A                               filename=filename, mode='single')%0A            exec(compiled, namespace)%0A%0A    return catch_display.output
 %0A

make sphinxext utils more robust