fix: resolve all 153 ruff lint errors for CI
Lint & Test / test (push) Failing after 9s

Auto-fixed 138 unused imports and f-string issues. Manually fixed:
ambiguous variable names (l→layer), availability-check imports using
importlib.util.find_spec, unused Color import, ImagePool forward ref
via TYPE_CHECKING, multi-statement semicolons, and E402 suppression.
This commit is contained in:
2026-03-22 01:29:26 +03:00
parent f2871319cb
commit 7380b33b9b
79 changed files with 73 additions and 146 deletions
@@ -141,7 +141,6 @@ class AudioAnalyzer:
Returns:
AudioAnalysis with spectrum, RMS, beat, etc.
"""
chunk_size = self._chunk_size
alpha = self._smoothing_alpha
one_minus_alpha = 1.0 - alpha
@@ -16,8 +16,6 @@ from typing import Any, Dict, List, Optional, Tuple
from wled_controller.core.audio.analysis import (
AudioAnalysis,
AudioAnalyzer,
DEFAULT_CHUNK_SIZE,
DEFAULT_SAMPLE_RATE,
)
from wled_controller.core.audio.base import AudioCaptureStreamBase
from wled_controller.core.audio.factory import AudioEngineRegistry
@@ -3,7 +3,7 @@
import asyncio
import re
from datetime import datetime, timezone
from typing import Dict, List, Optional, Set
from typing import Dict, Optional, Set
from wled_controller.core.automations.platform_detector import PlatformDetector
from wled_controller.storage.automation import (
@@ -1,7 +1,7 @@
"""Calibration system for mapping screen pixels to LED positions."""
from dataclasses import dataclass, field
from typing import Dict, List, Literal, Optional, Set, Tuple
from typing import Dict, List, Literal, Set, Tuple
import numpy as np
@@ -1,7 +1,7 @@
"""Screen capture functionality using mss library."""
from dataclasses import dataclass
from typing import Dict, List
from typing import List
import mss
import numpy as np
@@ -4,9 +4,8 @@ import colorsys
import logging
import sys
import threading
import time
import tkinter as tk
from typing import Dict, List, Optional, Tuple
from typing import Dict, List, Optional
from wled_controller.core.capture.calibration import CalibrationConfig
from wled_controller.core.capture_engines.base import DisplayInfo
@@ -4,7 +4,6 @@ import sys
import time
from typing import Any, Dict, List, Optional
import numpy as np
from wled_controller.core.capture_engines.base import (
CaptureEngine,
@@ -145,9 +144,9 @@ class BetterCamEngine(CaptureEngine):
if sys.platform != "win32":
return False
try:
import bettercam
return True
except ImportError:
import importlib.util
return importlib.util.find_spec("bettercam") is not None
except (ImportError, ModuleNotFoundError, ValueError):
return False
@classmethod
@@ -14,7 +14,6 @@ import threading
import time
from typing import Any, Dict, List, Optional, Set
import numpy as np
from wled_controller.core.capture_engines.base import (
CaptureEngine,
@@ -74,7 +74,6 @@ class DemoCaptureStream(CaptureStream):
hue = ((self._angle + rotation) / (2.0 * np.pi)) % 1.0
# Saturation: full
sat = 1.0
# Value: bright at centre, fading toward edges
max_r = float(self._radius.max()) or 1.0
@@ -4,7 +4,6 @@ import sys
import time
from typing import Any, Dict, List, Optional
import numpy as np
from wled_controller.core.capture_engines.base import (
CaptureEngine,
@@ -145,9 +144,9 @@ class DXcamEngine(CaptureEngine):
if sys.platform != "win32":
return False
try:
import dxcam
return True
except ImportError:
import importlib.util
return importlib.util.find_spec("dxcam") is not None
except (ImportError, ModuleNotFoundError, ValueError):
return False
@classmethod
@@ -91,9 +91,9 @@ class MSSEngine(CaptureEngine):
@classmethod
def is_available(cls) -> bool:
try:
import mss
return True
except ImportError:
import importlib.util
return importlib.util.find_spec("mss") is not None
except (ImportError, ModuleNotFoundError, ValueError):
return False
@classmethod
@@ -5,7 +5,6 @@ import sys
import threading
from typing import Any, Dict, List, Optional
import numpy as np
from wled_controller.core.capture_engines.base import (
CaptureEngine,
@@ -220,9 +219,9 @@ class WGCEngine(CaptureEngine):
pass
try:
import windows_capture
return True
except ImportError:
import importlib.util
return importlib.util.find_spec("windows_capture") is not None
except (ImportError, ModuleNotFoundError, ValueError):
return False
@classmethod
@@ -2,7 +2,7 @@
import asyncio
from datetime import datetime, timezone
from typing import List, Optional, Tuple
from typing import Optional, Tuple
import numpy as np
@@ -1,7 +1,6 @@
"""Razer Chroma SDK LED client — controls Razer RGB peripherals via REST API."""
import asyncio
import json
from datetime import datetime, timezone
from typing import List, Optional, Tuple, Union
@@ -1,6 +1,5 @@
"""Razer Chroma SDK device provider — control Razer RGB peripherals."""
from datetime import datetime, timezone
from typing import List
from wled_controller.core.devices.led_client import (
@@ -7,7 +7,7 @@ from typing import List, Optional, Tuple, Union
import numpy as np
from wled_controller.core.devices.led_client import LEDClient, DeviceHealth
from wled_controller.core.devices.led_client import LEDClient
from wled_controller.utils import get_logger
logger = get_logger(__name__)
@@ -1,6 +1,5 @@
"""ESP-NOW device provider — ultra-low-latency LED control via ESP32 gateway."""
from datetime import datetime, timezone
from typing import List
from wled_controller.core.devices.led_client import (
@@ -1,6 +1,5 @@
"""SteelSeries GameSense LED client — controls SteelSeries RGB peripherals via REST API."""
import asyncio
import json
import os
import platform
@@ -1,6 +1,5 @@
"""SteelSeries GameSense device provider — control SteelSeries RGB peripherals."""
from datetime import datetime, timezone
from typing import List
from wled_controller.core.devices.led_client import (
@@ -1,7 +1,6 @@
"""Philips Hue device provider — entertainment streaming to Hue lights."""
import asyncio
from datetime import datetime, timezone
from typing import List, Tuple
from wled_controller.core.devices.led_client import (
@@ -1,7 +1,7 @@
"""Abstract base class for LED device communication clients and provider registry."""
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from dataclasses import dataclass
from datetime import datetime, timezone
from typing import Dict, List, Optional, Tuple, Union
@@ -1,7 +1,7 @@
"""MQTT LED client — publishes pixel data to an MQTT topic."""
import json
from typing import List, Optional, Tuple, Union
from typing import List, Tuple, Union
import numpy as np
@@ -1,7 +1,6 @@
"""MQTT device provider — factory, validation, health checks."""
from datetime import datetime
from typing import List, Optional, Tuple
from typing import List
from wled_controller.core.devices.led_client import (
DeviceHealth,
@@ -11,7 +10,6 @@ from wled_controller.core.devices.led_client import (
)
from wled_controller.core.devices.mqtt_client import (
MQTTLEDClient,
get_mqtt_service,
parse_mqtt_url,
)
from wled_controller.utils import get_logger
@@ -5,7 +5,7 @@ import socket
import struct
import threading
from datetime import datetime, timezone
from typing import Any, Dict, List, Optional, Tuple, Union
from typing import Any, List, Optional, Tuple, Union
import numpy as np
@@ -165,7 +165,6 @@ class OpenRGBLEDClient(LEDClient):
def _connect_sync(self) -> Tuple[Any, Any]:
"""Synchronous connect — runs in thread pool."""
from openrgb import OpenRGBClient
from openrgb.utils import DeviceType
client = OpenRGBClient(self._host, self._port, name="WLED Controller")
devices = client.devices
@@ -1,7 +1,7 @@
"""OpenRGB device provider — factory, validation, health checks, discovery."""
import asyncio
from typing import List, Optional, Tuple
from typing import List, Tuple
from wled_controller.core.devices.led_client import (
DeviceHealth,
@@ -12,7 +12,6 @@ import numpy as np
from wled_controller.core.devices.led_client import (
DeviceHealth,
DiscoveredDevice,
LEDClient,
LEDDeviceProvider,
)
from wled_controller.utils import get_logger
@@ -94,7 +94,7 @@ class SPIClient(LEDClient):
def _connect_rpi_ws281x(self):
"""Connect via rpi_ws281x library (GPIO PWM/DMA)."""
try:
from rpi_ws281x import PixelStrip, Color
from rpi_ws281x import PixelStrip
except ImportError:
raise RuntimeError(
"rpi_ws281x is required for GPIO LED control: "
@@ -254,8 +254,10 @@ class SPIClient(LEDClient):
else:
# GPIO — check if we can import rpi_ws281x
try:
import rpi_ws281x
return DeviceHealth(online=True, latency_ms=0.0, last_checked=datetime.now(timezone.utc))
import importlib.util
if importlib.util.find_spec("rpi_ws281x") is not None:
return DeviceHealth(online=True, latency_ms=0.0, last_checked=datetime.now(timezone.utc))
raise ImportError("rpi_ws281x not found")
except ImportError:
return DeviceHealth(
online=False,
@@ -1,7 +1,6 @@
"""SPI Direct device provider — Raspberry Pi GPIO/SPI direct LED strip control."""
import platform
from datetime import datetime, timezone
from typing import List
from wled_controller.core.devices.led_client import (
@@ -1,6 +1,5 @@
"""USB HID LED device provider — control RGB peripherals via USB HID."""
from datetime import datetime, timezone
from typing import List
from wled_controller.core.devices.led_client import (
@@ -134,7 +134,7 @@ class WLEDClient(LEDClient):
except Exception as e:
logger.warning(f"Could not configure device for DDP: {e}")
logger.info(f"DDP protocol enabled for pixel data transmission (RGB mode)")
logger.info("DDP protocol enabled for pixel data transmission (RGB mode)")
self._connected = True
@@ -381,7 +381,7 @@ class WLEDClient(LEDClient):
# Note: brightness already applied by processor loop (_cached_brightness)
logger.debug(f"Sending {len(pixels)} LEDs via DDP")
self._ddp_client.send_pixels_numpy(pixels)
logger.debug(f"Successfully sent pixel colors via DDP")
logger.debug("Successfully sent pixel colors via DDP")
return True
except Exception as e:
@@ -430,7 +430,7 @@ class WLEDClient(LEDClient):
logger.debug(f"Payload size: ~{len(str(payload))} bytes")
await self._request("POST", "/json/state", json_data=payload)
logger.debug(f"Successfully sent pixel colors via HTTP")
logger.debug("Successfully sent pixel colors via HTTP")
return True
except Exception as e:
@@ -9,7 +9,7 @@ from wled_controller.core.devices.led_client import (
LEDClient,
LEDDeviceProvider,
)
from wled_controller.core.devices.ws_client import WSLEDClient, parse_ws_url
from wled_controller.core.devices.ws_client import WSLEDClient
from wled_controller.utils import get_logger
logger = get_logger(__name__)
@@ -1,6 +1,6 @@
"""Auto-crop postprocessing filter."""
from typing import Any, Dict, List, Optional
from typing import List, Optional
import numpy as np
@@ -1,11 +1,16 @@
"""Base classes for the postprocessing filter system."""
from __future__ import annotations
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any, Dict, List, Optional
import numpy as np
if TYPE_CHECKING:
from wled_controller.core.filters.image_pool import ImagePool
@dataclass
class FilterOptionDef:
@@ -1,6 +1,6 @@
"""Downscaler postprocessing filter."""
from typing import Any, Dict, List, Optional
from typing import List, Optional
import cv2
import numpy as np
@@ -1,6 +1,6 @@
"""Flip postprocessing filter."""
from typing import Any, Dict, List, Optional
from typing import List, Optional
import numpy as np
@@ -1,6 +1,6 @@
"""Pixelate postprocessing filter."""
from typing import Any, Dict, List, Optional
from typing import List, Optional
import cv2
import numpy as np
@@ -1,6 +1,6 @@
"""Filter registry for discovering and instantiating postprocessing filters."""
from typing import Dict, List, Type
from typing import Dict, Type
from wled_controller.core.filters.base import PostprocessingFilter
from wled_controller.utils import get_logger
@@ -9,7 +9,7 @@ Extracted from processor_manager.py to keep files under 800 lines.
import asyncio
import time
from dataclasses import dataclass
from typing import Dict, Optional
from typing import Optional
from wled_controller.utils import get_logger
@@ -19,9 +19,8 @@ from typing import Optional
import numpy as np
from wled_controller.core.capture.calibration import CalibrationConfig, PixelMapper, AdvancedPixelMapper, create_pixel_mapper
from wled_controller.core.capture.calibration import CalibrationConfig, AdvancedPixelMapper, create_pixel_mapper
from wled_controller.core.capture.screen_capture import extract_border_pixels
from wled_controller.core.processing.live_stream import LiveStream
from wled_controller.utils import get_logger
from wled_controller.utils.timer import high_resolution_timer
@@ -107,7 +106,6 @@ class PictureColorStripStream(ColorStripStream):
Lifecycle managed by ColorStripStreamManager.
source: PictureColorStripSource config
"""
from wled_controller.storage.color_strip_source import PictureColorStripSource
# Support both single LiveStream and dict of streams (advanced mode)
if isinstance(live_stream, dict):
@@ -1093,7 +1091,9 @@ class GradientColorStripStream(ColorStripStream):
(4, tt, p, v_arr), (5, v_arr, p, q),
):
m = hi == sxt
ro[m] = rv[m]; go[m] = gv[m]; bo[m] = bv[m]
ro[m] = rv[m]
go[m] = gv[m]
bo[m] = bv[m]
buf[:, 0] = np.clip(ro * 255.0, 0, 255).astype(np.uint8)
buf[:, 1] = np.clip(go * 255.0, 0, 255).astype(np.uint8)
buf[:, 2] = np.clip(bo * 255.0, 0, 255).astype(np.uint8)
@@ -127,7 +127,7 @@ class CompositeColorStripStream(ColorStripStream):
def get_layer_brightness(self) -> List[Optional[float]]:
"""Return per-layer brightness values (0.0-1.0) from value sources, or None if no source."""
enabled = [l for l in self._layers if l.get("enabled", True)]
enabled = [layer for layer in self._layers if layer.get("enabled", True)]
result: List[Optional[float]] = []
with self._sub_lock:
for i in range(len(enabled)):
@@ -155,10 +155,10 @@ class CompositeColorStripStream(ColorStripStream):
def update_source(self, source) -> None:
"""Hot-update: rebuild sub-streams if layer config changed."""
new_layers = list(source.layers)
old_layer_ids = [(l.get("source_id"), l.get("blend_mode"), l.get("opacity"), l.get("enabled"), l.get("brightness_source_id"))
for l in self._layers]
new_layer_ids = [(l.get("source_id"), l.get("blend_mode"), l.get("opacity"), l.get("enabled"), l.get("brightness_source_id"))
for l in new_layers]
old_layer_ids = [(layer.get("source_id"), layer.get("blend_mode"), layer.get("opacity"), layer.get("enabled"), layer.get("brightness_source_id"))
for layer in self._layers]
new_layer_ids = [(layer.get("source_id"), layer.get("blend_mode"), layer.get("opacity"), layer.get("enabled"), layer.get("brightness_source_id"))
for layer in new_layers]
self._layers = new_layers
@@ -5,7 +5,6 @@ that transitions through dawn, daylight, sunset, and night over a continuous
24-hour cycle. Can use real wall-clock time or a configurable simulation speed.
"""
import math
import threading
import time
from typing import Optional
@@ -3,7 +3,7 @@
Extracted from processor_manager.py to keep files under 800 lines.
"""
from typing import Dict, List, Optional, Tuple
from typing import Dict, List, Optional
from wled_controller.core.capture.calibration import CalibrationConfig
from wled_controller.core.devices.led_client import create_led_client
@@ -15,7 +15,7 @@ import httpx
import numpy as np
from wled_controller.core.capture_engines import EngineRegistry
from wled_controller.core.filters import FilterRegistry, PostprocessingFilter
from wled_controller.core.filters import FilterRegistry
from wled_controller.core.processing.live_stream import (
LiveStream,
ProcessedLiveStream,
@@ -12,9 +12,9 @@ from __future__ import annotations
import asyncio
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from dataclasses import dataclass
from datetime import datetime
from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Tuple
from typing import TYPE_CHECKING, Callable, Dict, Optional, Tuple
if TYPE_CHECKING:
from wled_controller.core.processing.color_strip_stream_manager import ColorStripStreamManager
@@ -613,7 +613,7 @@ class WledTargetProcessor(TargetProcessor):
last_send_time = 0.0
_last_preview_broadcast = 0.0
prev_frame_time_stamp = time.perf_counter()
loop = asyncio.get_running_loop()
asyncio.get_running_loop()
_init_device_info = self._ctx.get_device_info(self._device_id)
_total_leds = getattr(self, '_effective_led_count', None) or (_init_device_info.led_count if _init_device_info else 0)