<p dir="auto">parse_qs and then urlencode, things will changed.</p>
<p dir="auto"><a href="http://min.us/ldLJUS" rel="nofollow">test code and result</a></p>
<p dir="auto">Thank you for this great lib,</p>
<p dir="auto">the result of parse_qs is something like {'oauth': ['sig'], 'status': ['hanzi ok']}<br>
urlencode can't handle list as dictionary value without doseq<br>
doseq does three things,</p>
<ol dir="auto">
<li>if value is not list or unicode, behave like doseq=False</li>
<li>if value is unicode, decode unicode</li>
<li>if value is list, handle list as dict value</li>
</ol>
<p dir="auto">it will fall to decode if the unicode value is not encoded in ascii, Chinese for example.<br>
but _encode_params already made sure that no unicode will pass to urlencode,<br>
so I think it's safe to add doseq.</p>
<p dir="auto">snippet from Python2.7/Lib/urllib.py</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="   if not doseq:
        # preserve old behavior
        for k, v in query:
            k = quote_plus(str(k))
            v = quote_plus(str(v))
            l.append(k + '=' + v)
    else:
        for k, v in query:
            k = quote_plus(str(k))
            if isinstance(v, str):
                v = quote_plus(v)
                l.append(k + '=' + v)
            elif _is_unicode(v):
                # is there a reasonable way to convert to ASCII?
                # encode generates a string, but &quot;replace&quot; or &quot;ignore&quot;
                # lose information and &quot;strict&quot; can raise UnicodeError
                v = quote_plus(v.encode(&quot;ASCII&quot;,&quot;replace&quot;))
                l.append(k + '=' + v)
            else:
                try:
                    # is this a sufficient test for sequence-ness?
                    len(v)
                except TypeError:
                    # not a sequence
                    v = quote_plus(str(v))
                    l.append(k + '=' + v)
                else:
                    # loop over the sequence
                    for elt in v:
                        l.append(k + '=' + quote_plus(str(elt)))"><pre class="notranslate">   <span class="pl-k">if</span> <span class="pl-c1">not</span> <span class="pl-s1">doseq</span>:
        <span class="pl-c"># preserve old behavior</span>
        <span class="pl-k">for</span> <span class="pl-s1">k</span>, <span class="pl-s1">v</span> <span class="pl-c1">in</span> <span class="pl-s1">query</span>:
            <span class="pl-s1">k</span> <span class="pl-c1">=</span> <span class="pl-en">quote_plus</span>(<span class="pl-en">str</span>(<span class="pl-s1">k</span>))
            <span class="pl-s1">v</span> <span class="pl-c1">=</span> <span class="pl-en">quote_plus</span>(<span class="pl-en">str</span>(<span class="pl-s1">v</span>))
            <span class="pl-s1">l</span>.<span class="pl-en">append</span>(<span class="pl-s1">k</span> <span class="pl-c1">+</span> <span class="pl-s">'='</span> <span class="pl-c1">+</span> <span class="pl-s1">v</span>)
    <span class="pl-k">else</span>:
        <span class="pl-k">for</span> <span class="pl-s1">k</span>, <span class="pl-s1">v</span> <span class="pl-c1">in</span> <span class="pl-s1">query</span>:
            <span class="pl-s1">k</span> <span class="pl-c1">=</span> <span class="pl-en">quote_plus</span>(<span class="pl-en">str</span>(<span class="pl-s1">k</span>))
            <span class="pl-k">if</span> <span class="pl-en">isinstance</span>(<span class="pl-s1">v</span>, <span class="pl-s1">str</span>):
                <span class="pl-s1">v</span> <span class="pl-c1">=</span> <span class="pl-en">quote_plus</span>(<span class="pl-s1">v</span>)
                <span class="pl-s1">l</span>.<span class="pl-en">append</span>(<span class="pl-s1">k</span> <span class="pl-c1">+</span> <span class="pl-s">'='</span> <span class="pl-c1">+</span> <span class="pl-s1">v</span>)
            <span class="pl-k">elif</span> <span class="pl-en">_is_unicode</span>(<span class="pl-s1">v</span>):
                <span class="pl-c"># is there a reasonable way to convert to ASCII?</span>
                <span class="pl-c"># encode generates a string, but "replace" or "ignore"</span>
                <span class="pl-c"># lose information and "strict" can raise UnicodeError</span>
                <span class="pl-s1">v</span> <span class="pl-c1">=</span> <span class="pl-en">quote_plus</span>(<span class="pl-s1">v</span>.<span class="pl-en">encode</span>(<span class="pl-s">"ASCII"</span>,<span class="pl-s">"replace"</span>))
                <span class="pl-s1">l</span>.<span class="pl-en">append</span>(<span class="pl-s1">k</span> <span class="pl-c1">+</span> <span class="pl-s">'='</span> <span class="pl-c1">+</span> <span class="pl-s1">v</span>)
            <span class="pl-k">else</span>:
                <span class="pl-k">try</span>:
                    <span class="pl-c"># is this a sufficient test for sequence-ness?</span>
                    <span class="pl-en">len</span>(<span class="pl-s1">v</span>)
                <span class="pl-k">except</span> <span class="pl-v">TypeError</span>:
                    <span class="pl-c"># not a sequence</span>
                    <span class="pl-s1">v</span> <span class="pl-c1">=</span> <span class="pl-en">quote_plus</span>(<span class="pl-en">str</span>(<span class="pl-s1">v</span>))
                    <span class="pl-s1">l</span>.<span class="pl-en">append</span>(<span class="pl-s1">k</span> <span class="pl-c1">+</span> <span class="pl-s">'='</span> <span class="pl-c1">+</span> <span class="pl-s1">v</span>)
                <span class="pl-k">else</span>:
                    <span class="pl-c"># loop over the sequence</span>
                    <span class="pl-k">for</span> <span class="pl-s1">elt</span> <span class="pl-c1">in</span> <span class="pl-s1">v</span>:
                        <span class="pl-s1">l</span>.<span class="pl-en">append</span>(<span class="pl-s1">k</span> <span class="pl-c1">+</span> <span class="pl-s">'='</span> <span class="pl-c1">+</span> <span class="pl-en">quote_plus</span>(<span class="pl-en">str</span>(<span class="pl-s1">elt</span>)))</pre></div>
