broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(body, commands):
    state = 'created'
    pc = 0
    stack = []
    handlers = []
    out = []
    def run(inject, exc):
        nonlocal pc, state
        if exc is not None:
            while handlers and handlers[-1][0] != exc:
                handlers.pop()
            if not handlers:
                state = 'done'
                return ['raised', exc]
            pc = handlers.pop()[1]
        elif state == 'suspended':
            stack.append(inject)
        state = 'running'
        try:
            while True:
                ins = body[pc]
                op = ins[0]
                pc += 1
                if op == 'push':
                    stack.append(ins[1])
                elif op == 'pop':
                    stack.pop()
                elif op == 'add':
                    b = stack.pop()
                    a = stack.pop()
                    stack.append(a + b)
                elif op == 'yield':
                    state = 'suspended'
                    return ['yielded', stack.pop()]
                elif op == 'return':
                    state = 'done'
                    return ['StopIteration', stack.pop()]
                elif op == 'try':
                    handlers.append((ins[1], ins[2]))
                elif op == 'endtry':
                    handlers.pop()
        except (IndexError, TypeError):
            state = 'done'
            return ['vm-error']
    for cmd in commands:
        kind = cmd[0]
        if kind in ('next', 'send'):
            value = cmd[1] if kind == 'send' else None
            if state == 'done':
                out.append(['StopIteration', None])
            elif state == 'created' and value is not None:
                out.append(['TypeError'])
            else:
                out.append(run(value, None))
        elif kind == 'throw':
            if state == 'created' or state == 'done':
                state = 'done'
                out.append(['raised', cmd[1]])
            else:
                out.append(run(None, cmd[1]))
        else:
            state = 'done'
            out.append(['closed'])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['next'], ['send', 7], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 17], ['StopIteration', 6], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['send', 0], ['next'], ['send', 1]]),
   [['TypeError'], ['yielded', 1], ['yielded', 11]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 6]]),
  ('yield hands out and removes the value',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 8], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 43],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 43], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['next'], ['send', 14], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 24], ['StopIteration', 7], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['send', 0], ['next'], ['send', 2]]),
   [['TypeError'], ['yielded', 1], ['yielded', 12]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 7]]),
  ('yield hands out and removes the value',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 13], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 44],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 44], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['next'], ['send', 21], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 31], ['StopIteration', 8], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['send', 0], ['next'], ['send', 3]]),
   [['TypeError'], ['yielded', 1], ['yielded', 13]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 8]]),
  ('yield hands out and removes the value',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 18], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 45],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 45], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['next'], ['send', 28], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 38], ['StopIteration', 9], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['send', 0], ['next'], ['send', 4]]),
   [['TypeError'], ['yielded', 1], ['yielded', 14]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 9]]),
  ('yield hands out and removes the value',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 23], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 46],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 46], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['next'], ['send', 35], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 45], ['StopIteration', 10], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['send', 0], ['next'], ['send', 5]]),
   [['TypeError'], ['yielded', 1], ['yielded', 15]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 10]]),
  ('yield hands out and removes the value',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 28], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 47],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 47], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])]]
