import re


def LazyFormat(s, **kwargs):
  """Expands {key} => value for key, value in kwargs.

  Details:
    * {{<identifier>}} expands to {<identifier>}
    * {<unknown-key>} expands to {<unknown-key>}
    * {key} values are recursively expanded before substitution into the result

  Args:
    s: str, The string to format.
    **kwargs: {str:str}, A dict of strings for named parameters.

  Returns:
    str, The lazily-formatted string.
  """

  def _Replacement(match):
    """Returns one replacement string for LazyFormat re.sub()."""
    prefix = match.group(1)[1:]
    name = match.group(2)
    suffix = match.group(3)[1:]
    if prefix and suffix:
      # {{name}} => {name}
      return prefix + name + suffix
    value = kwargs.get(name)
    if value is None:
      # {unknown} => {unknown}
      return match.group(0)
    if callable(value):
      value = value()
    # The substituted value is expanded too.
    return prefix + LazyFormat(value, **kwargs) + suffix

  return re.sub(r'(\{+)(\w+)(\}+)', _Replacement, s)