mirror of
https://github.com/esphome/esphome.git
synced 2025-09-22 21:22:22 +01:00
[substitutions] implement !literal (#10785)
This commit is contained in:
@@ -4,7 +4,7 @@ from esphome import core
|
|||||||
from esphome.config_helpers import Extend, Remove, merge_config
|
from esphome.config_helpers import Extend, Remove, merge_config
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_SUBSTITUTIONS, VALID_SUBSTITUTIONS_CHARACTERS
|
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
|
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):
|
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):
|
if isinstance(item, list):
|
||||||
for i, it in enumerate(item):
|
for i, it in enumerate(item):
|
||||||
sub = _substitute_item(substitutions, it, path + [i], jinja, ignore_missing)
|
sub = _substitute_item(substitutions, it, path + [i], jinja, ignore_missing)
|
||||||
|
@@ -32,7 +32,7 @@ from esphome.log import AnsiFore, color
|
|||||||
from esphome.types import ConfigFragmentType, ConfigType
|
from esphome.types import ConfigFragmentType, ConfigType
|
||||||
from esphome.util import OrderedDict, safe_print
|
from esphome.util import OrderedDict, safe_print
|
||||||
from esphome.voluptuous_schema import ExtraKeysInvalid
|
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__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -306,7 +306,7 @@ def recursive_check_replaceme(value):
|
|||||||
return cv.Schema([recursive_check_replaceme])(value)
|
return cv.Schema([recursive_check_replaceme])(value)
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
return cv.Schema({cv.valid: recursive_check_replaceme})(value)
|
return cv.Schema({cv.valid: recursive_check_replaceme})(value)
|
||||||
if isinstance(value, ESPForceValue):
|
if isinstance(value, ESPLiteralValue):
|
||||||
pass
|
pass
|
||||||
if isinstance(value, str) and value == "REPLACEME":
|
if isinstance(value, str) and value == "REPLACEME":
|
||||||
raise cv.Invalid(
|
raise cv.Invalid(
|
||||||
@@ -314,7 +314,7 @@ def recursive_check_replaceme(value):
|
|||||||
"Please make sure you have replaced all fields from the sample "
|
"Please make sure you have replaced all fields from the sample "
|
||||||
"configuration.\n"
|
"configuration.\n"
|
||||||
"If you want to use the literal REPLACEME string, "
|
"If you want to use the literal REPLACEME string, "
|
||||||
'please use "!force REPLACEME"'
|
'please use "!literal REPLACEME"'
|
||||||
)
|
)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
@@ -69,7 +69,7 @@ class ESPHomeDataBase:
|
|||||||
self._content_offset = database.content_offset
|
self._content_offset = database.content_offset
|
||||||
|
|
||||||
|
|
||||||
class ESPForceValue:
|
class ESPLiteralValue:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@@ -348,9 +348,15 @@ class ESPHomeLoaderMixin:
|
|||||||
return Lambda(str(node.value))
|
return Lambda(str(node.value))
|
||||||
|
|
||||||
@_add_data_ref
|
@_add_data_ref
|
||||||
def construct_force(self, node: yaml.Node) -> ESPForceValue:
|
def construct_literal(self, node: yaml.Node) -> ESPLiteralValue:
|
||||||
|
obj = None
|
||||||
|
if isinstance(node, yaml.ScalarNode):
|
||||||
obj = self.construct_scalar(node)
|
obj = self.construct_scalar(node)
|
||||||
return add_class_to_obj(obj, ESPForceValue)
|
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
|
@_add_data_ref
|
||||||
def construct_extend(self, node: yaml.Node) -> Extend:
|
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
|
"!include_dir_merge_named", _loader.construct_include_dir_merge_named
|
||||||
)
|
)
|
||||||
_loader.add_constructor("!lambda", _loader.construct_lambda)
|
_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("!extend", _loader.construct_extend)
|
||||||
_loader.add_constructor("!remove", _loader.construct_remove)
|
_loader.add_constructor("!remove", _loader.construct_remove)
|
||||||
|
|
||||||
|
@@ -1,7 +1,11 @@
|
|||||||
substitutions:
|
substitutions:
|
||||||
|
substituted: 99
|
||||||
var1: '1'
|
var1: '1'
|
||||||
var2: '2'
|
var2: '2'
|
||||||
var21: '79'
|
var21: '79'
|
||||||
|
value: 33
|
||||||
|
values: 44
|
||||||
|
|
||||||
esphome:
|
esphome:
|
||||||
name: test
|
name: test
|
||||||
test_list:
|
test_list:
|
||||||
@@ -19,3 +23,6 @@ test_list:
|
|||||||
- ${ undefined_var }
|
- ${ undefined_var }
|
||||||
- key1: 1
|
- key1: 1
|
||||||
key2: 2
|
key2: 2
|
||||||
|
- Literal $values ${are not substituted}
|
||||||
|
- ["list $value", "${is not}", "${substituted}"]
|
||||||
|
- {"$dictionary": "$value", "${is not}": "${substituted}"}
|
||||||
|
@@ -2,9 +2,12 @@ esphome:
|
|||||||
name: test
|
name: test
|
||||||
|
|
||||||
substitutions:
|
substitutions:
|
||||||
|
substituted: 99
|
||||||
var1: "1"
|
var1: "1"
|
||||||
var2: "2"
|
var2: "2"
|
||||||
var21: "79"
|
var21: "79"
|
||||||
|
value: 33
|
||||||
|
values: 44
|
||||||
|
|
||||||
test_list:
|
test_list:
|
||||||
- "$var1"
|
- "$var1"
|
||||||
@@ -21,3 +24,6 @@ test_list:
|
|||||||
- ${ undefined_var }
|
- ${ undefined_var }
|
||||||
- key${var1}: 1
|
- key${var1}: 1
|
||||||
key${var2}: 2
|
key${var2}: 2
|
||||||
|
- !literal Literal $values ${are not substituted}
|
||||||
|
- !literal ["list $value", "${is not}", "${substituted}"]
|
||||||
|
- !literal {"$dictionary": "$value", "${is not}": "${substituted}"}
|
||||||
|
Reference in New Issue
Block a user