for label, args, expected in cases[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(body, commands):
    state = 'created'
    pc = 0
    stack = []
    handlers = []
    out = []
    def run(inject, exc):
        nonlocal pc, state
        if exc is not None:
            while handlers and not exc.startswith(handlers[-1][0]):
                handlers.pop()
            if not handlers:
                state = 'done'
                return ['raised', exc]
            pc = handlers.pop()[1]
        elif state == 'suspended':
            stack.append(inject)
        state = 'running'
        try:
            while True:
                ins = body[pc]
                op = ins[0]
                pc += 1
                if op == 'push':
                    stack.append(ins[1])
                elif op == 'pop':
                    stack.pop()
                elif op == 'add':
                    b = stack.pop()
                    a = stack.pop()
                    stack.append(a + b)
                elif op == 'yield':
                    state = 'suspended'
                    return ['yielded', stack.pop()]
                elif op == 'return':
                    state = 'done'
                    return ['StopIteration', stack.pop()]
                elif op == 'try':
                    handlers.append((ins[1], ins[2]))
                elif op == 'endtry':
                    handlers.pop()
        except (IndexError, TypeError):
            state = 'done'
            return ['vm-error']
    for cmd in commands:
        kind = cmd[0]
        if kind in ('next', 'send'):
            value = cmd[1] if kind == 'send' else None
            if state == 'done':
                out.append(['StopIteration', None])
            elif state == 'created' and value is not None:
                out.append(['TypeError'])
            else:
                out.append(run(value, None))
        elif kind == 'throw':
            if state == 'created' or state == 'done':
                state = 'done'
                out.append(['raised', cmd[1]])
            else:
                out.append(run(None, cmd[1]))
        else:
            state = 'done'
            out.append(['closed'])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['next'], ['send', 7], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 17], ['StopIteration', 6], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['send', 0], ['next'], ['send', 1]]),
   [['TypeError'], ['yielded', 1], ['yielded', 11]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 6]]),
  ('yield hands out and removes the value',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 8], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 43],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 43], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['next'], ['send', 14], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 24], ['StopIteration', 7], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['send', 0], ['next'], ['send', 2]]),
   [['TypeError'], ['yielded', 1], ['yielded', 12]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 7]]),
  ('yield hands out and removes the value',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 13], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 44],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 44], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['next'], ['send', 21], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 31], ['StopIteration', 8], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['send', 0], ['next'], ['send', 3]]),
   [['TypeError'], ['yielded', 1], ['yielded', 13]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 8]]),
  ('yield hands out and removes the value',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 18], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 45],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 45], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['next'], ['send', 28], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 38], ['StopIteration', 9], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['send', 0], ['next'], ['send', 4]]),
   [['TypeError'], ['yielded', 1], ['yielded', 14]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 9]]),
  ('yield hands out and removes the value',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 23], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 46],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 46], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['next'], ['send', 35], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 45], ['StopIteration', 10], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['send', 0], ['next'], ['send', 5]]),
   [['TypeError'], ['yielded', 1], ['yielded', 15]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 10]]),
  ('yield hands out and removes the value',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 28], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 47],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 47], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])]]
for label, args, expected in cases[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
A generator guarded by an Exception handler dies when throw() delivers ValueError.

A generator frame runs body ops push v, pop, add, yield (pop and hand out a value, suspend), return (pop, finish with StopIteration value), try exc target / endtry (handler stack; handler "Exception" catches any thrown name). Commands: next (= send None) and send v resume; resuming a suspended frame pushes the sent value as the result of its yield; sending non-None to a never-started generator is ["TypeError"]; a finished generator answers ["StopIteration", None]. throw into a created or finished generator finishes it with ["raised", exc]; otherwise the innermost matching handler is jumped to, or the generator finishes and re-raises. close finishes the generator. Frame faults are ["vm-error"].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(body, commands):
    state = 'created'
    pc = 0
    stack = []
    handlers = []
    out = []
    def run(inject, exc):
        nonlocal pc, state
        if exc is not None:
            while handlers and handlers[-1][0] not in (exc, 'Exception'):
                handlers.pop()
            if not handlers:
                return ['raised', exc]
            pc = handlers.pop()[1]
        elif state == 'suspended':
            stack.append(inject)
        state = 'running'
        try:
            while True:
                ins = body[pc]
                op = ins[0]
                pc += 1
                if op == 'push':
                    stack.append(ins[1])
                elif op == 'pop':
                    stack.pop()
                elif op == 'add':
                    b = stack.pop()
                    a = stack.pop()
                    stack.append(a + b)
                elif op == 'yield':
                    state = 'suspended'
                    return ['yielded', stack.pop()]
                elif op == 'return':
                    state = 'done'
                    return ['StopIteration', stack.pop()]
                elif op == 'try':
                    handlers.append((ins[1], ins[2]))
                elif op == 'endtry':
                    handlers.pop()
        except (IndexError, TypeError):
            state = 'done'
            return ['vm-error']
    for cmd in commands:
        kind = cmd[0]
        if kind in ('next', 'send'):
            value = cmd[1] if kind == 'send' else None
            if state == 'done':
                out.append(['StopIteration', None])
            elif state == 'created' and value is not None:
                out.append(['TypeError'])
            else:
                out.append(run(value, None))
        elif kind == 'throw':
            if state == 'created' or state == 'done':
                state = 'done'
                out.append(['raised', cmd[1]])
            else:
                out.append(run(None, cmd[1]))
        else:
            state = 'done'
            out.append(['closed'])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['next'], ['send', 7], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 17], ['StopIteration', 6], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['send', 0], ['next'], ['send', 1]]),
   [['TypeError'], ['yielded', 1], ['yielded', 11]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 6]]),
  ('yield hands out and removes the value',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 8], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 43],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 43], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['next'], ['send', 14], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 24], ['StopIteration', 7], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['send', 0], ['next'], ['send', 2]]),
   [['TypeError'], ['yielded', 1], ['yielded', 12]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 7]]),
  ('yield hands out and removes the value',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 13], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 44],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 44], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['next'], ['send', 21], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 31], ['StopIteration', 8], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['send', 0], ['next'], ['send', 3]]),
   [['TypeError'], ['yielded', 1], ['yielded', 13]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 8]]),
  ('yield hands out and removes the value',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 18], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 45],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 45], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['next'], ['send', 28], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 38], ['StopIteration', 9], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['send', 0], ['next'], ['send', 4]]),
   [['TypeError'], ['yielded', 1], ['yielded', 14]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 9]]),
  ('yield hands out and removes the value',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 23], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 46],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 46], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['next'], ['send', 35], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 45], ['StopIteration', 10], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['send', 0], ['next'], ['send', 5]]),
   [['TypeError'], ['yielded', 1], ['yielded', 15]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 10]]),
  ('yield hands out and removes the value',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 28], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 47],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 47], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])]]
