From cdb7b9cc25d10eb67bcc6fcd8023cc0b80abc8a3 Mon Sep 17 00:00:00 2001 From: Rene Nulsch <33263735+ReneNulschDE@users.noreply.github.com> Date: Tue, 23 Dec 2025 21:25:19 +0100 Subject: [PATCH] Fix ZeroDivisionError for inverse unit conversions (#159161) --- homeassistant/util/unit_conversion.py | 6 +++- tests/util/test_unit_conversion.py | 52 +++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/homeassistant/util/unit_conversion.py b/homeassistant/util/unit_conversion.py index b25895c3e8f..4593b0bd88c 100644 --- a/homeassistant/util/unit_conversion.py +++ b/homeassistant/util/unit_conversion.py @@ -154,7 +154,11 @@ class BaseUnitConverter: return lambda value: value from_ratio, to_ratio = cls._get_from_to_ratio(from_unit, to_unit) if cls._are_unit_inverses(from_unit, to_unit): - return lambda val: None if val is None else to_ratio / (val / from_ratio) + return ( + lambda val: None + if val is None or val == 0 + else to_ratio / (val / from_ratio) + ) return lambda val: None if val is None else (val / from_ratio) * to_ratio @classmethod diff --git a/tests/util/test_unit_conversion.py b/tests/util/test_unit_conversion.py index 345c0bbfd51..95d970d14d7 100644 --- a/tests/util/test_unit_conversion.py +++ b/tests/util/test_unit_conversion.py @@ -1258,6 +1258,58 @@ def test_unit_conversion_factory_allow_none_with_none() -> None: )(None) is None ) + assert ( + EnergyDistanceConverter.converter_factory_allow_none( + UnitOfEnergyDistance.MILES_PER_KILO_WATT_HOUR, + UnitOfEnergyDistance.KILO_WATT_HOUR_PER_100_KM, + )(0) + is None + ) + assert ( + EnergyDistanceConverter.converter_factory_allow_none( + UnitOfEnergyDistance.KILO_WATT_HOUR_PER_100_KM, + UnitOfEnergyDistance.WATT_HOUR_PER_KM, + )(0) + == 0 + ) + assert ( + EnergyDistanceConverter.converter_factory_allow_none( + UnitOfEnergyDistance.KM_PER_KILO_WATT_HOUR, + UnitOfEnergyDistance.MILES_PER_KILO_WATT_HOUR, + )(0.0) + == 0.0 + ) + assert ( + EnergyDistanceConverter.converter_factory_allow_none( + UnitOfEnergyDistance.MILES_PER_KILO_WATT_HOUR, + UnitOfEnergyDistance.KM_PER_KILO_WATT_HOUR, + )(0) + == 0.0 + ) + + +def test_unit_conversion_factory_allow_none_with_zero_for_inverse_units() -> None: + """Test converter_factory_allow_none returns None for zero with inverse units.""" + # Test EnergyDistanceConverter with inverse units (kWh/100km <-> km/kWh) + assert ( + EnergyDistanceConverter.converter_factory_allow_none( + UnitOfEnergyDistance.KILO_WATT_HOUR_PER_100_KM, + UnitOfEnergyDistance.KM_PER_KILO_WATT_HOUR, + )(0) + is None + ) + assert ( + EnergyDistanceConverter.converter_factory_allow_none( + UnitOfEnergyDistance.KM_PER_KILO_WATT_HOUR, + UnitOfEnergyDistance.KILO_WATT_HOUR_PER_100_KM, + )(0) + is None + ) + # Test with non-zero value to ensure normal conversion still works + assert EnergyDistanceConverter.converter_factory_allow_none( + UnitOfEnergyDistance.KILO_WATT_HOUR_PER_100_KM, + UnitOfEnergyDistance.KM_PER_KILO_WATT_HOUR, + )(25) == pytest.approx(4) @pytest.mark.parametrize(