Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion homeassistant/components/frontend/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
"documentation": "https://www.home-assistant.io/integrations/frontend",
"integration_type": "system",
"quality_scale": "internal",
"requirements": ["home-assistant-frontend==20250730.0"]
"requirements": ["home-assistant-frontend==20250731.0"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/kitchen_sink/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ async def async_step_options_1(
),
}
)
self.add_suggested_values_to_schema(
data_schema = self.add_suggested_values_to_schema(
data_schema,
{"section_1": {"int": self.config_entry.options.get(CONF_INT, 10)}},
)
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/litterrobot/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
"iot_class": "cloud_push",
"loggers": ["pylitterbot"],
"quality_scale": "bronze",
"requirements": ["pylitterbot==2024.2.2"]
"requirements": ["pylitterbot==2024.2.3"]
}
8 changes: 6 additions & 2 deletions homeassistant/components/zha/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ async def async_setup_entry(
zha_data = get_zha_data(hass)
if zha_data.update_coordinator is None:
zha_data.update_coordinator = ZHAFirmwareUpdateCoordinator(
hass, get_zha_gateway(hass).application_controller
hass, config_entry, get_zha_gateway(hass).application_controller
)
entities_to_create = zha_data.platforms[Platform.UPDATE]

Expand All @@ -79,12 +79,16 @@ class ZHAFirmwareUpdateCoordinator(DataUpdateCoordinator[None]): # pylint: disa
"""Firmware update coordinator that broadcasts updates network-wide."""

def __init__(
self, hass: HomeAssistant, controller_application: ControllerApplication
self,
hass: HomeAssistant,
config_entry: ConfigEntry,
controller_application: ControllerApplication,
) -> None:
"""Initialize the coordinator."""
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name="ZHA firmware update coordinator",
update_method=self.async_update_data,
)
Expand Down
7 changes: 4 additions & 3 deletions homeassistant/data_entry_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,9 +676,10 @@ def add_suggested_values_to_schema(
and key in suggested_values
):
new_section_key = copy.copy(key)
schema[new_section_key] = val
val.schema = self.add_suggested_values_to_schema(
val.schema, suggested_values[key]
new_val = copy.copy(val)
schema[new_section_key] = new_val
new_val.schema = self.add_suggested_values_to_schema(
new_val.schema, suggested_values[key]
)
continue

Expand Down
7 changes: 3 additions & 4 deletions homeassistant/package_constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ habluetooth==4.0.1
hass-nabucasa==0.110.0
hassil==2.2.3
home-assistant-bluetooth==1.13.1
home-assistant-frontend==20250730.0
home-assistant-frontend==20250731.0
home-assistant-intents==2025.7.30
httpx==0.28.1
ifaddr==0.2.0
Expand Down Expand Up @@ -209,7 +209,6 @@ aiofiles>=24.1.0
# https://github.com/aio-libs/multidict/issues/1131
multidict>=6.4.2

# rpds-py > 0.25.0 requires cargo 1.84.0
# Stable Alpine current only ships cargo 1.83.0
# rpds-py frequently updates cargo causing build failures
# No wheels upstream available for armhf & armv7
rpds-py==0.24.0
rpds-py==0.26.0
4 changes: 2 additions & 2 deletions requirements_all.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions requirements_test_all.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions script/gen_requirements_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,9 @@
# https://github.com/aio-libs/multidict/issues/1131
multidict>=6.4.2

# rpds-py > 0.25.0 requires cargo 1.84.0
# Stable Alpine current only ships cargo 1.83.0
# rpds-py frequently updates cargo causing build failures
# No wheels upstream available for armhf & armv7
rpds-py==0.24.0
rpds-py==0.26.0
"""

GENERATED_MESSAGE = (
Expand Down
64 changes: 54 additions & 10 deletions tests/test_data_entry_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,19 @@ async def async_step_init(self, user_input=None):

async def test_form_shows_with_added_suggested_values(manager: MockFlowManager) -> None:
"""Test that we can show a form with suggested values."""

def compare_schemas(schema: vol.Schema, expected_schema: vol.Schema) -> None:
"""Compare two schemas."""
assert schema.schema is not expected_schema.schema

assert list(schema.schema) == list(expected_schema.schema)

for key, validator in schema.schema.items():
if isinstance(validator, data_entry_flow.section):
assert validator.schema == expected_schema.schema[key].schema
continue
assert validator == expected_schema.schema[key]

schema = vol.Schema(
{
vol.Required("username"): str,
Expand All @@ -155,20 +168,25 @@ class TestFlow(data_entry_flow.FlowHandler):
async def async_step_init(self, user_input=None):
data_schema = self.add_suggested_values_to_schema(
schema,
{
"username": "doej",
"password": "verySecret1",
"section_1": {"full_name": "John Doe"},
},
user_input,
)
return self.async_show_form(
step_id="init",
data_schema=data_schema,
)

form = await manager.async_init("test")
form = await manager.async_init(
"test",
data={
"username": "doej",
"password": "verySecret1",
"section_1": {"full_name": "John Doe"},
},
)
assert form["type"] == data_entry_flow.FlowResultType.FORM
assert form["data_schema"].schema == schema.schema
assert form["data_schema"].schema is not schema.schema
assert form["data_schema"].schema != schema.schema
compare_schemas(form["data_schema"], schema)
markers = list(form["data_schema"].schema)
assert len(markers) == 3
assert markers[0] == "username"
Expand All @@ -178,14 +196,40 @@ async def async_step_init(self, user_input=None):
assert markers[2] == "section_1"
section_validator = form["data_schema"].schema["section_1"]
assert isinstance(section_validator, data_entry_flow.section)
# The section class was not replaced
# The section instance was copied
assert section_validator is not schema.schema["section_1"]
# The section schema instance was copied
assert section_validator.schema is not schema.schema["section_1"].schema
assert section_validator.schema == schema.schema["section_1"].schema
section_markers = list(section_validator.schema.schema)
assert len(section_markers) == 1
assert section_markers[0] == "full_name"
assert section_markers[0].description == {"suggested_value": "John Doe"}

# Test again without suggested values to make sure we're not mutating the schema
form = await manager.async_init(
"test",
)
assert form["type"] == data_entry_flow.FlowResultType.FORM
assert form["data_schema"].schema is not schema.schema
assert form["data_schema"].schema == schema.schema
markers = list(form["data_schema"].schema)
assert len(markers) == 3
assert markers[0] == "username"
assert markers[0].description is None
assert markers[1] == "password"
assert markers[1].description is None
assert markers[2] == "section_1"
section_validator = form["data_schema"].schema["section_1"]
assert isinstance(section_validator, data_entry_flow.section)
# The section class is not replaced if there is no suggested value for the section
assert section_validator is schema.schema["section_1"]
# The section schema was not replaced
# The section schema is not replaced if there is no suggested value for the section
assert section_validator.schema is schema.schema["section_1"].schema
section_markers = list(section_validator.schema.schema)
assert len(section_markers) == 1
assert section_markers[0] == "full_name"
assert section_markers[0].description == {"suggested_value": "John Doe"}
assert section_markers[0].description is None


async def test_abort_removes_instance(manager: MockFlowManager) -> None:
Expand Down
Loading