def assign_to_variable_spec(data, spec, value):
    if not spec.startswith('@') or not spec.endswith('@'):
        raise ValueError("{} is not a reference".format(spec))
    parts = spec.strip('@').split('.')
    data[parts[0]] = {}
    gen = data[parts[0]]
    for part in parts[1:-1]:
        gen[part] = {}
        gen = gen[part]
    gen[parts[-1]] = value
    return data[parts[0]]


def resolve_variable_spec(data, spec):
    if data and spec.startswith('@') and spec.endswith('@'):
        for element in spec.strip('@').split('.'):
            data = data.get(element, None)
            if not data:
                break
        if not data:
            raise ValueError("unresolved reference: {}".format(spec.strip("@")))
        return data
    return spec

def assign_to_variable_spec(data, spec, value):
    if not spec.startswith('@') or not spec.endswith('@'):
        raise ValueError("{} is not a reference".format(spec))
    parts = spec.strip('@').split('.')
    data[parts[0]] = {}
    gen = data[parts[0]]
    for part in parts[1:-1]:
        gen[part] = {}
        gen = gen[part]
    gen[parts[-1]] = value
    return data[parts[0]]


def resolve_variable_spec(data, spec):
    if data and spec.startswith('@') and spec.endswith('@'):
        for element in spec.strip('@').split('.'):
            data = data.get(element, None)
            if not data:
                break
        if data is None:
            raise ValueError("unresolved reference: {}".format(spec.strip("@")))
        return data
    return spec

Allow empty data in value
Allow empty data in value

  def assign_to_variable_spec(data, spec, value):
      if not spec.startswith('@') or not spec.endswith('@'):
          raise ValueError("{} is not a reference".format(spec))
      parts = spec.strip('@').split('.')
      data[parts[0]] = {}
      gen = data[parts[0]]
      for part in parts[1:-1]:
          gen[part] = {}
          gen = gen[part]
      gen[parts[-1]] = value
      return data[parts[0]]
  
  
  def resolve_variable_spec(data, spec):
      if data and spec.startswith('@') and spec.endswith('@'):
          for element in spec.strip('@').split('.'):
              data = data.get(element, None)
              if not data:
                  break
-         if not data:
+         if data is None:
              raise ValueError("unresolved reference: {}".format(spec.strip("@")))
          return data
      return spec
  
Allow empty data in value
## Code Before:
def assign_to_variable_spec(data, spec, value):
    if not spec.startswith('@') or not spec.endswith('@'):
        raise ValueError("{} is not a reference".format(spec))
    parts = spec.strip('@').split('.')
    data[parts[0]] = {}
    gen = data[parts[0]]
    for part in parts[1:-1]:
        gen[part] = {}
        gen = gen[part]
    gen[parts[-1]] = value
    return data[parts[0]]


def resolve_variable_spec(data, spec):
    if data and spec.startswith('@') and spec.endswith('@'):
        for element in spec.strip('@').split('.'):
            data = data.get(element, None)
            if not data:
                break
        if not data:
            raise ValueError("unresolved reference: {}".format(spec.strip("@")))
        return data
    return spec

## Instruction:
Allow empty data in value
## Code After:
def assign_to_variable_spec(data, spec, value):
    if not spec.startswith('@') or not spec.endswith('@'):
        raise ValueError("{} is not a reference".format(spec))
    parts = spec.strip('@').split('.')
    data[parts[0]] = {}
    gen = data[parts[0]]
    for part in parts[1:-1]:
        gen[part] = {}
        gen = gen[part]
    gen[parts[-1]] = value
    return data[parts[0]]


def resolve_variable_spec(data, spec):
    if data and spec.startswith('@') and spec.endswith('@'):
        for element in spec.strip('@').split('.'):
            data = data.get(element, None)
            if not data:
                break
        if data is None:
            raise ValueError("unresolved reference: {}".format(spec.strip("@")))
        return data
    return spec
