Enable basic type checking for cloud (#55337)

* Enable basic type checking for cloud

* Update mypy settings

* Address review comment

* Fix rebase mistakes

* Correct decorator order
pull/59821/head
Erik Montnemery 2021-11-17 09:07:01 +01:00 committed by GitHub
parent 593bc866f0
commit dec54488e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 31 additions and 29 deletions

View File

@ -42,12 +42,13 @@ class CloudClient(Interface):
self._websession = websession
self.google_user_config = google_user_config
self.alexa_user_config = alexa_user_config
self._alexa_config = None
self._google_config = None
self._alexa_config: alexa_config.AlexaConfig | None = None
self._google_config: google_config.CloudGoogleConfig | None = None
@property
def base_path(self) -> Path:
"""Return path to base dir."""
assert self._hass.config.config_dir is not None
return Path(self._hass.config.config_dir)
@property
@ -56,7 +57,7 @@ class CloudClient(Interface):
return self._prefs
@property
def loop(self) -> asyncio.BaseEventLoop:
def loop(self) -> asyncio.AbstractEventLoop:
"""Return client loop."""
return self._hass.loop
@ -66,7 +67,7 @@ class CloudClient(Interface):
return self._websession
@property
def aiohttp_runner(self) -> aiohttp.web.AppRunner:
def aiohttp_runner(self) -> aiohttp.web.AppRunner | None:
"""Return client webinterface aiohttp application."""
return self._hass.http.runner

View File

@ -264,8 +264,8 @@ class CloudForgotPasswordView(HomeAssistantView):
return self.json_message("ok")
@websocket_api.async_response
@websocket_api.websocket_command({vol.Required("type"): "cloud/status"})
@websocket_api.async_response
async def websocket_cloud_status(hass, connection, msg):
"""Handle request for account info.
@ -298,8 +298,8 @@ def _require_cloud_login(handler):
@_require_cloud_login
@websocket_api.async_response
@websocket_api.websocket_command({vol.Required("type"): "cloud/subscription"})
@websocket_api.async_response
async def websocket_subscription(hass, connection, msg):
"""Handle request for account info."""
cloud = hass.data[DOMAIN]
@ -315,7 +315,6 @@ async def websocket_subscription(hass, connection, msg):
@_require_cloud_login
@websocket_api.async_response
@websocket_api.websocket_command(
{
vol.Required("type"): "cloud/update_prefs",
@ -331,6 +330,7 @@ async def websocket_subscription(hass, connection, msg):
),
}
)
@websocket_api.async_response
async def websocket_update_prefs(hass, connection, msg):
"""Handle request for account info."""
cloud = hass.data[DOMAIN]
@ -365,14 +365,14 @@ async def websocket_update_prefs(hass, connection, msg):
@_require_cloud_login
@websocket_api.async_response
@_ws_handle_cloud_errors
@websocket_api.websocket_command(
{
vol.Required("type"): "cloud/cloudhook/create",
vol.Required("webhook_id"): str,
}
)
@websocket_api.async_response
@_ws_handle_cloud_errors
async def websocket_hook_create(hass, connection, msg):
"""Handle request for account info."""
cloud = hass.data[DOMAIN]
@ -381,14 +381,14 @@ async def websocket_hook_create(hass, connection, msg):
@_require_cloud_login
@websocket_api.async_response
@_ws_handle_cloud_errors
@websocket_api.websocket_command(
{
vol.Required("type"): "cloud/cloudhook/delete",
vol.Required("webhook_id"): str,
}
)
@websocket_api.async_response
@_ws_handle_cloud_errors
async def websocket_hook_delete(hass, connection, msg):
"""Handle request for account info."""
cloud = hass.data[DOMAIN]
@ -430,9 +430,9 @@ async def _account_data(cloud):
@websocket_api.require_admin
@_require_cloud_login
@websocket_api.websocket_command({"type": "cloud/remote/connect"})
@websocket_api.async_response
@_ws_handle_cloud_errors
@websocket_api.websocket_command({"type": "cloud/remote/connect"})
async def websocket_remote_connect(hass, connection, msg):
"""Handle request for connect remote."""
cloud = hass.data[DOMAIN]
@ -442,9 +442,9 @@ async def websocket_remote_connect(hass, connection, msg):
@websocket_api.require_admin
@_require_cloud_login
@websocket_api.websocket_command({"type": "cloud/remote/disconnect"})
@websocket_api.async_response
@_ws_handle_cloud_errors
@websocket_api.websocket_command({"type": "cloud/remote/disconnect"})
async def websocket_remote_disconnect(hass, connection, msg):
"""Handle request for disconnect remote."""
cloud = hass.data[DOMAIN]
@ -454,9 +454,9 @@ async def websocket_remote_disconnect(hass, connection, msg):
@websocket_api.require_admin
@_require_cloud_login
@websocket_api.websocket_command({"type": "cloud/google_assistant/entities"})
@websocket_api.async_response
@_ws_handle_cloud_errors
@websocket_api.websocket_command({"type": "cloud/google_assistant/entities"})
async def google_assistant_list(hass, connection, msg):
"""List all google assistant entities."""
cloud = hass.data[DOMAIN]
@ -479,8 +479,6 @@ async def google_assistant_list(hass, connection, msg):
@websocket_api.require_admin
@_require_cloud_login
@websocket_api.async_response
@_ws_handle_cloud_errors
@websocket_api.websocket_command(
{
"type": "cloud/google_assistant/entities/update",
@ -491,6 +489,8 @@ async def google_assistant_list(hass, connection, msg):
vol.Optional("disable_2fa"): bool,
}
)
@websocket_api.async_response
@_ws_handle_cloud_errors
async def google_assistant_update(hass, connection, msg):
"""Update google assistant config."""
cloud = hass.data[DOMAIN]
@ -507,9 +507,9 @@ async def google_assistant_update(hass, connection, msg):
@websocket_api.require_admin
@_require_cloud_login
@websocket_api.websocket_command({"type": "cloud/alexa/entities"})
@websocket_api.async_response
@_ws_handle_cloud_errors
@websocket_api.websocket_command({"type": "cloud/alexa/entities"})
async def alexa_list(hass, connection, msg):
"""List all alexa entities."""
cloud = hass.data[DOMAIN]
@ -532,8 +532,6 @@ async def alexa_list(hass, connection, msg):
@websocket_api.require_admin
@_require_cloud_login
@websocket_api.async_response
@_ws_handle_cloud_errors
@websocket_api.websocket_command(
{
"type": "cloud/alexa/entities/update",
@ -541,6 +539,8 @@ async def alexa_list(hass, connection, msg):
vol.Optional("should_expose"): vol.Any(None, bool),
}
)
@websocket_api.async_response
@_ws_handle_cloud_errors
async def alexa_update(hass, connection, msg):
"""Update alexa entity config."""
cloud = hass.data[DOMAIN]
@ -557,8 +557,8 @@ async def alexa_update(hass, connection, msg):
@websocket_api.require_admin
@_require_cloud_login
@websocket_api.async_response
@websocket_api.websocket_command({"type": "cloud/alexa/sync"})
@websocket_api.async_response
async def alexa_sync(hass, connection, msg):
"""Sync with Alexa."""
cloud = hass.data[DOMAIN]
@ -581,8 +581,8 @@ async def alexa_sync(hass, connection, msg):
connection.send_error(msg["id"], ws_const.ERR_UNKNOWN_ERROR, "Unknown error")
@websocket_api.async_response
@websocket_api.websocket_command({"type": "cloud/thingtalk/convert", "query": str})
@websocket_api.async_response
async def thingtalk_convert(hass, connection, msg):
"""Convert a query."""
cloud = hass.data[DOMAIN]

View File

@ -283,6 +283,7 @@ class CloudPreferences:
user = await self._hass.auth.async_create_system_user(
"Home Assistant Cloud", [GROUP_ID_ADMIN]
)
assert user is not None
await self.async_update(cloud_user=user.id)
return user.id

View File

@ -9,13 +9,17 @@ from aiohttp import payload, web
def aiohttp_serialize_response(response: web.Response) -> dict[str, Any]:
"""Serialize an aiohttp response to a dictionary."""
if (body := response.body) is None:
pass
body_decoded = None
elif isinstance(body, payload.StringPayload):
# pylint: disable=protected-access
body = body._value.decode(body.encoding)
body_decoded = body._value.decode(body.encoding)
elif isinstance(body, bytes):
body = body.decode(response.charset or "utf-8")
body_decoded = body.decode(response.charset or "utf-8")
else:
raise ValueError("Unknown payload encoding")
return {"status": response.status, "body": body, "headers": dict(response.headers)}
return {
"status": response.status,
"body": body_decoded,
"headers": dict(response.headers),
}

View File

@ -1670,9 +1670,6 @@ ignore_errors = true
[mypy-homeassistant.components.climacell.*]
ignore_errors = true
[mypy-homeassistant.components.cloud.*]
ignore_errors = true
[mypy-homeassistant.components.config.*]
ignore_errors = true

View File

@ -17,7 +17,6 @@ IGNORED_MODULES: Final[list[str]] = [
"homeassistant.components.awair.*",
"homeassistant.components.blueprint.*",
"homeassistant.components.climacell.*",
"homeassistant.components.cloud.*",
"homeassistant.components.config.*",
"homeassistant.components.conversation.*",
"homeassistant.components.deconz.*",