nodes: 0, module; 1, function_definition; 2, function_name:_normalize_request_parameters; 3, parameters; 4, block; 5, identifier:self; 6, identifier:oauth_params; 7, identifier:req_kwargs; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, expression_statement; 12, expression_statement; 13, comment:# process request parameters; 14, for_statement; 15, comment:# process request data; 16, if_statement; 17, comment:# extract values from our list of tuples; 18, expression_statement; 19, for_statement; 20, comment:# add in the params from oauth_params for signing; 21, for_statement; 22, comment:# sort the params as per the OAuth 1.0/a spec; 23, expression_statement; 24, comment:# finally encode the params as a string; 25, return_statement; 26, string; 27, assignment; 28, assignment; 29, assignment; 30, assignment; 31, pattern_list; 32, call; 33, block; 34, boolean_operator; 35, block; 36, assignment; 37, identifier:t; 38, identifier:normalized; 39, block; 40, pattern_list; 41, call; 42, block; 43, call; 44, call; 45, string_content:This process normalizes the request parameters as detailed in the OAuth
          1.0 spec.
  
          Additionally we apply a `Content-Type` header to the request of the
          `FORM_URLENCODE` type if the `Content-Type` was previously set, i.e. if
          this is a `POST` or `PUT` request. This ensures the correct header is
          set as per spec.
  
          Finally we sort the parameters in preparation for signing and return
          a URL encoded string of all normalized parameters.
  
          :param oauth_params: OAuth params to sign with.
          :type oauth_params: dict
          :param req_kwargs: Request kwargs to normalize.
          :type req_kwargs: dict; 46, identifier:normalized; 47, list; 48, identifier:params; 49, call; 50, identifier:data; 51, call; 52, identifier:headers; 53, call; 54, identifier:k; 55, identifier:v; 56, attribute; 57, argument_list; 58, if_statement; 59, comparison_operator:'Content-Type' in headers; 60, line_continuation:\; 61, comparison_operator:headers['Content-Type'] == FORM_URLENCODED; 62, for_statement; 63, identifier:all_normalized; 64, list; 65, expression_statement; 66, if_statement; 67, expression_statement; 68, identifier:k; 69, identifier:v; 70, attribute; 71, argument_list; 72, if_statement; 73, expression_statement; 74, attribute; 75, argument_list; 76, attribute; 77, argument_list; 78, attribute; 79, argument_list; 80, attribute; 81, argument_list; 82, attribute; 83, argument_list; 84, identifier:params; 85, identifier:items; 86, comparison_operator:v is not None; 87, block; 88, string; 89, identifier:headers; 90, subscript; 91, identifier:FORM_URLENCODED; 92, pattern_list; 93, call; 94, block; 95, assignment; 96, boolean_operator; 97, block; 98, augmented_assignment; 99, identifier:oauth_params; 100, identifier:items; 101, comparison_operator:(k, v) in all_normalized; 102, comment:# pragma: no cover; 103, block; 104, augmented_assignment; 105, identifier:all_normalized; 106, identifier:sort; 107, call; 108, line_continuation:\; 109, identifier:replace; 110, string; 111, string; 112, identifier:req_kwargs; 113, identifier:get; 114, string; 115, dictionary; 116, identifier:req_kwargs; 117, identifier:get; 118, string; 119, dictionary; 120, identifier:req_kwargs; 121, identifier:get; 122, string; 123, dictionary; 124, identifier:v; 125, None; 126, expression_statement; 127, string_content:Content-Type; 128, identifier:headers; 129, string; 130, identifier:k; 131, identifier:v; 132, attribute; 133, argument_list; 134, expression_statement; 135, pattern_list; 136, identifier:t; 137, call; 138, not_operator; 139, expression_statement; 140, identifier:all_normalized; 141, list; 142, tuple; 143, identifier:all_normalized; 144, continue_statement; 145, identifier:all_normalized; 146, list; 147, attribute; 148, argument_list; 149, string_content:%7E; 150, string_content:~; 151, string_content:params; 152, string_content:data; 153, string_content:headers; 154, augmented_assignment; 155, string_content:Content-Type; 156, identifier:data; 157, identifier:items; 158, augmented_assignment; 159, identifier:k; 160, identifier:v; 161, identifier:is_basestring; 162, argument_list; 163, call; 164, assignment; 165, tuple; 166, identifier:k; 167, identifier:v; 168, tuple; 169, call; 170, line_continuation:\; 171, identifier:replace; 172, string; 173, string; 174, identifier:normalized; 175, list; 176, identifier:normalized; 177, list; 178, identifier:v; 179, identifier:isinstance; 180, argument_list; 181, identifier:v; 182, call; 183, identifier:k; 184, identifier:v; 185, identifier:k; 186, identifier:v; 187, identifier:urlencode; 188, argument_list; 189, string_content:+; 190, string_content:%20; 191, tuple; 192, tuple; 193, identifier:v; 194, identifier:bytes; 195, attribute; 196, argument_list; 197, identifier:all_normalized; 198, True; 199, identifier:k; 200, identifier:v; 201, identifier:k; 202, identifier:v; 203, identifier:v; 204, identifier:encode; 205, string; 206, string_content:utf-8
code: def _normalize_request_parameters(self, oauth_params, req_kwargs):
          '''
          This process normalizes the request parameters as detailed in the OAuth
          1.0 spec.
  
          Additionally we apply a `Content-Type` header to the request of the
          `FORM_URLENCODE` type if the `Content-Type` was previously set, i.e. if
          this is a `POST` or `PUT` request. This ensures the correct header is
          set as per spec.
  
          Finally we sort the parameters in preparation for signing and return
          a URL encoded string of all normalized parameters.
  
          :param oauth_params: OAuth params to sign with.
          :type oauth_params: dict
          :param req_kwargs: Request kwargs to normalize.
          :type req_kwargs: dict
          '''
          normalized = []
  
          params = req_kwargs.get('params', {})
          data = req_kwargs.get('data', {})
          headers = req_kwargs.get('headers', {})
  
          # process request parameters
          for k, v in params.items():
              if v is not None:
                  normalized += [(k, v)]
  
          # process request data
          if 'Content-Type' in headers and \
                  headers['Content-Type'] == FORM_URLENCODED:
              for k, v in data.items():
                  normalized += [(k, v)]
  
          # extract values from our list of tuples
          all_normalized = []
          for t in normalized:
              k, v = t
              if is_basestring(v) and not isinstance(v, bytes):
                  v = v.encode('utf-8')
              all_normalized += [(k, v)]
  
          # add in the params from oauth_params for signing
          for k, v in oauth_params.items():
              if (k, v) in all_normalized:  # pragma: no cover
                  continue
              all_normalized += [(k, v)]
  
          # sort the params as per the OAuth 1.0/a spec
          all_normalized.sort()
  
          # finally encode the params as a string
          return urlencode(all_normalized, True)\
              .replace('+', '%20')\
              .replace('%7E', '~')