<p dir="auto">it's the first time I use github, I'm sorry for the duplicated pull request<br>
reallly appreciate for this great lib, it helps me a lot.<br>
and I'm looking forward to oauth feature so I don't need to roll my own:)</p>
<div class="highlight highlight-source-diff notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@@ -230,7 +230,7 @@ class Request(object):
             for (k, v) in data.items():
                 result[k.encode('utf-8') if isinstance(k, unicode) else k] \
                      = v.encode('utf-8') if isinstance(v, unicode) else v  
-            return result, urllib.urlencode(result)
+            return result, urllib.urlencode(result, doseq=True)
         else:
             return data, data"><pre class="notranslate"><span class="pl-mdr">@@ -230,7 +230,7 @@</span> class Request(object):
             for (k, v) in data.items():
                 result[k.encode('utf-8') if isinstance(k, unicode) else k] \
                      = v.encode('utf-8') if isinstance(v, unicode) else v  
<span class="pl-md"><span class="pl-md">-</span>            return result, urllib.urlencode(result)</span>
<span class="pl-mi1"><span class="pl-mi1">+</span>            return result, urllib.urlencode(result, doseq=True)</span>
         else:
             return data, data</pre></div>
<p dir="auto">We have a whole code branch that does chunked uploads that is not and has never been tested. That's a problem, because sometimes it breaks and we don't notice (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="115349215" data-permission-text="Title is private" data-url="https://github.com/psf/requests/issues/2861" data-hovercard-type="pull_request" data-hovercard-url="/psf/requests/pull/2861/hovercard" href="https://github.com/psf/requests/pull/2861">#2861</a>). I'd like to add more testing for chunked uploads.</p>
<p dir="auto">However, we can't use httpbin to do this testing. This is because the WSGI spec staunchly refuses to let applications see chunked transfer encoding at the app layer. For this reason, to test chunked transfer encoding requires a new style of testing, one that doesn't involve running a WSGI server but instead running something that can see the bytes <em>as they hit the wire</em>. Basically, something like the socket level tests of urllib3.</p>