Merge pull request #28399 from home-assistant/rc

0.101.1
This commit is contained in:
Paulus Schoutsen 2019-10-31 14:16:57 -07:00 committed by GitHub
commit c10e046323
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 70 additions and 37 deletions

View File

@ -1,15 +1,16 @@
"""The Airly component.""" """The Airly component."""
import asyncio import asyncio
import logging
from datetime import timedelta from datetime import timedelta
import logging
import async_timeout
from aiohttp.client_exceptions import ClientConnectorError from aiohttp.client_exceptions import ClientConnectorError
from airly import Airly from airly import Airly
from airly.exceptions import AirlyError from airly.exceptions import AirlyError
import async_timeout
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE
from homeassistant.core import Config, HomeAssistant from homeassistant.core import Config, HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.util import Throttle from homeassistant.util import Throttle
@ -45,6 +46,9 @@ async def async_setup_entry(hass, config_entry):
await airly.async_update() await airly.async_update()
if not airly.data:
raise ConfigEntryNotReady()
hass.data[DOMAIN] = {} hass.data[DOMAIN] = {}
hass.data[DOMAIN][DATA_CLIENT] = {} hass.data[DOMAIN][DATA_CLIENT] = {}
hass.data[DOMAIN][DATA_CLIENT][config_entry.entry_id] = airly hass.data[DOMAIN][DATA_CLIENT][config_entry.entry_id] = airly
@ -81,7 +85,7 @@ class AirlyData:
"""Update Airly data.""" """Update Airly data."""
try: try:
with async_timeout.timeout(10): with async_timeout.timeout(20):
measurements = self.airly.create_measurements_session_point( measurements = self.airly.create_measurements_session_point(
self.latitude, self.longitude self.latitude, self.longitude
) )
@ -104,11 +108,8 @@ class AirlyData:
self.data[ATTR_API_CAQI_DESCRIPTION] = index["description"] self.data[ATTR_API_CAQI_DESCRIPTION] = index["description"]
self.data[ATTR_API_ADVICE] = index["advice"] self.data[ATTR_API_ADVICE] = index["advice"]
_LOGGER.debug("Data retrieved from Airly") _LOGGER.debug("Data retrieved from Airly")
except ( except asyncio.TimeoutError:
ValueError, _LOGGER.error("Asyncio Timeout Error")
AirlyError, except (ValueError, AirlyError, ClientConnectorError) as error:
asyncio.TimeoutError,
ClientConnectorError,
) as error:
_LOGGER.error(error) _LOGGER.error(error)
self.data = {} self.data = {}

View File

@ -2,11 +2,7 @@
"domain": "environment_canada", "domain": "environment_canada",
"name": "Environment Canada", "name": "Environment Canada",
"documentation": "https://www.home-assistant.io/integrations/environment_canada", "documentation": "https://www.home-assistant.io/integrations/environment_canada",
"requirements": [ "requirements": ["env_canada==0.0.29"],
"env_canada==0.0.27"
],
"dependencies": [], "dependencies": [],
"codeowners": [ "codeowners": ["@michaeldavie"]
"@michaeldavie"
]
} }

View File

