From d167cd4dddece97c40dba807f0ebca18e6be2f0c Mon Sep 17 00:00:00 2001 From: Alpamys Date: Fri, 20 Feb 2026 16:36:18 +0500 Subject: [PATCH] Fix Python 3.9 compatibility + add .claude project settings - Replace `str | list[str]` with `Union[str, List[str]]` (3.9 compat) - Replace `str | None` with `Optional[str]` in validator.py - Replace `Live | None` with `Optional[Live]` in display.py - Add .claude/settings.json: auto-allow git, ruff, pytest, pip, soup Co-Authored-By: Claude Opus 4.6 --- .claude/settings.json | 24 ++++++++++++++++++++++++ soup_cli/config/schema.py | 6 +++--- soup_cli/data/validator.py | 4 +++- soup_cli/monitoring/display.py | 4 +++- 4 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 .claude/settings.json diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..372538d --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,24 @@ +{ + "permissions": { + "allow": [ + "Bash(git status*)", + "Bash(git diff*)", + "Bash(git log*)", + "Bash(git add*)", + "Bash(git commit*)", + "Bash(git push*)", + "Bash(git branch*)", + "Bash(git checkout*)", + "Bash(git stash*)", + "Bash(git remote*)", + "Bash(ruff check*)", + "Bash(ruff format*)", + "Bash(pytest*)", + "Bash(python -m pytest*)", + "Bash(pip install*)", + "Bash(pip list*)", + "Bash(soup *)", + "Bash(python -m soup_cli*)" + ] + } +} diff --git a/soup_cli/config/schema.py b/soup_cli/config/schema.py index 8259f5d..157d558 100644 --- a/soup_cli/config/schema.py +++ b/soup_cli/config/schema.py @@ -1,6 +1,6 @@ """Pydantic schemas for soup.yaml config — single source of truth.""" -from typing import Literal, Optional +from typing import List, Literal, Optional, Union from pydantic import BaseModel, Field @@ -9,7 +9,7 @@ class LoraConfig(BaseModel): r: int = Field(default=64, description="LoRA rank") alpha: int = Field(default=16, description="LoRA alpha") dropout: float = Field(default=0.05, description="LoRA dropout") - target_modules: str | list[str] = Field( + target_modules: Union[str, List[str]] = Field( default="auto", description="Target modules for LoRA. 'auto' = let peft decide.", ) @@ -28,7 +28,7 @@ class DataConfig(BaseModel): class TrainingConfig(BaseModel): epochs: int = Field(default=3, ge=1, description="Number of training epochs") lr: float = Field(default=2e-5, gt=0, description="Learning rate") - batch_size: int | Literal["auto"] = Field( + batch_size: Union[int, Literal["auto"]] = Field( default="auto", description="Batch size. 'auto' = find max that fits in memory.", ) diff --git a/soup_cli/data/validator.py b/soup_cli/data/validator.py index 1d322b8..688525f 100644 --- a/soup_cli/data/validator.py +++ b/soup_cli/data/validator.py @@ -1,9 +1,11 @@ """Dataset validation and statistics.""" +from typing import Optional + from soup_cli.data.formats import FORMAT_SIGNATURES -def validate_and_stats(data: list[dict], expected_format: str | None = None) -> dict: +def validate_and_stats(data: list[dict], expected_format: Optional[str] = None) -> dict: """Compute stats and validate dataset.""" if not data: return { diff --git a/soup_cli/monitoring/display.py b/soup_cli/monitoring/display.py index af78b65..b48e947 100644 --- a/soup_cli/monitoring/display.py +++ b/soup_cli/monitoring/display.py @@ -1,5 +1,7 @@ """Rich live training dashboard in the terminal.""" +from typing import Optional + from rich.console import Console from rich.live import Live from rich.panel import Panel @@ -23,7 +25,7 @@ class TrainingDisplay: self.grad_norm = 0.0 self.gpu_mem = "" self.speed = 0.0 - self._live: Live | None = None + self._live: Optional[Live] = None def start(self, total_steps: int): """Start the live display."""