Skip to content

Commit c4a93cb

Browse files
committed
fix: compatibility with HA 2026.3 mypy/ruff changes
- Cast energy_source flow_from/flow_to lists to fix mypy attr-defined errors - Replace GridSourceType constructor with plain dict to fix TypedDict key errors - Fix import formatting to satisfy ruff I001 - Pin pycares version / update requirements Update tests.yml: Update checkout to v6 Update tests.yml: Python req from 3.13 to 3.14 Bump HA Version to 2026.3.2 (also stubs) Bump Pycares to >= 5 (still have to check aiodns dependencies Update __init__.py HA 2026.3 update: Mypy fails to resolve flow_from on the TypedDict union, causing energy_source.get to return object. Fixed via type casting. Also from typing import Any to from typing import Any, from typing import cast Update flow_handler.py In HA 2026.3, GridSourceType lost the flow_from/flow_to fields—they were replaced by flat fields (stat_energy_from, stat_cost, etc.). However, the runtime structure of the dict passed to the Energy Manager still works. Fix: Annotate as a plain dict[str, Any] instead of using the TypedDict constructor. Lines 278 and 286 (grid_source["flow_from"].append(...) / grid_source["flow_to"].append(...)) will automatically work again, as dict[str, Any] allows for arbitrary key access.
1 parent fab5165 commit c4a93cb

4 files changed

Lines changed: 13 additions & 13 deletions

File tree

.github/workflows/tests.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@ on:
1111
- cron: "0 0 * * *"
1212

1313
env:
14-
DEFAULT_PYTHON: "3.13"
14+
DEFAULT_PYTHON: "3.14"
1515

1616
jobs:
1717
pre-commit:
1818
runs-on: "ubuntu-latest"
1919
name: Pre-commit and pytest
2020
steps:
2121
- name: Check out the repository
22-
uses: actions/checkout@v3.5.3
22+
uses: actions/checkout@v6
2323

2424
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
25-
uses: actions/setup-python@v4.6.1
25+
uses: actions/setup-python@v6
2626
with:
2727
python-version: ${{ env.DEFAULT_PYTHON }}
2828
cache: pip
@@ -44,7 +44,7 @@ jobs:
4444
name: HACS
4545
steps:
4646
- name: Check out the repository
47-
uses: "actions/checkout@v3.5.3"
47+
uses: "actions/checkout@v6"
4848

4949
- name: HACS validation
5050
uses: "hacs/action@22.5.0"
@@ -56,7 +56,7 @@ jobs:
5656
name: Hassfest
5757
steps:
5858
- name: Check out the repository
59-
uses: "actions/checkout@v3.5.3"
59+
uses: "actions/checkout@v6"
6060

6161
- name: Hassfest validation
6262
uses: "home-assistant/actions/hassfest@master"

custom_components/foxess_modbus/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import logging
1111
import uuid
1212
from typing import Any
13+
from typing import cast
1314

1415
from homeassistant.components.energy.data import async_get_manager
1516
from homeassistant.config_entries import ConfigEntry
@@ -194,11 +195,11 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
194195
if energy_source["type"] == "solar":
195196
energy_source.setdefault("config_entry_solar_forecast", None)
196197
elif energy_source["type"] == "grid":
197-
for flow_from in energy_source.get("flow_from", []):
198+
for flow_from in cast(list[Any], energy_source.get("flow_from", [])):
198199
flow_from.setdefault("stat_cost", None)
199200
flow_from.setdefault("entity_energy_price", None)
200201
flow_from.setdefault("number_energy_price", None)
201-
for flow_to in energy_source.get("flow_to", []):
202+
for flow_to in cast(list[Any], energy_source.get("flow_to", [])):
202203
flow_to.setdefault("stat_compensation", None)
203204
flow_to.setdefault("entity_energy_price", None)
204205
flow_to.setdefault("number_energy_price", None)

custom_components/foxess_modbus/flow/flow_handler.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from homeassistant.components.energy.data import EnergyPreferencesUpdate
1414
from homeassistant.components.energy.data import FlowFromGridSourceType
1515
from homeassistant.components.energy.data import FlowToGridSourceType
16-
from homeassistant.components.energy.data import GridSourceType
1716
from homeassistant.components.energy.data import SolarSourceType
1817
from homeassistant.config_entries import ConfigFlowResult
1918
from homeassistant.core import callback
@@ -272,7 +271,7 @@ def _prefix_name(name: str | None) -> str:
272271
]
273272
)
274273

275-
grid_source = GridSourceType(type="grid", flow_from=[], flow_to=[], cost_adjustment_day=0.0)
274+
grid_source: dict[str, Any] = {"type": "grid", "flow_from": [], "flow_to": [], "cost_adjustment_day": 0.0}
276275
for entity_id_prefix in entity_id_prefixes:
277276
name_prefix = _prefix_name(entity_id_prefix)
278277
grid_source["flow_from"].append(

requirements.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
homeassistant==2025.8.0
1+
homeassistant==2026.3.2
22

33
# Testing
4-
pytest-homeassistant-custom-component==0.13.269 # Matching version
4+
pytest-homeassistant-custom-component==0.13.318 # Matching version
55
psutil-home-assistant # Not sure why this is needed?
66
fnv_hash_fast # Or this?
77
pytest-asyncio
8-
pycares<5 # pycares 5.0.1 removed ares_query_a_result, incompatible with aiodns 3.5.0
8+
pycares>=5.0.0 # pycares 5.0.1 removed ares_query_a_result, incompatible with aiodns 3.5.0
99

1010
# For pytest. Keep in sync with manifest.json and https://github.com/home-assistant/core/blob/master/requirements_all.txt.
1111
pyserial==3.5
@@ -17,6 +17,6 @@ ruff==0.9.4
1717
mypy==1.15.0
1818

1919
# Typing
20-
homeassistant-stubs==2025.8.0 # Matching HA version
20+
homeassistant-stubs==2026.3.2 # Matching HA version
2121
types-python-slugify==8.0.0.2
2222
voluptuous-stubs==0.1.1

0 commit comments

Comments
 (0)