Pylint plugin to check that relative imports are used (#50937)
* Pylint plugin to check that relative imports are used * Fix existing sites * Update description message * Fix typopull/50955/head
parent
b704f0e729
commit
016abda12e
|
@ -9,13 +9,12 @@ from typing import Any, Dict, Mapping, Optional, Tuple, cast
|
|||
import jwt
|
||||
|
||||
from homeassistant import data_entry_flow
|
||||
from homeassistant.auth.const import ACCESS_TOKEN_EXPIRATION
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from . import auth_store, models
|
||||
from .const import GROUP_ID_ADMIN
|
||||
from .const import ACCESS_TOKEN_EXPIRATION, GROUP_ID_ADMIN
|
||||
from .mfa_modules import MultiFactorAuthModule, auth_mfa_module_from_config
|
||||
from .providers import AuthProvider, LoginFlow, auth_provider_from_config
|
||||
|
||||
|
|
|
@ -6,17 +6,6 @@ import logging
|
|||
from adguardhome import AdGuardHome, AdGuardHomeConnectionError, AdGuardHomeError
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.adguard.const import (
|
||||
CONF_FORCE,
|
||||
DATA_ADGUARD_CLIENT,
|
||||
DATA_ADGUARD_VERSION,
|
||||
DOMAIN,
|
||||
SERVICE_ADD_URL,
|
||||
SERVICE_DISABLE_URL,
|
||||
SERVICE_ENABLE_URL,
|
||||
SERVICE_REFRESH,
|
||||
SERVICE_REMOVE_URL,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
CONF_HOST,
|
||||
|
@ -34,6 +23,18 @@ from homeassistant.helpers import config_validation as cv
|
|||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.entity import DeviceInfo, Entity
|
||||
|
||||
from .const import (
|
||||
CONF_FORCE,
|
||||
DATA_ADGUARD_CLIENT,
|
||||
DATA_ADGUARD_VERSION,
|
||||
DOMAIN,
|
||||
SERVICE_ADD_URL,
|
||||
SERVICE_DISABLE_URL,
|
||||
SERVICE_ENABLE_URL,
|
||||
SERVICE_REFRESH,
|
||||
SERVICE_REMOVE_URL,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SERVICE_URL_SCHEMA = vol.Schema({vol.Required(CONF_URL): cv.url})
|
||||
|
|
|
@ -6,18 +6,13 @@ import logging
|
|||
from aioazuredevops.client import DevOpsClient
|
||||
import aiohttp
|
||||
|
||||
from homeassistant.components.azure_devops.const import (
|
||||
CONF_ORG,
|
||||
CONF_PAT,
|
||||
CONF_PROJECT,
|
||||
DATA_AZURE_DEVOPS_CLIENT,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
from homeassistant.helpers.entity import DeviceInfo, Entity
|
||||
|
||||
from .const import CONF_ORG, CONF_PAT, CONF_PROJECT, DATA_AZURE_DEVOPS_CLIENT, DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
PLATFORMS = ["sensor"]
|
||||
|
|
|
@ -7,7 +7,13 @@ from blinkpy.blinkpy import Blink
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components import persistent_notification
|
||||
from homeassistant.components.blink.const import (
|
||||
from homeassistant.config_entries import SOURCE_REAUTH
|
||||
from homeassistant.const import CONF_FILENAME, CONF_NAME, CONF_PIN, CONF_SCAN_INTERVAL
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
|
||||
from .const import (
|
||||
DEFAULT_SCAN_INTERVAL,
|
||||
DOMAIN,
|
||||
PLATFORMS,
|
||||
|
@ -15,11 +21,6 @@ from homeassistant.components.blink.const import (
|
|||
SERVICE_SAVE_VIDEO,
|
||||
SERVICE_SEND_PIN,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_REAUTH
|
||||
from homeassistant.const import CONF_FILENAME, CONF_NAME, CONF_PIN, CONF_SCAN_INTERVAL
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -9,12 +9,6 @@ import async_timeout
|
|||
from colorthief import ColorThief
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.color_extractor.const import (
|
||||
ATTR_PATH,
|
||||
ATTR_URL,
|
||||
DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
)
|
||||
from homeassistant.components.light import (
|
||||
ATTR_RGB_COLOR,
|
||||
DOMAIN as LIGHT_DOMAIN,
|
||||
|
@ -24,6 +18,8 @@ from homeassistant.components.light import (
|
|||
from homeassistant.helpers import aiohttp_client
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
from .const import ATTR_PATH, ATTR_URL, DOMAIN, SERVICE_TURN_ON
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
# Extend the existing light.turn_on service schema
|
||||
|
|
|
@ -6,7 +6,6 @@ import logging
|
|||
from pymfy.api.devices.category import Category
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.somfy import config_flow
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET, CONF_OPTIMISTIC
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
|
@ -21,7 +20,7 @@ from homeassistant.helpers.update_coordinator import (
|
|||
DataUpdateCoordinator,
|
||||
)
|
||||
|
||||
from . import api
|
||||
from . import api, config_flow
|
||||
from .const import API, COORDINATOR, DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
|
|
@ -5,7 +5,6 @@ from spotipy import Spotify, SpotifyException
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.media_player import DOMAIN as MEDIA_PLAYER_DOMAIN
|
||||
from homeassistant.components.spotify import config_flow
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import ATTR_CREDENTIALS, CONF_CLIENT_ID, CONF_CLIENT_SECRET
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
@ -17,6 +16,7 @@ from homeassistant.helpers.config_entry_oauth2_flow import (
|
|||
)
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from . import config_flow
|
||||
from .const import (
|
||||
DATA_SPOTIFY_CLIENT,
|
||||
DATA_SPOTIFY_ME,
|
||||
|
|
|
@ -7,13 +7,6 @@ from datetime import timedelta
|
|||
from twentemilieu import TwenteMilieu
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.twentemilieu.const import (
|
||||
CONF_HOUSE_LETTER,
|
||||
CONF_HOUSE_NUMBER,
|
||||
CONF_POST_CODE,
|
||||
DATA_UPDATE,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_ID
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
@ -23,6 +16,14 @@ from homeassistant.helpers.dispatcher import async_dispatcher_send
|
|||
from homeassistant.helpers.event import async_track_time_interval
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from .const import (
|
||||
CONF_HOUSE_LETTER,
|
||||
CONF_HOUSE_NUMBER,
|
||||
CONF_POST_CODE,
|
||||
DATA_UPDATE,
|
||||
DOMAIN,
|
||||
)
|
||||
|
||||
SCAN_INTERVAL = timedelta(seconds=3600)
|
||||
|
||||
SERVICE_UPDATE = "update"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""Plugin for constructor definitions."""
|
||||
from astroid import ClassDef, Const, FunctionDef
|
||||
from astroid import Const, FunctionDef
|
||||
from pylint.checkers import BaseChecker
|
||||
from pylint.interfaces import IAstroidChecker
|
||||
from pylint.lint import PyLinter
|
||||
|
@ -43,7 +43,7 @@ class HassConstructorFormatChecker(BaseChecker): # type: ignore[misc]
|
|||
return
|
||||
|
||||
# Check that return type is specified and it is "None".
|
||||
if not isinstance(node.returns, Const) or node.returns.value != None:
|
||||
if not isinstance(node.returns, Const) or node.returns.value is not None:
|
||||
self.add_message("hass-constructor-return", node=node)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
"""Plugin for checking imports."""
|
||||
from __future__ import annotations
|
||||
|
||||
from astroid import Import, ImportFrom, Module
|
||||
from pylint.checkers import BaseChecker
|
||||
from pylint.interfaces import IAstroidChecker
|
||||
from pylint.lint import PyLinter
|
||||
|
||||
|
||||
class HassImportsFormatChecker(BaseChecker): # type: ignore[misc]
|
||||
"""Checker for imports."""
|
||||
|
||||
__implements__ = IAstroidChecker
|
||||
|
||||
name = "hass_imports"
|
||||
priority = -1
|
||||
msgs = {
|
||||
"W0011": (
|
||||
"Relative import should be used",
|
||||
"hass-relative-import",
|
||||
"Used when absolute import should be replaced with relative import",
|
||||
),
|
||||
}
|
||||
options = ()
|
||||
|
||||
def __init__(self, linter: PyLinter | None = None) -> None:
|
||||
super().__init__(linter)
|
||||
self.current_module: str | None = None
|
||||
|
||||
def visit_module(self, node: Module) -> None:
|
||||
"""Called when a Import node is visited."""
|
||||
self.current_module = node.name
|
||||
|
||||
def visit_import(self, node: Import) -> None:
|
||||
"""Called when a Import node is visited."""
|
||||
for module, _alias in node.names:
|
||||
if module.startswith(f"{self.current_module}."):
|
||||
self.add_message("hass-relative-import", node=node)
|
||||
|
||||
def visit_importfrom(self, node: ImportFrom) -> None:
|
||||
"""Called when a ImportFrom node is visited."""
|
||||
if node.level is not None:
|
||||
return
|
||||
if node.modname == self.current_module or node.modname.startswith(
|
||||
f"{self.current_module}."
|
||||
):
|
||||
self.add_message("hass-relative-import", node=node)
|
||||
|
||||
|
||||
def register(linter: PyLinter) -> None:
|
||||
"""Register the checker."""
|
||||
linter.register_checker(HassImportsFormatChecker(linter))
|
|
@ -28,6 +28,7 @@ load-plugins = [
|
|||
"pylint.extensions.typing",
|
||||
"pylint_strict_informational",
|
||||
"hass_constructor",
|
||||
"hass_imports",
|
||||
"hass_logger",
|
||||
]
|
||||
persistent = false
|
||||
|
|
Loading…
Reference in New Issue