From 19f8d9d41b683ea28c2f5bc480d4bc6722cd40d7 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 d1c77a89170..68b27b98cd8 100644 --- a/homeassistant/util/unit_conversion.py +++ b/homeassistant/util/unit_conversion.py @@ -155,7 +155,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 8a3ce093935..7351ef60d3a 100644 --- a/tests/util/test_unit_conversion.py +++ b/tests/util/test_unit_conversion.py @@ -1264,6 +1264,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(