Update to python 3.11 (#4296)

This commit is contained in:
Mike Degatano 2023-05-22 13:12:34 -04:00 committed by GitHub
parent 61a7e6a87d
commit 5ced4e2f3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 132 additions and 31 deletions

View File

@ -33,12 +33,12 @@ on:
- setup.py
env:
DEFAULT_PYTHON: "3.10"
DEFAULT_PYTHON: "3.11"
BUILD_NAME: supervisor
BUILD_TYPE: supervisor
concurrency:
group: '${{ github.workflow }}-${{ github.ref }}'
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true
jobs:
@ -104,7 +104,7 @@ jobs:
if: needs.init.outputs.requirements == 'true'
uses: home-assistant/wheels@2023.04.0
with:
abi: cp310
abi: cp311
tag: musllinux_1_2
arch: ${{ matrix.arch }}
wheels-key: ${{ secrets.WHEELS_KEY }}

View File

@ -8,7 +8,7 @@ on:
pull_request: ~
env:
DEFAULT_PYTHON: "3.10"
DEFAULT_PYTHON: "3.11"
PRE_COMMIT_HOME: ~/.cache/pre-commit
DEFAULT_CAS: v1.0.2

View File

@ -1,11 +1,11 @@
image: homeassistant/{arch}-hassio-supervisor
shadow_repository: ghcr.io/home-assistant
build_from:
aarch64: ghcr.io/home-assistant/aarch64-base-python:3.10-alpine3.16
armhf: ghcr.io/home-assistant/armhf-base-python:3.10-alpine3.16
armv7: ghcr.io/home-assistant/armv7-base-python:3.10-alpine3.16
amd64: ghcr.io/home-assistant/amd64-base-python:3.10-alpine3.16
i386: ghcr.io/home-assistant/i386-base-python:3.10-alpine3.16
aarch64: ghcr.io/home-assistant/aarch64-base-python:3.11-alpine3.16
armhf: ghcr.io/home-assistant/armhf-base-python:3.11-alpine3.16
armv7: ghcr.io/home-assistant/armv7-base-python:3.11-alpine3.16
amd64: ghcr.io/home-assistant/amd64-base-python:3.11-alpine3.16
i386: ghcr.io/home-assistant/i386-base-python:3.11-alpine3.16
codenotary:
signer: notary@home-assistant.io
base_image: notary@home-assistant.io

View File

@ -5,7 +5,6 @@ atomicwrites-homeassistant==1.4.1
attrs==23.1.0
awesomeversion==23.5.0
brotli==1.0.9
cchardet==2.1.7
ciso8601==2.3.0
colorlog==6.7.0
cpe==1.2.1
@ -14,6 +13,7 @@ debugpy==1.6.7
deepmerge==1.1.0
dirhash==0.2.1
docker==6.1.2
faust-cchardet==2.1.18
gitpython==3.1.31
jinja2==3.1.2
pulsectl==23.5.1

View File

@ -79,7 +79,7 @@ class AddonManager(CoreSysAttributes):
tasks = []
for slug in self.data.system:
addon = self.local[slug] = Addon(self.coresys, slug)
tasks.append(addon.load())
tasks.append(self.sys_create_task(addon.load()))
# Run initial tasks
_LOGGER.info("Found %d installed add-ons", len(tasks))

View File

@ -148,8 +148,8 @@ class APIIngress(CoreSysAttributes):
# Proxy requests
await asyncio.wait(
[
_websocket_forward(ws_server, ws_client),
_websocket_forward(ws_client, ws_server),
self.sys_create_task(_websocket_forward(ws_server, ws_client)),
self.sys_create_task(_websocket_forward(ws_client, ws_server)),
],
return_when=asyncio.FIRST_COMPLETED,
)

View File

@ -117,7 +117,7 @@ class BackupManager(FileConfiguration, CoreSysAttributes):
self._backups[backup.slug] = backup
tasks = [
_load_backup(tar_file)
self.sys_create_task(_load_backup(tar_file))
for path in self.backup_locations
for tar_file in path.glob("*.tar")
]

View File

@ -285,9 +285,12 @@ class Core(CoreSysAttributes):
async with async_timeout.timeout(10):
await asyncio.wait(
[
self.sys_api.stop(),
self.sys_scheduler.shutdown(),
self.sys_docker.unload(),
self.sys_create_task(coro)
for coro in (
self.sys_api.stop(),
self.sys_scheduler.shutdown(),
self.sys_docker.unload(),
)
]
)
except asyncio.TimeoutError:
@ -298,10 +301,13 @@ class Core(CoreSysAttributes):
async with async_timeout.timeout(10):
await asyncio.wait(
[
self.sys_websession.close(),
self.sys_ingress.unload(),
self.sys_hardware.unload(),
self.sys_dbus.unload(),
self.sys_create_task(coro)
for coro in (
self.sys_websession.close(),
self.sys_ingress.unload(),
self.sys_hardware.unload(),
self.sys_dbus.unload(),
)
]
)
except asyncio.TimeoutError:

View File

@ -258,7 +258,12 @@ class HomeAssistant(FileConfiguration, CoreSysAttributes):
async def load(self) -> None:
"""Prepare Home Assistant object."""
await asyncio.wait([self.secrets.load(), self.core.load()])
await asyncio.wait(
[
self.sys_create_task(self.secrets.load()),
self.sys_create_task(self.core.load()),
]
)
# Register for events
self.sys_bus.register_event(BusEvent.HARDWARE_NEW_DEVICE, self._hardware_events)

View File

@ -109,11 +109,18 @@ class MountManager(FileConfiguration, CoreSysAttributes):
# Bind all media mounts to directories in media
if self.media_mounts:
await asyncio.wait([self._bind_media(mount) for mount in self.media_mounts])
await asyncio.wait(
[
self.sys_create_task(self._bind_media(mount))
for mount in self.media_mounts
]
)
async def reload(self) -> None:
"""Update mounts info via dbus and reload failed mounts."""
await asyncio.wait([mount.update() for mount in self.mounts])
await asyncio.wait(
[self.sys_create_task(mount.update()) for mount in self.mounts]
)
# Try to reload any newly failed mounts and report issues if failure persists
new_failures = [

View File

@ -107,7 +107,9 @@ class PluginManager(CoreSysAttributes):
async def repair(self) -> None:
"""Repair Supervisor plugins."""
await asyncio.wait([plugin.repair() for plugin in self.all_plugins])
await asyncio.wait(
[self.sys_create_task(plugin.repair()) for plugin in self.all_plugins]
)
async def shutdown(self) -> None:
"""Shutdown Supervisor plugin."""

View File

@ -83,7 +83,7 @@ class StoreManager(CoreSysAttributes, FileConfiguration):
@Job(conditions=[JobCondition.SUPERVISOR_UPDATED], on_condition=StoreJobError)
async def reload(self) -> None:
"""Update add-ons from repository and reload list."""
tasks = [repository.update() for repository in self.all]
tasks = [self.sys_create_task(repository.update()) for repository in self.all]
if tasks:
await asyncio.wait(tasks)

View File

@ -191,7 +191,7 @@ class Updater(FileConfiguration, CoreSysAttributes):
Is a coroutine.
"""
url = URL_HASSIO_VERSION.format(channel=self.channel)
url = URL_HASSIO_VERSION.format(channel=self.channel.value)
machine = self.sys_machine or "default"
# Get data

View File

@ -69,14 +69,14 @@ async def cas_validate(
async with async_timeout.timeout(15):
data, error = await proc.communicate()
except OSError as err:
raise CodeNotaryError(
f"CodeNotary fatal error: {err!s}", _LOGGER.critical
) from err
except asyncio.TimeoutError:
raise CodeNotaryBackendError(
"Timeout while processing CodeNotary", _LOGGER.warning
) from None
except OSError as err:
raise CodeNotaryError(
f"CodeNotary fatal error: {err!s}", _LOGGER.critical
) from err
# Check if Notarized
if proc.returncode != 0 and not data:

View File

@ -18,6 +18,7 @@ from supervisor.exceptions import (
DockerAPIError,
DockerNotFound,
)
from supervisor.plugins.dns import PluginDns
from supervisor.utils import check_exception_chain
from tests.common import load_json_fixture
@ -164,3 +165,20 @@ async def test_addon_uninstall_removes_discovery(
assert coresys.addons.installed == []
assert coresys.discovery.list_messages == []
async def test_load(
coresys: CoreSys, install_addon_ssh: Addon, caplog: pytest.LogCaptureFixture
):
"""Test addon manager load."""
caplog.clear()
with patch.object(DockerInterface, "attach") as attach, patch.object(
PluginDns, "write_hosts"
) as write_hosts:
await coresys.addons.load()
attach.assert_called_once_with(version=AwesomeVersion("9.2.1"))
write_hosts.assert_called_once()
assert "Found 1 installed add-ons" in caplog.text

View File

@ -0,0 +1,20 @@
"""Test Homeassistant module."""
from pathlib import Path
from unittest.mock import patch
from supervisor.coresys import CoreSys
from supervisor.docker.interface import DockerInterface
async def test_load(coresys: CoreSys, tmp_supervisor_data: Path):
"""Test homeassistant module load."""
with open(tmp_supervisor_data / "homeassistant" / "secrets.yaml", "w") as secrets:
secrets.write("hello: world\n")
with patch.object(DockerInterface, "attach") as attach:
await coresys.homeassistant.load()
attach.assert_called_once()
assert coresys.homeassistant.secrets.secrets == {"hello": "world"}

View File

@ -0,0 +1,31 @@
"""Test plugin manager."""
from unittest.mock import patch
from supervisor.coresys import CoreSys
from supervisor.docker.interface import DockerInterface
def mock_awaitable_bool(value: bool):
"""Return a mock of an awaitable bool."""
async def _mock_bool(*args, **kwargs) -> bool:
return value
return _mock_bool
async def test_repair(coresys: CoreSys):
"""Test repair."""
with patch.object(DockerInterface, "install") as install:
# If instance exists, repair does nothing
with patch.object(DockerInterface, "exists", new=mock_awaitable_bool(True)):
await coresys.plugins.repair()
install.assert_not_called()
# If not, repair installs the image
with patch.object(DockerInterface, "exists", new=mock_awaitable_bool(False)):
await coresys.plugins.repair()
assert install.call_count == len(coresys.plugins.all_plugins)

View File

@ -15,6 +15,7 @@ from supervisor.exceptions import AddonsNotSupportedError, StoreJobError
from supervisor.homeassistant.module import HomeAssistant
from supervisor.store import StoreManager
from supervisor.store.addon import AddonStore
from supervisor.store.git import GitRepo
from supervisor.store.repository import Repository
from tests.common import load_yaml_fixture
@ -231,3 +232,14 @@ async def test_install_unavailable_addon(
await coresys.addons.install("local_ssh")
assert log in caplog.text
async def test_reload(coresys: CoreSys):
"""Test store reload."""
await coresys.store.load()
assert len(coresys.store.all) == 4
with patch.object(GitRepo, "pull") as git_pull:
await coresys.store.reload()
assert git_pull.call_count == 3