@ -3,7 +3,7 @@
"name": "Jewish calendar", "name": "Jewish calendar",
"documentation": "https://www.home-assistant.io/integrations/jewish_calendar", "documentation": "https://www.home-assistant.io/integrations/jewish_calendar",
"requirements": [ "requirements": [
"hdate==0.9.1" "hdate==0.9.3"
], ],
"dependencies": [], "dependencies": [],
"codeowners": [ "codeowners": [

View File

@ -3,7 +3,7 @@
"name": "Myq", "name": "Myq",
"documentation": "https://www.home-assistant.io/integrations/myq", "documentation": "https://www.home-assistant.io/integrations/myq",
"requirements": [ "requirements": [
"pymyq==2.0.0" "pymyq==2.0.1"
], ],
"dependencies": [], "dependencies": [],
"codeowners": [] "codeowners": []

View File

@ -3,7 +3,7 @@
"name": "SAJ", "name": "SAJ",
"documentation": "https://www.home-assistant.io/integrations/saj", "documentation": "https://www.home-assistant.io/integrations/saj",
"requirements": [ "requirements": [
"pysaj==0.0.12" "pysaj==0.0.13"
], ],
"dependencies": [], "dependencies": [],
"codeowners": [ "codeowners": [

View File

@ -3,7 +3,7 @@
"name": "Songpal", "name": "Songpal",
"documentation": "https://www.home-assistant.io/integrations/songpal", "documentation": "https://www.home-assistant.io/integrations/songpal",
"requirements": [ "requirements": [
"python-songpal==0.11.1" "python-songpal==0.11.2"
], ],
"dependencies": [], "dependencies": [],
"codeowners": [ "codeowners": [

View File

@ -1,7 +1,7 @@
"""Constants used by Home Assistant components.""" """Constants used by Home Assistant components."""
MAJOR_VERSION = 0 MAJOR_VERSION = 0
MINOR_VERSION = 101 MINOR_VERSION = 101
PATCH_VERSION = "0" PATCH_VERSION = "1"
__short_version__ = "{}.{}".format(MAJOR_VERSION, MINOR_VERSION) __short_version__ = "{}.{}".format(MAJOR_VERSION, MINOR_VERSION)
__version__ = "{}.{}".format(__short_version__, PATCH_VERSION) __version__ = "{}.{}".format(__short_version__, PATCH_VERSION)
REQUIRED_PYTHON_VER = (3, 6, 1) REQUIRED_PYTHON_VER = (3, 6, 1)

View File

@ -35,13 +35,21 @@ async def async_get_integration_with_requirements(
This can raise IntegrationNotFound if manifest or integration This can raise IntegrationNotFound if manifest or integration
is invalid, RequirementNotFound if there was some type of is invalid, RequirementNotFound if there was some type of
failure to install requirements. failure to install requirements.
Does not handle circular dependencies.
""" """
integration = await async_get_integration(hass, domain) integration = await async_get_integration(hass, domain)
if hass.config.skip_pip or not integration.requirements: if hass.config.skip_pip:
return integration return integration
await async_process_requirements(hass, integration.domain, integration.requirements) if integration.requirements:
await async_process_requirements(
hass, integration.domain, integration.requirements
)
for dependency in integration.dependencies:
await async_get_integration_with_requirements(hass, dependency)
return integration return integration

View File

@ -132,6 +132,17 @@ async def _async_setup_component(
log_error(str(err)) log_error(str(err))
return False return False
# Some integrations fail on import because they call functions incorrectly.
# So we do it before validating config to catch these errors.
try:
component = integration.get_component()
except ImportError:
log_error("Unable to import component", False)
return False
except Exception: # pylint: disable=broad-except
_LOGGER.exception("Setup failed for %s: unknown error", domain)
return False
processed_config = await conf_util.async_process_component_config( processed_config = await conf_util.async_process_component_config(
hass, config, integration hass, config, integration
) )
@ -143,12 +154,6 @@ async def _async_setup_component(
start = timer() start = timer()
_LOGGER.info("Setting up %s", domain) _LOGGER.info("Setting up %s", domain)
try:
component = integration.get_component()
except ImportError:
log_error("Unable to import component", False)
return False
if hasattr(component, "PLATFORM_SCHEMA"): if hasattr(component, "PLATFORM_SCHEMA"):
# Entity components have their own warning # Entity components have their own warning
warn_task = None warn_task = None

View File

@ -456,7 +456,7 @@ enocean==0.50
enturclient==0.2.0 enturclient==0.2.0
# homeassistant.components.environment_canada # homeassistant.components.environment_canada
env_canada==0.0.27 env_canada==0.0.29
# homeassistant.components.envirophat # homeassistant.components.envirophat
# envirophat==0.0.6 # envirophat==0.0.6
@ -622,7 +622,7 @@ hass-nabucasa==0.22
hbmqtt==0.9.5 hbmqtt==0.9.5
# homeassistant.components.jewish_calendar # homeassistant.components.jewish_calendar
hdate==0.9.1 hdate==0.9.3
# homeassistant.components.heatmiser # homeassistant.components.heatmiser
heatmiserV3==0.9.1 heatmiserV3==0.9.1
@ -1328,7 +1328,7 @@ pymsteams==0.1.12
pymusiccast==0.1.6 pymusiccast==0.1.6
# homeassistant.components.myq # homeassistant.components.myq
pymyq==2.0.0 pymyq==2.0.1
# homeassistant.components.mysensors # homeassistant.components.mysensors
pymysensors==0.18.0 pymysensors==0.18.0
@ -1423,7 +1423,7 @@ pyrepetier==3.0.5
pysabnzbd==1.1.0 pysabnzbd==1.1.0
# homeassistant.components.saj # homeassistant.components.saj
pysaj==0.0.12 pysaj==0.0.13
# homeassistant.components.sony_projector # homeassistant.components.sony_projector
pysdcp==1 pysdcp==1
@ -1564,7 +1564,7 @@ python-ripple-api==0.0.3
python-sochain-api==0.0.2 python-sochain-api==0.0.2
# homeassistant.components.songpal # homeassistant.components.songpal
python-songpal==0.11.1 python-songpal==0.11.2
# homeassistant.components.synologydsm # homeassistant.components.synologydsm
python-synology==0.2.0 python-synology==0.2.0

View File

@ -230,7 +230,7 @@ hass-nabucasa==0.22
hbmqtt==0.9.5 hbmqtt==0.9.5
# homeassistant.components.jewish_calendar # homeassistant.components.jewish_calendar
hdate==0.9.1 hdate==0.9.3
# homeassistant.components.here_travel_time # homeassistant.components.here_travel_time
herepy==0.6.3.1 herepy==0.6.3.1

View File

@ -112,7 +112,17 @@ async def test_install_missing_package(hass):
async def test_get_integration_with_requirements(hass): async def test_get_integration_with_requirements(hass):
"""Check getting an integration with loaded requirements.""" """Check getting an integration with loaded requirements."""
hass.config.skip_pip = False hass.config.skip_pip = False
mock_integration(hass, MockModule("test_component", requirements=["hello==1.0.0"])) mock_integration(
hass, MockModule("test_component_dep", requirements=["test-comp-dep==1.0.0"])
)
mock_integration(
hass,
MockModule(
"test_component",
requirements=["test-comp==1.0.0"],
dependencies=["test_component_dep"],
),
)
with patch( with patch(
"homeassistant.util.package.is_installed", return_value=False "homeassistant.util.package.is_installed", return_value=False
@ -126,8 +136,13 @@ async def test_get_integration_with_requirements(hass):
assert integration assert integration
assert integration.domain == "test_component" assert integration.domain == "test_component"
assert len(mock_is_installed.mock_calls) == 1 assert len(mock_is_installed.mock_calls) == 2
assert len(mock_inst.mock_calls) == 1 assert mock_is_installed.mock_calls[0][1][0] == "test-comp==1.0.0"
assert mock_is_installed.mock_calls[1][1][0] == "test-comp-dep==1.0.0"
assert len(mock_inst.mock_calls) == 2
assert mock_inst.mock_calls[0][1][0] == "test-comp==1.0.0"
assert mock_inst.mock_calls[1][1][0] == "test-comp-dep==1.0.0"
async def test_install_with_wheels_index(hass): async def test_install_with_wheels_index(hass):

View File

@ -527,3 +527,11 @@ async def test_when_setup_already_loaded(hass):
setup.async_when_setup(hass, "test", mock_callback) setup.async_when_setup(hass, "test", mock_callback)
await hass.async_block_till_done() await hass.async_block_till_done()
assert calls == ["test", "test"] assert calls == ["test", "test"]
async def test_setup_import_blows_up(hass):
"""Test that we handle it correctly when importing integration blows up."""
with mock.patch(
"homeassistant.loader.Integration.get_component", side_effect=ValueError
):
assert not await setup.async_setup_component(hass, "sun", {})