[config] Use `cv.UNDEFINED instead of adhoc _UNDEF` objects (#8725)

This commit is contained in:
Jesse Hills 2025-05-09 20:18:52 +12:00 committed by GitHub
parent e1732c4945
commit 8399d894c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 82 additions and 102 deletions

View File

@ -37,16 +37,13 @@ AUDIO_COMPONENT_SCHEMA = cv.Schema(
) )
_UNDEF = object()
def set_stream_limits( def set_stream_limits(
min_bits_per_sample: int = _UNDEF, min_bits_per_sample: int = cv.UNDEFINED,
max_bits_per_sample: int = _UNDEF, max_bits_per_sample: int = cv.UNDEFINED,
min_channels: int = _UNDEF, min_channels: int = cv.UNDEFINED,
max_channels: int = _UNDEF, max_channels: int = cv.UNDEFINED,
min_sample_rate: int = _UNDEF, min_sample_rate: int = cv.UNDEFINED,
max_sample_rate: int = _UNDEF, max_sample_rate: int = cv.UNDEFINED,
): ):
"""Sets the limits for the audio stream that audio component can handle """Sets the limits for the audio stream that audio component can handle
@ -55,17 +52,17 @@ def set_stream_limits(
""" """
def set_limits_in_config(config): def set_limits_in_config(config):
if min_bits_per_sample is not _UNDEF: if min_bits_per_sample is not cv.UNDEFINED:
config[CONF_MIN_BITS_PER_SAMPLE] = min_bits_per_sample config[CONF_MIN_BITS_PER_SAMPLE] = min_bits_per_sample
if max_bits_per_sample is not _UNDEF: if max_bits_per_sample is not cv.UNDEFINED:
config[CONF_MAX_BITS_PER_SAMPLE] = max_bits_per_sample config[CONF_MAX_BITS_PER_SAMPLE] = max_bits_per_sample
if min_channels is not _UNDEF: if min_channels is not cv.UNDEFINED:
config[CONF_MIN_CHANNELS] = min_channels config[CONF_MIN_CHANNELS] = min_channels
if max_channels is not _UNDEF: if max_channels is not cv.UNDEFINED:
config[CONF_MAX_CHANNELS] = max_channels config[CONF_MAX_CHANNELS] = max_channels
if min_sample_rate is not _UNDEF: if min_sample_rate is not cv.UNDEFINED:
config[CONF_MIN_SAMPLE_RATE] = min_sample_rate config[CONF_MIN_SAMPLE_RATE] = min_sample_rate
if max_sample_rate is not _UNDEF: if max_sample_rate is not cv.UNDEFINED:
config[CONF_MAX_SAMPLE_RATE] = max_sample_rate config[CONF_MAX_SAMPLE_RATE] = max_sample_rate
return set_limits_in_config return set_limits_in_config
@ -75,10 +72,10 @@ def final_validate_audio_schema(
name: str, name: str,
*, *,
audio_device: str, audio_device: str,
bits_per_sample: int = _UNDEF, bits_per_sample: int = cv.UNDEFINED,
channels: int = _UNDEF, channels: int = cv.UNDEFINED,
sample_rate: int = _UNDEF, sample_rate: int = cv.UNDEFINED,
enabled_channels: list[int] = _UNDEF, enabled_channels: list[int] = cv.UNDEFINED,
audio_device_issue: bool = False, audio_device_issue: bool = False,
): ):
"""Validates audio compatibility when passed between different components. """Validates audio compatibility when passed between different components.
@ -101,7 +98,7 @@ def final_validate_audio_schema(
def validate_audio_compatiblity(audio_config): def validate_audio_compatiblity(audio_config):
audio_schema = {} audio_schema = {}
if bits_per_sample is not _UNDEF: if bits_per_sample is not cv.UNDEFINED:
try: try:
cv.int_range( cv.int_range(
min=audio_config.get(CONF_MIN_BITS_PER_SAMPLE), min=audio_config.get(CONF_MIN_BITS_PER_SAMPLE),
@ -114,7 +111,7 @@ def final_validate_audio_schema(
error_string = f"Invalid configuration for the {name} component. The {CONF_BITS_PER_SAMPLE} {str(exc)}" error_string = f"Invalid configuration for the {name} component. The {CONF_BITS_PER_SAMPLE} {str(exc)}"
raise cv.Invalid(error_string) from exc raise cv.Invalid(error_string) from exc
if channels is not _UNDEF: if channels is not cv.UNDEFINED:
try: try:
cv.int_range( cv.int_range(
min=audio_config.get(CONF_MIN_CHANNELS), min=audio_config.get(CONF_MIN_CHANNELS),
@ -127,7 +124,7 @@ def final_validate_audio_schema(
error_string = f"Invalid configuration for the {name} component. The {CONF_NUM_CHANNELS} {str(exc)}" error_string = f"Invalid configuration for the {name} component. The {CONF_NUM_CHANNELS} {str(exc)}"
raise cv.Invalid(error_string) from exc raise cv.Invalid(error_string) from exc
if sample_rate is not _UNDEF: if sample_rate is not cv.UNDEFINED:
try: try:
cv.int_range( cv.int_range(
min=audio_config.get(CONF_MIN_SAMPLE_RATE), min=audio_config.get(CONF_MIN_SAMPLE_RATE),
@ -140,7 +137,7 @@ def final_validate_audio_schema(
error_string = f"Invalid configuration for the {name} component. The {CONF_SAMPLE_RATE} {str(exc)}" error_string = f"Invalid configuration for the {name} component. The {CONF_SAMPLE_RATE} {str(exc)}"
raise cv.Invalid(error_string) from exc raise cv.Invalid(error_string) from exc
if enabled_channels is not _UNDEF: if enabled_channels is not cv.UNDEFINED:
for channel in enabled_channels: for channel in enabled_channels:
try: try:
# Channels are 0-indexed # Channels are 0-indexed

View File

@ -458,19 +458,17 @@ BINARY_SENSOR_SCHEMA = (
) )
) )
_UNDEF = object()
def binary_sensor_schema( def binary_sensor_schema(
class_: MockObjClass = _UNDEF, class_: MockObjClass = cv.UNDEFINED,
*, *,
icon: str = _UNDEF, icon: str = cv.UNDEFINED,
entity_category: str = _UNDEF, entity_category: str = cv.UNDEFINED,
device_class: str = _UNDEF, device_class: str = cv.UNDEFINED,
) -> cv.Schema: ) -> cv.Schema:
schema = {} schema = {}
if class_ is not _UNDEF: if class_ is not cv.UNDEFINED:
# Not cv.optional # Not cv.optional
schema[cv.GenerateID()] = cv.declare_id(class_) schema[cv.GenerateID()] = cv.declare_id(class_)
@ -479,7 +477,7 @@ def binary_sensor_schema(
(CONF_ENTITY_CATEGORY, entity_category, cv.entity_category), (CONF_ENTITY_CATEGORY, entity_category, cv.entity_category),
(CONF_DEVICE_CLASS, device_class, validate_device_class), (CONF_DEVICE_CLASS, device_class, validate_device_class),
]: ]:
if default is not _UNDEF: if default is not cv.UNDEFINED:
schema[cv.Optional(key, default=default)] = validator schema[cv.Optional(key, default=default)] = validator
return BINARY_SENSOR_SCHEMA.extend(schema) return BINARY_SENSOR_SCHEMA.extend(schema)

View File

@ -60,15 +60,13 @@ BUTTON_SCHEMA = (
) )
) )
_UNDEF = object()
def button_schema( def button_schema(
class_: MockObjClass, class_: MockObjClass,
*, *,
icon: str = _UNDEF, icon: str = cv.UNDEFINED,
entity_category: str = _UNDEF, entity_category: str = cv.UNDEFINED,
device_class: str = _UNDEF, device_class: str = cv.UNDEFINED,
) -> cv.Schema: ) -> cv.Schema:
schema = {cv.GenerateID(): cv.declare_id(class_)} schema = {cv.GenerateID(): cv.declare_id(class_)}
@ -77,7 +75,7 @@ def button_schema(
(CONF_ENTITY_CATEGORY, entity_category, cv.entity_category), (CONF_ENTITY_CATEGORY, entity_category, cv.entity_category),
(CONF_DEVICE_CLASS, device_class, validate_device_class), (CONF_DEVICE_CLASS, device_class, validate_device_class),
]: ]:
if default is not _UNDEF: if default is not cv.UNDEFINED:
schema[cv.Optional(key, default=default)] = validator schema[cv.Optional(key, default=default)] = validator
return BUTTON_SCHEMA.extend(schema) return BUTTON_SCHEMA.extend(schema)

View File

@ -58,19 +58,17 @@ EVENT_SCHEMA = (
) )
) )
_UNDEF = object()
def event_schema( def event_schema(
class_: MockObjClass = _UNDEF, class_: MockObjClass = cv.UNDEFINED,
*, *,
icon: str = _UNDEF, icon: str = cv.UNDEFINED,
entity_category: str = _UNDEF, entity_category: str = cv.UNDEFINED,
device_class: str = _UNDEF, device_class: str = cv.UNDEFINED,
) -> cv.Schema: ) -> cv.Schema:
schema = {} schema = {}
if class_ is not _UNDEF: if class_ is not cv.UNDEFINED:
schema[cv.GenerateID()] = cv.declare_id(class_) schema[cv.GenerateID()] = cv.declare_id(class_)
for key, default, validator in [ for key, default, validator in [
@ -78,7 +76,7 @@ def event_schema(
(CONF_ENTITY_CATEGORY, entity_category, cv.entity_category), (CONF_ENTITY_CATEGORY, entity_category, cv.entity_category),
(CONF_DEVICE_CLASS, device_class, validate_device_class), (CONF_DEVICE_CLASS, device_class, validate_device_class),
]: ]:
if default is not _UNDEF: if default is not cv.UNDEFINED:
schema[cv.Optional(key, default=default)] = validator schema[cv.Optional(key, default=default)] = validator
return EVENT_SCHEMA.extend(schema) return EVENT_SCHEMA.extend(schema)

View File

@ -123,11 +123,8 @@ def microphone_source_schema(
) )
_UNDEF = object()
def final_validate_microphone_source_schema( def final_validate_microphone_source_schema(
component_name: str, sample_rate: int = _UNDEF component_name: str, sample_rate: int = cv.UNDEFINED
): ):
"""Validates that the microphone source can provide audio in the correct format. In particular it validates the sample rate and the enabled channels. """Validates that the microphone source can provide audio in the correct format. In particular it validates the sample rate and the enabled channels.
@ -141,7 +138,7 @@ def final_validate_microphone_source_schema(
""" """
def _validate_audio_compatability(config): def _validate_audio_compatability(config):
if sample_rate is not _UNDEF: if sample_rate is not cv.UNDEFINED:
# Issues require changing the microphone configuration # Issues require changing the microphone configuration
# - Verifies sample rates match # - Verifies sample rates match
audio.final_validate_audio_schema( audio.final_validate_audio_schema(

View File

@ -196,16 +196,14 @@ NUMBER_SCHEMA = (
) )
) )
_UNDEF = object()
def number_schema( def number_schema(
class_: MockObjClass, class_: MockObjClass,
*, *,
icon: str = _UNDEF, icon: str = cv.UNDEFINED,
entity_category: str = _UNDEF, entity_category: str = cv.UNDEFINED,
device_class: str = _UNDEF, device_class: str = cv.UNDEFINED,
unit_of_measurement: str = _UNDEF, unit_of_measurement: str = cv.UNDEFINED,
) -> cv.Schema: ) -> cv.Schema:
schema = {cv.GenerateID(): cv.declare_id(class_)} schema = {cv.GenerateID(): cv.declare_id(class_)}
@ -215,7 +213,7 @@ def number_schema(
(CONF_DEVICE_CLASS, device_class, validate_device_class), (CONF_DEVICE_CLASS, device_class, validate_device_class),
(CONF_UNIT_OF_MEASUREMENT, unit_of_measurement, validate_unit_of_measurement), (CONF_UNIT_OF_MEASUREMENT, unit_of_measurement, validate_unit_of_measurement),
]: ]:
if default is not _UNDEF: if default is not cv.UNDEFINED:
schema[cv.Optional(key, default=default)] = validator schema[cv.Optional(key, default=default)] = validator
return NUMBER_SCHEMA.extend(schema) return NUMBER_SCHEMA.extend(schema)

