@@ -137,11 +137,21 @@ def encode_urlencoded_data(
137137 data : RequestData ,
138138) -> tuple [dict [str , str ], ByteStream ]:
139139 plain_data = []
140- for key , value in data . items ():
141- if isinstance (value , ( list , tuple ) ):
142- plain_data . extend ([( key , primitive_value_to_str ( item )) for item in value ])
143- else :
140+
141+ if isinstance (data , list ):
142+ # Handle list of tuples case
143+ for key , value in data :
144144 plain_data .append ((key , primitive_value_to_str (value )))
145+ else :
146+ # Handle dictionary case
147+ for key , value in data .items ():
148+ if isinstance (value , (list , tuple )):
149+ plain_data .extend (
150+ [(key , primitive_value_to_str (item )) for item in value ]
151+ )
152+ else :
153+ plain_data .append ((key , primitive_value_to_str (value )))
154+
145155 body = urlencode (plain_data , doseq = True ).encode ("utf-8" )
146156 content_length = str (len (body ))
147157 content_type = "application/x-www-form-urlencoded"
@@ -195,16 +205,30 @@ def encode_request(
195205 returning a two-tuple of (<headers>, <stream>).
196206 """
197207 if data is not None and not isinstance (data , Mapping ):
198- # We prefer to separate `content=<bytes|str|byte iterator|bytes aiterator>`
199- # for raw request content, and `data=<form data>` for url encoded or
200- # multipart form content.
201- #
202- # However for compat with requests, we *do* still support
203- # `data=<bytes...>` usages. We deal with that case here, treating it
204- # as if `content=<...>` had been supplied instead.
205- message = "Use 'content=<...>' to upload raw bytes/text content."
206- warnings .warn (message , DeprecationWarning , stacklevel = 2 )
207- return encode_content (data )
208+ # Check if this is a list of tuples (valid form data)
209+ if (
210+ isinstance (data , list )
211+ and data
212+ and all (isinstance (item , tuple ) and len (item ) == 2 for item in data )
213+ ):
214+ # This is valid form data as a list of tuples
215+ pass
216+ else :
217+ # We prefer to separate `content=<bytes|str|byte iterator|bytes aiterator>`
218+ # for raw request content, and `data=<form data>` for url encoded or
219+ # multipart form content.
220+ #
221+ # However for compat with requests, we *do* still support
222+ # `data=<bytes...>` usages. We deal with that case here, treating it
223+ # as if `content=<...>` had been supplied instead.
224+ message = "Use 'content=<...>' to upload raw bytes/text content."
225+ warnings .warn (message , DeprecationWarning , stacklevel = 2 )
226+ # At this point, data is not a list of tuples, so it's safe to pass to
227+ # encode_content
228+ from typing import cast
229+
230+ content_data = cast ("RequestContent" , data )
231+ return encode_content (content_data )
208232
209233 if content is not None :
210234 return encode_content (content )
0 commit comments