[Python-checkins] r88394 - in python/branches/py3k: Doc/library/urllib.parse.rst Doc/library/urllib.request.rst Lib/test/test_urllib2.py Lib/urllib/request.py

senthil.kumaran python-checkins at python.org
Fri Feb 11 12:25:47 CET 2011


Author: senthil.kumaran
Date: Fri Feb 11 12:25:47 2011
New Revision: 88394

Log:
Fixed issue11082 - Reject str for POST data with a TypeError. Document the need to explicitly encode to bytes when using urlencode.



Modified:
   python/branches/py3k/Doc/library/urllib.parse.rst
   python/branches/py3k/Doc/library/urllib.request.rst
   python/branches/py3k/Lib/test/test_urllib2.py
   python/branches/py3k/Lib/urllib/request.py

Modified: python/branches/py3k/Doc/library/urllib.parse.rst
==============================================================================
--- python/branches/py3k/Doc/library/urllib.parse.rst	(original)
+++ python/branches/py3k/Doc/library/urllib.parse.rst	Fri Feb 11 12:25:47 2011
@@ -140,6 +140,7 @@
    Use the :func:`urllib.parse.urlencode` function to convert such
    dictionaries into query strings.
 
+
    .. versionchanged:: 3.2
       Add *encoding* and *errors* parameters.
 
@@ -506,9 +507,10 @@
 .. function:: urlencode(query, doseq=False, safe='', encoding=None, errors=None)
 
    Convert a mapping object or a sequence of two-element tuples, which may
-   either be a :class:`str` or a :class:`bytes`,  to a "percent-encoded" string,
-   suitable to pass to :func:`urlopen` above as the optional *data* argument.
-   This is useful to pass a dictionary of form fields to a ``POST`` request.
+   either be a :class:`str` or a :class:`bytes`,  to a "percent-encoded"
+   string.  The resultant string must be converted to bytes using the
+   user-specified encoding before it is sent to :func:`urlopen` as the optional
+   *data* argument.
    The resulting string is a series of ``key=value`` pairs separated by ``'&'``
    characters, where both *key* and *value* are quoted using :func:`quote_plus`
    above. When a sequence of two-element tuples is used as the *query*
@@ -525,6 +527,9 @@
    To reverse this encoding process, :func:`parse_qs` and :func:`parse_qsl` are
    provided in this module to parse query strings into Python data structures.
 
+   Refer to :ref:`urllib examples <urllib-examples>` to find out how urlencode
+   method can be used for generating query string for a URL or data for POST.
+
    .. versionchanged:: 3.2
       Query parameter supports bytes and string objects.
 

Modified: python/branches/py3k/Doc/library/urllib.request.rst
==============================================================================
--- python/branches/py3k/Doc/library/urllib.request.rst	(original)
+++ python/branches/py3k/Doc/library/urllib.request.rst	Fri Feb 11 12:25:47 2011
@@ -967,7 +967,7 @@
 
    >>> import urllib.request
    >>> req = urllib.request.Request(url='https://localhost/cgi-bin/test.cgi',
-   ...                       data='This data is passed to stdin of the CGI')
+   ...                       data=b'This data is passed to stdin of the CGI')
    >>> f = urllib.request.urlopen(req)
    >>> print(f.read().decode('utf-8'))
    Got Data: "This data is passed to stdin of the CGI"
@@ -1043,11 +1043,13 @@
    >>> f = urllib.request.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)
    >>> print(f.read().decode('utf-8'))
 
-The following example uses the ``POST`` method instead::
+The following example uses the ``POST`` method instead. Note that params output
+from urlencode is encoded to bytes before it is sent to urlopen as data::
 
    >>> import urllib.request
    >>> import urllib.parse
    >>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
+   >>> params = params.encode('utf-8')
    >>> f = urllib.request.urlopen("http://www.musi-cal.com/cgi-bin/query", params)
    >>> print(f.read().decode('utf-8'))
 

Modified: python/branches/py3k/Lib/test/test_urllib2.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllib2.py	(original)
+++ python/branches/py3k/Lib/test/test_urllib2.py	Fri Feb 11 12:25:47 2011
@@ -794,6 +794,10 @@
         http.raise_on_endheaders = True
         self.assertRaises(urllib.error.URLError, h.do_open, http, req)
 
+        # Check for TypeError on POST data which is str.
+        req = Request("http://example.com/","badpost")
+        self.assertRaises(TypeError, h.do_request_, req)
+
         # check adding of standard headers
         o.addheaders = [("Spam", "eggs")]
         for data in b"", None:  # POST, GET
@@ -837,10 +841,11 @@
             else:
                 newreq = h.do_request_(req)
 
-        # A file object
+        # A file object.
+        # Test only Content-Length attribute of request.
 
-        file_obj = io.StringIO()
-        file_obj.write("Something\nSomething\nSomething\n")
+        file_obj = io.BytesIO()
+        file_obj.write(b"Something\nSomething\nSomething\n")
 
         for headers in {}, {"Content-Length": 30}:
             req = Request("http://example.com/", file_obj, headers)
@@ -863,7 +868,6 @@
             newreq = h.do_request_(req)
             self.assertEqual(int(newreq.get_header('Content-length')),16)
 
-
     def test_http_doubleslash(self):
         # Checks the presence of any unnecessary double slash in url does not
         # break anything. Previously, a double slash directly after the host

Modified: python/branches/py3k/Lib/urllib/request.py
==============================================================================
--- python/branches/py3k/Lib/urllib/request.py	(original)
+++ python/branches/py3k/Lib/urllib/request.py	Fri Feb 11 12:25:47 2011
@@ -1048,6 +1048,9 @@
 
         if request.data is not None:  # POST
             data = request.data
+            if isinstance(data, str):
+                raise TypeError("POST data should be bytes"
+                        " or an iterable of bytes. It cannot be str.")
             if not request.has_header('Content-type'):
                 request.add_unredirected_header(
                     'Content-type',


More information about the Python-checkins mailing list