View File

@ -12,9 +12,9 @@ COMPONENT_TYPE = const.BINARY_SENSOR
def get_entity_validation_schema(entity: schema.BinarySensorSchema) -> cv.Schema: def get_entity_validation_schema(entity: schema.BinarySensorSchema) -> cv.Schema:
return binary_sensor.binary_sensor_schema( return binary_sensor.binary_sensor_schema(
device_class=( device_class=(
entity.device_class or binary_sensor._UNDEF # pylint: disable=protected-access entity.device_class or cv.UNDEFINED # pylint: disable=protected-access
), ),
icon=(entity.icon or binary_sensor._UNDEF), # pylint: disable=protected-access icon=(entity.icon or cv.UNDEFINED), # pylint: disable=protected-access
) )

View File

@ -23,10 +23,10 @@ MSG_DATA_TYPES = {
def get_entity_validation_schema(entity: schema.SensorSchema) -> cv.Schema: def get_entity_validation_schema(entity: schema.SensorSchema) -> cv.Schema:
return sensor.sensor_schema( return sensor.sensor_schema(
unit_of_measurement=entity.unit_of_measurement or sensor._UNDEF, # pylint: disable=protected-access unit_of_measurement=entity.unit_of_measurement or cv.UNDEFINED, # pylint: disable=protected-access
accuracy_decimals=entity.accuracy_decimals, accuracy_decimals=entity.accuracy_decimals,
device_class=entity.device_class or sensor._UNDEF, # pylint: disable=protected-access device_class=entity.device_class or cv.UNDEFINED, # pylint: disable=protected-access
icon=entity.icon or sensor._UNDEF, # pylint: disable=protected-access icon=entity.icon or cv.UNDEFINED, # pylint: disable=protected-access
state_class=entity.state_class, state_class=entity.state_class,
).extend( ).extend(
{ {

View File

@ -64,19 +64,17 @@ SELECT_SCHEMA = (
) )
) )
_UNDEF = object()
def select_schema( def select_schema(
class_: MockObjClass = _UNDEF, class_: MockObjClass = cv.UNDEFINED,
*, *,
entity_category: str = _UNDEF, entity_category: str = cv.UNDEFINED,
icon: str = _UNDEF, icon: str = cv.UNDEFINED,
): ):
schema = cv.Schema({}) schema = cv.Schema({})
if class_ is not _UNDEF: if class_ is not cv.UNDEFINED:
schema = schema.extend({cv.GenerateID(): cv.declare_id(class_)}) schema = schema.extend({cv.GenerateID(): cv.declare_id(class_)})
if entity_category is not _UNDEF: if entity_category is not cv.UNDEFINED:
schema = schema.extend( schema = schema.extend(
{ {
cv.Optional( cv.Optional(
@ -84,7 +82,7 @@ def select_schema(
): cv.entity_category ): cv.entity_category
} }
) )
if icon is not _UNDEF: if icon is not cv.UNDEFINED:
schema = schema.extend({cv.Optional(CONF_ICON, default=icon): cv.icon}) schema = schema.extend({cv.Optional(CONF_ICON, default=icon): cv.icon})
return SELECT_SCHEMA.extend(schema) return SELECT_SCHEMA.extend(schema)

View File

@ -309,22 +309,20 @@ SENSOR_SCHEMA = (
) )
) )
_UNDEF = object()
def sensor_schema( def sensor_schema(
class_: MockObjClass = _UNDEF, class_: MockObjClass = cv.UNDEFINED,
*, *,
unit_of_measurement: str = _UNDEF, unit_of_measurement: str = cv.UNDEFINED,
icon: str = _UNDEF, icon: str = cv.UNDEFINED,
accuracy_decimals: int = _UNDEF, accuracy_decimals: int = cv.UNDEFINED,
device_class: str = _UNDEF, device_class: str = cv.UNDEFINED,
state_class: str = _UNDEF, state_class: str = cv.UNDEFINED,
entity_category: str = _UNDEF, entity_category: str = cv.UNDEFINED,
) -> cv.Schema: ) -> cv.Schema:
schema = {} schema = {}
if class_ is not _UNDEF: if class_ is not cv.UNDEFINED:
# Not optional. # Not optional.
schema[cv.GenerateID()] = cv.declare_id(class_) schema[cv.GenerateID()] = cv.declare_id(class_)
@ -336,7 +334,7 @@ def sensor_schema(
(CONF_STATE_CLASS, state_class, validate_state_class), (CONF_STATE_CLASS, state_class, validate_state_class),
(CONF_ENTITY_CATEGORY, entity_category, sensor_entity_category), (CONF_ENTITY_CATEGORY, entity_category, sensor_entity_category),
]: ]:
if default is not _UNDEF: if default is not cv.UNDEFINED:
schema[cv.Optional(key, default=default)] = validator schema[cv.Optional(key, default=default)] = validator
return SENSOR_SCHEMA.extend(schema) return SENSOR_SCHEMA.extend(schema)
@ -811,7 +809,9 @@ async def setup_sensor_core_(var, config):
mqtt_ = cg.new_Pvariable(mqtt_id, var) mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config) await mqtt.register_mqtt_component(mqtt_, config)
if (expire_after := config.get(CONF_EXPIRE_AFTER, _UNDEF)) is not _UNDEF: if (
expire_after := config.get(CONF_EXPIRE_AFTER, cv.UNDEFINED)
) is not cv.UNDEFINED:
if expire_after is None: if expire_after is None:
cg.add(mqtt_.disable_expire_after()) cg.add(mqtt_.disable_expire_after())
else: else:

