docs: def analyze_section(section: SoS_Step,
                      default_input: Optional[sos_targets] = None,
                      default_output: Optional[sos_targets] = None,
                      context={},
                      vars_and_output_only: bool = False) -> Dict[str, Any]:
      '''Analyze a section for how it uses input and output, what variables
      it uses, and input, output, etc.'''
      # analysis_key = (section.md5, section.step_name(),
      #     default_input.target_name() if hasattr(default_input, 'target_name') else '',
      #     default_output.target_name() if hasattr(default_output, 'target_name') else '', vars_and_output_only)
      #if analysis_key in analysis_cache:
      #    return analysis_cache[analysis_key]
  
      # use a fresh env for analysis
      new_env, old_env = env.request_new()
      try:
          prepare_env(section.global_def, section.global_vars, context)
  
          env.sos_dict.set('step_name', section.step_name())
          env.sos_dict.set('__null_func__', __null_func__)
          if 'STEP' in env.config['SOS_DEBUG'] or 'ALL' in env.config['SOS_DEBUG']:
              env.log_to_file(
                  'STEP',
                  f'Analyzing {section.step_name()} {"(output only)" if vars_and_output_only else ""}'
              )
  
          res = {
              'step_name': section.step_name(),
              'step_output': get_step_output(section, default_output),
              # variables starting with __ are internals...
              'environ_vars': get_environ_vars(section),
              'signature_vars': get_signature_vars(section),
              'changed_vars': get_changed_vars(section)
          }
          if not vars_and_output_only:
              inps = get_step_input(section, default_input)
              res['step_input'] = inps[0]
              res['dynamic_input'] = inps[1]
              deps = get_step_depends(section)
              res['step_depends'] = deps[0]
              res['dynamic_depends'] = deps[1]
      # analysis_cache[analysis_key] = res
      finally:
          # restore env
          env.restore_to_old(new_env, old_env)
  
      # #1225
      # The global section can contain a lot of variables, some of which can be large. Here we
      # found all variables that will be used in the step, including ones used in substep (signature_vars)
      # and ones that will be used in input statement etc.
      section.global_vars = {
          x: y
          for x, y in section.global_vars.items()
          if x in get_all_used_vars(section)
      }
      return res