1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-22 13:12:22 +01:00

[substitutions] implement !literal (#10785)

This commit is contained in:
Javier Peletier
2025-09-22 06:32:59 +02:00
committed by GitHub
parent 68eb4091b8
commit 7629903afb
5 changed files with 30 additions and 9 deletions

View File

@@ -4,7 +4,7 @@ from esphome import core
from esphome.config_helpers import Extend, Remove, merge_config
import esphome.config_validation as cv
from esphome.const import CONF_SUBSTITUTIONS, VALID_SUBSTITUTIONS_CHARACTERS
from esphome.yaml_util import ESPHomeDataBase, make_data_base
from esphome.yaml_util import ESPHomeDataBase, ESPLiteralValue, make_data_base
from .jinja import Jinja, JinjaStr, TemplateError, TemplateRuntimeError, has_jinja
@@ -127,6 +127,8 @@ def _expand_substitutions(substitutions, value, path, jinja, ignore_missing):
def _substitute_item(substitutions, item, path, jinja, ignore_missing):
if isinstance(item, ESPLiteralValue):
return None # do not substitute inside literal blocks
if isinstance(item, list):
for i, it in enumerate(item):
sub = _substitute_item(substitutions, it, path + [i], jinja, ignore_missing)

View File

@@ -32,7 +32,7 @@ from esphome.log import AnsiFore, color
from esphome.types import ConfigFragmentType, ConfigType
from esphome.util import OrderedDict, safe_print
from esphome.voluptuous_schema import ExtraKeysInvalid
from esphome.yaml_util import ESPForceValue, ESPHomeDataBase, is_secret
from esphome.yaml_util import ESPHomeDataBase, ESPLiteralValue, is_secret
_LOGGER = logging.getLogger(__name__)
@@ -306,7 +306,7 @@ def recursive_check_replaceme(value):
return cv.Schema([recursive_check_replaceme])(value)
if isinstance(value, dict):
return cv.Schema({cv.valid: recursive_check_replaceme})(value)
if isinstance(value, ESPForceValue):
if isinstance(value, ESPLiteralValue):
pass
if isinstance(value, str) and value == "REPLACEME":
raise cv.Invalid(
@@ -314,7 +314,7 @@ def recursive_check_replaceme(value):
"Please make sure you have replaced all fields from the sample "
"configuration.\n"
"If you want to use the literal REPLACEME string, "
'please use "!force REPLACEME"'
'please use "!literal REPLACEME"'
)
return value

View File

@@ -69,7 +69,7 @@ class ESPHomeDataBase:
self._content_offset = database.content_offset
class ESPForceValue:
class ESPLiteralValue:
pass
@@ -348,9 +348,15 @@ class ESPHomeLoaderMixin:
return Lambda(str(node.value))
@_add_data_ref
def construct_force(self, node: yaml.Node) -> ESPForceValue:
obj = self.construct_scalar(node)
return add_class_to_obj(obj, ESPForceValue)
def construct_literal(self, node: yaml.Node) -> ESPLiteralValue:
obj = None
if isinstance(node, yaml.ScalarNode):
obj = self.construct_scalar(node)
elif isinstance(node, yaml.SequenceNode):
obj = self.construct_sequence(node)
elif isinstance(node, yaml.MappingNode):
obj = self.construct_mapping(node)
return add_class_to_obj(obj, ESPLiteralValue)
@_add_data_ref
def construct_extend(self, node: yaml.Node) -> Extend:
@@ -407,7 +413,7 @@ for _loader in (ESPHomeLoader, ESPHomePurePythonLoader):
"!include_dir_merge_named", _loader.construct_include_dir_merge_named
)
_loader.add_constructor("!lambda", _loader.construct_lambda)
_loader.add_constructor("!force", _loader.construct_force)
_loader.add_constructor("!literal", _loader.construct_literal)
_loader.add_constructor("!extend", _loader.construct_extend)
_loader.add_constructor("!remove", _loader.construct_remove)

View File

@@ -1,7 +1,11 @@
substitutions:
substituted: 99
var1: '1'
var2: '2'
var21: '79'
value: 33
values: 44
esphome:
name: test
test_list:
@@ -19,3 +23,6 @@ test_list:
- ${ undefined_var }
- key1: 1
key2: 2
- Literal $values ${are not substituted}
- ["list $value", "${is not}", "${substituted}"]
- {"$dictionary": "$value", "${is not}": "${substituted}"}

View File

@@ -2,9 +2,12 @@ esphome:
name: test
substitutions:
substituted: 99
var1: "1"
var2: "2"
var21: "79"
value: 33
values: 44
test_list:
- "$var1"
@@ -21,3 +24,6 @@ test_list:
- ${ undefined_var }
- key${var1}: 1
key${var2}: 2
- !literal Literal $values ${are not substituted}
- !literal ["list $value", "${is not}", "${substituted}"]
- !literal {"$dictionary": "$value", "${is not}": "${substituted}"}