Increase ruff coverage (#23644)
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions
CI / Jetson Jetpack 6 (push) Waiting to run

* Pin ruff

* Add python upgrade fixes

This enables python upgrade checks in ruff to look for deprecated types and patterns. This namely fixes:
- usage of deprecated `Typing` which is now built in
- some specific exceptions which are caught and have new aliases

Some specific UP checks were also ignored as they are stylistic / unimportant and likely to cause bugs

* Remove async blocking calls

Use asyncio.to_thread on two remaining blocking calls to fix hanging event thread loop. Enable this specific rule to block it in the future.

* Use proper logging mechanism

* Correctly format logs

* Raise with context

When raising an exception include the from context to improve debugging

* Cleanup
This commit is contained in:
Nicolas Mowen
2026-07-06 12:28:02 -05:00
committed by GitHub
parent 455b8687e8
commit 4ee12e6237
169 changed files with 1053 additions and 1150 deletions
+1 -2
View File
@@ -1,6 +1,5 @@
import logging
from abc import ABC, abstractmethod
from typing import List
import numpy as np
@@ -11,7 +10,7 @@ logger = logging.getLogger(__name__)
class DetectionApi(ABC):
type_key: str
supported_models: List[ModelTypeEnum]
supported_models: list[ModelTypeEnum]
@abstractmethod
def __init__(self, detector_config: BaseDetectorConfig):
+1 -1
View File
@@ -491,7 +491,7 @@ class RKNNModelRunner(BaseModelRunner):
except ImportError:
logger.error("RKNN Lite not available")
raise ImportError("RKNN Lite not available")
raise ImportError("RKNN Lite not available") from None
except Exception as e:
logger.error(f"Error loading RKNN model: {e}")
raise
+12 -12
View File
@@ -3,7 +3,7 @@ import json
import logging
import os
from enum import Enum
from typing import Any, Dict, Optional, Tuple
from typing import Any
import requests
from pydantic import BaseModel, ConfigDict, Field
@@ -45,12 +45,12 @@ class ModelTypeEnum(str, Enum):
class ModelConfig(BaseModel):
path: Optional[str] = Field(
path: str | None = Field(
None,
title="Custom object detector model path",
description="Path to a custom detection model file (or plus://<model_id> for Frigate+ models).",
)
labelmap_path: Optional[str] = Field(
labelmap_path: str | None = Field(
None,
title="Label map for custom object detector",
description="Path to a labelmap file that maps numeric classes to string labels for the detector.",
@@ -65,12 +65,12 @@ class ModelConfig(BaseModel):
title="Object detection model input height",
description="Height of the model input tensor in pixels.",
)
labelmap: Dict[int, str] = Field(
labelmap: dict[int, str] = Field(
default_factory=dict,
title="Labelmap customization",
description="Overrides or remapping entries to merge into the standard labelmap.",
)
attributes_map: Dict[str, list[str]] = Field(
attributes_map: dict[str, list[str]] = Field(
default=DEFAULT_ATTRIBUTE_LABEL_MAP,
title="Map of object labels to their attribute labels",
description="Mapping from object labels to attribute labels used to attach metadata (for example 'car' -> ['license_plate']).",
@@ -95,18 +95,18 @@ class ModelConfig(BaseModel):
title="Object Detection Model Type",
description="Detector model architecture type (ssd, yolox, yolonas) used by some detectors for optimization.",
)
_merged_labelmap: Optional[Dict[int, str]] = PrivateAttr()
_colormap: Dict[int, Tuple[int, int, int]] = PrivateAttr()
_merged_labelmap: dict[int, str] | None = PrivateAttr()
_colormap: dict[int, tuple[int, int, int]] = PrivateAttr()
_all_attributes: list[str] = PrivateAttr()
_all_attribute_logos: list[str] = PrivateAttr()
_model_hash: str = PrivateAttr()
@property
def merged_labelmap(self) -> Dict[int, str]:
def merged_labelmap(self) -> dict[int, str]:
return self._merged_labelmap
@property
def colormap(self) -> Dict[int, Tuple[int, int, int]]:
def colormap(self) -> dict[int, tuple[int, int, int]]:
return self._colormap
@property
@@ -171,7 +171,7 @@ class ModelConfig(BaseModel):
with open(model_info_path, "w") as f:
json.dump(model_info, f)
else:
with open(model_info_path, "r") as f:
with open(model_info_path) as f:
model_info: dict[str, Any] = json.load(f)
if detector and detector not in model_info["supportedDetectors"]:
@@ -240,12 +240,12 @@ class BaseDetectorConfig(BaseModel):
title="Detector Type",
description="Type of detector to use for object detection (for example 'cpu', 'edgetpu', 'openvino').",
)
model: Optional[ModelConfig] = Field(
model: ModelConfig | None = Field(
default=None,
title="Detector specific model configuration",
description="Detector-specific model configuration options (path, input size, etc.).",
)
model_path: Optional[str] = Field(
model_path: str | None = Field(
default=None,
title="Detector specific model path",
description="File path to the detector model binary if required by the chosen detector.",
+2 -3
View File
@@ -2,10 +2,9 @@ import importlib
import logging
import pkgutil
from enum import Enum
from typing import Union
from typing import Annotated, Union
from pydantic import Field
from typing_extensions import Annotated
from . import plugins
from .detection_api import DetectionApi
@@ -37,6 +36,6 @@ class StrEnum(str, Enum):
DetectorTypeEnum = StrEnum("DetectorTypeEnum", {k: k for k in api_types})
DetectorConfig = Annotated[
Union[tuple(BaseDetectorConfig.__subclasses__())],
Union[tuple(BaseDetectorConfig.__subclasses__())], # noqa: UP007
Field(discriminator="type"),
]
+1 -2
View File
@@ -39,8 +39,7 @@ class Axengine(DetectionApi):
try:
import axengine as axe
except ModuleNotFoundError:
raise ImportError("AXEngine is not installed.")
return
raise ImportError("AXEngine is not installed.") from None
logger.info("__init__ axengine")
super().__init__(config)
+1 -1
View File
@@ -1,7 +1,7 @@
import logging
from typing import Literal
from pydantic import ConfigDict, Field
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detector_config import BaseDetectorConfig
+1 -1
View File
@@ -1,11 +1,11 @@
import io
import logging
from typing import Literal
import numpy as np
import requests
from PIL import Image
from pydantic import ConfigDict, Field
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detector_config import BaseDetectorConfig
+2 -2
View File
@@ -1,9 +1,9 @@
import logging
import queue
from typing import Literal
import numpy as np
from pydantic import ConfigDict, Field
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detector_config import BaseDetectorConfig
@@ -46,7 +46,7 @@ class DGDetector(DetectionApi):
try:
import degirum as dg
except ModuleNotFoundError:
raise ImportError("Unable to import DeGirum detector.")
raise ImportError("Unable to import DeGirum detector.") from None
self._queue = queue.Queue()
self._zoo = dg.connect(
+1 -1
View File
@@ -1,11 +1,11 @@
import logging
import math
import os
from typing import Literal
import cv2
import numpy as np
from pydantic import ConfigDict, Field
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detector_config import BaseDetectorConfig, ModelTypeEnum
+9 -10
View File
@@ -4,12 +4,11 @@ import subprocess
import threading
import urllib.request
from functools import partial
from typing import Dict, List, Optional, Tuple
from typing import Literal
import cv2
import numpy as np
from pydantic import ConfigDict, Field
from typing_extensions import Literal
from frigate.const import MODEL_CACHE_DIR
from frigate.detectors.detection_api import DetectionApi
@@ -83,8 +82,8 @@ class HailoAsyncInference:
input_store: RequestStore,
output_store: ResponseStore,
batch_size: int = 1,
input_type: Optional[str] = None,
output_type: Optional[Dict[str, str]] = None,
input_type: str | None = None,
output_type: dict[str, str] | None = None,
send_original_frame: bool = False,
) -> None:
# when importing hailo it activates the driver
@@ -125,9 +124,9 @@ class HailoAsyncInference:
def callback(
self,
completion_info,
bindings_list: List,
input_batch: List,
request_ids: List[int],
bindings_list: list,
input_batch: list,
request_ids: list[int],
):
if completion_info.exception:
logger.error(f"Inference error: {completion_info.exception}")
@@ -163,7 +162,7 @@ class HailoAsyncInference:
}
return configured_infer_model.create_bindings(output_buffers=output_buffers)
def get_input_shape(self) -> Tuple[int, ...]:
def get_input_shape(self) -> tuple[int, ...]:
return self.hef.get_input_vstream_infos()[0].shape
def run(self) -> None:
@@ -304,7 +303,7 @@ class HailoDetector(DetectionApi):
urllib.request.urlretrieve(url, destination)
logger.debug(f"Downloaded model to {destination}")
except Exception as e:
raise RuntimeError(f"Failed to download model from {url}: {str(e)}")
raise RuntimeError(f"Failed to download model from {url}: {str(e)}") from e
def check_and_prepare(self) -> str:
if not os.path.exists(self.cache_dir):
@@ -350,7 +349,7 @@ class HailoDetector(DetectionApi):
if not self.inference_thread.is_alive():
raise RuntimeError(
"HailoRT inference thread has stopped, restart required."
)
) from None
return np.zeros((20, 6), dtype=np.float32)
+2 -2
View File
@@ -5,11 +5,11 @@ import shutil
import urllib.request
import zipfile
from queue import Queue
from typing import Literal
import cv2
import numpy as np
from pydantic import BaseModel, ConfigDict, Field
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detector_config import (
@@ -61,7 +61,7 @@ class MemryXDetector(DetectionApi):
except ModuleNotFoundError:
raise ImportError(
"MemryX SDK is not installed. Install it and set up MIX environment."
)
) from None
return
# Initialize stop_event as None, will be set later by set_stop_event()
+1 -1
View File
@@ -1,8 +1,8 @@
import logging
from typing import Literal
import numpy as np
from pydantic import ConfigDict, Field
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detection_runners import get_optimized_runner
+1 -1
View File
@@ -1,9 +1,9 @@
import logging
from typing import Literal
import numpy as np
import openvino as ov
from pydantic import ConfigDict, Field
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detection_runners import OpenVINOModelRunner
+1 -1
View File
@@ -90,7 +90,7 @@ class Rknn(DetectionApi):
with open("/proc/device-tree/compatible") as file:
soc = file.read().split(",")[-1].strip("\x00")
except FileNotFoundError:
raise Exception("Make sure to run docker in privileged mode.")
raise Exception("Make sure to run docker in privileged mode.") from None
if soc not in SUPPORTED_RK_SOCS:
raise Exception(
+1 -1
View File
@@ -1,9 +1,9 @@
import logging
import os
from typing import Literal
import numpy as np
from pydantic import ConfigDict
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detector_config import (
+1 -1
View File
@@ -1,7 +1,7 @@
import logging
from typing import Literal
from pydantic import ConfigDict
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detector_config import BaseDetectorConfig
+3 -2
View File
@@ -14,8 +14,9 @@ try:
except ModuleNotFoundError:
TRT_SUPPORT = False
from typing import Literal
from pydantic import ConfigDict, Field
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detector_config import BaseDetectorConfig
@@ -58,7 +59,7 @@ class TensorRTDetectorConfig(BaseDetectorConfig):
)
class HostDeviceMem(object):
class HostDeviceMem:
"""Simple helper data class that's a little nicer to use than a 2-tuple."""
def __init__(self, host_mem, device_mem, nbytes, size):
+2 -3
View File
@@ -1,12 +1,11 @@
import json
import logging
import os
from typing import Any, List
from typing import Any, Literal
import numpy as np
import zmq
from pydantic import ConfigDict, Field
from typing_extensions import Literal
from frigate.detectors.detection_api import DetectionApi
from frigate.detectors.detector_config import BaseDetectorConfig
@@ -274,7 +273,7 @@ class ZmqIpcDetector(DetectionApi):
}
return json.dumps(header).encode("utf-8")
def _decode_response(self, frames: List[bytes]) -> np.ndarray:
def _decode_response(self, frames: list[bytes]) -> np.ndarray:
try:
if len(frames) == 1:
# Single-frame raw float32 (20x6)