mirror of
https://github.com/esphome/esphome.git
synced 2024-12-25 23:14:54 +01:00
Check lambdas for return statement (#539)
This commit is contained in:
parent
9dd9e523ed
commit
953d7f6193
15 changed files with 30 additions and 16 deletions
|
@ -87,7 +87,7 @@ HOMEASSISTANT_SERVICE_ACTION_SCHEMA = cv.Schema({
|
|||
cv.string: cv.string,
|
||||
}),
|
||||
cv.Optional(CONF_VARIABLES): cv.Schema({
|
||||
cv.string: cv.lambda_,
|
||||
cv.string: cv.returning_lambda,
|
||||
}),
|
||||
})
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ def delayed_off_filter_to_code(config, filter_id):
|
|||
yield var
|
||||
|
||||
|
||||
@FILTER_REGISTRY.register('lambda', LambdaFilter, cv.lambda_)
|
||||
@FILTER_REGISTRY.register('lambda', LambdaFilter, cv.returning_lambda)
|
||||
def lambda_filter_to_code(config, filter_id):
|
||||
lambda_ = yield cg.process_lambda(config, [(bool, 'x')], return_type=cg.optional.template(bool))
|
||||
yield cg.new_Pvariable(filter_id, lambda_)
|
||||
|
|
|
@ -8,7 +8,7 @@ CustomBinarySensorConstructor = custom_ns.class_('CustomBinarySensorConstructor'
|
|||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomBinarySensorConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.lambda_,
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_BINARY_SENSORS): cv.ensure_list(binary_sensor.BINARY_SENSOR_SCHEMA),
|
||||
})
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ CustomFloatOutputConstructor = custom_ns.class_('CustomFloatOutputConstructor')
|
|||
|
||||
BINARY_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomBinaryOutputConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.lambda_,
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_TYPE): 'binary',
|
||||
cv.Required(CONF_OUTPUTS):
|
||||
cv.ensure_list(output.BINARY_OUTPUT_SCHEMA.extend({
|
||||
|
@ -19,7 +19,7 @@ BINARY_SCHEMA = cv.Schema({
|
|||
|
||||
FLOAT_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomFloatOutputConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.lambda_,
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_TYPE): 'float',
|
||||
cv.Required(CONF_OUTPUTS):
|
||||
cv.ensure_list(output.FLOAT_OUTPUT_SCHEMA.extend({
|
||||
|
|
|
@ -8,7 +8,7 @@ CustomSensorConstructor = custom_ns.class_('CustomSensorConstructor')
|
|||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomSensorConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.lambda_,
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_SENSORS): cv.ensure_list(sensor.SENSOR_SCHEMA),
|
||||
})
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ CustomSwitchConstructor = custom_ns.class_('CustomSwitchConstructor')
|
|||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomSwitchConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.lambda_,
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_SWITCHES):
|
||||
cv.ensure_list(switch.SWITCH_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(switch.Switch),
|
||||
|
|
|
@ -8,7 +8,7 @@ CustomTextSensorConstructor = custom_ns.class_('CustomTextSensorConstructor')
|
|||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomTextSensorConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.lambda_,
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_TEXT_SENSORS):
|
||||
cv.ensure_list(text_sensor.TEXT_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(text_sensor.TextSensor),
|
||||
|
|
|
@ -8,7 +8,7 @@ CustomComponentConstructor = custom_component_ns.class_('CustomComponentConstruc
|
|||
MULTI_CONF = True
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomComponentConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.lambda_,
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Optional(CONF_COMPONENTS): cv.ensure_list(cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(cg.Component)
|
||||
}).extend(cv.COMPONENT_SCHEMA)),
|
||||
|
|
|
@ -148,7 +148,7 @@ def exponential_moving_average_filter_to_code(config, filter_id):
|
|||
yield cg.new_Pvariable(filter_id, config[CONF_ALPHA], config[CONF_SEND_EVERY])
|
||||
|
||||
|
||||
@FILTER_REGISTRY.register('lambda', LambdaFilter, cv.lambda_)
|
||||
@FILTER_REGISTRY.register('lambda', LambdaFilter, cv.returning_lambda)
|
||||
def lambda_filter_to_code(config, filter_id):
|
||||
lambda_ = yield cg.process_lambda(config, [(float, 'x')],
|
||||
return_type=cg.optional.template(float))
|
||||
|
|
|
@ -10,7 +10,7 @@ TemplateBinarySensor = template_ns.class_('TemplateBinarySensor', binary_sensor.
|
|||
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(TemplateBinarySensor),
|
||||
cv.Optional(CONF_LAMBDA): cv.lambda_,
|
||||
cv.Optional(CONF_LAMBDA): cv.returning_lambda,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ RESTORE_MODES = {
|
|||
|
||||
CONFIG_SCHEMA = cover.COVER_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(TemplateCover),
|
||||
cv.Optional(CONF_LAMBDA): cv.lambda_,
|
||||
cv.Optional(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Optional(CONF_OPTIMISTIC, default=False): cv.boolean,
|
||||
cv.Optional(CONF_ASSUMED_STATE, default=False): cv.boolean,
|
||||
cv.Optional(CONF_OPEN_ACTION): automation.validate_automation(single=True),
|
||||
|
|
|
@ -9,7 +9,7 @@ TemplateSensor = template_ns.class_('TemplateSensor', sensor.Sensor, cg.PollingC
|
|||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_EMPTY, ICON_EMPTY, 1).extend({
|
||||
cv.GenerateID(): cv.declare_id(TemplateSensor),
|
||||
cv.Optional(CONF_LAMBDA): cv.lambda_,
|
||||
cv.Optional(CONF_LAMBDA): cv.returning_lambda,
|
||||
}).extend(cv.polling_component_schema('60s'))
|
||||
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ TemplateSwitch = template_ns.class_('TemplateSwitch', switch.Switch, cg.Componen
|
|||
|
||||
CONFIG_SCHEMA = switch.SWITCH_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(TemplateSwitch),
|
||||
cv.Optional(CONF_LAMBDA): cv.lambda_,
|
||||
cv.Optional(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Optional(CONF_OPTIMISTIC, default=False): cv.boolean,
|
||||
cv.Optional(CONF_ASSUMED_STATE, default=False): cv.boolean,
|
||||
cv.Optional(CONF_TURN_OFF_ACTION): automation.validate_automation(single=True),
|
||||
|
|
|
@ -11,7 +11,7 @@ TemplateTextSensor = template_ns.class_('TemplateTextSensor', text_sensor.TextSe
|
|||
|
||||
CONFIG_SCHEMA = text_sensor.TEXT_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(TemplateTextSensor),
|
||||
cv.Optional(CONF_LAMBDA): cv.lambda_,
|
||||
cv.Optional(CONF_LAMBDA): cv.returning_lambda,
|
||||
}).extend(cv.polling_component_schema('60s'))
|
||||
|
||||
|
||||
|
|
|
@ -333,7 +333,7 @@ def templatable(other_validators):
|
|||
|
||||
def validator(value):
|
||||
if isinstance(value, Lambda):
|
||||
return lambda_(value)
|
||||
return returning_lambda(value)
|
||||
if isinstance(other_validators, dict):
|
||||
return schema(value)
|
||||
return schema(value)
|
||||
|
@ -974,6 +974,20 @@ def lambda_(value):
|
|||
return value
|
||||
|
||||
|
||||
def returning_lambda(value):
|
||||
"""Coerce this configuration option to a lambda.
|
||||
|
||||
Additionally, make sure the lambda returns something.
|
||||
"""
|
||||
value = lambda_(value)
|
||||
if u'return' not in value.value:
|
||||
raise Invalid("Lambda doesn't contain a 'return' statement, but the lambda "
|
||||
"is expected to return a value. \n"
|
||||
"Please make sure the lambda contains at least one "
|
||||
"return statement.")
|
||||
return value
|
||||
|
||||
|
||||
def dimensions(value):
|
||||
if isinstance(value, list):
|
||||
if len(value) != 2:
|
||||
|
|
Loading…
Reference in a new issue