class_docstr: A facility for config and config files.
  
  It supports common file formats as configs: python/json/yaml. The interface
  is the same as a dict object and also allows access config values as
  attributes.
  
  Example:
      >>> cfg = Config(dict(a=1, b=dict(b1=[0, 1])))
      >>> cfg.a
      1
      >>> cfg.b
      {'b1': [0, 1]}
      >>> cfg.b.b1
      [0, 1]
      >>> cfg = Config.fromfile('tests/data/config/a.py')
      >>> cfg.filename
      "/home/kchen/projects/mmcv/tests/data/config/a.py"
      >>> cfg.item4
      'test'
      >>> cfg
      "Config [path: /home/kchen/projects/mmcv/tests/data/config/a.py]: "
      "{'item1': [1, 2], 'item2': {'a': 0}, 'item3': True, 'item4': 'test'}"
code: def _file2dict(filename, use_predefined_variables=True):
      filename = osp.abspath(osp.expanduser(filename))
      check_file_exist(filename)
      fileExtname = osp.splitext(filename)[1]
      if fileExtname not in [".py", ".json", ".yaml", ".yml"]:
          raise IOError("Only py/yml/yaml/json type are supported now!")
  
      with tempfile.TemporaryDirectory() as temp_config_dir:
          temp_config_file = tempfile.NamedTemporaryFile(
              dir=temp_config_dir, suffix=fileExtname
          )
          if platform.system() == "Windows":
              temp_config_file.close()
          temp_config_name = osp.basename(temp_config_file.name)
          # Substitute predefined variables
          if use_predefined_variables:
              Config._substitute_predefined_vars(
                  filename, temp_config_file.name
              )
          else:
              shutil.copyfile(filename, temp_config_file.name)
          # Substitute base variables from placeholders to strings
          base_var_dict = Config._pre_substitute_base_vars(
              temp_config_file.name, temp_config_file.name
          )
  
          if filename.endswith(".py"):
              temp_module_name = osp.splitext(temp_config_name)[0]
              sys.path.insert(0, temp_config_dir)
              Config._validate_py_syntax(filename)
              mod = import_module(temp_module_name)
              sys.path.pop(0)
              cfg_dict = {
                  name: value
                  for name, value in mod.__dict__.items()
                  if not name.startswith("__")
              }
              # delete imported module
              del sys.modules[temp_module_name]
          elif filename.endswith((".yml", ".yaml", ".json")):
              import annotator.uniformer.mmcv as mmcv
  
              cfg_dict = mmcv.load(temp_config_file.name)
          # close temp file
          temp_config_file.close()
  
      # check deprecation information
      if DEPRECATION_KEY in cfg_dict:
          deprecation_info = cfg_dict.pop(DEPRECATION_KEY)
          warning_msg = (
              f"The config file {filename} will be deprecated "
              "in the future."
          )
          if "expected" in deprecation_info:
              warning_msg += (
                  f' Please use {deprecation_info["expected"]} '
                  "instead."
              )
          if "reference" in deprecation_info:
              warning_msg += (
                  " More information can be found at "
                  f'{deprecation_info["reference"]}'
              )
          warnings.warn(warning_msg)
  
      cfg_text = filename + "\n"
      with open(filename, "r", encoding="utf-8") as f:
          # Setting encoding explicitly to resolve coding issue on windows
          cfg_text += f.read()
  
      if BASE_KEY in cfg_dict:
          cfg_dir = osp.dirname(filename)
          base_filename = cfg_dict.pop(BASE_KEY)
          base_filename = (
              base_filename
              if isinstance(base_filename, list)
              else [base_filename]
          )
  
          cfg_dict_list = list()
          cfg_text_list = list()
          for f in base_filename:
              _cfg_dict, _cfg_text = Config._file2dict(
                  osp.join(cfg_dir, f)
              )
              cfg_dict_list.append(_cfg_dict)
              cfg_text_list.append(_cfg_text)
  
          base_cfg_dict = dict()
          for c in cfg_dict_list:
              duplicate_keys = base_cfg_dict.keys() & c.keys()
              if len(duplicate_keys) > 0:
                  raise KeyError(
                      "Duplicate key is not allowed among bases. "
                      f"Duplicate keys: {duplicate_keys}"
                  )
              base_cfg_dict.update(c)
  
          # Substitute base variables from strings to their actual values
          cfg_dict = Config._substitute_base_vars(
              cfg_dict, base_var_dict, base_cfg_dict
          )
  
          base_cfg_dict = Config._merge_a_into_b(
              cfg_dict, base_cfg_dict
          )
          cfg_dict = base_cfg_dict
  
          # merge cfg_text
          cfg_text_list.append(cfg_text)
          cfg_text = "\n".join(cfg_text_list)
  
      return cfg_dict, cfg_text
  
imports: import ast
  import copy
  import os
  import os.path
  import platform
  import shutil
  import sys
  import tempfile
  import uuid
  import warnings
  from argparse import Action, ArgumentParser
  from collections import abc
  from importlib import import_module
  from addict import Dict
  from yapf.yapflib.yapf_api import FormatCode
  from .misc import import_modules_from_strings
  from .path import check_file_exist
label_desc: Use image node_id 5 for calling the Config obj's underlying member method code with example usage: obj._file2dict(filename, use_predefined_variables) and returns: cfg_dict,  cfg_text