[substitutions] Fix sibling references inside dict-valued substitutions (#16273)

This commit is contained in:
J. Nick Koston
2026-05-06 08:41:17 -05:00
committed by GitHub
parent ff0c5f575e
commit caaa1aefc7
3 changed files with 46 additions and 1 deletions
+12 -1
View File
@@ -278,7 +278,18 @@ def _push_context(
"""Resolve a variable, recursively resolving any dependencies it references."""
value = unresolved_vars.pop(key, Missing)
if value is Missing:
return Missing
# Either already resolved (in resolved_vars) or currently being
# resolved (self-reference from inside a dict-valued substitution).
# Returning what we have lets sibling references inside a dict
# value, e.g. ``${device.manufacturer}`` inside ``device.name``,
# see literal sibling values during their own resolution.
return resolved_vars.get(key, Missing)
if isinstance(value, dict):
# Dict-valued substitutions form a namespace; eagerly publish the
# original mapping so its members can reference each other while
# the dict's own substitution pass is still running. The entry is
# replaced with the fully-substituted dict once recursion returns.
resolved_vars[key] = value
try:
value = substitute(value, [], resolver_context, True)
except UndefinedError as err:
@@ -0,0 +1,16 @@
substitutions:
device:
manufacturer: espressif
model: esp32
mac_suffix: ffffff
name: espressif-esp32-ffffff
network:
host: example.com
port: 8080
url: http://example.com:8080/api
esphome:
name: espressif-esp32-ffffff
test_list:
- espressif-esp32-ffffff
- http://example.com:8080/api
- espressif/esp32
@@ -0,0 +1,18 @@
substitutions:
device:
manufacturer: "espressif"
model: "esp32"
mac_suffix: "ffffff"
name: ${device.manufacturer}-${device.model}-${device.mac_suffix}
network:
host: "example.com"
port: 8080
url: "http://${network.host}:${network.port}/api"
esphome:
name: ${device.name}
test_list:
- ${device.name}
- ${network.url}
- "${device.manufacturer}/${device.model}"