nodes: 0, module; 1, function_definition; 2, function_name:__encoded_params_for_signature; 3, parameters; 4, block; 5, identifier:cls; 6, identifier:params; 7, expression_statement; 8, function_definition; 9, return_statement; 10, comment:"""
          Sort and combine query parameters into a single string, excluding those that should be removed and joining with '&'
          """; 11, function_name:encoded_pairs; 12, parameters; 13, block; 14, call; 15, identifier:params; 16, for_statement; 17, attribute; 18, argument_list; 19, pattern_list; 20, call; 21, block; 22, string:"&"; 23, identifier:join; 24, call; 25, identifier:k; 26, identifier:v; 27, attribute; 28, argument_list; 29, if_statement; 30, if_statement; 31, comment:# escape delimiters to avoid tampering; 32, expression_statement; 33, expression_statement; 34, expression_statement; 35, identifier:sorted; 36, argument_list; 37, identifier:six; 38, identifier:iteritems; 39, identifier:params; 40, comparison_operator:k == 'hmac'; 41, block; 42, call; 43, comment:#foo[]=1&foo[]=2 has to be transformed as foo=["1", "2"] note the whitespace after comma; 44, block; 45, assignment; 46, assignment; 47, yield; 48, call; 49, identifier:k; 50, string; 51, continue_statement; 52, attribute; 53, argument_list; 54, expression_statement; 55, expression_statement; 56, identifier:k; 57, call; 58, identifier:v; 59, call; 60, call; 61, identifier:encoded_pairs; 62, argument_list; 63, string_content:hmac; 64, identifier:k; 65, identifier:endswith; 66, string; 67, assignment; 68, assignment; 69, attribute; 70, argument_list; 71, attribute; 72, argument_list; 73, attribute; 74, argument_list; 75, identifier:params; 76, string_content:[]; 77, identifier:k; 78, call; 79, identifier:v; 80, call; 81, call; 82, identifier:replace; 83, string:"="; 84, string:"%3D"; 85, call; 86, identifier:replace; 87, string:"%"; 88, string:"%25"; 89, call; 90, identifier:replace; 91, string:"&"; 92, string:"%26"; 93, attribute; 94, argument_list; 95, attribute; 96, argument_list; 97, attribute; 98, argument_list; 99, identifier:str; 100, argument_list; 101, attribute; 102, argument_list; 103, identifier:k; 104, identifier:rstrip; 105, string; 106, identifier:json; 107, identifier:dumps; 108, call; 109, call; 110, identifier:replace; 111, string:"%"; 112, string:"%25"; 113, identifier:v; 114, string; 115, identifier:format; 116, identifier:k; 117, identifier:v; 118, string_content:[]; 119, identifier:list; 120, argument_list; 121, identifier:str; 122, argument_list; 123, string_content:{0}={1}; 124, call; 125, identifier:k; 126, identifier:map; 127, argument_list; 128, identifier:str; 129, identifier:v
code: def __encoded_params_for_signature(cls, params):
          """
          Sort and combine query parameters into a single string, excluding those that should be removed and joining with '&'
          """
          def encoded_pairs(params):
              for k, v in six.iteritems(params):
                  if k == 'hmac':
                      continue
  
                  if k.endswith('[]'):
                      #foo[]=1&foo[]=2 has to be transformed as foo=["1", "2"] note the whitespace after comma
                      k = k.rstrip('[]')
                      v = json.dumps(list(map(str, v)))
  
                  # escape delimiters to avoid tampering
                  k = str(k).replace("%", "%25").replace("=", "%3D")
                  v = str(v).replace("%", "%25")
                  yield '{0}={1}'.format(k, v).replace("&", "%26")
  
          return "&".join(sorted(encoded_pairs(params)))