mirror of
https://github.com/home-assistant/core.git
synced 2026-10-08 15:29:17 -04:00
2026.7.4 (#177169)
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["pybravia"],
|
||||
"requirements": ["pybravia==0.4.1"],
|
||||
"requirements": ["pybravia==0.5.1"],
|
||||
"ssdp": [
|
||||
{
|
||||
"manufacturer": "Sony Corporation",
|
||||
|
||||
@@ -79,7 +79,9 @@ async def _get_fixture_collection(envoy: Envoy, serial: str) -> dict[str, Any]:
|
||||
try:
|
||||
response: ClientResponse = await envoy.request(end_point)
|
||||
fixture_data[end_point] = (
|
||||
(await response.text()).replace("\n", "").replace(serial, CLEAN_TEXT)
|
||||
(await response.text(errors="replace"))
|
||||
.replace("\n", "")
|
||||
.replace(serial, CLEAN_TEXT)
|
||||
)
|
||||
fixture_data[f"{end_point}_log"] = json_dumps(
|
||||
{
|
||||
|
||||
@@ -37,5 +37,5 @@
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["pylamarzocco"],
|
||||
"quality_scale": "platinum",
|
||||
"requirements": ["pylamarzocco==2.4.2"]
|
||||
"requirements": ["pylamarzocco==2.4.3"]
|
||||
}
|
||||
|
||||
@@ -193,9 +193,9 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ProxmoxConfigEntry) ->
|
||||
if "@" in data.get(CONF_USERNAME, ""):
|
||||
username, realm = data[CONF_USERNAME].split("@", 1)
|
||||
data[CONF_USERNAME] = username
|
||||
data[CONF_REALM] = realm.lower()
|
||||
data[CONF_REALM] = realm
|
||||
|
||||
realm = data[CONF_REALM].lower()
|
||||
realm = data[CONF_REALM]
|
||||
|
||||
# If the realm is one of the base providers,
|
||||
# set the provider to match the realm.
|
||||
|
||||
@@ -16,7 +16,7 @@ def sanitize_config_entry(input_data: Mapping[str, Any]) -> dict[str, Any]:
|
||||
|
||||
realm = provider.lower()
|
||||
if provider == AUTH_OTHER:
|
||||
realm = data[CONF_REALM].lower()
|
||||
realm = data[CONF_REALM]
|
||||
|
||||
data[CONF_REALM] = realm
|
||||
data[CONF_USERNAME] = f"{username}@{realm}"
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["yoto_api"],
|
||||
"quality_scale": "platinum",
|
||||
"requirements": ["yoto-api==4.3.1"]
|
||||
"requirements": ["yoto-api==4.3.2"]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ if TYPE_CHECKING:
|
||||
APPLICATION_NAME: Final = "HomeAssistant"
|
||||
MAJOR_VERSION: Final = 2026
|
||||
MINOR_VERSION: Final = 7
|
||||
PATCH_VERSION: Final = "3"
|
||||
PATCH_VERSION: Final = "4"
|
||||
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
||||
__version__: Final = f"{__short_version__}.{PATCH_VERSION}"
|
||||
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 14, 2)
|
||||
|
||||
@@ -6,7 +6,7 @@ aiodns==4.0.4
|
||||
aiogithubapi==26.0.0
|
||||
aiohttp-asyncmdnsresolver==0.2.0
|
||||
aiohttp-fast-zlib==0.3.0
|
||||
aiohttp==3.14.1
|
||||
aiohttp==3.14.3
|
||||
aiohttp_cors==0.8.1
|
||||
aiousbwatcher==1.1.2
|
||||
aiozoneinfo==0.2.3
|
||||
@@ -75,7 +75,7 @@ voluptuous-openapi==0.4.1
|
||||
voluptuous-serialize==2.7.0
|
||||
voluptuous==0.15.2
|
||||
webrtc-models==0.3.0
|
||||
yarl==1.24.2
|
||||
yarl==1.24.5
|
||||
zeroconf==0.150.0
|
||||
|
||||
# Constrain pycryptodome to avoid vulnerability
|
||||
|
||||
+3
-3
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "homeassistant"
|
||||
version = "2026.7.3"
|
||||
version = "2026.7.4"
|
||||
license = "Apache-2.0"
|
||||
license-files = ["LICENSE*", "homeassistant/backports/LICENSE*"]
|
||||
description = "Open-source home automation platform running on Python 3."
|
||||
@@ -28,7 +28,7 @@ dependencies = [
|
||||
# module level in `bootstrap.py` and its requirements thus need to be in
|
||||
# requirements.txt to ensure they are always installed
|
||||
"aiogithubapi==26.0.0",
|
||||
"aiohttp==3.14.1",
|
||||
"aiohttp==3.14.3",
|
||||
"aiohttp_cors==0.8.1",
|
||||
"aiohttp-fast-zlib==0.3.0",
|
||||
"aiohttp-asyncmdnsresolver==0.2.0",
|
||||
@@ -78,7 +78,7 @@ dependencies = [
|
||||
"voluptuous==0.15.2",
|
||||
"voluptuous-serialize==2.7.0",
|
||||
"voluptuous-openapi==0.4.1",
|
||||
"yarl==1.24.2",
|
||||
"yarl==1.24.5",
|
||||
"webrtc-models==0.3.0",
|
||||
"zeroconf==0.150.0",
|
||||
]
|
||||
|
||||
Generated
+2
-2
@@ -7,7 +7,7 @@ aiodns==4.0.4
|
||||
aiogithubapi==26.0.0
|
||||
aiohttp-asyncmdnsresolver==0.2.0
|
||||
aiohttp-fast-zlib==0.3.0
|
||||
aiohttp==3.14.1
|
||||
aiohttp==3.14.3
|
||||
aiohttp_cors==0.8.1
|
||||
aiozoneinfo==0.2.3
|
||||
annotatedyaml==1.0.2
|
||||
@@ -60,5 +60,5 @@ voluptuous-openapi==0.4.1
|
||||
voluptuous-serialize==2.7.0
|
||||
voluptuous==0.15.2
|
||||
webrtc-models==0.3.0
|
||||
yarl==1.24.2
|
||||
yarl==1.24.5
|
||||
zeroconf==0.150.0
|
||||
|
||||
Generated
+3
-3
@@ -2048,7 +2048,7 @@ pyblu==2.0.8
|
||||
pybotvac==0.0.29
|
||||
|
||||
# homeassistant.components.braviatv
|
||||
pybravia==0.4.1
|
||||
pybravia==0.5.1
|
||||
|
||||
# homeassistant.components.nissan_leaf
|
||||
pycarwings2==2.14
|
||||
@@ -2298,7 +2298,7 @@ pykwb==0.0.8
|
||||
pylacrosse==0.4
|
||||
|
||||
# homeassistant.components.lamarzocco
|
||||
pylamarzocco==2.4.2
|
||||
pylamarzocco==2.4.3
|
||||
|
||||
# homeassistant.components.lastfm
|
||||
pylast==5.1.0
|
||||
@@ -3414,7 +3414,7 @@ yeelightsunflower==0.0.10
|
||||
yolink-api==0.6.5
|
||||
|
||||
# homeassistant.components.yoto
|
||||
yoto-api==4.3.1
|
||||
yoto-api==4.3.2
|
||||
|
||||
# homeassistant.components.youless
|
||||
youless-api==2.2.0
|
||||
|
||||
@@ -64,8 +64,8 @@ MOCK_TEST_TOKEN_CONFIG = {
|
||||
MOCK_TEST_OTHER_CONFIG = {
|
||||
**MOCK_TEST_CONFIG,
|
||||
CONF_AUTH_METHOD: "other",
|
||||
CONF_REALM: "test_realm",
|
||||
CONF_USERNAME: "test_user@test_realm",
|
||||
CONF_REALM: "Test_Realm",
|
||||
CONF_USERNAME: "test_user@Test_Realm",
|
||||
}
|
||||
|
||||
MOCK_TEST_TOKEN_OTHER_CONFIG = {
|
||||
@@ -74,8 +74,8 @@ MOCK_TEST_TOKEN_OTHER_CONFIG = {
|
||||
CONF_TOKEN_ID: "test_token_id",
|
||||
CONF_TOKEN_SECRET: "test_token_secret",
|
||||
CONF_AUTH_METHOD: "other",
|
||||
CONF_REALM: "test_realm",
|
||||
CONF_USERNAME: "test_user@test_realm",
|
||||
CONF_REALM: "Test_Realm",
|
||||
CONF_USERNAME: "test_user@Test_Realm",
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ MOCK_USER_STEP_OTHER = {
|
||||
|
||||
MOCK_USER_AUTH_STEP_OTHER = {
|
||||
**MOCK_USER_AUTH_STEP_PASSWORD,
|
||||
CONF_REALM: "test_realm",
|
||||
CONF_REALM: "Test_Realm",
|
||||
}
|
||||
|
||||
# Other authentication method with realm and token
|
||||
@@ -86,7 +86,7 @@ MOCK_USER_STEP_OTHER_TOKEN = {
|
||||
|
||||
MOCK_USER_AUTH_STEP_OTHER_TOKEN = {
|
||||
**MOCK_USER_AUTH_STEP_TOKEN,
|
||||
CONF_REALM: "test_realm",
|
||||
CONF_REALM: "Test_Realm",
|
||||
}
|
||||
|
||||
MOCK_USER_SETUP = {CONF_NODES: ["pve1"]}
|
||||
@@ -724,7 +724,7 @@ async def test_full_flow_reauth_token_other(
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
CONF_REALM: "test_realm",
|
||||
CONF_REALM: "Test_Realm",
|
||||
CONF_TOKEN_ID: "test_token_id",
|
||||
CONF_TOKEN_SECRET: "new_token_secret",
|
||||
},
|
||||
|
||||
@@ -9,6 +9,7 @@ import requests
|
||||
from requests.exceptions import ConnectTimeout, SSLError
|
||||
|
||||
from homeassistant.components.proxmoxve.const import (
|
||||
AUTH_OTHER,
|
||||
AUTH_PAM,
|
||||
CONF_AUTH_METHOD,
|
||||
CONF_CONTAINERS,
|
||||
@@ -165,25 +166,56 @@ async def test_setup_exceptions(
|
||||
assert mock_config_entry.state is expected_state
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("mock_config_entry", "expected_auth_method", "expected_realm"),
|
||||
[
|
||||
(
|
||||
MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
version=1,
|
||||
unique_id="1",
|
||||
data={
|
||||
CONF_HOST: "http://test_host",
|
||||
CONF_PORT: 8006,
|
||||
CONF_REALM: "pam",
|
||||
CONF_USERNAME: "test_user@pam",
|
||||
CONF_PASSWORD: "test_password",
|
||||
CONF_VERIFY_SSL: True,
|
||||
},
|
||||
),
|
||||
AUTH_PAM,
|
||||
"pam",
|
||||
),
|
||||
(
|
||||
MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
version=1,
|
||||
unique_id="1",
|
||||
data={
|
||||
CONF_HOST: "http://test_host",
|
||||
CONF_PORT: 8006,
|
||||
CONF_REALM: "Test_Realm",
|
||||
CONF_USERNAME: "test_user@Test_Realm",
|
||||
CONF_PASSWORD: "test_password",
|
||||
CONF_VERIFY_SSL: True,
|
||||
},
|
||||
),
|
||||
AUTH_OTHER,
|
||||
"Test_Realm",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_migration_v1_to_v3(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
expected_auth_method: str,
|
||||
expected_realm: str,
|
||||
) -> None:
|
||||
"""Test migration from version 1."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
version=1,
|
||||
unique_id="1",
|
||||
data={
|
||||
CONF_HOST: "http://test_host",
|
||||
CONF_PORT: 8006,
|
||||
CONF_REALM: "pam",
|
||||
CONF_USERNAME: "test_user@pam",
|
||||
CONF_PASSWORD: "test_password",
|
||||
CONF_VERIFY_SSL: True,
|
||||
},
|
||||
)
|
||||
"""Test migration from version 1 to 3."""
|
||||
entry = mock_config_entry
|
||||
|
||||
entry.add_to_hass(hass)
|
||||
assert entry.version == 1
|
||||
|
||||
@@ -227,6 +259,8 @@ async def test_migration_v1_to_v3(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.version == 3
|
||||
assert entry.data[CONF_AUTH_METHOD] == expected_auth_method
|
||||
assert entry.data[CONF_REALM] == expected_realm
|
||||
|
||||
vm_entity_after = entity_registry.async_get(vm_entity.entity_id)
|
||||
container_entity_after = entity_registry.async_get(container_entity.entity_id)
|
||||
@@ -235,6 +269,97 @@ async def test_migration_v1_to_v3(
|
||||
assert container_entity_after.unique_id == f"{entry.entry_id}_200_status"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("mock_config_entry", "expected_auth_method", "expected_realm"),
|
||||
[
|
||||
(
|
||||
MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
version=2,
|
||||
unique_id="1",
|
||||
data={
|
||||
CONF_HOST: "http://test_host",
|
||||
CONF_PORT: 8006,
|
||||
CONF_REALM: "pam",
|
||||
CONF_USERNAME: "test_user@pam",
|
||||
CONF_PASSWORD: "test_password",
|
||||
CONF_VERIFY_SSL: True,
|
||||
},
|
||||
),
|
||||
AUTH_PAM,
|
||||
"pam",
|
||||
),
|
||||
(
|
||||
MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
version=2,
|
||||
unique_id="1",
|
||||
data={
|
||||
CONF_HOST: "http://test_host",
|
||||
CONF_PORT: 8006,
|
||||
CONF_REALM: "Test_Realm",
|
||||
CONF_USERNAME: "test_user@Test_Realm",
|
||||
CONF_PASSWORD: "test_password",
|
||||
CONF_VERIFY_SSL: True,
|
||||
},
|
||||
),
|
||||
AUTH_OTHER,
|
||||
"Test_Realm",
|
||||
),
|
||||
(
|
||||
MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
version=2,
|
||||
unique_id="1",
|
||||
data={
|
||||
CONF_HOST: "http://test_host",
|
||||
CONF_PORT: 8006,
|
||||
CONF_USERNAME: "test_user@pam",
|
||||
CONF_PASSWORD: "test_password",
|
||||
CONF_VERIFY_SSL: True,
|
||||
},
|
||||
),
|
||||
AUTH_PAM,
|
||||
"pam",
|
||||
),
|
||||
(
|
||||
MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
version=2,
|
||||
unique_id="1",
|
||||
data={
|
||||
CONF_HOST: "http://test_host",
|
||||
CONF_PORT: 8006,
|
||||
CONF_USERNAME: "test_user@Test_Realm",
|
||||
CONF_PASSWORD: "test_password",
|
||||
CONF_VERIFY_SSL: True,
|
||||
},
|
||||
),
|
||||
AUTH_OTHER,
|
||||
"Test_Realm",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_migration_v2_to_v3(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
expected_auth_method: str,
|
||||
expected_realm: str,
|
||||
) -> None:
|
||||
"""Test migration from version 2 to 3."""
|
||||
entry = mock_config_entry
|
||||
|
||||
entry.add_to_hass(hass)
|
||||
assert entry.version == 2
|
||||
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.version == 3
|
||||
assert entry.data[CONF_AUTH_METHOD] == expected_auth_method
|
||||
assert entry.data[CONF_REALM] == expected_realm
|
||||
|
||||
|
||||
async def test_offline_node(
|
||||
hass: HomeAssistant,
|
||||
mock_proxmox_client: MagicMock,
|
||||
@@ -253,61 +378,6 @@ async def test_offline_node(
|
||||
assert state.state == STATE_OFF
|
||||
|
||||
|
||||
async def test_migration_v2_to_v3(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test migration from version 2 to 3."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
version=2,
|
||||
unique_id="1",
|
||||
data={
|
||||
CONF_HOST: "http://test_host",
|
||||
CONF_PORT: 8006,
|
||||
CONF_REALM: "pam",
|
||||
CONF_USERNAME: "test_user@pam",
|
||||
CONF_PASSWORD: "test_password",
|
||||
CONF_VERIFY_SSL: True,
|
||||
},
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
assert entry.version == 2
|
||||
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.version == 3
|
||||
assert entry.data[CONF_AUTH_METHOD] == AUTH_PAM
|
||||
assert entry.data[CONF_REALM] == AUTH_PAM
|
||||
|
||||
|
||||
async def test_migration_v2_to_v3_without_realm(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test migration from version 2 to 3."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
version=2,
|
||||
unique_id="1",
|
||||
data={
|
||||
CONF_HOST: "http://test_host",
|
||||
CONF_PORT: 8006,
|
||||
CONF_USERNAME: "test_user@pam",
|
||||
CONF_PASSWORD: "test_password",
|
||||
CONF_VERIFY_SSL: True,
|
||||
},
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
assert entry.version == 2
|
||||
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.version == 3
|
||||
assert entry.data[CONF_AUTH_METHOD] == AUTH_PAM
|
||||
assert entry.data[CONF_REALM] == AUTH_PAM
|
||||
|
||||
|
||||
async def test_new_vm_creates_entity(
|
||||
hass: HomeAssistant,
|
||||
mock_proxmox_client: MagicMock,
|
||||
|
||||
Reference in New Issue
Block a user