Enable Ruff TRY300 (#114437)
* Enable Ruff TRY300 * Update validation.py * Address review comments
This commit is contained in:
parent
9a79320861
commit
6587ee20db
97 changed files with 259 additions and 243 deletions
|
@ -60,10 +60,6 @@ class AmberElectricConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||
|
||||
try:
|
||||
sites: list[Site] = filter_sites(api.get_sites())
|
||||
if len(sites) == 0:
|
||||
self._errors[CONF_API_TOKEN] = "no_site"
|
||||
return None
|
||||
return sites
|
||||
except amberelectric.ApiException as api_exception:
|
||||
if api_exception.status == 403:
|
||||
self._errors[CONF_API_TOKEN] = "invalid_api_token"
|
||||
|
@ -71,6 +67,11 @@ class AmberElectricConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||
self._errors[CONF_API_TOKEN] = "unknown_error"
|
||||
return None
|
||||
|
||||
if len(sites) == 0:
|
||||
self._errors[CONF_API_TOKEN] = "no_site"
|
||||
return None
|
||||
return sites
|
||||
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, str] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
|
|
|
@ -76,9 +76,9 @@ async def device_scan(
|
|||
return None
|
||||
try:
|
||||
ip_address(identifier)
|
||||
return [identifier]
|
||||
except ValueError:
|
||||
return None
|
||||
return [identifier]
|
||||
|
||||
# If we have an address, only probe that address to avoid
|
||||
# broadcast traffic on the network
|
||||
|
|
|
@ -127,9 +127,9 @@ def verify_client_id(client_id: str) -> bool:
|
|||
"""Verify that the client id is valid."""
|
||||
try:
|
||||
_parse_client_id(client_id)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _parse_url(url: str) -> ParseResult:
|
||||
|
|
|
@ -250,13 +250,12 @@ class AwairFlowHandler(ConfigFlow, domain=DOMAIN):
|
|||
try:
|
||||
user = await awair.user()
|
||||
devices = await user.devices()
|
||||
if not devices:
|
||||
return (None, "no_devices_found")
|
||||
|
||||
return (user, None)
|
||||
|
||||
except AuthError:
|
||||
return (None, "invalid_access_token")
|
||||
except AwairError as err:
|
||||
LOGGER.error("Unexpected API error: %s", err)
|
||||
return (None, "unknown")
|
||||
|
||||
if not devices:
|
||||
return (None, "no_devices_found")
|
||||
return (user, None)
|
||||
|
|
|
@ -111,7 +111,7 @@ class AwairLocalDataUpdateCoordinator(AwairDataUpdateCoordinator):
|
|||
devices = await self._awair.devices()
|
||||
self._device = devices[0]
|
||||
result = await self._fetch_air_data(self._device)
|
||||
return {result.device.uuid: result}
|
||||
except AwairError as err:
|
||||
LOGGER.error("Unexpected API error: %s", err)
|
||||
raise UpdateFailed(err) from err
|
||||
return {result.device.uuid: result}
|
||||
|
|
|
@ -819,22 +819,23 @@ class BrSensor(SensorEntity):
|
|||
self._attr_native_value = data.get(FORECAST)[fcday].get(
|
||||
sensor_type[:-3]
|
||||
)
|
||||
if self.state is not None:
|
||||
self._attr_native_value = round(self.state * 3.6, 1)
|
||||
return True
|
||||
except IndexError:
|
||||
_LOGGER.warning("No forecast for fcday=%s", fcday)
|
||||
return False
|
||||
|
||||
if self.state is not None:
|
||||
self._attr_native_value = round(self.state * 3.6, 1)
|
||||
return True
|
||||
|
||||
# update all other sensors
|
||||
try:
|
||||
self._attr_native_value = data.get(FORECAST)[fcday].get(
|
||||
sensor_type[:-3]
|
||||
)
|
||||
return True
|
||||
except IndexError:
|
||||
_LOGGER.warning("No forecast for fcday=%s", fcday)
|
||||
return False
|
||||
return True
|
||||
|
||||
if sensor_type == SYMBOL or sensor_type.startswith(CONDITION):
|
||||
# update weather symbol & status text
|
||||
|
|
|
@ -43,7 +43,6 @@ class CertexpiryConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||
user_input[CONF_HOST],
|
||||
user_input.get(CONF_PORT, DEFAULT_PORT),
|
||||
)
|
||||
return True
|
||||
except ResolveFailed:
|
||||
self._errors[CONF_HOST] = "resolve_failed"
|
||||
except ConnectionTimeout:
|
||||
|
@ -52,6 +51,8 @@ class CertexpiryConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||
self._errors[CONF_HOST] = "connection_refused"
|
||||
except ValidationFailure:
|
||||
return True
|
||||
else:
|
||||
return True
|
||||
return False
|
||||
|
||||
async def async_step_user(
|
||||
|
|
|
@ -228,6 +228,9 @@ class CityBikesNetworks:
|
|||
self.hass, NETWORKS_URI, NETWORKS_RESPONSE_SCHEMA
|
||||
)
|
||||
self.networks = networks[ATTR_NETWORKS_LIST]
|
||||
except CityBikesRequestError as err:
|
||||
raise PlatformNotReady from err
|
||||
else:
|
||||
result = None
|
||||
minimum_dist = None
|
||||
for network in self.networks:
|
||||
|
@ -241,8 +244,6 @@ class CityBikesNetworks:
|
|||
result = network[ATTR_ID]
|
||||
|
||||
return result
|
||||
except CityBikesRequestError as err:
|
||||
raise PlatformNotReady from err
|
||||
finally:
|
||||
self.networks_loading.release()
|
||||
|
||||
|
|
|
@ -509,16 +509,13 @@ class CloudAlexaConfig(alexa_config.AbstractConfig):
|
|||
try:
|
||||
async with asyncio.timeout(10):
|
||||
await asyncio.wait(tasks, return_when=asyncio.ALL_COMPLETED)
|
||||
|
||||
return True
|
||||
|
||||
except TimeoutError:
|
||||
_LOGGER.warning("Timeout trying to sync entities to Alexa")
|
||||
return False
|
||||
|
||||
except aiohttp.ClientError as err:
|
||||
_LOGGER.warning("Error trying to sync entities to Alexa: %s", err)
|
||||
return False
|
||||
return True
|
||||
|
||||
async def _handle_entity_registry_updated(self, event: Event) -> None:
|
||||
"""Handle when entity registry updated."""
|
||||
|
|
|
@ -135,12 +135,12 @@ def _handle_cloud_errors(
|
|||
"""Handle exceptions that raise from the wrapped request handler."""
|
||||
try:
|
||||
result = await handler(view, request, *args, **kwargs)
|
||||
return result
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
status, msg = _process_cloud_exception(err, request.path)
|
||||
return view.json_message(
|
||||
msg, status_code=status, message_code=err.__class__.__name__.lower()
|
||||
)
|
||||
return result
|
||||
|
||||
return error_handler
|
||||
|
||||
|
|
|
@ -25,20 +25,21 @@ async def async_call_shell_with_timeout(
|
|||
)
|
||||
async with asyncio.timeout(timeout):
|
||||
await proc.communicate()
|
||||
return_code = proc.returncode
|
||||
if return_code == _EXEC_FAILED_CODE:
|
||||
_LOGGER.error("Error trying to exec command: %s", command)
|
||||
elif log_return_code and return_code != 0:
|
||||
_LOGGER.error(
|
||||
"Command failed (with return code %s): %s",
|
||||
proc.returncode,
|
||||
command,
|
||||
)
|
||||
return return_code or 0
|
||||
except TimeoutError:
|
||||
_LOGGER.error("Timeout for command: %s", command)
|
||||
return -1
|
||||
|
||||
return_code = proc.returncode
|
||||
if return_code == _EXEC_FAILED_CODE:
|
||||
_LOGGER.error("Error trying to exec command: %s", command)
|
||||
elif log_return_code and return_code != 0:
|
||||
_LOGGER.error(
|
||||
"Command failed (with return code %s): %s",
|
||||
proc.returncode,
|
||||
command,
|
||||
)
|
||||
return return_code or 0
|
||||
|
||||
|
||||
async def async_check_output_or_log(command: str, timeout: int) -> str | None:
|
||||
"""Run a shell command with a timeout and return the output."""
|
||||
|
|
|
@ -68,9 +68,9 @@ class Control4Validator:
|
|||
self.director_bearer_token = (
|
||||
await account.getDirectorBearerToken(self.controller_unique_id)
|
||||
)["token"]
|
||||
return True
|
||||
except (Unauthorized, NotFound):
|
||||
return False
|
||||
return True
|
||||
|
||||
async def connect_to_director(self) -> bool:
|
||||
"""Test if we can connect to the local Control4 Director."""
|
||||
|
@ -82,10 +82,10 @@ class Control4Validator:
|
|||
self.host, self.director_bearer_token, director_session
|
||||
)
|
||||
await director.getAllItemInfo()
|
||||
return True
|
||||
except (Unauthorized, ClientError, TimeoutError):
|
||||
_LOGGER.error("Failed to connect to the Control4 controller")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class Control4ConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
|
|
|
@ -26,7 +26,6 @@ async def get_deconz_api(
|
|||
try:
|
||||
async with asyncio.timeout(10):
|
||||
await api.refresh_state()
|
||||
return api
|
||||
|
||||
except errors.Unauthorized as err:
|
||||
LOGGER.warning("Invalid key for deCONZ at %s", config.host)
|
||||
|
@ -35,3 +34,4 @@ async def get_deconz_api(
|
|||
except (TimeoutError, errors.RequestError, errors.ResponseError) as err:
|
||||
LOGGER.error("Error connecting to deCONZ gateway at %s", config.host)
|
||||
raise CannotConnect from err
|
||||
return api
|
||||
|
|
|
@ -139,10 +139,10 @@ class Dominos:
|
|||
"""Update the shared closest store (if open)."""
|
||||
try:
|
||||
self.closest_store = self.address.closest_store()
|
||||
return True
|
||||
except StoreException:
|
||||
self.closest_store = None
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_menu(self):
|
||||
"""Return the products from the closest stores menu."""
|
||||
|
|
|
@ -107,8 +107,6 @@ class DoorBirdCamera(DoorBirdEntity, Camera):
|
|||
response = await websession.get(self._url)
|
||||
|
||||
self._last_image = await response.read()
|
||||
self._last_update = now
|
||||
return self._last_image
|
||||
except TimeoutError:
|
||||
_LOGGER.error("DoorBird %s: Camera image timed out", self.name)
|
||||
return self._last_image
|
||||
|
@ -118,6 +116,9 @@ class DoorBirdCamera(DoorBirdEntity, Camera):
|
|||
)
|
||||
return self._last_image
|
||||
|
||||
self._last_update = now
|
||||
return self._last_image
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Subscribe to events."""
|
||||
await super().async_added_to_hass()
|
||||
|
|
|
@ -74,10 +74,11 @@ class DovadoData:
|
|||
if not self.state:
|
||||
return False
|
||||
self.state.update(connected=self.state.get("modem status") == "CONNECTED")
|
||||
_LOGGER.debug("Received: %s", self.state)
|
||||
return True
|
||||
except OSError as error:
|
||||
_LOGGER.warning("Could not contact the router: %s", error)
|
||||
return None
|
||||
_LOGGER.debug("Received: %s", self.state)
|
||||
return True
|
||||
|
||||
@property
|
||||
def client(self):
|
||||
|
|
|
@ -67,21 +67,20 @@ def setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
|
||||
try:
|
||||
ebusdpy.init(server_address)
|
||||
hass.data[DOMAIN] = EbusdData(server_address, circuit)
|
||||
|
||||
sensor_config = {
|
||||
CONF_MONITORED_CONDITIONS: monitored_conditions,
|
||||
"client_name": name,
|
||||
"sensor_types": SENSOR_TYPES[circuit],
|
||||
}
|
||||
load_platform(hass, Platform.SENSOR, DOMAIN, sensor_config, config)
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_EBUSD_WRITE, hass.data[DOMAIN].write)
|
||||
|
||||
_LOGGER.debug("Ebusd integration setup completed")
|
||||
return True
|
||||
except (TimeoutError, OSError):
|
||||
return False
|
||||
hass.data[DOMAIN] = EbusdData(server_address, circuit)
|
||||
sensor_config = {
|
||||
CONF_MONITORED_CONDITIONS: monitored_conditions,
|
||||
"client_name": name,
|
||||
"sensor_types": SENSOR_TYPES[circuit],
|
||||
}
|
||||
load_platform(hass, Platform.SENSOR, DOMAIN, sensor_config, config)
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_EBUSD_WRITE, hass.data[DOMAIN].write)
|
||||
|
||||
_LOGGER.debug("Ebusd integration setup completed")
|
||||
return True
|
||||
|
||||
|
||||
class EbusdData:
|
||||
|
|
|
@ -32,7 +32,8 @@ class EcoforestCoordinator(DataUpdateCoordinator[Device]):
|
|||
"""Fetch all device and sensor data from api."""
|
||||
try:
|
||||
data = await self.api.get()
|
||||
_LOGGER.debug("Ecoforest data: %s", data)
|
||||
return data
|
||||
except EcoforestError as err:
|
||||
raise UpdateFailed(f"Error communicating with API: {err}") from err
|
||||
|
||||
_LOGGER.debug("Ecoforest data: %s", data)
|
||||
return data
|
||||
|
|
|
@ -82,7 +82,7 @@ def validate_path(path: str):
|
|||
# Creating the serial communicator will raise an exception
|
||||
# if it cannot connect
|
||||
SerialCommunicator(port=path)
|
||||
return True
|
||||
except serial.SerialException as exception:
|
||||
_LOGGER.warning("Dongle path %s is invalid: %s", path, str(exception))
|
||||
return False
|
||||
return True
|
||||
|
|
|
@ -147,8 +147,6 @@ class EnphaseUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
|||
self._async_mark_setup_complete()
|
||||
# dump all received data in debug mode to assist troubleshooting
|
||||
envoy_data = await envoy.update()
|
||||
_LOGGER.debug("Envoy data: %s", envoy_data)
|
||||
return envoy_data.raw
|
||||
except INVALID_AUTH_ERRORS as err:
|
||||
if self._setup_complete and tries == 0:
|
||||
# token likely expired or firmware changed, try to re-authenticate
|
||||
|
@ -157,5 +155,7 @@ class EnphaseUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
|||
raise ConfigEntryAuthFailed from err
|
||||
except EnvoyError as err:
|
||||
raise UpdateFailed(f"Error communicating with API: {err}") from err
|
||||
_LOGGER.debug("Envoy data: %s", envoy_data)
|
||||
return envoy_data.raw
|
||||
|
||||
raise RuntimeError("Unreachable code in _async_update_data") # pragma: no cover
|
||||
|
|
|
@ -43,7 +43,6 @@ def is_json(json_str: str) -> bool:
|
|||
"""Validate if a String is a JSON value or not."""
|
||||
try:
|
||||
json.loads(json_str)
|
||||
return True
|
||||
except (ValueError, TypeError) as err:
|
||||
_LOGGER.error(
|
||||
"Failed to parse JSON '%s', error '%s'",
|
||||
|
@ -51,6 +50,7 @@ def is_json(json_str: str) -> bool:
|
|||
err,
|
||||
)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
async def get_api(hass: HomeAssistant, host: str) -> Freepybox:
|
||||
|
|
|
@ -789,24 +789,26 @@ class AvmWrapper(FritzBoxTools): # pylint: disable=hass-enforce-coordinator-mod
|
|||
**kwargs,
|
||||
)
|
||||
)
|
||||
return result
|
||||
except FritzSecurityError:
|
||||
_LOGGER.exception(
|
||||
"Authorization Error: Please check the provided credentials and"
|
||||
" verify that you can log into the web interface"
|
||||
)
|
||||
return {}
|
||||
except FRITZ_EXCEPTIONS:
|
||||
_LOGGER.exception(
|
||||
"Service/Action Error: cannot execute service %s with action %s",
|
||||
service_name,
|
||||
action_name,
|
||||
)
|
||||
return {}
|
||||
except FritzConnectionException:
|
||||
_LOGGER.exception(
|
||||
"Connection Error: Please check the device is properly configured"
|
||||
" for remote login"
|
||||
)
|
||||
return {}
|
||||
return {}
|
||||
return result
|
||||
|
||||
async def async_get_upnp_configuration(self) -> dict[str, Any]:
|
||||
"""Call X_AVM-DE_UPnP service."""
|
||||
|
|
|
@ -82,13 +82,13 @@ class FritzboxConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||
fritzbox.login()
|
||||
fritzbox.get_device_elements()
|
||||
fritzbox.logout()
|
||||
return RESULT_SUCCESS
|
||||
except LoginError:
|
||||
return RESULT_INVALID_AUTH
|
||||
except HTTPError:
|
||||
return RESULT_NOT_SUPPORTED
|
||||
except OSError:
|
||||
return RESULT_NO_DEVICES_FOUND
|
||||
return RESULT_SUCCESS
|
||||
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
|
|
|
@ -109,9 +109,6 @@ class FritzBoxCallMonitorConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||
address=self._host, user=self._username, password=self._password
|
||||
)
|
||||
info = fritz_connection.updatecheck
|
||||
self._serial_number = info[FRITZ_ATTR_SERIAL_NUMBER]
|
||||
|
||||
return ConnectResult.SUCCESS
|
||||
except RequestsConnectionError:
|
||||
return ConnectResult.NO_DEVIES_FOUND
|
||||
except FritzSecurityError:
|
||||
|
@ -119,6 +116,9 @@ class FritzBoxCallMonitorConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||
except FritzConnectionException:
|
||||
return ConnectResult.INVALID_AUTH
|
||||
|
||||
self._serial_number = info[FRITZ_ATTR_SERIAL_NUMBER]
|
||||
return ConnectResult.SUCCESS
|
||||
|
||||
async def _get_name_of_phonebook(self, phonebook_id: int) -> str:
|
||||
"""Return name of phonebook for given phonebook_id."""
|
||||
phonebook_info = await self.hass.async_add_executor_job(
|
||||
|
|
|
@ -483,28 +483,28 @@ class HassioDataUpdateCoordinator(DataUpdateCoordinator): # pylint: disable=has
|
|||
"""Update single addon stats."""
|
||||
try:
|
||||
stats = await self.hassio.get_addon_stats(slug)
|
||||
return (slug, stats)
|
||||
except HassioAPIError as err:
|
||||
_LOGGER.warning("Could not fetch stats for %s: %s", slug, err)
|
||||
return (slug, None)
|
||||
return (slug, None)
|
||||
return (slug, stats)
|
||||
|
||||
async def _update_addon_changelog(self, slug: str) -> tuple[str, str | None]:
|
||||
"""Return the changelog for an add-on."""
|
||||
try:
|
||||
changelog = await self.hassio.get_addon_changelog(slug)
|
||||
return (slug, changelog)
|
||||
except HassioAPIError as err:
|
||||
_LOGGER.warning("Could not fetch changelog for %s: %s", slug, err)
|
||||
return (slug, None)
|
||||
return (slug, None)
|
||||
return (slug, changelog)
|
||||
|
||||
async def _update_addon_info(self, slug: str) -> tuple[str, dict[str, Any] | None]:
|
||||
"""Return the info for an add-on."""
|
||||
try:
|
||||
info = await self.hassio.get_addon_info(slug)
|
||||
return (slug, info)
|
||||
except HassioAPIError as err:
|
||||
_LOGGER.warning("Could not fetch info for %s: %s", slug, err)
|
||||
return (slug, None)
|
||||
return (slug, None)
|
||||
return (slug, info)
|
||||
|
||||
@callback
|
||||
def async_enable_container_updates(
|
||||
|
|
|
@ -188,15 +188,13 @@ class HassIOView(HomeAssistantView):
|
|||
async for data, _ in client.content.iter_chunks():
|
||||
await response.write(data)
|
||||
|
||||
return response
|
||||
|
||||
except aiohttp.ClientError as err:
|
||||
_LOGGER.error("Client error on api %s request %s", path, err)
|
||||
|
||||
except TimeoutError:
|
||||
raise HTTPBadGateway from err
|
||||
except TimeoutError as err:
|
||||
_LOGGER.error("Client timeout error on API request %s", path)
|
||||
|
||||
raise HTTPBadGateway
|
||||
raise HTTPBadGateway from err
|
||||
return response
|
||||
|
||||
get = _handle
|
||||
post = _handle
|
||||
|
|
|
@ -478,7 +478,6 @@ class SourceManager:
|
|||
if controller.is_signed_in:
|
||||
favorites = await controller.get_favorites()
|
||||
inputs = await controller.get_input_sources()
|
||||
return favorites, inputs
|
||||
except HeosError as error:
|
||||
if retry_attempts < self.max_retry_attempts:
|
||||
retry_attempts += 1
|
||||
|
@ -488,7 +487,9 @@ class SourceManager:
|
|||
await asyncio.sleep(self.retry_delay)
|
||||
else:
|
||||
_LOGGER.error("Unable to update sources: %s", error)
|
||||
return
|
||||
return None
|
||||
else:
|
||||
return favorites, inputs
|
||||
|
||||
async def update_sources(event, data=None):
|
||||
if event in (
|
||||
|
|
|
@ -95,10 +95,10 @@ class HitronCODADeviceScanner(DeviceScanner):
|
|||
return False
|
||||
try:
|
||||
self._userid = res.cookies["userid"]
|
||||
return True
|
||||
except KeyError:
|
||||
_LOGGER.error("Failed to log in to router")
|
||||
return False
|
||||
return True
|
||||
|
||||
def _update_info(self):
|
||||
"""Get ARP from router."""
|
||||
|
|
|
@ -494,11 +494,12 @@ class Camera(HomeAccessory, PyhapCamera): # type: ignore[misc]
|
|||
_LOGGER.info("[%s] %s stream", session_id, shutdown_method)
|
||||
try:
|
||||
await getattr(stream, shutdown_method)()
|
||||
return
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception(
|
||||
"[%s] Failed to %s stream", session_id, shutdown_method
|
||||
)
|
||||
else:
|
||||
return
|
||||
|
||||
async def reconfigure_stream(
|
||||
self, session_info: dict[str, Any], stream_config: dict[str, Any]
|
||||
|
|
|
@ -572,11 +572,12 @@ def _async_find_next_available_port(start_port: int, exclude_ports: set) -> int:
|
|||
continue
|
||||
try:
|
||||
test_socket.bind(("", port))
|
||||
return port
|
||||
except OSError:
|
||||
if port == MAX_PORT:
|
||||
raise
|
||||
continue
|
||||
else:
|
||||
return port
|
||||
raise RuntimeError("unreachable")
|
||||
|
||||
|
||||
|
@ -584,10 +585,9 @@ def pid_is_alive(pid: int) -> bool:
|
|||
"""Check to see if a process is alive."""
|
||||
try:
|
||||
os.kill(pid, 0)
|
||||
return True
|
||||
except OSError:
|
||||
pass
|
||||
return False
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def accessory_friendly_name(hass_name: str, accessory: Accessory) -> str:
|
||||
|
|
|
@ -39,9 +39,9 @@ class HomematicipAuth:
|
|||
self.auth = await self.get_auth(
|
||||
self.hass, self.config.get(HMIPC_HAPID), self.config.get(HMIPC_PIN)
|
||||
)
|
||||
return self.auth is not None
|
||||
except HmipcConnectionError:
|
||||
return False
|
||||
return self.auth is not None
|
||||
|
||||
async def async_checkbutton(self) -> bool:
|
||||
"""Check blue butten has been pressed."""
|
||||
|
@ -55,9 +55,9 @@ class HomematicipAuth:
|
|||
try:
|
||||
authtoken = await self.auth.requestAuthToken()
|
||||
await self.auth.confirmAuthToken(authtoken)
|
||||
return authtoken
|
||||
except HmipConnectionError:
|
||||
return False
|
||||
return authtoken
|
||||
|
||||
async def get_auth(self, hass: HomeAssistant, hapid, pin):
|
||||
"""Create a HomematicIP access point object."""
|
||||
|
|
|
@ -79,9 +79,9 @@ def format_last_reset_elapsed_seconds(value: str | None) -> datetime | None:
|
|||
try:
|
||||
last_reset = datetime.now() - timedelta(seconds=int(value))
|
||||
last_reset.replace(microsecond=0)
|
||||
return last_reset
|
||||
except ValueError:
|
||||
return None
|
||||
return last_reset
|
||||
|
||||
|
||||
def signal_icon(limits: Sequence[int], value: StateType) -> str:
|
||||
|
|
|
@ -199,7 +199,6 @@ class ImageEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||
url, timeout=GET_IMAGE_TIMEOUT, follow_redirects=True
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response
|
||||
except httpx.TimeoutException:
|
||||
_LOGGER.error("%s: Timeout getting image from %s", self.entity_id, url)
|
||||
return None
|
||||
|
@ -211,6 +210,7 @@ class ImageEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||
err,
|
||||
)
|
||||
return None
|
||||
return response
|
||||
|
||||
async def _async_load_image_from_url(self, url: str) -> Image | None:
|
||||
"""Load an image by url."""
|
||||
|
|
|
@ -398,8 +398,6 @@ class ImapPollingDataUpdateCoordinator(ImapDataUpdateCoordinator):
|
|||
"""Update the number of unread emails."""
|
||||
try:
|
||||
messages = await self._async_fetch_number_of_messages()
|
||||
self.auth_errors = 0
|
||||
return messages
|
||||
except (
|
||||
AioImapException,
|
||||
UpdateFailed,
|
||||
|
@ -426,6 +424,9 @@ class ImapPollingDataUpdateCoordinator(ImapDataUpdateCoordinator):
|
|||
self.async_set_update_error(ex)
|
||||
raise ConfigEntryAuthFailed from ex
|
||||
|
||||
self.auth_errors = 0
|
||||
return messages
|
||||
|
||||
|
||||
class ImapPushDataUpdateCoordinator(ImapDataUpdateCoordinator):
|
||||
"""Class for imap client."""
|
||||
|
|
|
@ -72,12 +72,13 @@ async def _async_connect(**kwargs):
|
|||
"""Connect to the Insteon modem."""
|
||||
try:
|
||||
await async_connect(**kwargs)
|
||||
_LOGGER.info("Connected to Insteon modem")
|
||||
return True
|
||||
except ConnectionError:
|
||||
_LOGGER.error("Could not connect to Insteon modem")
|
||||
return False
|
||||
|
||||
_LOGGER.info("Connected to Insteon modem")
|
||||
return True
|
||||
|
||||
|
||||
def _remove_override(address, options):
|
||||
"""Remove a device override from config."""
|
||||
|
|
|
@ -145,9 +145,9 @@ class _Right(_IntegrationMethod):
|
|||
def _is_numeric_state(state: State) -> bool:
|
||||
try:
|
||||
float(state.state)
|
||||
return True
|
||||
except (ValueError, TypeError):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
_NAME_TO_INTEGRATION_METHOD: dict[str, type[_IntegrationMethod]] = {
|
||||
|
|
|
@ -79,12 +79,14 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||
def get_ip_mode(host):
|
||||
"""Get the 'mode' used to retrieve the MAC address."""
|
||||
try:
|
||||
if ipaddress.ip_address(host).version == 6:
|
||||
return "ip6"
|
||||
return "ip"
|
||||
ip_address = ipaddress.ip_address(host)
|
||||
except ValueError:
|
||||
return "hostname"
|
||||
|
||||
if ip_address.version == 6:
|
||||
return "ip6"
|
||||
return "ip"
|
||||
|
||||
|
||||
async def async_setup_platform(
|
||||
hass: HomeAssistant,
|
||||
|
|
|
@ -37,17 +37,17 @@ string_type_validator = dpt_subclass_validator(DPTString)
|
|||
|
||||
def ga_validator(value: Any) -> str | int:
|
||||
"""Validate that value is parsable as GroupAddress or InternalGroupAddress."""
|
||||
if isinstance(value, (str, int)):
|
||||
try:
|
||||
parse_device_group_address(value)
|
||||
return value
|
||||
except CouldNotParseAddress as exc:
|
||||
raise vol.Invalid(
|
||||
f"'{value}' is not a valid KNX group address: {exc.message}"
|
||||
) from exc
|
||||
raise vol.Invalid(
|
||||
f"'{value}' is not a valid KNX group address: Invalid type '{type(value).__name__}'"
|
||||
)
|
||||
if not isinstance(value, (str, int)):
|
||||
raise vol.Invalid(
|
||||
f"'{value}' is not a valid KNX group address: Invalid type '{type(value).__name__}'"
|
||||
)
|
||||
try:
|
||||
parse_device_group_address(value)
|
||||
except CouldNotParseAddress as exc:
|
||||
raise vol.Invalid(
|
||||
f"'{value}' is not a valid KNX group address: {exc.message}"
|
||||
) from exc
|
||||
return value
|
||||
|
||||
|
||||
ga_list_validator = vol.All(
|
||||
|
|
|
@ -55,7 +55,6 @@ class LitterRobotHub:
|
|||
load_robots=load_robots,
|
||||
subscribe_for_updates=subscribe_for_updates,
|
||||
)
|
||||
return
|
||||
except LitterRobotLoginException as ex:
|
||||
raise ConfigEntryAuthFailed("Invalid credentials") from ex
|
||||
except LitterRobotException as ex:
|
||||
|
|
|
@ -77,7 +77,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
try:
|
||||
async with asyncio.timeout(60):
|
||||
await lyric.get_locations()
|
||||
return lyric
|
||||
except LyricAuthenticationException as exception:
|
||||
# Attempt to refresh the token before failing.
|
||||
# Honeywell appear to have issues keeping tokens saved.
|
||||
|
@ -87,6 +86,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
raise ConfigEntryAuthFailed from exception
|
||||
except (LyricException, ClientResponseError) as exception:
|
||||
raise UpdateFailed(exception) from exception
|
||||
return lyric
|
||||
|
||||
coordinator = DataUpdateCoordinator[Lyric](
|
||||
hass,
|
||||
|
|
|
@ -25,9 +25,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
data = await hass.async_add_executor_job(
|
||||
meteoclimatic_client.weather_at_station, station_code
|
||||
)
|
||||
return data.__dict__
|
||||
except MeteoclimaticError as err:
|
||||
raise UpdateFailed(f"Error while retrieving data: {err}") from err
|
||||
return data.__dict__
|
||||
|
||||
coordinator = DataUpdateCoordinator(
|
||||
hass,
|
||||
|
|
|
@ -325,8 +325,6 @@ def get_api(entry: dict[str, Any]) -> librouteros.Api:
|
|||
entry[CONF_PASSWORD],
|
||||
**kwargs,
|
||||
)
|
||||
_LOGGER.debug("Connected to %s successfully", entry[CONF_HOST])
|
||||
return api
|
||||
except (
|
||||
librouteros.exceptions.LibRouterosError,
|
||||
OSError,
|
||||
|
@ -336,3 +334,6 @@ def get_api(entry: dict[str, Any]) -> librouteros.Api:
|
|||
if "invalid user name or password" in str(api_error):
|
||||
raise LoginError from api_error
|
||||
raise CannotConnect from api_error
|
||||
|
||||
_LOGGER.debug("Connected to %s successfully", entry[CONF_HOST])
|
||||
return api
|
||||
|
|
|
@ -71,9 +71,9 @@ def is_socket_address(value: str) -> str:
|
|||
"""Validate that value is a valid address."""
|
||||
try:
|
||||
socket.getaddrinfo(value, None)
|
||||
return value
|
||||
except OSError as err:
|
||||
raise vol.Invalid("Device is not a valid domain name or ip address") from err
|
||||
return value
|
||||
|
||||
|
||||
async def try_connect(
|
||||
|
|
|
@ -72,8 +72,8 @@ class NextBusDataUpdateCoordinator(DataUpdateCoordinator):
|
|||
# Casting here because we expect dict and not a str due to the input format selected being JSON
|
||||
data = cast(dict[str, Any], data)
|
||||
self._calc_predictions(data)
|
||||
return data
|
||||
except (NextBusHTTPError, NextBusFormatError) as ex:
|
||||
raise UpdateFailed("Failed updating nextbus data", ex) from ex
|
||||
return data
|
||||
|
||||
return await self.hass.async_add_executor_job(_update_data)
|
||||
|
|
|
@ -418,13 +418,13 @@ class LeafDataStore:
|
|||
server_info = await self.hass.async_add_executor_job(
|
||||
self.leaf.get_latest_battery_status
|
||||
)
|
||||
return server_info
|
||||
except CarwingsError:
|
||||
_LOGGER.error("An error occurred getting battery status")
|
||||
return None
|
||||
except (KeyError, TypeError):
|
||||
_LOGGER.error("An error occurred parsing response from server")
|
||||
return None
|
||||
return server_info
|
||||
|
||||
async def async_get_climate(
|
||||
self,
|
||||
|
|
|
@ -109,15 +109,15 @@ class ObihaiServiceSensors(SensorEntity):
|
|||
LOGGER.info("Connection restored")
|
||||
self._attr_available = True
|
||||
|
||||
return
|
||||
|
||||
except RequestException as exc:
|
||||
if self.requester.available:
|
||||
LOGGER.warning("Connection failed, Obihai offline? %s", exc)
|
||||
self._attr_native_value = None
|
||||
self._attr_available = False
|
||||
self.requester.available = False
|
||||
except IndexError as exc:
|
||||
if self.requester.available:
|
||||
LOGGER.warning("Connection failed, bad response: %s", exc)
|
||||
|
||||
self._attr_native_value = None
|
||||
self._attr_available = False
|
||||
self.requester.available = False
|
||||
self._attr_native_value = None
|
||||
self._attr_available = False
|
||||
self.requester.available = False
|
||||
|
|
|
@ -218,12 +218,13 @@ class ONVIFDevice:
|
|||
try:
|
||||
await device_mgmt.SetSystemDateAndTime(dt_param)
|
||||
LOGGER.debug("%s: SetSystemDateAndTime: success", self.name)
|
||||
return
|
||||
# Some cameras don't support setting the timezone and will throw an IndexError
|
||||
# if we try to set it. If we get an error, try again without the timezone.
|
||||
except (IndexError, Fault):
|
||||
if idx == timezone_max_idx:
|
||||
raise
|
||||
else:
|
||||
return
|
||||
|
||||
async def async_check_date_and_time(self) -> None:
|
||||
"""Warns if device and system date not synced."""
|
||||
|
|
|
@ -221,9 +221,9 @@ async def async_parse_field_detector(uid: str, msg) -> Event | None:
|
|||
None,
|
||||
payload.Data.SimpleItem[0].Value == "true",
|
||||
)
|
||||
return evt
|
||||
except (AttributeError, KeyError):
|
||||
return None
|
||||
return evt
|
||||
|
||||
|
||||
@PARSERS.register("tns1:RuleEngine/CellMotionDetector/Motion")
|
||||
|
|
|
@ -135,8 +135,6 @@ def _decrypt_payload(secret, topic, ciphertext):
|
|||
try:
|
||||
message = decrypt(ciphertext, key)
|
||||
message = message.decode("utf-8")
|
||||
_LOGGER.debug("Decrypted payload: %s", message)
|
||||
return message
|
||||
except ValueError:
|
||||
_LOGGER.warning(
|
||||
(
|
||||
|
@ -146,6 +144,8 @@ def _decrypt_payload(secret, topic, ciphertext):
|
|||
topic,
|
||||
)
|
||||
return None
|
||||
_LOGGER.debug("Decrypted payload: %s", message)
|
||||
return message
|
||||
|
||||
|
||||
def encrypt_message(secret, topic, message):
|
||||
|
|
|
@ -247,9 +247,6 @@ class Remote:
|
|||
"""Handle errors from func, set available and reconnect if needed."""
|
||||
try:
|
||||
result = await self._hass.async_add_executor_job(func, *args)
|
||||
self.state = STATE_ON
|
||||
self.available = True
|
||||
return result
|
||||
except EncryptionRequired:
|
||||
_LOGGER.error(
|
||||
"The connection couldn't be encrypted. Please reconfigure your TV"
|
||||
|
@ -260,12 +257,18 @@ class Remote:
|
|||
self.state = STATE_OFF
|
||||
self.available = True
|
||||
await self.async_create_remote_control()
|
||||
return None
|
||||
except (URLError, OSError) as err:
|
||||
_LOGGER.debug("An error occurred: %s", err)
|
||||
self.state = STATE_OFF
|
||||
self.available = self._on_action is not None
|
||||
await self.async_create_remote_control()
|
||||
return None
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("An unknown error occurred")
|
||||
self.state = STATE_OFF
|
||||
self.available = self._on_action is not None
|
||||
return None
|
||||
self.state = STATE_ON
|
||||
self.available = True
|
||||
return result
|
||||
|
|
|
@ -50,14 +50,14 @@ class PicnicUpdateCoordinator(DataUpdateCoordinator):
|
|||
|
||||
# Update the auth token in the config entry if applicable
|
||||
self._update_auth_token()
|
||||
|
||||
# Return the fetched data
|
||||
return data
|
||||
except ValueError as error:
|
||||
raise UpdateFailed(f"API response was malformed: {error}") from error
|
||||
except PicnicAuthError as error:
|
||||
raise ConfigEntryAuthFailed from error
|
||||
|
||||
# Return the fetched data
|
||||
return data
|
||||
|
||||
def fetch_data(self):
|
||||
"""Fetch the data from the Picnic API and return a flat dict with only needed sensor data."""
|
||||
# Fetch from the API and pre-process the data
|
||||
|
|
|
@ -140,7 +140,6 @@ class PingDataSubProcess(PingData):
|
|||
if TYPE_CHECKING:
|
||||
assert match is not None
|
||||
rtt_min, rtt_avg, rtt_max, rtt_mdev = match.groups()
|
||||
return {"min": rtt_min, "avg": rtt_avg, "max": rtt_max, "mdev": rtt_mdev}
|
||||
except TimeoutError:
|
||||
_LOGGER.exception(
|
||||
"Timed out running command: `%s`, after: %ss",
|
||||
|
@ -155,6 +154,7 @@ class PingDataSubProcess(PingData):
|
|||
return None
|
||||
except AttributeError:
|
||||
return None
|
||||
return {"min": rtt_min, "avg": rtt_avg, "max": rtt_max, "mdev": rtt_mdev}
|
||||
|
||||
async def async_update(self) -> None:
|
||||
"""Retrieve the latest details from the host."""
|
||||
|
|
|
@ -35,11 +35,11 @@ async def validate_input(hass: HomeAssistant, data):
|
|||
auth = Auth(session, data[CONF_USERNAME], data[CONF_PASSWORD], data[CONF_COUNTRY])
|
||||
try:
|
||||
contracts = await Installation.list(auth)
|
||||
return auth, contracts
|
||||
except ConnectionRefusedError:
|
||||
raise InvalidAuth from ConnectionRefusedError
|
||||
except ConnectionError:
|
||||
raise CannotConnect from ConnectionError
|
||||
return auth, contracts
|
||||
|
||||
|
||||
class ProsegurConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
|
|
|
@ -43,19 +43,18 @@ def get_stream_source(guid, client):
|
|||
"""Get channel stream source."""
|
||||
try:
|
||||
resp = client.get_channel_live_stream(guid, protocol="rtsp")
|
||||
|
||||
full_url = resp["resourceUris"]
|
||||
|
||||
protocol = full_url[:7]
|
||||
auth = f"{client.get_auth_string()}@"
|
||||
url = full_url[7:]
|
||||
|
||||
return f"{protocol}{auth}{url}"
|
||||
|
||||
except QVRResponseError as ex:
|
||||
_LOGGER.error(ex)
|
||||
return None
|
||||
|
||||
full_url = resp["resourceUris"]
|
||||
|
||||
protocol = full_url[:7]
|
||||
auth = f"{client.get_auth_string()}@"
|
||||
url = full_url[7:]
|
||||
|
||||
return f"{protocol}{auth}{url}"
|
||||
|
||||
|
||||
class QVRProCamera(Camera):
|
||||
"""Representation of a QVR Pro camera."""
|
||||
|
|
|
@ -1179,7 +1179,6 @@ class Recorder(threading.Thread):
|
|||
while tries <= self.db_max_retries:
|
||||
try:
|
||||
self._commit_event_session()
|
||||
return
|
||||
except (exc.InternalError, exc.OperationalError) as err:
|
||||
_LOGGER.error(
|
||||
"%s: Error executing query: %s. (retrying in %s seconds)",
|
||||
|
@ -1192,6 +1191,8 @@ class Recorder(threading.Thread):
|
|||
|
||||
tries += 1
|
||||
time.sleep(self.db_retry_wait)
|
||||
else:
|
||||
return
|
||||
|
||||
def _commit_event_session(self) -> None:
|
||||
assert self.event_session is not None
|
||||
|
|
|
@ -341,10 +341,10 @@ def _execute_or_collect_error(
|
|||
with session_scope(session=session_maker()) as session:
|
||||
try:
|
||||
session.connection().execute(text(query))
|
||||
return True
|
||||
except SQLAlchemyError as err:
|
||||
errors.append(str(err))
|
||||
return False
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _drop_index(
|
||||
|
@ -439,11 +439,12 @@ def _add_columns(
|
|||
)
|
||||
)
|
||||
)
|
||||
return
|
||||
except (InternalError, OperationalError, ProgrammingError):
|
||||
# Some engines support adding all columns at once,
|
||||
# this error is when they don't
|
||||
_LOGGER.info("Unable to use quick column add. Adding 1 by 1")
|
||||
else:
|
||||
return
|
||||
|
||||
for column_def in columns_def:
|
||||
with session_scope(session=session_maker()) as session:
|
||||
|
@ -510,9 +511,10 @@ def _modify_columns(
|
|||
)
|
||||
)
|
||||
)
|
||||
return
|
||||
except (InternalError, OperationalError):
|
||||
_LOGGER.info("Unable to use quick column modify. Modifying 1 by 1")
|
||||
else:
|
||||
return
|
||||
|
||||
for column_def in columns_def:
|
||||
with session_scope(session=session_maker()) as session:
|
||||
|
|
|
@ -641,7 +641,6 @@ def _insert_statistics(
|
|||
try:
|
||||
stat = table.from_stats(metadata_id, statistic)
|
||||
session.add(stat)
|
||||
return stat
|
||||
except SQLAlchemyError:
|
||||
_LOGGER.exception(
|
||||
"Unexpected exception when inserting statistics %s:%s ",
|
||||
|
@ -649,6 +648,7 @@ def _insert_statistics(
|
|||
statistic,
|
||||
)
|
||||
return None
|
||||
return stat
|
||||
|
||||
|
||||
def _update_statistics(
|
||||
|
|
|
@ -192,13 +192,14 @@ def execute(
|
|||
elapsed,
|
||||
)
|
||||
|
||||
return result
|
||||
except SQLAlchemyError as err:
|
||||
_LOGGER.error("Error executing query: %s", err)
|
||||
|
||||
if tryno == RETRIES - 1:
|
||||
raise
|
||||
time.sleep(QUERY_RETRY_WAIT)
|
||||
else:
|
||||
return result
|
||||
|
||||
# Unreachable
|
||||
raise RuntimeError # pragma: no cover
|
||||
|
@ -685,7 +686,6 @@ def database_job_retry_wrapper(
|
|||
for attempt in range(attempts):
|
||||
try:
|
||||
job(instance, *args, **kwargs)
|
||||
return
|
||||
except OperationalError as err:
|
||||
if attempt == attempts - 1 or not _is_retryable_error(
|
||||
instance, err
|
||||
|
@ -697,6 +697,8 @@ def database_job_retry_wrapper(
|
|||
)
|
||||
time.sleep(instance.db_retry_wait)
|
||||
# Failed with retryable error
|
||||
else:
|
||||
return
|
||||
|
||||
return wrapper
|
||||
|
||||
|
|
|
@ -55,8 +55,6 @@ class RenaultDataUpdateCoordinator(DataUpdateCoordinator[T]):
|
|||
try:
|
||||
async with _PARALLEL_SEMAPHORE:
|
||||
data = await self.update_method()
|
||||
self._has_already_worked = True
|
||||
return data
|
||||
|
||||
except AccessDeniedException as err:
|
||||
# This can mean both a temporary error or a permanent error. If it has
|
||||
|
@ -76,6 +74,9 @@ class RenaultDataUpdateCoordinator(DataUpdateCoordinator[T]):
|
|||
# Other Renault errors.
|
||||
raise UpdateFailed(f"Error communicating with API: {err}") from err
|
||||
|
||||
self._has_already_worked = True
|
||||
return data
|
||||
|
||||
async def async_config_entry_first_refresh(self) -> None:
|
||||
"""Refresh data for the first time when a config entry is setup.
|
||||
|
||||
|
|
|
@ -62,10 +62,10 @@ class RokuDataUpdateCoordinator(DataUpdateCoordinator[Device]):
|
|||
|
||||
try:
|
||||
data = await self.roku.update(full_update=full_update)
|
||||
|
||||
if full_update:
|
||||
self.last_full_update = utcnow()
|
||||
|
||||
return data
|
||||
except RokuError as error:
|
||||
raise UpdateFailed(f"Invalid response from API: {error}") from error
|
||||
|
||||
if full_update:
|
||||
self.last_full_update = utcnow()
|
||||
|
||||
return data
|
||||
|
|
|
@ -39,10 +39,10 @@ class RymProDataUpdateCoordinator(DataUpdateCoordinator[dict[int, dict]]):
|
|||
meter["consumption_forecast"] = await self.rympro.consumption_forecast(
|
||||
meter_id
|
||||
)
|
||||
return meters
|
||||
except UnauthorizedError as error:
|
||||
assert self.config_entry
|
||||
await self.hass.config_entries.async_reload(self.config_entry.entry_id)
|
||||
raise UpdateFailed(error) from error
|
||||
except (CannotConnectError, OperationError) as error:
|
||||
raise UpdateFailed(error) from error
|
||||
return meters
|
||||
|
|
|
@ -135,12 +135,12 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
service_response["stdout"] = stdout_data.decode("utf-8").strip()
|
||||
if stderr_data:
|
||||
service_response["stderr"] = stderr_data.decode("utf-8").strip()
|
||||
return service_response
|
||||
except UnicodeDecodeError:
|
||||
_LOGGER.exception(
|
||||
"Unable to handle non-utf8 output of command: `%s`", cmd
|
||||
)
|
||||
raise
|
||||
return service_response
|
||||
return None
|
||||
|
||||
for name in conf:
|
||||
|
|
|
@ -210,7 +210,7 @@ async def create_sms_gateway(config, hass):
|
|||
_LOGGER.error("Failed to initialize, error %s", exc)
|
||||
await gateway.terminate_async()
|
||||
return None
|
||||
return gateway
|
||||
except gammu.GSMError as exc:
|
||||
_LOGGER.error("Failed to create async worker, error %s", exc)
|
||||
return None
|
||||
return gateway
|
||||
|
|
|
@ -44,14 +44,14 @@ class SolarLogConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||
"""Check if we can connect to the Solar-Log device."""
|
||||
try:
|
||||
await self.hass.async_add_executor_job(SolarLog, host)
|
||||
return True
|
||||
except (OSError, HTTPError, Timeout):
|
||||
self._errors[CONF_HOST] = "cannot_connect"
|
||||
_LOGGER.error(
|
||||
"Could not connect to Solar-Log device at %s, check host ip address",
|
||||
host,
|
||||
)
|
||||
return False
|
||||
return False
|
||||
return True
|
||||
|
||||
async def async_step_user(self, user_input=None):
|
||||
"""Step when user initializes a integration."""
|
||||
|
|
|
@ -101,8 +101,6 @@ def spotify_exception_handler(
|
|||
# pylint: disable=protected-access
|
||||
try:
|
||||
result = func(self, *args, **kwargs)
|
||||
self._attr_available = True
|
||||
return result
|
||||
except requests.RequestException:
|
||||
self._attr_available = False
|
||||
return None
|
||||
|
@ -111,6 +109,8 @@ def spotify_exception_handler(
|
|||
if exc.reason == "NO_ACTIVE_DEVICE":
|
||||
raise HomeAssistantError("No active playback device found") from None
|
||||
raise HomeAssistantError(f"Spotify error: {exc.reason}") from exc
|
||||
self._attr_available = True
|
||||
return result
|
||||
|
||||
return wrapper
|
||||
|
||||
|
|
|
@ -735,10 +735,11 @@ async def _async_find_next_available_port(source: AddressTupleVXType) -> int:
|
|||
addr = (source[0],) + (port,) + source[2:]
|
||||
try:
|
||||
test_socket.bind(addr)
|
||||
return port
|
||||
except OSError:
|
||||
if port == UPNP_SERVER_MAX_PORT - 1:
|
||||
raise
|
||||
else:
|
||||
return port
|
||||
|
||||
raise RuntimeError("unreachable")
|
||||
|
||||
|
|
|
@ -28,9 +28,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
)
|
||||
if not client.check_credentials():
|
||||
raise ConfigEntryError
|
||||
return client
|
||||
except PySuezError as ex:
|
||||
raise ConfigEntryNotReady from ex
|
||||
return client
|
||||
|
||||
hass.data.setdefault(DOMAIN, {})[
|
||||
entry.entry_id
|
||||
|
|
|
@ -235,11 +235,12 @@ async def async_check_can_reach_url(
|
|||
|
||||
try:
|
||||
await session.get(url, timeout=5)
|
||||
return "ok"
|
||||
except aiohttp.ClientError:
|
||||
data = {"type": "failed", "error": "unreachable"}
|
||||
except TimeoutError:
|
||||
data = {"type": "failed", "error": "timeout"}
|
||||
else:
|
||||
return "ok"
|
||||
if more_info is not None:
|
||||
data["more_info"] = more_info
|
||||
return data
|
||||
|
|
|
@ -149,7 +149,6 @@ class TcpEntity(Entity):
|
|||
if value_template is not None:
|
||||
try:
|
||||
self._state = value_template.render(parse_result=False, value=value)
|
||||
return
|
||||
except TemplateError:
|
||||
_LOGGER.error(
|
||||
"Unable to render template of %r with value: %r",
|
||||
|
@ -157,5 +156,6 @@ class TcpEntity(Entity):
|
|||
value,
|
||||
)
|
||||
return
|
||||
return
|
||||
|
||||
self._state = value
|
||||
|
|
|
@ -687,11 +687,12 @@ class TelegramNotificationService:
|
|||
_LOGGER.warning(
|
||||
"Update last message: out_type:%s, out=%s", type(out), out
|
||||
)
|
||||
return out
|
||||
except TelegramError as exc:
|
||||
_LOGGER.error(
|
||||
"%s: %s. Args: %s, kwargs: %s", msg_error, exc, args_msg, kwargs_msg
|
||||
)
|
||||
return None
|
||||
return out
|
||||
|
||||
async def send_message(self, message="", target=None, **kwargs):
|
||||
"""Send a message to one or multiple pre-allowed chat IDs."""
|
||||
|
|
|
@ -267,9 +267,6 @@ async def get_api(
|
|||
path=path,
|
||||
)
|
||||
)
|
||||
_LOGGER.debug("Successfully connected to %s", host)
|
||||
return api
|
||||
|
||||
except TransmissionAuthError as error:
|
||||
_LOGGER.error("Credentials for Transmission client are not valid")
|
||||
raise AuthenticationError from error
|
||||
|
@ -279,3 +276,5 @@ async def get_api(
|
|||
except TransmissionError as error:
|
||||
_LOGGER.error(error)
|
||||
raise UnknownError from error
|
||||
_LOGGER.debug("Successfully connected to %s", host)
|
||||
return api
|
||||
|
|
|
@ -56,7 +56,6 @@ async def get_unifi_api(
|
|||
try:
|
||||
async with asyncio.timeout(10):
|
||||
await api.login()
|
||||
return api
|
||||
|
||||
except aiounifi.Unauthorized as err:
|
||||
LOGGER.warning(
|
||||
|
@ -90,3 +89,5 @@ async def get_unifi_api(
|
|||
except aiounifi.AiounifiException as err:
|
||||
LOGGER.exception("Unknown UniFi Network communication error occurred: %s", err)
|
||||
raise AuthenticationRequired from err
|
||||
|
||||
return api
|
||||
|
|
|
@ -408,10 +408,10 @@ class UpdateEntity(
|
|||
|
||||
try:
|
||||
newer = _version_is_newer(latest_version, installed_version)
|
||||
return STATE_ON if newer else STATE_OFF
|
||||
except AwesomeVersionCompareException:
|
||||
# Can't compare versions, already tried exact match
|
||||
return STATE_ON
|
||||
return STATE_ON if newer else STATE_OFF
|
||||
|
||||
@final
|
||||
@property
|
||||
|
|
|
@ -175,11 +175,10 @@ class ValloxServiceHandler:
|
|||
|
||||
try:
|
||||
await self._client.set_fan_speed(Profile.HOME, fan_speed)
|
||||
return True
|
||||
|
||||
except ValloxApiException as err:
|
||||
_LOGGER.error("Error setting fan speed for Home profile: %s", err)
|
||||
return False
|
||||
return True
|
||||
|
||||
async def async_set_profile_fan_speed_away(
|
||||
self, fan_speed: int = DEFAULT_FAN_SPEED_AWAY
|
||||
|
@ -189,11 +188,10 @@ class ValloxServiceHandler:
|
|||
|
||||
try:
|
||||
await self._client.set_fan_speed(Profile.AWAY, fan_speed)
|
||||
return True
|
||||
|
||||
except ValloxApiException as err:
|
||||
_LOGGER.error("Error setting fan speed for Away profile: %s", err)
|
||||
return False
|
||||
return True
|
||||
|
||||
async def async_set_profile_fan_speed_boost(
|
||||
self, fan_speed: int = DEFAULT_FAN_SPEED_BOOST
|
||||
|
@ -203,11 +201,10 @@ class ValloxServiceHandler:
|
|||
|
||||
try:
|
||||
await self._client.set_fan_speed(Profile.BOOST, fan_speed)
|
||||
return True
|
||||
|
||||
except ValloxApiException as err:
|
||||
_LOGGER.error("Error setting fan speed for Boost profile: %s", err)
|
||||
return False
|
||||
return True
|
||||
|
||||
async def async_handle(self, call: ServiceCall) -> None:
|
||||
"""Dispatch a service call."""
|
||||
|
|
|
@ -84,11 +84,13 @@ async def async_http_request(hass, uri):
|
|||
if req.status != HTTPStatus.OK:
|
||||
return {"error": req.status}
|
||||
json_response = await req.json()
|
||||
return json_response
|
||||
except (TimeoutError, aiohttp.ClientError) as exc:
|
||||
_LOGGER.error("Cannot connect to ViaggiaTreno API endpoint: %s", exc)
|
||||
return None
|
||||
except ValueError:
|
||||
_LOGGER.error("Received non-JSON data from ViaggiaTreno API endpoint")
|
||||
return None
|
||||
return json_response
|
||||
|
||||
|
||||
class ViaggiaTrenoSensor(SensorEntity):
|
||||
|
|
|
@ -35,13 +35,14 @@ def is_supported(
|
|||
"""Check if the PyViCare device supports the requested sensor."""
|
||||
try:
|
||||
entity_description.value_getter(vicare_device)
|
||||
_LOGGER.debug("Found entity %s", name)
|
||||
return True
|
||||
except PyViCareNotSupportedFeatureError:
|
||||
_LOGGER.debug("Feature not supported %s", name)
|
||||
return False
|
||||
except AttributeError as error:
|
||||
_LOGGER.debug("Feature not supported %s: %s", name, error)
|
||||
return False
|
||||
return False
|
||||
_LOGGER.debug("Found entity %s", name)
|
||||
return True
|
||||
|
||||
|
||||
def get_burners(device: PyViCareDevice) -> list[PyViCareHeatingDeviceComponent]:
|
||||
|
|
|
@ -178,10 +178,10 @@ async def async_handle_webhook(
|
|||
response: Response | None = await webhook["handler"](hass, webhook_id, request)
|
||||
if response is None:
|
||||
response = Response(status=HTTPStatus.OK)
|
||||
return response
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Error processing webhook %s", webhook_id)
|
||||
return Response(status=HTTPStatus.OK)
|
||||
return response
|
||||
|
||||
|
||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
|
|
|
@ -94,9 +94,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
if bulb.power_monitoring is not False:
|
||||
power: float | None = await bulb.get_power()
|
||||
return power
|
||||
return None
|
||||
except WIZ_EXCEPTIONS as ex:
|
||||
raise UpdateFailed(f"Failed to update device at {ip_address}: {ex}") from ex
|
||||
return None
|
||||
|
||||
coordinator = DataUpdateCoordinator(
|
||||
hass=hass,
|
||||
|
|
|
@ -150,16 +150,15 @@ class XiaomiCoordinatedMiioEntity(CoordinatorEntity[_T]):
|
|||
result = await self.hass.async_add_executor_job(
|
||||
partial(func, *args, **kwargs)
|
||||
)
|
||||
|
||||
_LOGGER.debug("Response received from miio device: %s", result)
|
||||
|
||||
return True
|
||||
except DeviceException as exc:
|
||||
if self.available:
|
||||
_LOGGER.error(mask_error, exc)
|
||||
|
||||
return False
|
||||
|
||||
_LOGGER.debug("Response received from miio device: %s", result)
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def _extract_value_from_attribute(cls, state, attribute):
|
||||
value = getattr(state, attribute)
|
||||
|
|
|
@ -292,10 +292,6 @@ class XiaomiPhilipsAbstractLight(XiaomiMiioEntity, LightEntity):
|
|||
result = await self.hass.async_add_executor_job(
|
||||
partial(func, *args, **kwargs)
|
||||
)
|
||||
|
||||
_LOGGER.debug("Response received from light: %s", result)
|
||||
|
||||
return result == SUCCESS
|
||||
except DeviceException as exc:
|
||||
if self._available:
|
||||
_LOGGER.error(mask_error, exc)
|
||||
|
@ -303,6 +299,9 @@ class XiaomiPhilipsAbstractLight(XiaomiMiioEntity, LightEntity):
|
|||
|
||||
return False
|
||||
|
||||
_LOGGER.debug("Response received from light: %s", result)
|
||||
return result == SUCCESS
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the light on."""
|
||||
if ATTR_BRIGHTNESS in kwargs:
|
||||
|
|
|
@ -225,9 +225,9 @@ class XiaomiMiioRemote(RemoteEntity):
|
|||
"""Return False if device is unreachable, else True."""
|
||||
try:
|
||||
self.device.info()
|
||||
return True
|
||||
except DeviceException:
|
||||
return False
|
||||
return True
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the device on."""
|
||||
|
|
|
@ -805,14 +805,6 @@ class XiaomiPlugGenericSwitch(XiaomiMiioEntity, SwitchEntity):
|
|||
result = await self.hass.async_add_executor_job(
|
||||
partial(func, *args, **kwargs)
|
||||
)
|
||||
|
||||
_LOGGER.debug("Response received from plug: %s", result)
|
||||
|
||||
# The Chuangmi Plug V3 returns 0 on success on usb_on/usb_off.
|
||||
if func in ["usb_on", "usb_off"] and result == 0:
|
||||
return True
|
||||
|
||||
return result == SUCCESS
|
||||
except DeviceException as exc:
|
||||
if self._available:
|
||||
_LOGGER.error(mask_error, exc)
|
||||
|
@ -820,6 +812,14 @@ class XiaomiPlugGenericSwitch(XiaomiMiioEntity, SwitchEntity):
|
|||
|
||||
return False
|
||||
|
||||
_LOGGER.debug("Response received from plug: %s", result)
|
||||
|
||||
# The Chuangmi Plug V3 returns 0 on success on usb_on/usb_off.
|
||||
if func in ["usb_on", "usb_off"] and result == 0:
|
||||
return True
|
||||
|
||||
return result == SUCCESS
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the plug on."""
|
||||
result = await self._try_command("Turning the plug on failed", self._device.on)
|
||||
|
|
|
@ -281,10 +281,10 @@ class MiroboVacuum(
|
|||
try:
|
||||
await self.hass.async_add_executor_job(partial(func, *args, **kwargs))
|
||||
await self.coordinator.async_refresh()
|
||||
return True
|
||||
except DeviceException as exc:
|
||||
_LOGGER.error(mask_error, exc)
|
||||
return False
|
||||
return True
|
||||
|
||||
async def async_start(self) -> None:
|
||||
"""Start or resume the cleaning task."""
|
||||
|
|
|
@ -66,9 +66,9 @@ class ZamgWeather(CoordinatorEntity, WeatherEntity):
|
|||
value := self.coordinator.data[self.station_id]["TL"]["data"]
|
||||
) is not None:
|
||||
return float(value)
|
||||
return None
|
||||
except (KeyError, ValueError, TypeError):
|
||||
return None
|
||||
return None
|
||||
|
||||
@property
|
||||
def native_pressure(self) -> float | None:
|
||||
|
@ -98,9 +98,9 @@ class ZamgWeather(CoordinatorEntity, WeatherEntity):
|
|||
value := self.coordinator.data[self.station_id]["FFX"]["data"]
|
||||
) is not None:
|
||||
return float(value)
|
||||
return None
|
||||
except (KeyError, ValueError, TypeError):
|
||||
return None
|
||||
return None
|
||||
|
||||
@property
|
||||
def wind_bearing(self) -> float | None:
|
||||
|
@ -114,6 +114,6 @@ class ZamgWeather(CoordinatorEntity, WeatherEntity):
|
|||
value := self.coordinator.data[self.station_id]["DDX"]["data"]
|
||||
) is not None:
|
||||
return float(value)
|
||||
return None
|
||||
except (KeyError, ValueError, TypeError):
|
||||
return None
|
||||
return None
|
||||
|
|
|
@ -789,15 +789,6 @@ class ZHADevice(LogMixin):
|
|||
response = await cluster.write_attributes(
|
||||
{attribute: value}, manufacturer=manufacturer
|
||||
)
|
||||
self.debug(
|
||||
"set: %s for attr: %s to cluster: %s for ept: %s - res: %s",
|
||||
value,
|
||||
attribute,
|
||||
cluster_id,
|
||||
endpoint_id,
|
||||
response,
|
||||
)
|
||||
return response
|
||||
except zigpy.exceptions.ZigbeeException as exc:
|
||||
raise HomeAssistantError(
|
||||
f"Failed to set attribute: "
|
||||
|
@ -807,6 +798,16 @@ class ZHADevice(LogMixin):
|
|||
f"{ATTR_ENDPOINT_ID}: {endpoint_id}"
|
||||
) from exc
|
||||
|
||||
self.debug(
|
||||
"set: %s for attr: %s to cluster: %s for ept: %s - res: %s",
|
||||
value,
|
||||
attribute,
|
||||
cluster_id,
|
||||
endpoint_id,
|
||||
response,
|
||||
)
|
||||
return response
|
||||
|
||||
async def issue_cluster_command(
|
||||
self,
|
||||
endpoint_id: int,
|
||||
|
|
|
@ -102,9 +102,9 @@ async def safe_read(
|
|||
only_cache=only_cache,
|
||||
manufacturer=manufacturer,
|
||||
)
|
||||
return result
|
||||
except Exception: # pylint: disable=broad-except
|
||||
return {}
|
||||
return result
|
||||
|
||||
|
||||
async def get_matched_clusters(
|
||||
|
|
|
@ -464,14 +464,12 @@ def _write_default_config(config_dir: str) -> bool:
|
|||
if not os.path.isfile(scene_yaml_path):
|
||||
with open(scene_yaml_path, "w", encoding="utf8"):
|
||||
pass
|
||||
|
||||
return True
|
||||
|
||||
except OSError:
|
||||
print( # noqa: T201
|
||||
f"Unable to create default configuration file {config_path}"
|
||||
)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
async def async_hass_config_yaml(hass: HomeAssistant) -> dict:
|
||||
|
|
|
@ -763,8 +763,6 @@ class ConfigEntry:
|
|||
self._async_set_state(hass, ConfigEntryState.NOT_LOADED, None)
|
||||
|
||||
await self._async_process_on_unload(hass)
|
||||
|
||||
return result
|
||||
except Exception as exc: # pylint: disable=broad-except
|
||||
_LOGGER.exception(
|
||||
"Error unloading entry %s for %s", self.title, integration.domain
|
||||
|
@ -774,6 +772,7 @@ class ConfigEntry:
|
|||
hass, ConfigEntryState.FAILED_UNLOAD, str(exc) or "Unknown error"
|
||||
)
|
||||
return False
|
||||
return result
|
||||
|
||||
async def async_remove(self, hass: HomeAssistant) -> None:
|
||||
"""Invoke remove callback on component."""
|
||||
|
@ -872,12 +871,12 @@ class ConfigEntry:
|
|||
if result:
|
||||
# pylint: disable-next=protected-access
|
||||
hass.config_entries._async_schedule_save()
|
||||
return result
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception(
|
||||
"Error migrating entry %s for %s", self.title, self.domain
|
||||
)
|
||||
return False
|
||||
return result
|
||||
|
||||
def add_update_listener(self, listener: UpdateListenerType) -> CALLBACK_TYPE:
|
||||
"""Listen for when entry is updated.
|
||||
|
|
|
@ -2691,9 +2691,10 @@ class Config:
|
|||
for allowed_path in self.allowlist_external_dirs:
|
||||
try:
|
||||
thepath.relative_to(allowed_path)
|
||||
return True
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
|
|
@ -248,13 +248,13 @@ def is_regex(value: Any) -> re.Pattern[Any]:
|
|||
"""Validate that a string is a valid regular expression."""
|
||||
try:
|
||||
r = re.compile(value)
|
||||
return r
|
||||
except TypeError as err:
|
||||
raise vol.Invalid(
|
||||
f"value {value} is of the wrong type for a regular expression"
|
||||
) from err
|
||||
except re.error as err:
|
||||
raise vol.Invalid(f"value {value} is not a valid regular expression") from err
|
||||
return r
|
||||
|
||||
|
||||
def isfile(value: Any) -> str:
|
||||
|
@ -671,9 +671,9 @@ def template(value: Any | None) -> template_helper.Template:
|
|||
|
||||
try:
|
||||
template_value.ensure_valid()
|
||||
return template_value
|
||||
except TemplateError as ex:
|
||||
raise vol.Invalid(f"invalid template ({ex})") from ex
|
||||
return template_value
|
||||
|
||||
|
||||
def dynamic_template(value: Any | None) -> template_helper.Template:
|
||||
|
@ -693,9 +693,9 @@ def dynamic_template(value: Any | None) -> template_helper.Template:
|
|||
|
||||
try:
|
||||
template_value.ensure_valid()
|
||||
return template_value
|
||||
except TemplateError as ex:
|
||||
raise vol.Invalid(f"invalid template ({ex})") from ex
|
||||
return template_value
|
||||
|
||||
|
||||
def template_complex(value: Any) -> Any:
|
||||
|
|
|
@ -362,10 +362,6 @@ class EntityPlatform:
|
|||
pending = self._tasks.copy()
|
||||
self._tasks.clear()
|
||||
await asyncio.gather(*pending)
|
||||
|
||||
hass.config.components.add(full_name)
|
||||
self._setup_complete = True
|
||||
return True
|
||||
except PlatformNotReady as ex:
|
||||
tries += 1
|
||||
wait_time = min(tries, 6) * PLATFORM_NOT_READY_BASE_WAIT_TIME
|
||||
|
@ -417,6 +413,10 @@ class EntityPlatform:
|
|||
self.domain,
|
||||
)
|
||||
return False
|
||||
else:
|
||||
hass.config.components.add(full_name)
|
||||
self._setup_complete = True
|
||||
return True
|
||||
finally:
|
||||
warn_task.cancel()
|
||||
|
||||
|
|
|
@ -243,7 +243,6 @@ class RegistryEntry:
|
|||
try:
|
||||
dict_repr = self._as_display_dict
|
||||
json_repr: bytes | None = json_bytes(dict_repr) if dict_repr else None
|
||||
return json_repr
|
||||
except (ValueError, TypeError):
|
||||
_LOGGER.error(
|
||||
"Unable to serialize entry %s to JSON. Bad data found at %s",
|
||||
|
@ -252,8 +251,8 @@ class RegistryEntry:
|
|||
find_paths_unserializable_data(dict_repr, dump=JSON_DUMP)
|
||||
),
|
||||
)
|
||||
|
||||
return None
|
||||
return None
|
||||
return json_repr
|
||||
|
||||
@cached_property
|
||||
def as_partial_dict(self) -> dict[str, Any]:
|
||||
|
|
|
@ -109,7 +109,6 @@ async def async_handle(
|
|||
try:
|
||||
_LOGGER.info("Triggering intent handler %s", handler)
|
||||
result = await handler.async_handle(intent)
|
||||
return result
|
||||
except vol.Invalid as err:
|
||||
_LOGGER.warning("Received invalid slot info for %s: %s", intent_type, err)
|
||||
raise InvalidSlotInfo(f"Received invalid slot info for {intent_type}") from err
|
||||
|
@ -117,6 +116,7 @@ async def async_handle(
|
|||
raise # bubble up intent related errors
|
||||
except Exception as err:
|
||||
raise IntentUnexpectedError(f"Error handling {intent_type}") from err
|
||||
return result
|
||||
|
||||
|
||||
class IntentError(HomeAssistantError):
|
||||
|
|
|
@ -31,9 +31,9 @@ def is_internal_request(hass: HomeAssistant) -> bool:
|
|||
get_url(
|
||||
hass, allow_external=False, allow_cloud=False, require_current_request=True
|
||||
)
|
||||
return True
|
||||
except NoURLAvailableError:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@bind_hass
|
||||
|
|
|
@ -166,7 +166,6 @@ async def async_setup_component(
|
|||
setup_future.set_result(result)
|
||||
if setup_done_future := setup_done_futures.pop(domain, None):
|
||||
setup_done_future.set_result(result)
|
||||
return result
|
||||
except BaseException as err:
|
||||
futures = [setup_future]
|
||||
if setup_done_future := setup_done_futures.pop(domain, None):
|
||||
|
@ -185,6 +184,7 @@ async def async_setup_component(
|
|||
# if there are no concurrent setup attempts
|
||||
await future
|
||||
raise
|
||||
return result
|
||||
|
||||
|
||||
async def _async_process_dependencies(
|
||||
|
|
|
@ -714,8 +714,7 @@ ignore = [
|
|||
# temporarily disabled
|
||||
"PT019",
|
||||
"TRY002",
|
||||
"TRY301",
|
||||
"TRY300"
|
||||
"TRY301"
|
||||
]
|
||||
|
||||
[tool.ruff.lint.flake8-import-conventions.extend-aliases]
|
||||
|
|
|
@ -88,11 +88,11 @@ def mock_client(
|
|||
val = mock_read_char_raw[uuid]
|
||||
if isinstance(val, Exception):
|
||||
raise val
|
||||
return val
|
||||
except KeyError:
|
||||
if default is SENTINEL:
|
||||
raise CharacteristicNotFound from KeyError
|
||||
return default
|
||||
return val
|
||||
|
||||
def _all_char():
|
||||
return set(mock_read_char_raw.keys())
|
||||
|
|
Loading…
Add table
Reference in a new issue