nodes: 0, module; 1, function_definition; 2, function_name:_do_serialize; 3, parameters; 4, block; 5, identifier:struct; 6, identifier:fmt; 7, identifier:encoding; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, if_statement; 12, return_statement; 13, comment:"""Actually serialize input.
  
      Args:
          struct: structure to serialize to
          fmt: format to serialize to
          encoding: encoding to use while serializing
      Returns:
          encoded serialized structure
      Raises:
          various sorts of errors raised by libraries while serializing
      """; 14, assignment; 15, call; 16, comparison_operator:fmt == 'ini'; 17, block; 18, elif_clause; 19, elif_clause; 20, elif_clause; 21, elif_clause; 22, else_clause; 23, identifier:res; 24, identifier:res; 25, None; 26, identifier:_check_lib_installed; 27, argument_list; 28, identifier:fmt; 29, string; 30, expression_statement; 31, for_statement; 32, expression_statement; 33, comparison_operator:fmt in ['json', 'json5']; 34, comment:# specify separators to get rid of trailing whitespace; 35, comment:# specify ensure_ascii to make sure unicode is serialized in \x... sequences,; 36, comment:#  not in \u sequences; 37, block; 38, comparison_operator:fmt == 'toml'; 39, block; 40, comparison_operator:fmt == 'xml'; 41, comment:# passing encoding argument doesn't encode, just sets the xml property; 42, block; 43, comparison_operator:fmt == 'yaml'; 44, block; 45, block; 46, identifier:fmt; 47, string; 48, string_content:ini; 49, assignment; 50, pattern_list; 51, call; 52, block; 53, assignment; 54, identifier:fmt; 55, list; 56, expression_statement; 57, identifier:fmt; 58, string; 59, if_statement; 60, expression_statement; 61, identifier:fmt; 62, string; 63, expression_statement; 64, identifier:fmt; 65, string; 66, expression_statement; 67, raise_statement; 68, comment:# unknown format; 69, string_content:serialize; 70, identifier:config; 71, call; 72, identifier:k; 73, identifier:v; 74, attribute; 75, argument_list; 76, expression_statement; 77, identifier:res; 78, call; 79, string; 80, string; 81, assignment; 82, string_content:toml; 83, not_operator; 84, block; 85, assignment; 86, string_content:xml; 87, assignment; 88, string_content:yaml; 89, assignment; 90, attribute; 91, argument_list; 92, identifier:struct; 93, identifier:items; 94, assignment; 95, attribute; 96, argument_list; 97, string_content:json; 98, string_content:json5; 99, identifier:res; 100, call; 101, call; 102, raise_statement; 103, identifier:res; 104, call; 105, identifier:res; 106, call; 107, identifier:res; 108, call; 109, identifier:configobj; 110, identifier:ConfigObj; 111, keyword_argument; 112, subscript; 113, identifier:v; 114, string; 115, identifier:join; 116, call; 117, attribute; 118, argument_list; 119, identifier:_is_utf8; 120, argument_list; 121, call; 122, attribute; 123, argument_list; 124, attribute; 125, argument_list; 126, attribute; 127, argument_list; 128, identifier:encoding; 129, identifier:encoding; 130, identifier:config; 131, identifier:k; 132, string_content; 133, attribute; 134, argument_list; 135, call; 136, identifier:encode; 137, identifier:encoding; 138, identifier:encoding; 139, identifier:AnyMarkupError; 140, argument_list; 141, call; 142, identifier:encode; 143, identifier:encoding; 144, call; 145, identifier:encode; 146, string; 147, identifier:yaml; 148, identifier:safe_dump; 149, identifier:struct; 150, keyword_argument; 151, keyword_argument; 152, escape_sequence:\n; 153, identifier:config; 154, identifier:write; 155, attribute; 156, argument_list; 157, string; 158, attribute; 159, argument_list; 160, attribute; 161, argument_list; 162, string_content:utf-8; 163, identifier:encoding; 164, string; 165, identifier:default_flow_style; 166, False; 167, parenthesized_expression; 168, identifier:dumps; 169, identifier:struct; 170, keyword_argument; 171, keyword_argument; 172, keyword_argument; 173, string_content:toml must always be utf-8 encoded according to specification; 174, identifier:toml; 175, identifier:dumps; 176, identifier:struct; 177, identifier:xmltodict; 178, identifier:unparse; 179, identifier:struct; 180, keyword_argument; 181, keyword_argument; 182, string_content:utf-8; 183, conditional_expression:json if fmt == 'json' else json5; 184, identifier:indent; 185, integer:2; 186, identifier:separators; 187, tuple; 188, identifier:ensure_ascii; 189, False; 190, identifier:pretty; 191, True; 192, identifier:encoding; 193, string; 194, identifier:json; 195, comparison_operator:fmt == 'json'; 196, identifier:json5; 197, string; 198, string; 199, string_content:utf-8; 200, identifier:fmt; 201, string; 202, string_content:,; 203, string_content::; 204, string_content:json
code: def _do_serialize(struct, fmt, encoding):
      """Actually serialize input.
  
      Args:
          struct: structure to serialize to
          fmt: format to serialize to
          encoding: encoding to use while serializing
      Returns:
          encoded serialized structure
      Raises:
          various sorts of errors raised by libraries while serializing
      """
      res = None
      _check_lib_installed(fmt, 'serialize')
  
      if fmt == 'ini':
          config = configobj.ConfigObj(encoding=encoding)
          for k, v in struct.items():
              config[k] = v
          res = b'\n'.join(config.write())
      elif fmt in ['json', 'json5']:
          # specify separators to get rid of trailing whitespace
          # specify ensure_ascii to make sure unicode is serialized in \x... sequences,
          #  not in \u sequences
          res = (json if fmt == 'json' else json5).dumps(struct,
                                                         indent=2,
                                                         separators=(',', ': '),
                                                         ensure_ascii=False).encode(encoding)
      elif fmt == 'toml':
          if not _is_utf8(encoding):
              raise AnyMarkupError('toml must always be utf-8 encoded according to specification')
          res = toml.dumps(struct).encode(encoding)
      elif fmt == 'xml':
          # passing encoding argument doesn't encode, just sets the xml property
          res = xmltodict.unparse(struct, pretty=True, encoding='utf-8').encode('utf-8')
      elif fmt == 'yaml':
          res = yaml.safe_dump(struct, encoding='utf-8', default_flow_style=False)
      else:
          raise  # unknown format
  
      return res