|
25 | 25 | from uuid import uuid4 |
26 | 26 |
|
27 | 27 | from marimo import _loggers |
28 | | -from marimo._ast.cell import CellConfig, CellImpl |
| 28 | +from marimo._ast.cell import CellConfig, CellImpl, RuntimeStateType |
29 | 29 | from marimo._ast.compiler import _build_source_position_map, compile_cell |
30 | 30 | from marimo._ast.errors import ImportStarError |
31 | 31 | from marimo._ast.names import SETUP_CELL_NAME |
@@ -1401,12 +1401,39 @@ async def _run_cells(self, cell_ids: set[CellId_t]) -> None: |
1401 | 1401 | # common cases. We could also be more aggressive and run this before |
1402 | 1402 | # every cell, or even before pickle.dump/pickle.dumps() |
1403 | 1403 | with patches.patch_main_module_context(self._module): |
| 1404 | + # Snapshot disabled cells that are in an error/cancelled state |
| 1405 | + # BEFORE running, so we can clear them after the run if their |
| 1406 | + # ancestor recovered. |
| 1407 | + pre_run_errored_disabled = { |
| 1408 | + cid |
| 1409 | + for cid, cell in self.graph.cells.items() |
| 1410 | + if self.graph.is_disabled(cid) |
| 1411 | + and cell.run_result_status |
| 1412 | + in ("exception", "marimo-error", "cancelled") |
| 1413 | + } |
1404 | 1414 | while cell_ids := await self._run_cells_internal(cell_ids): |
1405 | 1415 | LOGGER.debug("Running state updates ...") |
1406 | 1416 | if self.lazy() and cell_ids: |
1407 | 1417 | self.graph.set_stale(cell_ids, prune_imports=True) |
1408 | 1418 | break |
1409 | 1419 | LOGGER.debug("Finished run.") |
| 1420 | + # Clear stale error state from disabled cells whose ancestor |
| 1421 | + # recovered. Uses pre-run snapshot since run_result_status is |
| 1422 | + # updated during the run. |
| 1423 | + for cid in pre_run_errored_disabled: |
| 1424 | + cell_impl = self.graph.cells[cid] |
| 1425 | + if not self.graph.is_any_ancestor_errored(cid): |
| 1426 | + cell_impl.set_run_result_status("disabled") |
| 1427 | + status = cast( |
| 1428 | + RuntimeStateType, |
| 1429 | + "idle" |
| 1430 | + if cell_impl.config.disabled |
| 1431 | + else "disabled-transitively", |
| 1432 | + ) |
| 1433 | + cell_impl.set_runtime_state(status) |
| 1434 | + CellNotificationUtils.broadcast_empty_output( |
| 1435 | + cell_id=cid, status=status |
| 1436 | + ) |
1410 | 1437 |
|
1411 | 1438 | async def _if_autorun_then_run_cells( |
1412 | 1439 | self, cell_ids: set[CellId_t] |
@@ -1814,6 +1841,7 @@ async def run_stale_cells(self) -> None: |
1814 | 1841 | relatives=dataflow.get_import_block_relatives(self.graph), |
1815 | 1842 | ) |
1816 | 1843 | ) |
| 1844 | + |
1817 | 1845 | if self.module_watcher is not None: |
1818 | 1846 | self.module_watcher.run_is_processed.set() |
1819 | 1847 |
|
|
0 commit comments