Repository: web2py/web2py

Issue:
python3.5 : AttributeError: module 'urllib' has no attribute 'quote_plus'
python 3.5, web2py version 2.16.1-stable+timestamp.2017.11.14.05.54.25

```
ERROR:Rocket.Errors.Thread-4:Traceback (most recent call last):

  File "/home/web2py/gluon/rocket.py", line 1319, in run
    self.run_app(conn)

  File "/home/web2py/gluon/rocket.py", line 1820, in run_app
    output = self.app(environ, self.start_response)

  File "/home/web2py/gluon/main.py", line 650, in app_with_logging
    ret[0] = wsgiapp(environ, responder2)

  File "/home/web2py/gluon/main.py", line 559, in wsgibase
    http_response, request, environ, ticket)

  File "/home/web2py/gluon/rewrite.py", line 238, in try_rewrite_on_error
    (status, ticket, urllib.quote_plus(

AttributeError: module 'urllib' has no attribute 'quote_plus'
```


Discussion:

Resolving patch:
diff --git a/gluon/_compat.py b/gluon/_compat.py
--- a/gluon/_compat.py
+++ b/gluon/_compat.py
@@ -26,7 +26,7 @@
     from email.MIMEText import MIMEText
     from email.Charset import add_charset, QP as charset_QP
     from urllib import FancyURLopener, urlencode, urlopen
-    from urllib import quote as urllib_quote, unquote as urllib_unquote
+    from urllib import quote as urllib_quote, unquote as urllib_unquote, quote_plus as urllib_quote_plus
     from string import maketrans
     from types import ClassType
     import cgi
@@ -94,7 +94,7 @@ def to_native(obj, charset='utf8', errors='strict'):
     from email.header import Header
     from email.charset import Charset, add_charset, QP as charset_QP
     from urllib.request import FancyURLopener, urlopen
-    from urllib.parse import quote as urllib_quote, unquote as urllib_unquote, urlencode
+    from urllib.parse import quote as urllib_quote, unquote as urllib_unquote, urlencode, quote_plus as urllib_quote_plus
     from http import cookiejar as cookielib
     from xmlrpc.client import ProtocolError
     import html # warning, this is the python3 module and not the web2py html module
diff --git a/gluon/rewrite.py b/gluon/rewrite.py
--- a/gluon/rewrite.py
+++ b/gluon/rewrite.py
@@ -22,12 +22,11 @@
 import logging
 import traceback
 import threading
-import urllib
 from gluon.storage import Storage, List
 from gluon.http import HTTP
 from gluon.fileutils import abspath, read_file
 from gluon.settings import global_settings
-from gluon._compat import urllib_unquote, urllib_quote, iteritems, xrange
+from gluon._compat import urllib_unquote, urllib_quote, iteritems, xrange, urllib_quote_plus
 
 isdir = os.path.isdir
 isfile = os.path.isfile
@@ -235,7 +234,7 @@ def try_rewrite_on_error(http_response, request, environ, ticket=None):
                     path_info, query_string = uri, ''
                 query_string += \
                     'code=%s&ticket=%s&requested_uri=%s&request_url=%s' % \
-                    (status, ticket, urllib.quote_plus(
+                    (status, ticket, urllib_quote_plus(
                         request.env.request_uri), request.url)
                 if uri.startswith('http://') or uri.startswith('https://'):
                     # make up a response
@@ -270,12 +269,12 @@ def try_redirect_on_error(http_object, request, ticket=None):
                 elif '?' in redir:
                     url = '%s&code=%s&ticket=%s&requested_uri=%s&request_url=%s' % \
                         (redir, status, ticket,
-                         urllib.quote_plus(request.env.request_uri),
+                         urllib_quote_plus(request.env.request_uri),
                          request.url)
                 else:
                     url = '%s?code=%s&ticket=%s&requested_uri=%s&request_url=%s' % \
                         (redir, status, ticket,
-                         urllib.quote_plus(request.env.request_uri),
+                         urllib_quote_plus(request.env.request_uri),
                          request.url)
                 return HTTP(303, 'You are being redirected <a href="%s">here</a>' % url, Location=url)
     return http_object


Test patch: