diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5b282b3f..136c84bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,9 +11,10 @@ jobs: steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v5 - # Error-level rules only for now (syntax errors, undefined names, - # invalid prints/f-strings). Widen as the Phase 2 burndown lands. - - run: uvx ruff check --select E9,F63,F7,F82 gas neurons tests + # Error-level rules plus T201 (no print() in library code — CLI + # presenters are exempted via per-file-ignores in pyproject). + # Widen further as the Phase 2 burndown lands. + - run: uvx ruff check --select E9,F63,F7,F82,T201 gas neurons tests test: runs-on: ubuntu-latest diff --git a/gas/cache/media_storage.py b/gas/cache/media_storage.py index 46dee9a5..bd8b095e 100644 --- a/gas/cache/media_storage.py +++ b/gas/cache/media_storage.py @@ -3,6 +3,7 @@ from typing import Dict, Any, Optional, List from pathlib import Path +import bittensor as bt import cv2 import numpy as np from diffusers.utils import export_to_video @@ -107,7 +108,7 @@ def write_media(self, media_data: "Media") -> tuple[Optional[str], Optional[str] return str(save_path), str(mask_path) if mask_path else None except Exception as e: - print(f"Error writing media: {e}") + bt.logging.error(f"Error writing media: {e}") return None, None def _write_image_content(self, media_data: "Media", save_path: Path) -> None: @@ -162,12 +163,12 @@ def read_image( """ try: if not image_path.exists(): - print(f"Image file not found: {image_path}") + bt.logging.warning(f"Image file not found: {image_path}") return None image = cv2.imread(str(image_path)) if image is None: - print(f"Failed to load image: {image_path}") + bt.logging.warning(f"Failed to load image: {image_path}") return None if as_rgb: @@ -182,7 +183,7 @@ def read_image( return image except Exception as e: - print(f"Error reading image {image_path}: {e}") + bt.logging.error(f"Error reading image {image_path}: {e}") return None def read_mask(self, mask_path: Path) -> Optional[np.ndarray]: @@ -195,13 +196,13 @@ def read_mask(self, mask_path: Path) -> Optional[np.ndarray]: """ try: if not mask_path.exists(): - print(f"Mask file not found: {mask_path}") + bt.logging.warning(f"Mask file not found: {mask_path}") return None return np.load(mask_path) except Exception as e: - print(f"Error reading mask {mask_path}: {e}") + bt.logging.error(f"Error reading mask {mask_path}: {e}") return None def read_video_frames( @@ -223,7 +224,7 @@ def read_video_frames( """ try: if not video_path.exists(): - print(f"Video file not found: {video_path}") + bt.logging.warning(f"Video file not found: {video_path}") return None return sample_frames( @@ -234,7 +235,7 @@ def read_video_frames( ) except Exception as e: - print(f"Error reading video {video_path}: {e}") + bt.logging.error(f"Error reading video {video_path}: {e}") return None def list_media_files( @@ -286,7 +287,7 @@ def delete_media_file(self, file_path: Path) -> bool: return True except Exception as e: - print(f"Error deleting media file {file_path}: {e}") + bt.logging.error(f"Error deleting media file {file_path}: {e}") return False def retrieve_media( @@ -314,7 +315,7 @@ def retrieve_media( for media_entry in media_entries: file_path = Path(media_entry.file_path) if not file_path.exists(): - print(f"Media file not found: {file_path}") + bt.logging.warning(f"Media file not found: {file_path}") continue try: @@ -335,7 +336,7 @@ def retrieve_media( mask_path = file_path.parent / (file_path.stem + "_mask.npy") mask = self.read_mask(mask_path) if mask is None: - print(f"Mask not found for {file_path}") + bt.logging.warning(f"Mask not found for {file_path}") continue item = { @@ -372,6 +373,6 @@ def retrieve_media( sampled_items.append(item) except Exception as e: - print(f"Error processing {file_path}: {e}") + bt.logging.error(f"Error processing {file_path}: {e}") return {"count": len(sampled_items), "items": sampled_items} diff --git a/gas/cache/util/filesystem.py b/gas/cache/util/filesystem.py index 25e6a557..7720841e 100644 --- a/gas/cache/util/filesystem.py +++ b/gas/cache/util/filesystem.py @@ -1,5 +1,4 @@ import asyncio -import sys import time from pathlib import Path from typing import Any, Callable, Dict, List, Optional, Tuple, Union @@ -81,7 +80,7 @@ def get_dir_size( total_size += subdir_size file_count += subdir_count except (PermissionError, OSError) as e: - print(f"Error accessing {path}: {e}", file=sys.stderr) + bt.logging.warning(f"Error accessing {path}: {e}") return total_size, file_count @@ -181,7 +180,7 @@ def analyze_directory( if log_func: log_func(error_msg) else: - print(error_msg, file=sys.stderr) + bt.logging.warning(error_msg) return result @@ -215,7 +214,7 @@ def print_directory_tree( if log_func: log_func(tree_line) else: - print(tree_line) + print(tree_line) # noqa: T201 - display fallback for interactive tree output num_subdirs = len(tree_data["subdirs"]) diff --git a/gas/cache/util/video.py b/gas/cache/util/video.py index 2d5bd238..f54c1db9 100644 --- a/gas/cache/util/video.py +++ b/gas/cache/util/video.py @@ -6,6 +6,7 @@ from pathlib import Path from typing import Any, Dict, Optional, Tuple +import bittensor as bt import ffmpeg import numpy as np from PIL import Image @@ -53,7 +54,7 @@ def sample_frames( height = int(video_info.get("height", 256)) reported_fps = float(video_info.get("fps", max_fps)) except Exception as e: - print(f"Unable to extract video metadata from {str(video_path)}: {e}") + bt.logging.warning(f"Unable to extract video metadata from {str(video_path)}: {e}") return None if ( @@ -61,7 +62,7 @@ def sample_frames( or reported_fps <= 0 or not math.isfinite(reported_fps) ): - print(f"Unreasonable FPS ({reported_fps}) detected in {video_path}, capping at {max_fps}") + bt.logging.warning(f"Unreasonable FPS ({reported_fps}) detected in {video_path}, capping at {max_fps}") frame_rate = max_fps else: frame_rate = reported_fps @@ -106,19 +107,19 @@ def sample_frames( frame.load() # Verify image can be loaded frames.append(np.array(frame)) except Exception as e: - print(f"Failed to process frame at {timestamp}s: {e}") + bt.logging.warning(f"Failed to process frame at {timestamp}s: {e}") continue except ffmpeg.Error as e: - print(f"FFmpeg error at {timestamp}s: {e.stderr.decode()}") + bt.logging.warning(f"FFmpeg error at {timestamp}s: {e.stderr.decode()}") continue if len(no_data) > 0: tmin, tmax = min(no_data), max(no_data) - print(f"No data received for {len(no_data)} frames between {tmin} and {tmax}") + bt.logging.warning(f"No data received for {len(no_data)} frames between {tmin} and {tmax}") if not frames: - print(f"No frames successfully extracted from {video_path}") + bt.logging.warning(f"No frames successfully extracted from {video_path}") return None frames = np.stack(frames, axis=0) @@ -139,7 +140,7 @@ def sample_frames( with open(metadata_path, "r") as f: metadata = json.load(f) except Exception as e: - print(f"Error loading metadata for {video_path}: {e}") + bt.logging.warning(f"Error loading metadata for {video_path}: {e}") result = { "video": frames, @@ -156,14 +157,14 @@ def sample_frames( }, } - print(f"Successfully sampled {actual_duration}s segment ({len(frames)} frames)") + bt.logging.debug(f"Successfully sampled {actual_duration}s segment ({len(frames)} frames)") return result except Exception as e: - print(f"Error sampling from {video_path}: {e}") + bt.logging.warning(f"Error sampling from {video_path}: {e}") continue - print("Failed to sample any video after multiple attempts") + bt.logging.error("Failed to sample any video after multiple attempts") return None diff --git a/gas/generation/util/image.py b/gas/generation/util/image.py index 624baf67..6a204ca9 100644 --- a/gas/generation/util/image.py +++ b/gas/generation/util/image.py @@ -1,6 +1,7 @@ import numpy as np import PIL import os +import bittensor as bt from PIL import Image, ImageDraw from typing import Tuple, Union, List @@ -65,9 +66,9 @@ def save_images_to_disk( # if resize: # image = resize_image(image, TARGET_IMAGE_SIZE[0], TARGET_IMAGE_SIZE[1]) image.save(file_path, "JPEG") # Save the image - print(f"Saved: {file_path}") + bt.logging.debug(f"Saved: {file_path}") except Exception as e: - print(f"Failed to save image {i}: {e}") + bt.logging.error(f"Failed to save image {i}: {e}") def ensure_mask_3d(mask: np.ndarray) -> np.ndarray: diff --git a/pyproject.toml b/pyproject.toml index 3e2383df..5365123a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,6 +73,16 @@ dev = ["pytest>=8.0"] testpaths = ["tests"] pythonpath = ["."] +[tool.ruff.lint.per-file-ignores] +# T201 (print): allowed in genuine CLI presenters / tools / scripts, where +# stdout is the intended output. Library code must use bt.logging. +"gas/cache/util/miner_stats.py" = ["T201"] +"gas/protocol/miner_requests.py" = ["T201"] +"neurons/discriminator/push_model.py" = ["T201"] +"neurons/generator/helper/verify_c2pa.py" = ["T201"] +"scripts/**" = ["T201"] +"tests/**" = ["T201"] + [tool.setuptools] packages = { find = { where = [ ".",