mirror of https://github.com/home-assistant/core
78 lines
2.4 KiB
Python
78 lines
2.4 KiB
Python
"""Plugin to enforce type hints on specific functions."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
|
|
from astroid import nodes
|
|
from pylint.checkers import BaseChecker
|
|
from pylint.lint import PyLinter
|
|
|
|
_MODULE_REGEX: re.Pattern[str] = re.compile(r"^homeassistant\.components\.\w+(\.\w+)?$")
|
|
|
|
|
|
def _get_module_platform(module_name: str) -> str | None:
|
|
"""Return the platform for the module name."""
|
|
if not (module_match := _MODULE_REGEX.match(module_name)):
|
|
# Ensure `homeassistant.components.<component>`
|
|
# Or `homeassistant.components.<component>.<platform>`
|
|
return None
|
|
|
|
platform = module_match.groups()[0]
|
|
return platform.lstrip(".") if platform else "__init__"
|
|
|
|
|
|
class HassInheritanceChecker(BaseChecker):
|
|
"""Checker for invalid inheritance."""
|
|
|
|
name = "hass_inheritance"
|
|
priority = -1
|
|
msgs = {
|
|
"W7411": (
|
|
"Invalid inheritance: %s",
|
|
"hass-invalid-inheritance",
|
|
"Used when a class has inheritance has issues",
|
|
),
|
|
}
|
|
options = ()
|
|
|
|
_module_name: str
|
|
_module_platform: str | None
|
|
|
|
def visit_module(self, node: nodes.Module) -> None:
|
|
"""Populate matchers for a Module node."""
|
|
self._module_name = node.name
|
|
self._module_platform = _get_module_platform(node.name)
|
|
|
|
def visit_classdef(self, node: nodes.ClassDef) -> None:
|
|
"""Apply relevant type hint checks on a ClassDef node."""
|
|
if self._module_platform not in {"number", "sensor"}:
|
|
return
|
|
|
|
ancestors = [a.name for a in node.ancestors()]
|
|
if (
|
|
"RestoreEntity" in ancestors
|
|
and "SensorEntity" in ancestors
|
|
and "RestoreSensor" not in ancestors
|
|
):
|
|
self.add_message(
|
|
"hass-invalid-inheritance",
|
|
node=node,
|
|
args="SensorEntity and RestoreEntity should not be combined, please use RestoreSensor",
|
|
)
|
|
elif (
|
|
"RestoreEntity" in ancestors
|
|
and "NumberEntity" in ancestors
|
|
and "RestoreNumber" not in ancestors
|
|
):
|
|
self.add_message(
|
|
"hass-invalid-inheritance",
|
|
node=node,
|
|
args="NumberEntity and RestoreEntity should not be combined, please use RestoreNumber",
|
|
)
|
|
|
|
|
|
def register(linter: PyLinter) -> None:
|
|
"""Register the checker."""
|
|
linter.register_checker(HassInheritanceChecker(linter))
|