for label, args, expected in cases[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(body, commands):
    state = 'created'
    pc = 0
    stack = []
    handlers = []
    out = []
    def run(inject, exc):
        nonlocal pc, state
        if exc is not None:
            while handlers and handlers[-1][0] not in (exc, 'Exception'):
                handlers.pop()
            if not handlers:
                handlers.clear()
                return ['raised', exc]
            pc = handlers.pop()[1]
        elif state == 'suspended':
            stack.append(inject)
        state = 'running'
        try:
            while True:
                ins = body[pc]
                op = ins[0]
                pc += 1
                if op == 'push':
                    stack.append(ins[1])
                elif op == 'pop':
                    stack.pop()
                elif op == 'add':
                    b = stack.pop()
                    a = stack.pop()
                    stack.append(a + b)
                elif op == 'yield':
                    state = 'suspended'
                    return ['yielded', stack.pop()]
                elif op == 'return':
                    state = 'done'
                    return ['StopIteration', stack.pop()]
                elif op == 'try':
                    handlers.append((ins[1], ins[2]))
                elif op == 'endtry':
                    handlers.pop()
        except (IndexError, TypeError):
            state = 'done'
            return ['vm-error']
    for cmd in commands:
        kind = cmd[0]
        if kind in ('next', 'send'):
            value = cmd[1] if kind == 'send' else None
            if state == 'done':
                out.append(['StopIteration', None])
            elif state == 'created' and value is not None:
                out.append(['TypeError'])
            else:
                out.append(run(value, None))
        elif kind == 'throw':
            if state == 'created' or state == 'done':
                state = 'done'
                out.append(['raised', cmd[1]])
            else:
                out.append(run(None, cmd[1]))
        else:
            state = 'done'
            out.append(['closed'])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['next'], ['send', 7], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 17], ['StopIteration', 6], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['send', 0], ['next'], ['send', 1]]),
   [['TypeError'], ['yielded', 1], ['yielded', 11]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 6]]),
  ('yield hands out and removes the value',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 8], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 43],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 43], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['next'], ['send', 14], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 24], ['StopIteration', 7], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['send', 0], ['next'], ['send', 2]]),
   [['TypeError'], ['yielded', 1], ['yielded', 12]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 7]]),
  ('yield hands out and removes the value',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 13], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 44],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 44], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['next'], ['send', 21], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 31], ['StopIteration', 8], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['send', 0], ['next'], ['send', 3]]),
   [['TypeError'], ['yielded', 1], ['yielded', 13]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 8]]),
  ('yield hands out and removes the value',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 18], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 45],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 45], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['next'], ['send', 28], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 38], ['StopIteration', 9], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['send', 0], ['next'], ['send', 4]]),
   [['TypeError'], ['yielded', 1], ['yielded', 14]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 9]]),
  ('yield hands out and removes the value',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 23], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 46],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 46], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['next'], ['send', 35], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 45], ['StopIteration', 10], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['send', 0], ['next'], ['send', 5]]),
   [['TypeError'], ['yielded', 1], ['yielded', 15]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 10]]),
  ('yield hands out and removes the value',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 28], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 47],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 47], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])]]
