From e09ec4a6f3e0321431451f5cd1f2c0ebec898be1 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Mon, 3 Nov 2025 12:07:38 -0600 Subject: [PATCH] Use character code in language matching (voice) (#155738) --- homeassistant/util/language.py | 24 +++++++++++++++++------- tests/util/test_language.py | 3 +++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/homeassistant/util/language.py b/homeassistant/util/language.py index 8a82de9065f..b56c20a9803 100644 --- a/homeassistant/util/language.py +++ b/homeassistant/util/language.py @@ -104,20 +104,30 @@ class Dialect: return (-1, 0) is_exact_language = self.language == dialect.language + is_exact_language_and_code = is_exact_language and (self.code == dialect.code) if (self.region is None) and (dialect.region is None): # Weak match with no region constraint # Prefer exact language match - return (2 if is_exact_language else 1, 0) + if is_exact_language_and_code: + return (3, 0) + + if is_exact_language: + return (2, 0) + + return (1, 0) if (self.region is not None) and (dialect.region is not None): if self.region == dialect.region: # Same language + region match # Prefer exact language match - return ( - math.inf, - 1 if is_exact_language else 0, - ) + if is_exact_language_and_code: + return (math.inf, 2) + + if is_exact_language: + return (math.inf, 1) + + return (math.inf, 0) # Regions are both set, but don't match return (0, 0) @@ -139,8 +149,8 @@ class Dialect: region_idx = pref_regions.index(dialect.region) # More preferred regions are at the front. - # Add 1 to boost above a weak match where no regions are set. - return (1 + (len(pref_regions) - region_idx), 0) + # Add 2 to boost above a weak match where no regions are set. + return (2 + (len(pref_regions) - region_idx), 0) except ValueError: # Region was not in preferred list pass diff --git a/tests/util/test_language.py b/tests/util/test_language.py index a1d0cdf1a53..89b3c2256ab 100644 --- a/tests/util/test_language.py +++ b/tests/util/test_language.py @@ -192,6 +192,9 @@ def test_sr_latn() -> None: "sr-RS", ] + # Prefer exact match with code + assert language.matches("sr", ["sr-Latn", "sr"]) == ["sr", "sr-Latn"] + def test_no_nb_same() -> None: """Test that the no/nb are interchangeable."""