Improve type hints in image-processing (#78351)

This commit is contained in:
epenet 2022-09-13 14:39:39 +02:00 committed by GitHub
parent 6256d07255
commit 458ddb6f4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 15 deletions

View File

@ -1,11 +1,14 @@
"""Provides functionality to interact with image processing services."""
from __future__ import annotations
import asyncio
from datetime import timedelta
import logging
from typing import Final, TypedDict, final
from typing import Any, Final, TypedDict, final
import voluptuous as vol
from homeassistant.components.camera import Image
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_NAME,
@ -22,8 +25,6 @@ from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.typing import ConfigType
from homeassistant.util.async_ import run_callback_threadsafe
# mypy: allow-untyped-defs, no-check-untyped-defs
_LOGGER = logging.getLogger(__name__)
DOMAIN = "image_processing"
@ -44,7 +45,7 @@ ATTR_CONFIDENCE: Final = "confidence"
ATTR_FACES = "faces"
ATTR_GENDER = "gender"
ATTR_GLASSES = "glasses"
ATTR_MOTION = "motion"
ATTR_MOTION: Final = "motion"
ATTR_TOTAL_FACES = "total_faces"
CONF_CONFIDENCE = "confidence"
@ -113,24 +114,24 @@ class ImageProcessingEntity(Entity):
timeout = DEFAULT_TIMEOUT
@property
def camera_entity(self):
def camera_entity(self) -> str | None:
"""Return camera entity id from process pictures."""
return None
@property
def confidence(self):
def confidence(self) -> float | None:
"""Return minimum confidence for do some things."""
return None
def process_image(self, image):
def process_image(self, image: Image) -> None:
"""Process image."""
raise NotImplementedError()
async def async_process_image(self, image):
async def async_process_image(self, image: Image) -> None:
"""Process image."""
return await self.hass.async_add_executor_job(self.process_image, image)
async def async_update(self):
async def async_update(self) -> None:
"""Update image and process it.
This method is a coroutine.
@ -160,9 +161,9 @@ class ImageProcessingFaceEntity(ImageProcessingEntity):
self.total_faces = 0
@property
def state(self):
def state(self) -> str | int | None:
"""Return the state of the entity."""
confidence = 0
confidence: float = 0
state = None
# No confidence support
@ -178,19 +179,19 @@ class ImageProcessingFaceEntity(ImageProcessingEntity):
confidence = f_co
for attr in (ATTR_NAME, ATTR_MOTION):
if attr in face:
state = face[attr]
state = face[attr] # type: ignore[literal-required]
break
return state
@property
def device_class(self):
def device_class(self) -> str:
"""Return the class of this device, from component DEVICE_CLASSES."""
return "face"
@final
@property
def state_attributes(self):
def state_attributes(self) -> dict[str, Any]:
"""Return device specific state attributes."""
return {ATTR_FACES: self.faces, ATTR_TOTAL_FACES: self.total_faces}

View File

@ -148,7 +148,7 @@ class ImageProcessingAlprEntity(ImageProcessingEntity):
plates = {
plate: confidence
for plate, confidence in plates.items()
if confidence >= self.confidence
if self.confidence is None or confidence >= self.confidence
}
new_plates = set(plates) - set(self.plates)

View File

@ -1348,6 +1348,45 @@ _INHERITANCE_MATCH: dict[str, list[ClassTypeHintMatch]] = {
],
),
],
"image_processing": [
ClassTypeHintMatch(
base_class="Entity",
matches=_ENTITY_MATCH,
),
ClassTypeHintMatch(
base_class="ImageProcessingEntity",
matches=[
TypeHintMatch(
function_name="camera_entity",
return_type=["str", None],
),
TypeHintMatch(
function_name="confidence",
return_type=["float", None],
),
TypeHintMatch(
function_name="process_image",
arg_types={1: "Image"},
return_type=None,
has_async_counterpart=True,
),
],
),
ClassTypeHintMatch(
base_class="ImageProcessingFaceEntity",
matches=[
TypeHintMatch(
function_name="process_faces",
arg_types={
1: "list[FaceInformation]",
2: "int",
},
return_type=None,
has_async_counterpart=True,
),
],
),
],
"light": [
ClassTypeHintMatch(
base_class="Entity",