Add YAPF style + ignore, and format tracked Python files

This commit is contained in:
2025-12-29 18:42:02 -08:00
parent c019c00aed
commit 507946a3e4
108 changed files with 11664 additions and 6494 deletions

210
models.py
View File

@@ -117,7 +117,9 @@ class PipeObject:
import pipeline as ctx
current = (
ctx.get_current_cmdlet_name("") if hasattr(ctx, "get_current_cmdlet_name") else ""
ctx.get_current_cmdlet_name("")
if hasattr(ctx,
"get_current_cmdlet_name") else ""
)
if current:
cmdlet_name = current
@@ -142,10 +144,11 @@ class PipeObject:
def to_dict(self) -> Dict[str, Any]:
"""Serialize to dictionary, excluding None and empty values."""
data: Dict[str, Any] = {
"hash": self.hash,
"store": self.store,
}
data: Dict[str,
Any] = {
"hash": self.hash,
"store": self.store,
}
if self.provider:
data["provider"] = self.provider
@@ -176,7 +179,10 @@ class PipeObject:
data["parent_hash"] = self.parent_hash
# Add extra fields
data.update({k: v for k, v in self.extra.items() if v is not None})
data.update({
k: v
for k, v in self.extra.items() if v is not None
})
return data
@@ -190,7 +196,9 @@ class FileRelationshipTracker:
"""
def __init__(self) -> None:
self.relationships: Dict[str, Dict[str, Any]] = {}
self.relationships: Dict[str,
Dict[str,
Any]] = {}
def register_king(self, file_path: str, file_hash: str) -> None:
"""Register a file as the king (primary) version."""
@@ -271,7 +279,8 @@ class DownloadOptions:
debug_log: Optional[Path] = None
native_progress: bool = False
clip_sections: Optional[str] = None
playlist_items: Optional[str] = None # yt-dlp --playlist-items format (e.g., "1-3,5,8")
playlist_items: Optional[
str] = None # yt-dlp --playlist-items format (e.g., "1-3,5,8")
no_playlist: bool = False # If True, pass --no-playlist to yt-dlp
quiet: bool = False # If True, suppress all console output (progress, debug logs)
embed_chapters: bool = False # If True, pass yt-dlp --embed-chapters / embedchapters
@@ -281,7 +290,8 @@ class DownloadOptions:
class SendFunc(Protocol):
"""Protocol for event sender function."""
def __call__(self, event: str, **payload: Any) -> None: ...
def __call__(self, event: str, **payload: Any) -> None:
...
@dataclass(slots=True)
@@ -324,7 +334,11 @@ class DebugLogger:
if self.session_started:
return
self.session_started = True
self.write_record("session-start", {"pid": os.getpid(), "exe": sys.executable})
self.write_record("session-start",
{
"pid": os.getpid(),
"exe": sys.executable
})
def write_raw(self, text: str) -> None:
"""Write raw text to debug log."""
@@ -334,7 +348,12 @@ class DebugLogger:
self.file.write(text + "\n")
self.file.flush()
def write_record(self, event: str, payload: Optional[Dict[str, Any]] = None) -> None:
def write_record(
self,
event: str,
payload: Optional[Dict[str,
Any]] = None
) -> None:
"""Write a structured event record to debug log."""
record = {
"timestamp": datetime.datetime.utcnow().isoformat(timespec="seconds") + "Z",
@@ -353,7 +372,12 @@ class DebugLogger:
self.file = None
def _sanitise_for_json(value: Any, *, max_depth: int = 8, _seen: Optional[set[int]] = None) -> Any:
def _sanitise_for_json(
value: Any,
*,
max_depth: int = 8,
_seen: Optional[set[int]] = None
) -> Any:
"""Best-effort conversion to JSON-serialisable types without raising on cycles."""
import math
from dataclasses import asdict, is_dataclass
@@ -386,16 +410,24 @@ def _sanitise_for_json(value: Any, *, max_depth: int = 8, _seen: Optional[set[in
try:
if isinstance(value, dict):
return {
str(key): _sanitise_for_json(val, max_depth=max_depth - 1, _seen=_seen)
str(key): _sanitise_for_json(val,
max_depth=max_depth - 1,
_seen=_seen)
for key, val in value.items()
}
if isinstance(value, (list, tuple, set)):
iterable = value if not isinstance(value, set) else list(value)
return [
_sanitise_for_json(item, max_depth=max_depth - 1, _seen=_seen) for item in iterable
_sanitise_for_json(item,
max_depth=max_depth - 1,
_seen=_seen) for item in iterable
]
if is_dataclass(value) and not isinstance(value, type):
return _sanitise_for_json(asdict(value), max_depth=max_depth - 1, _seen=_seen)
return _sanitise_for_json(
asdict(value),
max_depth=max_depth - 1,
_seen=_seen
)
finally:
_seen.discard(obj_id)
@@ -423,13 +455,21 @@ class ProgressBar:
self._pipeline_ui: Any = None
self._pipeline_label: Optional[str] = None
def _ensure_started(self, *, label: str, total: Optional[int], file: Any = None) -> None:
def _ensure_started(
self,
*,
label: str,
total: Optional[int],
file: Any = None
) -> None:
if self._pipeline_ui is not None and self._pipeline_label:
# Pipeline-backed transfer task is already registered; update its total if needed.
try:
if total is not None and total > 0:
self._pipeline_ui.update_transfer(
label=self._pipeline_label, completed=None, total=int(total)
label=self._pipeline_label,
completed=None,
total=int(total)
)
except Exception:
pass
@@ -445,13 +485,17 @@ class ProgressBar:
import pipeline as pipeline_context
ui = pipeline_context.get_live_progress()
if ui is not None and hasattr(ui, "begin_transfer") and hasattr(ui, "update_transfer"):
if ui is not None and hasattr(ui,
"begin_transfer") and hasattr(
ui,
"update_transfer"):
self._pipeline_ui = ui
self._pipeline_label = str(label or "download")
try:
ui.begin_transfer(
label=self._pipeline_label,
total=int(total) if isinstance(total, int) and total > 0 else None,
total=int(total) if isinstance(total,
int) and total > 0 else None,
)
except Exception:
# If pipeline integration fails, fall back to standalone progress.
@@ -508,7 +552,8 @@ class ProgressBar:
self._pipeline_ui.update_transfer(
label=self._pipeline_label,
completed=int(downloaded or 0) if downloaded is not None else None,
total=int(total) if isinstance(total, int) and total > 0 else None,
total=int(total) if isinstance(total,
int) and total > 0 else None,
)
except Exception:
pass
@@ -518,10 +563,17 @@ class ProgressBar:
return
if total is not None and total > 0:
self._progress.update(
self._task_id, completed=int(downloaded or 0), total=int(total), refresh=True
self._task_id,
completed=int(downloaded or 0),
total=int(total),
refresh=True
)
else:
self._progress.update(self._task_id, completed=int(downloaded or 0), refresh=True)
self._progress.update(
self._task_id,
completed=int(downloaded or 0),
refresh=True
)
def finish(self) -> None:
if self._pipeline_ui is not None and self._pipeline_label:
@@ -660,13 +712,14 @@ class ProgressFileReader:
def _pipeline_progress_item_label(value: Any, *, max_len: int = 72) -> str:
def _clip(text: str) -> str:
text = str(text or "").strip()
if not text:
return "(item)"
if len(text) <= max_len:
return text
return text[: max(0, max_len - 1)] + ""
return text[:max(0, max_len - 1)] + ""
try:
if isinstance(value, PipeObject):
@@ -715,18 +768,23 @@ class PipelineLiveProgress:
self._overall_task: Optional[TaskID] = None
self._pipe_tasks: List[TaskID] = []
self._transfer_tasks: Dict[str, TaskID] = {}
self._transfer_tasks: Dict[str,
TaskID] = {}
# Per-pipe status line shown below the pipe bars.
self._status_tasks: Dict[int, TaskID] = {}
self._status_tasks: Dict[int,
TaskID] = {}
# When a pipe is operating on a single item, allow percent-based progress
# updates on the pipe bar (0..100) so it doesn't sit at 0% until emit().
self._pipe_percent_mode: Dict[int, bool] = {}
self._pipe_percent_mode: Dict[int,
bool] = {}
# Per-pipe step counters used for status lines and percent mapping.
self._pipe_step_total: Dict[int, int] = {}
self._pipe_step_done: Dict[int, int] = {}
self._pipe_step_total: Dict[int,
int] = {}
self._pipe_step_done: Dict[int,
int] = {}
# Per-pipe state
self._pipe_totals: List[int] = [0 for _ in self._pipe_labels]
@@ -782,7 +840,12 @@ class PipelineLiveProgress:
body_parts.append(status)
body_parts.append(transfers)
yield Group(Panel(Group(*body_parts), title=self._title_text(), expand=False), overall)
yield Group(
Panel(Group(*body_parts),
title=self._title_text(),
expand=False),
overall
)
def _render_group(self) -> Group:
# Backward-compatible helper (some callers may still expect a Group).
@@ -797,7 +860,12 @@ class PipelineLiveProgress:
if status is not None and self._status_tasks:
body_parts.append(status)
body_parts.append(transfers)
return Group(Panel(Group(*body_parts), title=self._title_text(), expand=False), overall)
return Group(
Panel(Group(*body_parts),
title=self._title_text(),
expand=False),
overall
)
def start(self) -> None:
if not self._enabled:
@@ -875,10 +943,16 @@ class PipelineLiveProgress:
self._overall_task = self._overall.add_task(
f"Pipeline: 0/{len(self._pipe_labels)} pipes completed",
total=max(1, len(self._pipe_labels)),
total=max(1,
len(self._pipe_labels)),
)
self._live = Live(self, console=self._console, refresh_per_second=10, transient=True)
self._live = Live(
self,
console=self._console,
refresh_per_second=10,
transient=True
)
self._live.start()
def pause(self) -> None:
@@ -896,17 +970,18 @@ class PipelineLiveProgress:
return
if self._live is not None:
return
if (
self._console is None
or self._pipe_progress is None
or self._subtasks is None
or self._transfers is None
or self._overall is None
):
if (self._console is None or self._pipe_progress is None
or self._subtasks is None or self._transfers is None
or self._overall is None):
# Not initialized yet; start fresh.
self.start()
return
self._live = Live(self, console=self._console, refresh_per_second=10, transient=True)
self._live = Live(
self,
console=self._console,
refresh_per_second=10,
transient=True
)
self._live.start()
def stop(self) -> None:
@@ -1116,7 +1191,11 @@ class PipelineLiveProgress:
pass
def update_transfer(
self, *, label: str, completed: Optional[int], total: Optional[int] = None
self,
*,
label: str,
completed: Optional[int],
total: Optional[int] = None
) -> None:
if not self._enabled:
return
@@ -1129,7 +1208,8 @@ class PipelineLiveProgress:
if task_id is None:
return
try:
kwargs: Dict[str, Any] = {}
kwargs: Dict[str,
Any] = {}
if completed is not None:
kwargs["completed"] = int(completed)
if total is not None and total > 0:
@@ -1160,7 +1240,11 @@ class PipelineLiveProgress:
return True
def begin_pipe(
self, pipe_index: int, *, total_items: int, items_preview: Optional[List[Any]] = None
self,
pipe_index: int,
*,
total_items: int,
items_preview: Optional[List[Any]] = None
) -> None:
if not self._ensure_pipe(pipe_index):
return
@@ -1192,7 +1276,11 @@ class PipelineLiveProgress:
self._pipe_percent_mode[pipe_index] = percent_mode
pipe_task = self._pipe_tasks[pipe_index]
pipe_progress.update(pipe_task, completed=0, total=(100 if percent_mode else total_items))
pipe_progress.update(
pipe_task,
completed=0,
total=(100 if percent_mode else total_items)
)
# Start the per-pipe timer now that the pipe is actually running.
try:
pipe_progress.start_task(pipe_task)
@@ -1212,7 +1300,10 @@ class PipelineLiveProgress:
for i in range(total_items):
suffix = labels[i] if i < len(labels) else f"item {i + 1}/{total_items}"
# Use start=False so elapsed time starts when we explicitly start_task().
sub_id = subtasks.add_task(f"{self._pipe_labels[pipe_index]}: {suffix}", start=False)
sub_id = subtasks.add_task(
f"{self._pipe_labels[pipe_index]}: {suffix}",
start=False
)
subtasks.update(sub_id, visible=False)
self._subtask_ids[pipe_index].append(sub_id)
@@ -1223,7 +1314,9 @@ class PipelineLiveProgress:
subtasks.start_task(first)
try:
t = subtasks.tasks[first]
self._active_subtask_text = str(getattr(t, "description", "") or "").strip() or None
self._active_subtask_text = str(getattr(t,
"description",
"") or "").strip() or None
except Exception:
self._active_subtask_text = None
@@ -1262,7 +1355,8 @@ class PipelineLiveProgress:
# If we didnt have a preview label, set it now.
subtasks.update(
current,
description=f"{self._pipe_labels[pipe_index]}: {_pipeline_progress_item_label(emitted)}",
description=
f"{self._pipe_labels[pipe_index]}: {_pipeline_progress_item_label(emitted)}",
)
except Exception:
pass
@@ -1298,7 +1392,9 @@ class PipelineLiveProgress:
subtasks.start_task(nxt)
try:
t = subtasks.tasks[nxt]
self._active_subtask_text = str(getattr(t, "description", "") or "").strip() or None
self._active_subtask_text = str(getattr(t,
"description",
"") or "").strip() or None
except Exception:
self._active_subtask_text = None
else:
@@ -1360,16 +1456,18 @@ class PipelineLiveProgress:
completed = 0
try:
completed = sum(
1
for i in range(len(self._pipe_labels))
1 for i in range(len(self._pipe_labels))
if self._pipe_done[i] >= max(1, self._pipe_totals[i])
)
except Exception:
completed = 0
overall.update(
self._overall_task,
completed=min(completed, max(1, len(self._pipe_labels))),
description=f"Pipeline: {completed}/{len(self._pipe_labels)} pipes completed",
completed=min(completed,
max(1,
len(self._pipe_labels))),
description=
f"Pipeline: {completed}/{len(self._pipe_labels)} pipes completed",
)
@@ -1382,7 +1480,8 @@ class PipelineStageContext:
total_stages: int,
pipe_index: Optional[int] = None,
worker_id: Optional[str] = None,
on_emit: Optional[Callable[[Any], None]] = None,
on_emit: Optional[Callable[[Any],
None]] = None,
):
self.stage_index = stage_index
self.total_stages = total_stages
@@ -1505,7 +1604,10 @@ class ResultColumn:
def to_dict(self) -> Dict[str, str]:
"""Convert to dictionary."""
return {"name": self.name, "value": self.value}
return {
"name": self.name,
"value": self.value
}
@dataclass