From e708c85100f1b2342a2d3b0c60e70d8aa5abde42 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Oct 2026 18:12:34 -0500 Subject: [PATCH] [uart] Skip the parity setter when it matches the default (#20069) --- esphome/components/uart/__init__.py | 4 +++- esphome/components/uart/uart_component.h | 2 +- .../uart/config/parity_default.yaml | 12 ++++++++++ .../uart/config/parity_even.yaml | 13 ++++++++++ tests/component_tests/uart/test_parity.py | 24 +++++++++++++++++++ 5 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 tests/component_tests/uart/config/parity_default.yaml create mode 100644 tests/component_tests/uart/config/parity_even.yaml create mode 100644 tests/component_tests/uart/test_parity.py diff --git a/esphome/components/uart/__init__.py b/esphome/components/uart/__init__.py index 598e3df168..24a854ec39 100644 --- a/esphome/components/uart/__init__.py +++ b/esphome/components/uart/__init__.py @@ -402,7 +402,9 @@ async def to_code(config): cg.add(var.set_clock_source(UART_CLOCK_SOURCES[clock_source])) cg.add(var.set_stop_bits(config[CONF_STOP_BITS])) cg.add(var.set_data_bits(config[CONF_DATA_BITS])) - cg.add(var.set_parity(config[CONF_PARITY])) + # Skip the setter when the config matches the C++ initializer (UART_CONFIG_PARITY_NONE). + if (parity := config[CONF_PARITY]) != "NONE": + cg.add(var.set_parity(parity)) if CONF_DEBUG in config: await debug_to_code(config[CONF_DEBUG], var) diff --git a/esphome/components/uart/uart_component.h b/esphome/components/uart/uart_component.h index 4269ef0b16..8f143b7977 100644 --- a/esphome/components/uart/uart_component.h +++ b/esphome/components/uart/uart_component.h @@ -217,7 +217,7 @@ class UARTComponent { uint32_t baud_rate_{0}; uint8_t stop_bits_{0}; uint8_t data_bits_{0}; - UARTParityOptions parity_{UART_CONFIG_PARITY_NONE}; + UARTParityOptions parity_{UART_CONFIG_PARITY_NONE}; // Must match the parity check in __init__.py #ifdef USE_UART_DEBUGGER CallbackManager debug_callback_{}; #endif diff --git a/tests/component_tests/uart/config/parity_default.yaml b/tests/component_tests/uart/config/parity_default.yaml new file mode 100644 index 0000000000..0f073aaac8 --- /dev/null +++ b/tests/component_tests/uart/config/parity_default.yaml @@ -0,0 +1,12 @@ +--- +esphome: + name: test + +esp32: + board: esp32dev + +uart: + - id: default_uart + tx_pin: GPIO17 + rx_pin: GPIO16 + baud_rate: 9600 diff --git a/tests/component_tests/uart/config/parity_even.yaml b/tests/component_tests/uart/config/parity_even.yaml new file mode 100644 index 0000000000..1ae742d57a --- /dev/null +++ b/tests/component_tests/uart/config/parity_even.yaml @@ -0,0 +1,13 @@ +--- +esphome: + name: test + +esp32: + board: esp32dev + +uart: + - id: even_uart + tx_pin: GPIO17 + rx_pin: GPIO16 + baud_rate: 9600 + parity: EVEN diff --git a/tests/component_tests/uart/test_parity.py b/tests/component_tests/uart/test_parity.py new file mode 100644 index 0000000000..c18869a8c4 --- /dev/null +++ b/tests/component_tests/uart/test_parity.py @@ -0,0 +1,24 @@ +"""Tests for UART parity code generation.""" + +from collections.abc import Callable +from pathlib import Path + + +def test_default_parity_is_not_emitted( + generate_main: Callable[[str | Path], str], + component_config_path: Callable[[str], Path], +) -> None: + """Parity NONE is the C++ initializer, so the setter is skipped.""" + main_cpp = generate_main(component_config_path("parity_default.yaml")) + + assert "default_uart->set_parity(" not in main_cpp + + +def test_custom_parity_is_emitted( + generate_main: Callable[[str | Path], str], + component_config_path: Callable[[str], Path], +) -> None: + """A non default parity still reaches the setter.""" + main_cpp = generate_main(component_config_path("parity_even.yaml")) + + assert "even_uart->set_parity(uart::UART_CONFIG_PARITY_EVEN);" in main_cpp