for label, args, expected in cases[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
After throw() propagates out, next() resumes the dead frame and faults.

A generator frame runs body ops push v, pop, add, yield (pop and hand out a value, suspend), return (pop, finish with StopIteration value), try exc target / endtry (handler stack; handler "Exception" catches any thrown name). Commands: next (= send None) and send v resume; resuming a suspended frame pushes the sent value as the result of its yield; sending non-None to a never-started generator is ["TypeError"]; a finished generator answers ["StopIteration", None]. throw into a created or finished generator finishes it with ["raised", exc]; otherwise the innermost matching handler is jumped to, or the generator finishes and re-raises. close finishes the generator. Frame faults are ["vm-error"].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(body, commands):
    state = 'created'
    pc = 0
    stack = []
    handlers = []
    out = []
    def run(inject, exc):
        nonlocal pc, state
        if exc is not None:
            while handlers and handlers[-1][0] not in (exc, 'Exception'):
                handlers.pop()
            if not handlers:
                state = 'done'
                return ['raised', exc]
            pc = handlers.pop()[1]
        elif state == 'suspended':
            stack.append(inject)
        state = 'running'
        try:
            while True:
                ins = body[pc]
                op = ins[0]
                pc += 1
                if op == 'push':
                    stack.append(ins[1])
                elif op == 'pop':
                    stack.pop()
                elif op == 'add':
                    b = stack.pop()
                    a = stack.pop()
                    stack.append(a + b)
                elif op == 'yield':
                    state = 'suspended'
                    return ['yielded', stack[-1]]
                elif op == 'return':
                    state = 'done'
                    return ['StopIteration', stack.pop()]
                elif op == 'try':
                    handlers.append((ins[1], ins[2]))
                elif op == 'endtry':
                    handlers.pop()
        except (IndexError, TypeError):
            state = 'done'
            return ['vm-error']
    for cmd in commands:
        kind = cmd[0]
        if kind in ('next', 'send'):
            value = cmd[1] if kind == 'send' else None
            if state == 'done':
                out.append(['StopIteration', None])
            elif state == 'created' and value is not None:
                out.append(['TypeError'])
            else:
                out.append(run(value, None))
        elif kind == 'throw':
            if state == 'created' or state == 'done':
                state = 'done'
                out.append(['raised', cmd[1]])
            else:
                out.append(run(None, cmd[1]))
        else:
            state = 'done'
            out.append(['closed'])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['next'], ['send', 7], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 17], ['StopIteration', 6], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['send', 0], ['next'], ['send', 1]]),
   [['TypeError'], ['yielded', 1], ['yielded', 11]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 6]]),
  ('yield hands out and removes the value',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 8], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 43],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 43], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['next'], ['send', 14], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 24], ['StopIteration', 7], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['send', 0], ['next'], ['send', 2]]),
   [['TypeError'], ['yielded', 1], ['yielded', 12]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 7]]),
  ('yield hands out and removes the value',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 13], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 44],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 44], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['next'], ['send', 21], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 31], ['StopIteration', 8], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['send', 0], ['next'], ['send', 3]]),
   [['TypeError'], ['yielded', 1], ['yielded', 13]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 8]]),
  ('yield hands out and removes the value',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 18], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 45],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 45], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['next'], ['send', 28], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 38], ['StopIteration', 9], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['send', 0], ['next'], ['send', 4]]),
   [['TypeError'], ['yielded', 1], ['yielded', 14]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 9]]),
  ('yield hands out and removes the value',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 23], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 46],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 46], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['next'], ['send', 35], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 45], ['StopIteration', 10], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['send', 0], ['next'], ['send', 5]]),
   [['TypeError'], ['yielded', 1], ['yielded', 15]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 10]]),
  ('yield hands out and removes the value',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 28], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 47],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 47], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])]]
