Bump mypy to 0.930 (#62642)

Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
This commit is contained in:
Tobias Sauerwein 2021-12-27 17:55:17 +01:00 committed by GitHub
parent b0704c190f
commit 2c904c0974
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 73 additions and 58 deletions

View File

@ -133,7 +133,7 @@ async def auth_mfa_module_from_config(
module = await _load_mfa_module(hass, module_name) module = await _load_mfa_module(hass, module_name)
try: try:
config = module.CONFIG_SCHEMA(config) # type: ignore config = module.CONFIG_SCHEMA(config)
except vol.Invalid as err: except vol.Invalid as err:
_LOGGER.error( _LOGGER.error(
"Invalid configuration for multi-factor module %s: %s", "Invalid configuration for multi-factor module %s: %s",
@ -168,7 +168,7 @@ async def _load_mfa_module(hass: HomeAssistant, module_name: str) -> types.Modul
# https://github.com/python/mypy/issues/1424 # https://github.com/python/mypy/issues/1424
await requirements.async_process_requirements( await requirements.async_process_requirements(
hass, module_path, module.REQUIREMENTS # type: ignore hass, module_path, module.REQUIREMENTS
) )
processed.add(module_name) processed.add(module_name)

View File

@ -142,7 +142,7 @@ async def auth_provider_from_config(
module = await load_auth_provider_module(hass, provider_name) module = await load_auth_provider_module(hass, provider_name)
try: try:
config = module.CONFIG_SCHEMA(config) # type: ignore config = module.CONFIG_SCHEMA(config)
except vol.Invalid as err: except vol.Invalid as err:
_LOGGER.error( _LOGGER.error(
"Invalid configuration for auth provider %s: %s", "Invalid configuration for auth provider %s: %s",
@ -174,8 +174,7 @@ async def load_auth_provider_module(
elif provider in processed: elif provider in processed:
return module return module
# https://github.com/python/mypy/issues/1424 reqs = module.REQUIREMENTS
reqs = module.REQUIREMENTS # type: ignore
await requirements.async_process_requirements( await requirements.async_process_requirements(
hass, f"auth provider {provider}", reqs hass, f"auth provider {provider}", reqs
) )

View File

@ -14,7 +14,7 @@ class StrEnum(str, Enum):
"""Create a new StrEnum instance.""" """Create a new StrEnum instance."""
if not isinstance(value, str): if not isinstance(value, str):
raise TypeError(f"{value!r} is not a string") raise TypeError(f"{value!r} is not a string")
return super().__new__(cls, value, *args, **kwargs) # type: ignore[call-overload,no-any-return] return super().__new__(cls, value, *args, **kwargs)
def __str__(self) -> str: def __str__(self) -> str:
"""Return self.value.""" """Return self.value."""

View File

@ -238,22 +238,22 @@ class DeviceTrackerPlatform:
scanner = None scanner = None
setup = None setup = None
if hasattr(self.platform, "async_get_scanner"): if hasattr(self.platform, "async_get_scanner"):
scanner = await self.platform.async_get_scanner( # type: ignore[attr-defined] scanner = await self.platform.async_get_scanner(
hass, {DOMAIN: self.config} hass, {DOMAIN: self.config}
) )
elif hasattr(self.platform, "get_scanner"): elif hasattr(self.platform, "get_scanner"):
scanner = await hass.async_add_executor_job( scanner = await hass.async_add_executor_job(
self.platform.get_scanner, # type: ignore[attr-defined] self.platform.get_scanner,
hass, hass,
{DOMAIN: self.config}, {DOMAIN: self.config},
) )
elif hasattr(self.platform, "async_setup_scanner"): elif hasattr(self.platform, "async_setup_scanner"):
setup = await self.platform.async_setup_scanner( # type: ignore[attr-defined] setup = await self.platform.async_setup_scanner(
hass, self.config, tracker.async_see, discovery_info hass, self.config, tracker.async_see, discovery_info
) )
elif hasattr(self.platform, "setup_scanner"): elif hasattr(self.platform, "setup_scanner"):
setup = await hass.async_add_executor_job( setup = await hass.async_add_executor_job(
self.platform.setup_scanner, # type: ignore[attr-defined] self.platform.setup_scanner,
hass, hass,
self.config, self.config,
tracker.see, tracker.see,

View File

@ -60,7 +60,8 @@ class EsphomeCamera(Camera, EsphomeEntity[CameraInfo, CameraState]):
async with self._image_cond: async with self._image_cond:
await self._image_cond.wait() await self._image_cond.wait()
if not self.available: if not self.available:
return None # Availability can change while waiting for 'self._image.cond'
return None # type: ignore[unreachable]
return self._state.data[:] return self._state.data[:]
async def _async_camera_stream_image(self) -> bytes | None: async def _async_camera_stream_image(self) -> bytes | None:
@ -71,7 +72,8 @@ class EsphomeCamera(Camera, EsphomeEntity[CameraInfo, CameraState]):
async with self._image_cond: async with self._image_cond:
await self._image_cond.wait() await self._image_cond.wait()
if not self.available: if not self.available:
return None # Availability can change while waiting for 'self._image.cond'
return None # type: ignore[unreachable]
return self._state.data[:] return self._state.data[:]
async def handle_async_mjpeg_stream( async def handle_async_mjpeg_stream(

View File

@ -88,7 +88,7 @@ def async_setup_forwarded(
remote = False remote = False
# Skip requests from Remote UI # Skip requests from Remote UI
if remote and remote.is_cloud_request.get(): # type: ignore if remote and remote.is_cloud_request.get():
return await handler(request) return await handler(request)
# Handle X-Forwarded-For # Handle X-Forwarded-For

View File

@ -58,12 +58,12 @@ async def async_setup_legacy(hass: HomeAssistant, config: ConfigType) -> None:
notify_service = None notify_service = None
try: try:
if hasattr(platform, "async_get_service"): if hasattr(platform, "async_get_service"):
notify_service = await platform.async_get_service( # type: ignore notify_service = await platform.async_get_service(
hass, p_config, discovery_info hass, p_config, discovery_info
) )
elif hasattr(platform, "get_service"): elif hasattr(platform, "get_service"):
notify_service = await hass.async_add_executor_job( notify_service = await hass.async_add_executor_job(
platform.get_service, hass, p_config, discovery_info # type: ignore platform.get_service, hass, p_config, discovery_info
) )
else: else:
raise HomeAssistantError("Invalid notify platform.") raise HomeAssistantError("Invalid notify platform.")

View File

@ -642,10 +642,10 @@ def _log_pkg_error(package: str, component: str, config: dict, message: str) ->
def _identify_config_schema(module: ModuleType) -> str | None: def _identify_config_schema(module: ModuleType) -> str | None:
"""Extract the schema and identify list or dict based.""" """Extract the schema and identify list or dict based."""
if not isinstance(module.CONFIG_SCHEMA, vol.Schema): # type: ignore if not isinstance(module.CONFIG_SCHEMA, vol.Schema):
return None return None
schema = module.CONFIG_SCHEMA.schema # type: ignore schema = module.CONFIG_SCHEMA.schema
if isinstance(schema, vol.All): if isinstance(schema, vol.All):
for subschema in schema.validators: for subschema in schema.validators:
@ -656,7 +656,7 @@ def _identify_config_schema(module: ModuleType) -> str | None:
return None return None
try: try:
key = next(k for k in schema if k == module.DOMAIN) # type: ignore key = next(k for k in schema if k == module.DOMAIN)
except (TypeError, AttributeError, StopIteration): except (TypeError, AttributeError, StopIteration):
return None return None
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
@ -666,8 +666,8 @@ def _identify_config_schema(module: ModuleType) -> str | None:
if hasattr(key, "default") and not isinstance( if hasattr(key, "default") and not isinstance(
key.default, vol.schema_builder.Undefined key.default, vol.schema_builder.Undefined
): ):
default_value = module.CONFIG_SCHEMA({module.DOMAIN: key.default()})[ # type: ignore default_value = module.CONFIG_SCHEMA({module.DOMAIN: key.default()})[
module.DOMAIN # type: ignore module.DOMAIN
] ]
if isinstance(default_value, dict): if isinstance(default_value, dict):
@ -747,7 +747,7 @@ async def merge_packages_config(
# If integration has a custom config validator, it needs to provide a hint. # If integration has a custom config validator, it needs to provide a hint.
if config_platform is not None: if config_platform is not None:
merge_list = config_platform.PACKAGE_MERGE_HINT == "list" # type: ignore[attr-defined] merge_list = config_platform.PACKAGE_MERGE_HINT == "list"
if not merge_list: if not merge_list:
merge_list = hasattr(component, "PLATFORM_SCHEMA") merge_list = hasattr(component, "PLATFORM_SCHEMA")
@ -889,7 +889,7 @@ async def async_process_component_config( # noqa: C901
# Validate platform specific schema # Validate platform specific schema
if hasattr(platform, "PLATFORM_SCHEMA"): if hasattr(platform, "PLATFORM_SCHEMA"):
try: try:
p_validated = platform.PLATFORM_SCHEMA(p_config) # type: ignore p_validated = platform.PLATFORM_SCHEMA(p_config)
except vol.Invalid as ex: except vol.Invalid as ex:
async_log_exception( async_log_exception(
ex, ex,

View File

@ -9,7 +9,7 @@ from enum import Enum
import functools import functools
import logging import logging
from types import MappingProxyType, MethodType from types import MappingProxyType, MethodType
from typing import TYPE_CHECKING, Any, Callable, Optional, cast from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar, cast
import weakref import weakref
from . import data_entry_flow, loader from . import data_entry_flow, loader
@ -70,6 +70,8 @@ PATH_CONFIG = ".config_entries.json"
SAVE_DELAY = 1 SAVE_DELAY = 1
_T = TypeVar("_T", bound="ConfigEntryState")
class ConfigEntryState(Enum): class ConfigEntryState(Enum):
"""Config entry state.""" """Config entry state."""
@ -89,12 +91,12 @@ class ConfigEntryState(Enum):
_recoverable: bool _recoverable: bool
def __new__(cls: type[object], value: str, recoverable: bool) -> ConfigEntryState: def __new__(cls: type[_T], value: str, recoverable: bool) -> _T:
"""Create new ConfigEntryState.""" """Create new ConfigEntryState."""
obj = object.__new__(cls) obj = object.__new__(cls)
obj._value_ = value obj._value_ = value
obj._recoverable = recoverable obj._recoverable = recoverable
return cast("ConfigEntryState", obj) return obj
@property @property
def recoverable(self) -> bool: def recoverable(self) -> bool:
@ -321,7 +323,7 @@ class ConfigEntry:
error_reason = None error_reason = None
try: try:
result = await component.async_setup_entry(hass, self) # type: ignore result = await component.async_setup_entry(hass, self)
if not isinstance(result, bool): if not isinstance(result, bool):
_LOGGER.error( _LOGGER.error(
@ -460,7 +462,7 @@ class ConfigEntry:
return False return False
try: try:
result = await component.async_unload_entry(hass, self) # type: ignore result = await component.async_unload_entry(hass, self)
assert isinstance(result, bool) assert isinstance(result, bool)
@ -471,7 +473,8 @@ class ConfigEntry:
self._async_process_on_unload() self._async_process_on_unload()
return result # https://github.com/python/mypy/issues/11839
return result # type: ignore[no-any-return]
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
_LOGGER.exception( _LOGGER.exception(
"Error unloading entry %s for %s", self.title, integration.domain "Error unloading entry %s for %s", self.title, integration.domain
@ -499,7 +502,7 @@ class ConfigEntry:
if not hasattr(component, "async_remove_entry"): if not hasattr(component, "async_remove_entry"):
return return
try: try:
await component.async_remove_entry(hass, self) # type: ignore await component.async_remove_entry(hass, self)
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
_LOGGER.exception( _LOGGER.exception(
"Error calling entry remove callback %s for %s", "Error calling entry remove callback %s for %s",
@ -536,7 +539,7 @@ class ConfigEntry:
return False return False
try: try:
result = await component.async_migrate_entry(hass, self) # type: ignore result = await component.async_migrate_entry(hass, self)
if not isinstance(result, bool): if not isinstance(result, bool):
_LOGGER.error( _LOGGER.error(
"%s.async_migrate_entry did not return boolean", self.domain "%s.async_migrate_entry did not return boolean", self.domain
@ -545,7 +548,8 @@ class ConfigEntry:
if result: if result:
# pylint: disable=protected-access # pylint: disable=protected-access
hass.config_entries._async_schedule_save() hass.config_entries._async_schedule_save()
return result # https://github.com/python/mypy/issues/11839
return result # type: ignore[no-any-return]
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
_LOGGER.exception( _LOGGER.exception(
"Error migrating entry %s for %s", self.title, self.domain "Error migrating entry %s for %s", self.title, self.domain
@ -1169,7 +1173,7 @@ class ConfigFlow(data_entry_flow.FlowHandler):
def __init_subclass__(cls, domain: str | None = None, **kwargs: Any) -> None: def __init_subclass__(cls, domain: str | None = None, **kwargs: Any) -> None:
"""Initialize a subclass, register if possible.""" """Initialize a subclass, register if possible."""
super().__init_subclass__(**kwargs) # type: ignore super().__init_subclass__(**kwargs)
if domain is not None: if domain is not None:
HANDLERS.register(domain)(cls) HANDLERS.register(domain)(cls)

View File

@ -362,7 +362,7 @@ class HomeAssistant:
raise ValueError("Don't call async_add_job with None") raise ValueError("Don't call async_add_job with None")
if asyncio.iscoroutine(target): if asyncio.iscoroutine(target):
return self.async_create_task(cast(Coroutine, target)) return self.async_create_task(target)
return self.async_add_hass_job(HassJob(target), *args) return self.async_add_hass_job(HassJob(target), *args)
@ -462,7 +462,7 @@ class HomeAssistant:
args: parameters for method to call. args: parameters for method to call.
""" """
if asyncio.iscoroutine(target): if asyncio.iscoroutine(target):
return self.async_create_task(cast(Coroutine, target)) return self.async_create_task(target)
return self.async_run_hass_job(HassJob(target), *args) return self.async_run_hass_job(HassJob(target), *args)

View File

@ -159,9 +159,7 @@ async def async_check_ha_config_file( # noqa: C901
): ):
try: try:
result[domain] = ( result[domain] = (
await config_validator.async_validate_config( # type: ignore await config_validator.async_validate_config(hass, config)
hass, config
)
)[domain] )[domain]
continue continue
except (vol.Invalid, HomeAssistantError) as ex: except (vol.Invalid, HomeAssistantError) as ex:

View File

@ -880,7 +880,7 @@ async def async_device_from_config(
return trace_condition_function( return trace_condition_function(
cast( cast(
ConditionCheckerType, ConditionCheckerType,
platform.async_condition_from_config(hass, config), # type: ignore platform.async_condition_from_config(hass, config),
) )
) )
@ -946,7 +946,7 @@ async def async_validate_condition_config(
) )
if hasattr(platform, "async_validate_condition_config"): if hasattr(platform, "async_validate_condition_config"):
return await platform.async_validate_condition_config(hass, config) # type: ignore return await platform.async_validate_condition_config(hass, config) # type: ignore
return cast(ConfigType, platform.CONDITION_SCHEMA(config)) # type: ignore return cast(ConfigType, platform.CONDITION_SCHEMA(config))
if condition in ("numeric_state", "state"): if condition in ("numeric_state", "state"):
validator = getattr( validator = getattr(

View File

@ -16,7 +16,7 @@ from numbers import Number
import os import os
import re import re
from socket import _GLOBAL_DEFAULT_TIMEOUT # type: ignore # private, not in typeshed from socket import _GLOBAL_DEFAULT_TIMEOUT # type: ignore # private, not in typeshed
from typing import Any, Dict, TypeVar, cast from typing import Any, Dict, TypeVar, cast, overload
from urllib.parse import urlparse from urllib.parse import urlparse
from uuid import UUID from uuid import UUID
@ -245,7 +245,17 @@ def isdir(value: Any) -> str:
return dir_in return dir_in
def ensure_list(value: T | list[T] | None) -> list[T]: @overload
def ensure_list(value: None) -> list[Any]:
...
@overload
def ensure_list(value: T | list[T]) -> list[T]:
...
def ensure_list(value: T | list[T] | None) -> list[T] | list[Any]:
"""Wrap value in list if it is not one.""" """Wrap value in list if it is not one."""
if value is None: if value is None:
return [] return []

View File

@ -79,8 +79,8 @@ async def _resetup_platform(
if hasattr(component, "async_reset_platform"): if hasattr(component, "async_reset_platform"):
# If the integration has its own way to reset # If the integration has its own way to reset
# use this method. # use this method.
await component.async_reset_platform(hass, integration_name) # type: ignore await component.async_reset_platform(hass, integration_name)
await component.async_setup(hass, root_config) # type: ignore await component.async_setup(hass, root_config)
return return
# If it's an entity platform, we use the entity_platform # If it's an entity platform, we use the entity_platform

View File

@ -248,9 +248,9 @@ async def async_validate_action_config(
hass, config[CONF_DOMAIN], device_automation.DeviceAutomationType.ACTION hass, config[CONF_DOMAIN], device_automation.DeviceAutomationType.ACTION
) )
if hasattr(platform, "async_validate_action_config"): if hasattr(platform, "async_validate_action_config"):
config = await platform.async_validate_action_config(hass, config) # type: ignore config = await platform.async_validate_action_config(hass, config)
else: else:
config = platform.ACTION_SCHEMA(config) # type: ignore config = platform.ACTION_SCHEMA(config)
elif action_type == cv.SCRIPT_ACTION_CHECK_CONDITION: elif action_type == cv.SCRIPT_ACTION_CHECK_CONDITION:
config = await condition.async_validate_condition_config(hass, config) config = await condition.async_validate_condition_config(hass, config)

View File

@ -8,6 +8,7 @@ from functools import partial, wraps
import logging import logging
from typing import TYPE_CHECKING, Any, TypedDict from typing import TYPE_CHECKING, Any, TypedDict
from typing_extensions import TypeGuard
import voluptuous as vol import voluptuous as vol
from homeassistant.auth.permissions.const import CAT_ENTITIES, POLICY_CONTROL from homeassistant.auth.permissions.const import CAT_ENTITIES, POLICY_CONTROL
@ -319,7 +320,7 @@ async def async_extract_entity_ids(
return referenced.referenced | referenced.indirectly_referenced return referenced.referenced | referenced.indirectly_referenced
def _has_match(ids: str | list | None) -> bool: def _has_match(ids: str | list[str] | None) -> TypeGuard[str | list[str]]:
"""Check if ids can match anything.""" """Check if ids can match anything."""
return ids not in (None, ENTITY_MATCH_NONE) return ids not in (None, ENTITY_MATCH_NONE)
@ -706,7 +707,7 @@ async def _handle_entity_call(
func, func,
entity.entity_id, entity.entity_id,
) )
await result # type: ignore await result
@bind_hass @bind_hass

View File

@ -318,7 +318,7 @@ class Integration:
cls, hass: HomeAssistant, root_module: ModuleType, domain: str cls, hass: HomeAssistant, root_module: ModuleType, domain: str
) -> Integration | None: ) -> Integration | None:
"""Resolve an integration from a root module.""" """Resolve an integration from a root module."""
for base in root_module.__path__: # type: ignore for base in root_module.__path__:
manifest_path = pathlib.Path(base) / domain / "manifest.json" manifest_path = pathlib.Path(base) / domain / "manifest.json"
if not manifest_path.is_file(): if not manifest_path.is_file():

View File

@ -64,7 +64,7 @@ def run(args: list[str]) -> int:
asyncio.set_event_loop_policy(runner.HassEventLoopPolicy(False)) asyncio.set_event_loop_policy(runner.HassEventLoopPolicy(False))
return script.run(args[1:]) # type: ignore return script.run(args[1:])
def extract_config_dir(args: Sequence[str] | None = None) -> str: def extract_config_dir(args: Sequence[str] | None = None) -> str:

View File

@ -7,6 +7,7 @@ import contextlib
import logging.handlers import logging.handlers
from timeit import default_timer as timer from timeit import default_timer as timer
from types import ModuleType from types import ModuleType
from typing import Any
from . import config as conf_util, core, loader, requirements from . import config as conf_util, core, loader, requirements
from .config import async_notify_setup_error from .config import async_notify_setup_error
@ -210,15 +211,15 @@ async def _async_setup_component(
) )
task = None task = None
result = True result: Any | bool = True
try: try:
if hasattr(component, "async_setup"): if hasattr(component, "async_setup"):
task = component.async_setup(hass, processed_config) # type: ignore task = component.async_setup(hass, processed_config)
elif hasattr(component, "setup"): elif hasattr(component, "setup"):
# This should not be replaced with hass.async_add_executor_job because # This should not be replaced with hass.async_add_executor_job because
# we don't want to track this task in case it blocks startup. # we don't want to track this task in case it blocks startup.
task = hass.loop.run_in_executor( task = hass.loop.run_in_executor(
None, component.setup, hass, processed_config # type: ignore None, component.setup, hass, processed_config
) )
elif not hasattr(component, "async_setup_entry"): elif not hasattr(component, "async_setup_entry"):
log_error("No setup or config entry setup function defined.") log_error("No setup or config entry setup function defined.")

View File

@ -3,7 +3,7 @@ from __future__ import annotations
import colorsys import colorsys
import math import math
from typing import NamedTuple from typing import NamedTuple, cast
import attr import attr
@ -299,7 +299,7 @@ def color_xy_brightness_to_RGB(
r, g, b = map( r, g, b = map(
lambda x: (12.92 * x) lambda x: (12.92 * x)
if (x <= 0.0031308) if (x <= 0.0031308)
else ((1.0 + 0.055) * pow(x, (1.0 / 2.4)) - 0.055), else ((1.0 + 0.055) * cast(float, pow(x, (1.0 / 2.4))) - 0.055),
[r, g, b], [r, g, b],
) )

View File

@ -64,7 +64,7 @@ class InterruptibleThreadPoolExecutor(ThreadPoolExecutor):
def shutdown(self, *args, **kwargs) -> None: # type: ignore def shutdown(self, *args, **kwargs) -> None: # type: ignore
"""Shutdown backport from cpython 3.9 with interrupt support added.""" """Shutdown backport from cpython 3.9 with interrupt support added."""
with self._shutdown_lock: # type: ignore[attr-defined] with self._shutdown_lock:
self._shutdown = True self._shutdown = True
# Drain all work items from the queue, and then cancel their # Drain all work items from the queue, and then cancel their
# associated futures. # associated futures.
@ -77,7 +77,7 @@ class InterruptibleThreadPoolExecutor(ThreadPoolExecutor):
work_item.future.cancel() work_item.future.cancel()
# Send a wake-up to prevent threads calling # Send a wake-up to prevent threads calling
# _work_queue.get(block=True) from permanently blocking. # _work_queue.get(block=True) from permanently blocking.
self._work_queue.put(None) self._work_queue.put(None) # type: ignore[arg-type]
# The above code is backported from python 3.9 # The above code is backported from python 3.9
# #
@ -89,7 +89,7 @@ class InterruptibleThreadPoolExecutor(ThreadPoolExecutor):
def join_threads_or_timeout(self) -> None: def join_threads_or_timeout(self) -> None:
"""Join threads or timeout.""" """Join threads or timeout."""
remaining_threads = set(self._threads) # type: ignore[attr-defined] remaining_threads = set(self._threads)
start_time = time.monotonic() start_time = time.monotonic()
timeout_remaining: float = EXECUTOR_SHUTDOWN_TIMEOUT timeout_remaining: float = EXECUTOR_SHUTDOWN_TIMEOUT
attempt = 0 attempt = 0

View File

@ -12,7 +12,7 @@ coverage==6.2.0
freezegun==1.1.0 freezegun==1.1.0
jsonpickle==1.4.1 jsonpickle==1.4.1
mock-open==1.4.0 mock-open==1.4.0
mypy==0.910 mypy==0.930
pre-commit==2.16.0 pre-commit==2.16.0
pylint==2.12.1 pylint==2.12.1
pipdeptree==2.2.0 pipdeptree==2.2.0