h
This commit is contained in:
@@ -8,7 +8,10 @@ import os
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
import logging
|
||||
from threading import RLock
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
from typing import Any, Callable, Dict, List, Optional, Protocol, TextIO
|
||||
@@ -474,7 +477,7 @@ class ProgressBar:
|
||||
total=int(total)
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to update pipeline UI transfer in ProgressBar._ensure_started")
|
||||
return
|
||||
|
||||
if self._progress is not None and self._task_id is not None:
|
||||
@@ -506,8 +509,8 @@ class ProgressBar:
|
||||
else:
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
logger.exception("Failed to initialize pipeline Live UI integration in ProgressBar._ensure_started")
|
||||
|
||||
stream = file if file is not None else sys.stderr
|
||||
# Use shared stderr console when rendering to stderr (cooperates with PipelineLiveProgress).
|
||||
if stream is sys.stderr:
|
||||
@@ -516,6 +519,7 @@ class ProgressBar:
|
||||
|
||||
console = stderr_console()
|
||||
except Exception:
|
||||
logger.exception("Failed to acquire shared stderr Console from SYS.rich_display; using fallback Console")
|
||||
console = Console(file=stream)
|
||||
else:
|
||||
console = Console(file=stream)
|
||||
@@ -558,7 +562,7 @@ class ProgressBar:
|
||||
int) and total > 0 else None,
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to update pipeline UI transfer in ProgressBar.update")
|
||||
return
|
||||
|
||||
if self._progress is None or self._task_id is None:
|
||||
@@ -582,7 +586,7 @@ class ProgressBar:
|
||||
try:
|
||||
self._pipeline_ui.finish_transfer(label=self._pipeline_label)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to finish pipeline UI transfer in ProgressBar.finish")
|
||||
finally:
|
||||
self._pipeline_ui = None
|
||||
self._pipeline_label = None
|
||||
@@ -681,7 +685,7 @@ class ProgressFileReader:
|
||||
# EOF
|
||||
self._finish()
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Error while reading and updating ProgressFileReader")
|
||||
return chunk
|
||||
|
||||
def seek(self, offset: int, whence: int = 0) -> Any:
|
||||
@@ -695,7 +699,7 @@ class ProgressFileReader:
|
||||
else:
|
||||
self._read = pos
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to determine file position in ProgressFileReader.seek")
|
||||
return out
|
||||
|
||||
def tell(self) -> Any:
|
||||
@@ -705,7 +709,7 @@ class ProgressFileReader:
|
||||
try:
|
||||
self._finish()
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to finish ProgressFileReader progress in close")
|
||||
return self._f.close()
|
||||
|
||||
def __getattr__(self, name: str) -> Any:
|
||||
@@ -825,6 +829,7 @@ class PipelineLiveProgress:
|
||||
try:
|
||||
value = str(text or "").strip()
|
||||
except Exception:
|
||||
logger.exception("Failed to compute active subtask text in PipelineLiveProgress.set_active_subtask_text")
|
||||
value = ""
|
||||
self._active_subtask_text = value or None
|
||||
|
||||
@@ -1011,10 +1016,11 @@ class PipelineLiveProgress:
|
||||
else:
|
||||
stop_fn()
|
||||
except Exception:
|
||||
logger.exception("Failed to stop Live with clear parameter; retrying without clear")
|
||||
try:
|
||||
stop_fn()
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to stop Live on retry")
|
||||
|
||||
self._live = None
|
||||
self._console = None
|
||||
@@ -1043,9 +1049,9 @@ class PipelineLiveProgress:
|
||||
subtasks.stop_task(sub_id)
|
||||
subtasks.update(sub_id, visible=False)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to stop or hide subtask %s in PipelineLiveProgress._hide_pipe_subtasks", sub_id)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to hide pipe subtasks for index %s", pipe_index)
|
||||
|
||||
def set_pipe_status_text(self, pipe_index: int, text: str) -> None:
|
||||
"""Set a status line under the pipe bars for the given pipe."""
|
||||
@@ -1071,20 +1077,21 @@ class PipelineLiveProgress:
|
||||
try:
|
||||
self._hide_pipe_subtasks(pidx)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to hide pipe subtasks while setting status text for pipe %s", pidx)
|
||||
|
||||
task_id = self._status_tasks.get(pidx)
|
||||
if task_id is None:
|
||||
try:
|
||||
task_id = prog.add_task(msg)
|
||||
except Exception:
|
||||
logger.exception("Failed to add status task for pipe %s in set_pipe_status_text", pidx)
|
||||
return
|
||||
self._status_tasks[pidx] = task_id
|
||||
|
||||
try:
|
||||
prog.update(task_id, description=msg, refresh=True)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to update status task %s in set_pipe_status_text", task_id)
|
||||
|
||||
def clear_pipe_status_text(self, pipe_index: int) -> None:
|
||||
if not self._enabled:
|
||||
@@ -1104,7 +1111,7 @@ class PipelineLiveProgress:
|
||||
try:
|
||||
prog.remove_task(task_id)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to remove pipe status task %s in clear_pipe_status_text", task_id)
|
||||
|
||||
def set_pipe_percent(self, pipe_index: int, percent: int) -> None:
|
||||
"""Update the pipe bar as a percent (only when single-item mode is enabled)."""
|
||||
@@ -1127,7 +1134,7 @@ class PipelineLiveProgress:
|
||||
pipe_progress.update(pipe_task, completed=pct, total=100, refresh=True)
|
||||
self._update_overall()
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to set pipe percent for pipe %s in set_pipe_percent", pipe_index)
|
||||
|
||||
def _update_overall(self) -> None:
|
||||
"""Update the overall pipeline progress task."""
|
||||
@@ -1142,6 +1149,7 @@ class PipelineLiveProgress:
|
||||
if self._pipe_done[i] >= max(1, self._pipe_totals[i])
|
||||
)
|
||||
except Exception:
|
||||
logger.exception("Failed to compute completed pipes in _update_overall")
|
||||
completed = 0
|
||||
|
||||
try:
|
||||
@@ -1151,7 +1159,7 @@ class PipelineLiveProgress:
|
||||
description=f"Pipeline: {completed}/{len(self._pipe_labels)} pipes completed",
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to update overall pipeline task in _update_overall")
|
||||
|
||||
# Auto-stop Live rendering once all pipes are complete so the progress
|
||||
# UI clears itself even if callers forget to stop it explicitly.
|
||||
@@ -1161,7 +1169,7 @@ class PipelineLiveProgress:
|
||||
if total_pipes > 0 and completed >= total_pipes:
|
||||
self.stop()
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to auto-stop Live UI after all pipes completed")
|
||||
|
||||
def begin_pipe_steps(self, pipe_index: int, *, total_steps: int) -> None:
|
||||
"""Initialize step tracking for a pipe.
|
||||
@@ -1187,11 +1195,11 @@ class PipelineLiveProgress:
|
||||
try:
|
||||
self.clear_pipe_status_text(pidx)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to clear pipe status text in begin_pipe_steps for %s", pidx)
|
||||
try:
|
||||
self.set_pipe_percent(pidx, 0)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to set initial pipe percent in begin_pipe_steps for %s", pidx)
|
||||
|
||||
def advance_pipe_step(self, pipe_index: int, text: str) -> None:
|
||||
"""Advance the pipe's step counter by one.
|
||||
@@ -1226,14 +1234,14 @@ class PipelineLiveProgress:
|
||||
try:
|
||||
self.set_pipe_status_text(pidx, line)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to set pipe status text in advance_pipe_step for pipe %s", pidx)
|
||||
|
||||
# Percent mapping only applies when the pipe is in percent mode (single-item).
|
||||
try:
|
||||
pct = 100 if done >= total else int(round((done / max(1, total)) * 100.0))
|
||||
self.set_pipe_percent(pidx, pct)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to set pipe percent in advance_pipe_step for pipe %s", pidx)
|
||||
|
||||
def begin_transfer(self, *, label: str, total: Optional[int] = None) -> None:
|
||||
if not self._enabled:
|
||||
@@ -1247,14 +1255,14 @@ class PipelineLiveProgress:
|
||||
if total is not None and total > 0:
|
||||
self._transfers.update(self._transfer_tasks[key], total=int(total))
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to update existing transfer task total for %s in begin_transfer", key)
|
||||
return
|
||||
task_total = int(total) if isinstance(total, int) and total > 0 else None
|
||||
try:
|
||||
task_id = self._transfers.add_task(key, total=task_total)
|
||||
self._transfer_tasks[key] = task_id
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to add transfer task %s in begin_transfer", key)
|
||||
|
||||
def update_transfer(
|
||||
self,
|
||||
@@ -1282,7 +1290,7 @@ class PipelineLiveProgress:
|
||||
kwargs["total"] = int(total)
|
||||
self._transfers.update(task_id, refresh=True, **kwargs)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to update transfer '%s'", key)
|
||||
|
||||
def finish_transfer(self, *, label: str) -> None:
|
||||
if self._transfers is None:
|
||||
@@ -1294,7 +1302,7 @@ class PipelineLiveProgress:
|
||||
try:
|
||||
self._transfers.remove_task(task_id)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to remove transfer task '%s' in finish_transfer", key)
|
||||
|
||||
def _ensure_pipe(self, pipe_index: int) -> bool:
|
||||
if not self._enabled:
|
||||
@@ -1330,12 +1338,12 @@ class PipelineLiveProgress:
|
||||
try:
|
||||
self.clear_pipe_status_text(pipe_index)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to clear pipe status text during begin_pipe for %s", pipe_index)
|
||||
try:
|
||||
self._pipe_step_total.pop(pipe_index, None)
|
||||
self._pipe_step_done.pop(pipe_index, None)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to reset pipe step totals during begin_pipe for %s", pipe_index)
|
||||
|
||||
# If this pipe will process exactly one item, allow percent-based updates.
|
||||
percent_mode = bool(int(total_items) == 1)
|
||||
@@ -1351,7 +1359,7 @@ class PipelineLiveProgress:
|
||||
try:
|
||||
pipe_progress.start_task(pipe_task)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to start pipe task timer in begin_pipe for %s", pipe_index)
|
||||
|
||||
self._update_overall()
|
||||
|
||||
@@ -1386,6 +1394,7 @@ class PipelineLiveProgress:
|
||||
"description",
|
||||
"") or "").strip() or None
|
||||
except Exception:
|
||||
logger.exception("Failed to set active subtask text for first subtask %s in begin_pipe", first)
|
||||
self._active_subtask_text = None
|
||||
|
||||
def on_emit(self, pipe_index: int, emitted: Any) -> None:
|
||||
@@ -1429,7 +1438,7 @@ class PipelineLiveProgress:
|
||||
f"{self._pipe_labels[pipe_index]}: {_pipeline_progress_item_label(emitted)}",
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to update subtask description for current %s in on_emit", current)
|
||||
subtasks.stop_task(current)
|
||||
subtasks.update(current, visible=False)
|
||||
|
||||
@@ -1448,12 +1457,12 @@ class PipelineLiveProgress:
|
||||
try:
|
||||
self.clear_pipe_status_text(pipe_index)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to clear pipe status text after emit for %s", pipe_index)
|
||||
try:
|
||||
self._pipe_step_total.pop(pipe_index, None)
|
||||
self._pipe_step_done.pop(pipe_index, None)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to pop pipe step totals after emit for %s", pipe_index)
|
||||
|
||||
# Start next subtask spinner.
|
||||
next_index = active + 1
|
||||
@@ -1468,6 +1477,7 @@ class PipelineLiveProgress:
|
||||
"description",
|
||||
"") or "").strip() or None
|
||||
except Exception:
|
||||
logger.exception("Failed to set active subtask text for next subtask %s in on_emit", nxt)
|
||||
self._active_subtask_text = None
|
||||
else:
|
||||
self._active_subtask_text = None
|
||||
@@ -1504,7 +1514,7 @@ class PipelineLiveProgress:
|
||||
subtasks.stop_task(sub_id)
|
||||
subtasks.update(sub_id, visible=False)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to stop or hide subtask %s during finish_pipe for pipe %s", sub_id, pipe_index)
|
||||
|
||||
# If we just finished the active pipe, clear the title context.
|
||||
self._active_subtask_text = None
|
||||
@@ -1513,19 +1523,19 @@ class PipelineLiveProgress:
|
||||
try:
|
||||
self.clear_pipe_status_text(pipe_index)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to clear pipe status text during finish_pipe for %s", pipe_index)
|
||||
try:
|
||||
self._pipe_step_total.pop(pipe_index, None)
|
||||
self._pipe_step_done.pop(pipe_index, None)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to pop pipe step totals during finish_pipe for %s", pipe_index)
|
||||
|
||||
# Stop the per-pipe timer once the pipe is finished.
|
||||
try:
|
||||
pipe_task = self._pipe_tasks[pipe_index]
|
||||
pipe_progress.stop_task(pipe_task)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to stop pipe task %s during finish_pipe", pipe_index)
|
||||
|
||||
self._update_overall()
|
||||
|
||||
@@ -1537,7 +1547,7 @@ class PipelineLiveProgress:
|
||||
try:
|
||||
self.finish_pipe(idx)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to finish pipe %s in complete_all_pipes", idx)
|
||||
|
||||
|
||||
class PipelineStageContext:
|
||||
@@ -1568,7 +1578,7 @@ class PipelineStageContext:
|
||||
try:
|
||||
cb(obj)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Error in PipelineStageContext.emit callback")
|
||||
|
||||
def get_current_command_text(self) -> str:
|
||||
"""Get the current command text (for backward compatibility)."""
|
||||
|
||||
Reference in New Issue
Block a user