for label, args, expected in cases[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(body, commands):
    state = 'created'
    pc = 0
    stack = []
    handlers = []
    out = []
    def run(inject, exc):
        nonlocal pc, state
        if exc is not None:
            while handlers and handlers[-1][0] not in (exc, 'Exception'):
                handlers.pop()
            if not handlers:
                state = 'done'
                return ['raised', exc]
            pc = handlers.pop()[1]
        elif state == 'suspended':
            stack.append(inject)
        state = 'running'
        try:
            while True:
                ins = body[pc]
                op = ins[0]
                pc += 1
                if op == 'push':
                    stack.append(ins[1])
                elif op == 'pop':
                    stack.pop()
                elif op == 'add':
                    b = stack.pop()
                    a = stack.pop()
                    stack.append(a + b)
                elif op == 'yield':
                    state = 'suspended'
                    return ['yielded', stack.pop(0)]
                elif op == 'return':
                    state = 'done'
                    return ['StopIteration', stack.pop()]
                elif op == 'try':
                    handlers.append((ins[1], ins[2]))
                elif op == 'endtry':
                    handlers.pop()
        except (IndexError, TypeError):
            state = 'done'
            return ['vm-error']
    for cmd in commands:
        kind = cmd[0]
        if kind in ('next', 'send'):
            value = cmd[1] if kind == 'send' else None
            if state == 'done':
                out.append(['StopIteration', None])
            elif state == 'created' and value is not None:
                out.append(['TypeError'])
            else:
                out.append(run(value, None))
        elif kind == 'throw':
            if state == 'created' or state == 'done':
                state = 'done'
                out.append(['raised', cmd[1]])
            else:
                out.append(run(None, cmd[1]))
        else:
            state = 'done'
            out.append(['closed'])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['next'], ['send', 7], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 17], ['StopIteration', 6], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['send', 0], ['next'], ['send', 1]]),
   [['TypeError'], ['yielded', 1], ['yielded', 11]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 6]]),
  ('yield hands out and removes the value',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 8], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 43],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 43], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 5], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 6], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['next'], ['send', 14], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 24], ['StopIteration', 7], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['send', 0], ['next'], ['send', 2]]),
   [['TypeError'], ['yielded', 1], ['yielded', 12]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 7]]),
  ('yield hands out and removes the value',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 13], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 44],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 44], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 10], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 7], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['next'], ['send', 21], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 31], ['StopIteration', 8], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['send', 0], ['next'], ['send', 3]]),
   [['TypeError'], ['yielded', 1], ['yielded', 13]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 8]]),
  ('yield hands out and removes the value',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 18], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 45],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 45], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 15], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 8], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['next'], ['send', 28], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 38], ['StopIteration', 9], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['send', 0], ['next'], ['send', 4]]),
   [['TypeError'], ['yielded', 1], ['yielded', 14]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 9]]),
  ('yield hands out and removes the value',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 23], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 46],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 46], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 20], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 9], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])],
 [('regression: send values through two yields',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['next'], ['send', 35], ['next'], ['next']]),
   [['yielded', 1], ['yielded', 45], ['StopIteration', 10], ['StopIteration', None]]),
  ('non-None send to a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['send', 0], ['next'], ['send', 5]]),
   [['TypeError'], ['yielded', 1], ['yielded', 15]]),
  ('sending zero to a suspended generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['next'], ['send', 0], ['next']]),
   [['yielded', 1], ['yielded', 10], ['StopIteration', 10]]),
  ('yield hands out and removes the value',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['send', 3], ['next']]),
   [['yielded', 1], ['StopIteration', 28], ['StopIteration', None]]),
  ('thrown exception caught by catch-all handler',
   ([['try', 'Exception', 7],
     ['push', 1],
     ['yield'],
     ['pop'],
     ['endtry'],
     ['push', -1],
     ['return'],
     ['push', 47],
     ['yield'],
     ['pop'],
     ['push', 0],
     ['return']],
    [['next'], ['throw', 'ValueError'], ['next']]),
   [['yielded', 1], ['yielded', 47], ['StopIteration', 0]]),
  ('uncaught throw finishes the generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['throw', 'KeyError'], ['next']]),
   [['yielded', 1], ['raised', 'KeyError'], ['StopIteration', None]]),
  ('closing a fresh generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['close'], ['next']]),
   [['closed'], ['StopIteration', None]]),
  ('closing a suspended generator',
   ([['push', 25], ['push', 1], ['yield'], ['add'], ['return']], [['next'], ['close'], ['next']]),
   [['yielded', 1], ['closed'], ['StopIteration', None]]),
  ('control: throw into a fresh generator',
   ([['push', 1], ['yield'], ['push', 10], ['add'], ['yield'], ['pop'], ['push', 10], ['return']],
    [['throw', 'ValueError'], ['next']]),
   [['raised', 'ValueError'], ['StopIteration', None]])]]
for label, args, expected in cases[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Arithmetic after resumption combines the sent value with the stale yielded value.

A generator frame runs body ops push v, pop, add, yield (pop and hand out a value, suspend), return (pop, finish with StopIteration value), try exc target / endtry (handler stack; handler "Exception" catches any thrown name). Commands: next (= send None) and send v resume; resuming a suspended frame pushes the sent value as the result of its yield; sending non-None to a never-started generator is ["TypeError"]; a finished generator answers ["StopIteration", None]. throw into a created or finished generator finishes it with ["raised", exc]; otherwise the innermost matching handler is jumped to, or the generator finishes and re-raises. close finishes the generator. Frame faults are ["vm-error"].

split: open-access