| 322 | self.side_effect = side_effect |
| 323 | |
| 324 | def playbook_eval(self, playbook: Playbook) -> events.CommandCompleted: |
| 325 | if isinstance(self.to, int): |
| 326 | expected = playbook.expected[: playbook.expected.index(self)] |
| 327 | assert abs(self.to) < len(expected) |
| 328 | to = expected[self.to] |
| 329 | if not isinstance(to, commands.Command): |
| 330 | raise AssertionError(f"There is no command at offset {self.to}: {to}") |
| 331 | else: |
| 332 | self.to = to |
| 333 | elif isinstance(self.to, type): |
| 334 | for cmd in reversed(playbook.actual): |
| 335 | if isinstance(cmd, self.to): |
| 336 | assert isinstance(cmd, commands.Command) |
| 337 | self.to = cmd |
| 338 | break |
| 339 | else: |
| 340 | raise AssertionError(f"There is no command of type {self.to}.") |
| 341 | for cmd in reversed(playbook.actual): |
| 342 | if eq(self.to, cmd): |
| 343 | self.to = cmd |
| 344 | break |
| 345 | else: |
| 346 | raise AssertionError(f"Expected command {self.to} did not occur.") |
| 347 | |
| 348 | assert isinstance(self.to, commands.Command) |
| 349 | if isinstance(self.to, commands.StartHook): |
| 350 | self.side_effect(*self.to.args()) |
| 351 | reply_cls = events.HookCompleted |
| 352 | else: |
| 353 | self.side_effect(self.to) |
| 354 | reply_cls = command_reply_subclasses[type(self.to)] |
| 355 | try: |
| 356 | inst = reply_cls(self.to, *self.args) |
| 357 | except TypeError as e: |
| 358 | raise ValueError(f"Cannot instantiate {reply_cls.__name__}: {e}") |
| 359 | return inst |
| 360 | |
| 361 | |
| 362 | T = TypeVar("T") |