Skip to content
Closed
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
5 changes: 4 additions & 1 deletion .github/workflows/quality.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ jobs:
- uses: actions/setup-python@v5
name: Setup Python
with:
python-version: 3.13
# Home Assistant 2026.7+ requires Python >= 3.14.2, and requirements.txt
# installs `homeassistant` unpinned. On 3.13 pip resolves the newest HA
# that still supports 3.13 (2026.2.x), which predates UnitOfRatio.
python-version: "3.14"
- name: Update pip
run: python -m pip install --upgrade pip
- name: Install dependencies
Expand Down
6 changes: 3 additions & 3 deletions custom_components/ac_infinity/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONCENTRATION_PARTS_PER_MILLION,
PERCENTAGE,
Platform,
UnitOfConductivity,
UnitOfPressure,
UnitOfRatio,
UnitOfTemperature,
UnitOfTime,
)
Expand Down Expand Up @@ -375,7 +375,7 @@ def __get_next_mode_change_timestamp(
key=SensorReferenceKey.CO2_SENSOR,
device_class=SensorDeviceClass.CO2,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
native_unit_of_measurement=UnitOfRatio.PARTS_PER_MILLION,
suggested_unit_of_measurement=None,
icon=None, # default
translation_key="co2_sensor",
Expand Down Expand Up @@ -447,7 +447,7 @@ def __get_next_mode_change_timestamp(
key=SensorReferenceKey.HYDRO_TDS,
device_class=None,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
native_unit_of_measurement=UnitOfRatio.PARTS_PER_MILLION,
suggested_unit_of_measurement=None,
icon=MdiIcon.WATER_OPACITY,
translation_key="hydro_tds_sensor",
Expand Down
1 change: 1 addition & 0 deletions hacs.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "AC Infinity",
"homeassistant": "2026.7.0",
"render_readme": true,
"zip_release": true,
"filename": "ac_infinity.zip"
Expand Down
57 changes: 57 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""Shared test fixtures and compatibility shims.

Installs a small aioresponses/aiohttp compatibility shim; see
``_patch_client_response_for_aioresponses`` below.
"""

from __future__ import annotations

import inspect
from typing import Any

from aiohttp.client_reqrep import ClientResponse


class _NullStreamWriter:
"""Stand-in for the stream writer aiohttp>=3.13 reads on construction.

A mocked response is never actually written to the wire, so aiohttp only
reads ``output_size`` off this object (client_reqrep records it when the
request was "already sent").
"""

output_size = 0


def _patch_client_response_for_aioresponses() -> None:
"""Let aioresponses build responses on aiohttp>=3.13.

aiohttp 3.13 added a required keyword-only ``stream_writer`` argument to
``ClientResponse.__init__``. aioresponses (through 0.7.9, current) does
not pass it, so every mocked request in tests/test_client.py dies with::

TypeError: ClientResponse.__init__() missing 1 required
keyword-only argument: 'stream_writer'

Default that kwarg rather than capping the test-time aiohttp: this
integration's runtime dependency is uncapped, so pinning the tests to an
old aiohttp would mean never exercising the version users actually run.

The shim is self-limiting in both directions -- on aiohttp<3.13 the
parameter does not exist and we skip patching entirely, and once
aioresponses passes ``stream_writer`` itself the ``setdefault`` becomes a
no-op. Remove it once aioresponses supports aiohttp>=3.13 natively.
"""
if "stream_writer" not in inspect.signature(ClientResponse.__init__).parameters:
return

original_init = ClientResponse.__init__

def _init(self: ClientResponse, *args: Any, **kwargs: Any) -> None:
kwargs.setdefault("stream_writer", _NullStreamWriter())
original_init(self, *args, **kwargs)

ClientResponse.__init__ = _init # type: ignore[method-assign]


_patch_client_response_for_aioresponses()