View File

@ -87,15 +87,13 @@ _SWITCH_SCHEMA = (
) )
) )
_UNDEF = object()
def switch_schema( def switch_schema(
class_: MockObjClass = _UNDEF, class_: MockObjClass = cv.UNDEFINED,
*, *,
entity_category: str = _UNDEF, entity_category: str = cv.UNDEFINED,
device_class: str = _UNDEF, device_class: str = cv.UNDEFINED,
icon: str = _UNDEF, icon: str = cv.UNDEFINED,
block_inverted: bool = False, block_inverted: bool = False,
default_restore_mode: str = "ALWAYS_OFF", default_restore_mode: str = "ALWAYS_OFF",
): ):
@ -106,9 +104,9 @@ def switch_schema(
), ),
} }
) )
if class_ is not _UNDEF: if class_ is not cv.UNDEFINED:
schema = schema.extend({cv.GenerateID(): cv.declare_id(class_)}) schema = schema.extend({cv.GenerateID(): cv.declare_id(class_)})
if entity_category is not _UNDEF: if entity_category is not cv.UNDEFINED:
schema = schema.extend( schema = schema.extend(
{ {
cv.Optional( cv.Optional(
@ -116,7 +114,7 @@ def switch_schema(
): cv.entity_category ): cv.entity_category
} }
) )
if device_class is not _UNDEF: if device_class is not cv.UNDEFINED:
schema = schema.extend( schema = schema.extend(
{ {
cv.Optional( cv.Optional(
@ -124,7 +122,7 @@ def switch_schema(
): validate_device_class ): validate_device_class
} }
) )
if icon is not _UNDEF: if icon is not cv.UNDEFINED:
schema = schema.extend({cv.Optional(CONF_ICON, default=icon): cv.icon}) schema = schema.extend({cv.Optional(CONF_ICON, default=icon): cv.icon})
if block_inverted: if block_inverted:
schema = schema.extend( schema = schema.extend(

View File

@ -152,22 +152,20 @@ TEXT_SENSOR_SCHEMA = (
) )
) )
_UNDEF = object()
def text_sensor_schema( def text_sensor_schema(
class_: MockObjClass = _UNDEF, class_: MockObjClass = cv.UNDEFINED,
*, *,
icon: str = _UNDEF, icon: str = cv.UNDEFINED,
entity_category: str = _UNDEF, entity_category: str = cv.UNDEFINED,
device_class: str = _UNDEF, device_class: str = cv.UNDEFINED,
) -> cv.Schema: ) -> cv.Schema:
schema = TEXT_SENSOR_SCHEMA schema = TEXT_SENSOR_SCHEMA
if class_ is not _UNDEF: if class_ is not cv.UNDEFINED:
schema = schema.extend({cv.GenerateID(): cv.declare_id(class_)}) schema = schema.extend({cv.GenerateID(): cv.declare_id(class_)})
if icon is not _UNDEF: if icon is not cv.UNDEFINED:
schema = schema.extend({cv.Optional(CONF_ICON, default=icon): cv.icon}) schema = schema.extend({cv.Optional(CONF_ICON, default=icon): cv.icon})
if device_class is not _UNDEF: if device_class is not cv.UNDEFINED:
schema = schema.extend( schema = schema.extend(
{ {
cv.Optional( cv.Optional(
@ -175,7 +173,7 @@ def text_sensor_schema(
): validate_device_class ): validate_device_class
} }
) )
if entity_category is not _UNDEF: if entity_category is not cv.UNDEFINED:
schema = schema.extend( schema = schema.extend(
{ {
cv.Optional( cv.Optional(