code: def string_variable_lookup(tb, s):
      
  
      refs = []
      dot_refs = s.split('.')
      DOT_LOOKUP = 0
      DICT_LOOKUP = 1
      for ii, ref in enumerate(dot_refs):
          dict_refs = dict_lookup_regex.findall(ref)
          if dict_refs:
              bracket = ref.index('[')
              refs.append((DOT_LOOKUP, ref[:bracket]))
              refs.extend([(DICT_LOOKUP, t) for t in dict_refs])
          else:
              refs.append((DOT_LOOKUP, ref))
  
      scope = tb.tb_frame.f_locals.get(refs[0][1], ValueError)
      if scope is ValueError:
          return scope
      for lookup, ref in refs[1:]:
          try:
              if lookup == DOT_LOOKUP:
                  scope = getattr(scope, ref, ValueError)
              else:
                  scope = scope.get(ref, ValueError)
          except Exception as e:
              logging.error(e)
              scope = ValueError
  
          if scope is ValueError:
              return scope
          elif isinstance(scope, (FunctionType, MethodType, ModuleType, BuiltinMethodType, BuiltinFunctionType)):
              return ValueError
      return scope
docs: Look up the value of an object in a traceback by a dot-lookup string.
      ie. "self.crashreporter.application_name"
  
      Returns ValueError if value was not found in the scope of the traceback.
  
      :param tb: traceback
      :param s: lookup string
      :return: value of the