summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2012-07-20 15:36:52 +0200
committerAymeric Augustin <aymeric.augustin@m4x.org>2012-07-22 09:29:55 +0200
commit0d914d08a0d7b5a1521f498a8047971fe6cd61e7 (patch)
treed0ab08b0b5b2041bd796c10a26a358ae60d0914a /django
parentbdca5ea345c548a82a80d198906818c9ccbef896 (diff)
[py3] Updated urllib/urllib2/urlparse imports.
Lots of functions were moved. Use explicit imports in all cases to keey it easy to identify where the functions come from.
Diffstat (limited to 'django')
-rw-r--r--django/contrib/auth/decorators.py10
-rw-r--r--django/contrib/auth/models.py6
-rw-r--r--django/contrib/auth/tests/views.py10
-rw-r--r--django/contrib/auth/views.py13
-rw-r--r--django/contrib/comments/views/utils.py8
-rw-r--r--django/contrib/contenttypes/tests.py6
-rw-r--r--django/contrib/databrowse/plugins/fieldchoices.py8
-rw-r--r--django/contrib/databrowse/plugins/objects.py8
-rw-r--r--django/contrib/sitemaps/__init__.py10
-rw-r--r--django/contrib/staticfiles/handlers.py10
-rw-r--r--django/contrib/staticfiles/storage.py7
-rw-r--r--django/contrib/staticfiles/views.py7
-rw-r--r--django/core/cache/__init__.py5
-rw-r--r--django/core/files/storage.py7
-rw-r--r--django/core/management/templates.py8
-rw-r--r--django/core/servers/basehttp.py11
-rw-r--r--django/core/validators.py9
-rw-r--r--django/forms/fields.py11
-rw-r--r--django/forms/widgets.py5
-rw-r--r--django/http/__init__.py7
-rw-r--r--django/templatetags/static.py6
-rw-r--r--django/test/client.py11
-rw-r--r--django/test/testcases.py5
-rw-r--r--django/utils/encoding.py13
-rw-r--r--django/utils/feedgenerator.py7
-rw-r--r--django/utils/html.py13
-rw-r--r--django/utils/http.py22
-rw-r--r--django/views/static.py7
28 files changed, 162 insertions, 88 deletions
diff --git a/django/contrib/auth/decorators.py b/django/contrib/auth/decorators.py
index 5805a3122c..7a608d0777 100644
--- a/django/contrib/auth/decorators.py
+++ b/django/contrib/auth/decorators.py
@@ -1,4 +1,7 @@
-import urlparse
+try:
+ from urllib.parse import urlparse
+except ImportError: # Python 2
+ from urlparse import urlparse
from functools import wraps
from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
@@ -21,9 +24,8 @@ def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIE
path = request.build_absolute_uri()
# If the login url is the same scheme and net location then just
# use the path as the "next" url.
- login_scheme, login_netloc = urlparse.urlparse(login_url or
- settings.LOGIN_URL)[:2]
- current_scheme, current_netloc = urlparse.urlparse(path)[:2]
+ login_scheme, login_netloc = urlparse(login_url or settings.LOGIN_URL)[:2]
+ current_scheme, current_netloc = urlparse(path)[:2]
if ((not login_scheme or login_scheme == current_scheme) and
(not login_netloc or login_netloc == current_netloc)):
path = request.get_full_path()
diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py
index 95a7494d38..39d9e8408d 100644
--- a/django/contrib/auth/models.py
+++ b/django/contrib/auth/models.py
@@ -1,13 +1,11 @@
from __future__ import unicode_literals
-import urllib
-
from django.core.exceptions import ImproperlyConfigured
from django.core.mail import send_mail
from django.db import models
from django.db.models.manager import EmptyManager
from django.utils.crypto import get_random_string
-from django.utils.encoding import smart_str
+from django.utils.http import urlquote
from django.utils import six
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
@@ -268,7 +266,7 @@ class User(models.Model):
return (self.username,)
def get_absolute_url(self):
- return "/users/%s/" % urllib.quote(smart_str(self.username))
+ return "/users/%s/" % urlquote(self.username)
def is_anonymous(self):
"""
diff --git a/django/contrib/auth/tests/views.py b/django/contrib/auth/tests/views.py
index a9754c5bad..e76e7dd10f 100644
--- a/django/contrib/auth/tests/views.py
+++ b/django/contrib/auth/tests/views.py
@@ -1,6 +1,5 @@
import os
import re
-import urllib
from django.conf import settings
from django.contrib.sites.models import Site, RequestSite
@@ -10,6 +9,7 @@ from django.core.urlresolvers import reverse, NoReverseMatch
from django.http import QueryDict
from django.utils.encoding import force_unicode
from django.utils.html import escape
+from django.utils.http import urlquote
from django.test import TestCase
from django.test.utils import override_settings
@@ -256,7 +256,7 @@ class LoginTest(AuthViewsTestCase):
nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
'url': login_url,
'next': REDIRECT_FIELD_NAME,
- 'bad_url': urllib.quote(bad_url),
+ 'bad_url': urlquote(bad_url),
}
response = self.client.post(nasty_url, {
'username': 'testclient',
@@ -277,7 +277,7 @@ class LoginTest(AuthViewsTestCase):
safe_url = '%(url)s?%(next)s=%(good_url)s' % {
'url': login_url,
'next': REDIRECT_FIELD_NAME,
- 'good_url': urllib.quote(good_url),
+ 'good_url': urlquote(good_url),
}
response = self.client.post(safe_url, {
'username': 'testclient',
@@ -412,7 +412,7 @@ class LogoutTest(AuthViewsTestCase):
nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
'url': logout_url,
'next': REDIRECT_FIELD_NAME,
- 'bad_url': urllib.quote(bad_url),
+ 'bad_url': urlquote(bad_url),
}
self.login()
response = self.client.get(nasty_url)
@@ -432,7 +432,7 @@ class LogoutTest(AuthViewsTestCase):
safe_url = '%(url)s?%(next)s=%(good_url)s' % {
'url': logout_url,
'next': REDIRECT_FIELD_NAME,
- 'good_url': urllib.quote(good_url),
+ 'good_url': urlquote(good_url),
}
self.login()
response = self.client.get(safe_url)
diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py
index c86ef53595..ccfc7a1003 100644
--- a/django/contrib/auth/views.py
+++ b/django/contrib/auth/views.py
@@ -1,4 +1,7 @@
-import urlparse
+try:
+ from urllib.parse import urlparse, urlunparse
+except ImportError: # Python 2
+ from urlparse import urlparse, urlunparse
from django.conf import settings
from django.core.urlresolvers import reverse
@@ -34,7 +37,7 @@ def login(request, template_name='registration/login.html',
if request.method == "POST":
form = authentication_form(data=request.POST)
if form.is_valid():
- netloc = urlparse.urlparse(redirect_to)[1]
+ netloc = urlparse(redirect_to)[1]
# Use default setting if redirect_to is empty
if not redirect_to:
@@ -80,7 +83,7 @@ def logout(request, next_page=None,
auth_logout(request)
redirect_to = request.REQUEST.get(redirect_field_name, '')
if redirect_to:
- netloc = urlparse.urlparse(redirect_to)[1]
+ netloc = urlparse(redirect_to)[1]
# Security check -- don't allow redirection to a different host.
if not (netloc and netloc != request.get_host()):
return HttpResponseRedirect(redirect_to)
@@ -116,13 +119,13 @@ def redirect_to_login(next, login_url=None,
if not login_url:
login_url = settings.LOGIN_URL
- login_url_parts = list(urlparse.urlparse(login_url))
+ login_url_parts = list(urlparse(login_url))
if redirect_field_name:
querystring = QueryDict(login_url_parts[4], mutable=True)
querystring[redirect_field_name] = next
login_url_parts[4] = querystring.urlencode(safe='/')
- return HttpResponseRedirect(urlparse.urlunparse(login_url_parts))
+ return HttpResponseRedirect(urlunparse(login_url_parts))
# 4 views for password reset:
# - password_reset sends the mail
diff --git a/django/contrib/comments/views/utils.py b/django/contrib/comments/views/utils.py
index 8879e9fb8f..abaed68560 100644
--- a/django/contrib/comments/views/utils.py
+++ b/django/contrib/comments/views/utils.py
@@ -2,8 +2,12 @@
A few bits of helper functions for comment views.
"""
-import urllib
import textwrap
+try:
+ from urllib.parse import urlencode
+except ImportError: # Python 2
+ from urllib import urlencode
+
from django.http import HttpResponseRedirect
from django.core import urlresolvers
from django.shortcuts import render_to_response
@@ -33,7 +37,7 @@ def next_redirect(data, default, default_view, **get_kwargs):
anchor = ''
joiner = ('?' in next) and '&' or '?'
- next += joiner + urllib.urlencode(get_kwargs) + anchor
+ next += joiner + urlencode(get_kwargs) + anchor
return HttpResponseRedirect(next)
def confirmation_view(template, doc="Display a confirmation view."):
diff --git a/django/contrib/contenttypes/tests.py b/django/contrib/contenttypes/tests.py
index 1ecabc16e9..cfd7e6ff32 100644
--- a/django/contrib/contenttypes/tests.py
+++ b/django/contrib/contenttypes/tests.py
@@ -1,14 +1,12 @@
from __future__ import unicode_literals
-import urllib
-
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.views import shortcut
from django.contrib.sites.models import Site
from django.http import HttpRequest, Http404
from django.test import TestCase
-from django.utils.encoding import smart_str
+from django.utils.http import urlquote
from django.utils import six
@@ -36,7 +34,7 @@ class FooWithUrl(FooWithoutUrl):
"""
def get_absolute_url(self):
- return "/users/%s/" % urllib.quote(smart_str(self.name))
+ return "/users/%s/" % urlquote(self.name)
class FooWithBrokenAbsoluteUrl(FooWithoutUrl):
"""
diff --git a/django/contrib/databrowse/plugins/fieldchoices.py b/django/contrib/databrowse/plugins/fieldchoices.py
index 4b1f0e6614..c016385ffb 100644
--- a/django/contrib/databrowse/plugins/fieldchoices.py
+++ b/django/contrib/databrowse/plugins/fieldchoices.py
@@ -6,9 +6,10 @@ from django.contrib.databrowse.datastructures import EasyModel
from django.contrib.databrowse.sites import DatabrowsePlugin
from django.shortcuts import render_to_response
from django.utils.html import format_html, format_html_join
+from django.utils.http import urlquote
from django.utils.text import capfirst
-from django.utils.encoding import smart_str, force_unicode
-import urllib
+from django.utils.encoding import force_unicode
+
class FieldChoicePlugin(DatabrowsePlugin):
def __init__(self, field_filter=None):
@@ -38,11 +39,10 @@ class FieldChoicePlugin(DatabrowsePlugin):
def urls(self, plugin_name, easy_instance_field):
if easy_instance_field.field in self.field_dict(easy_instance_field.model.model).values():
- field_value = smart_str(easy_instance_field.raw_value)
return ['%s%s/%s/%s/' % (
easy_instance_field.model.url(),
plugin_name, easy_instance_field.field.name,
- urllib.quote(field_value, safe=''))]
+ urlquote(easy_instance_field.raw_value, safe=''))]
def model_view(self, request, model_databrowse, url):
self.model, self.site = model_databrowse.model, model_databrowse.site
diff --git a/django/contrib/databrowse/plugins/objects.py b/django/contrib/databrowse/plugins/objects.py
index 7326566655..e956f4ea67 100644
--- a/django/contrib/databrowse/plugins/objects.py
+++ b/django/contrib/databrowse/plugins/objects.py
@@ -1,14 +1,18 @@
+try:
+ from urllib.parse import urljoin
+except ImportError: # Python 2
+ from urlparse import urljoin
+
from django import http
from django.contrib.databrowse.datastructures import EasyModel
from django.contrib.databrowse.sites import DatabrowsePlugin
from django.shortcuts import render_to_response
-import urlparse
class ObjectDetailPlugin(DatabrowsePlugin):
def model_view(self, request, model_databrowse, url):
# If the object ID wasn't provided, redirect to the model page, which is one level up.
if url is None:
- return http.HttpResponseRedirect(urlparse.urljoin(request.path, '../'))
+ return http.HttpResponseRedirect(urljoin(request.path, '../'))
easy_model = EasyModel(model_databrowse.site, model_databrowse.model)
obj = easy_model.object_by_pk(url)
return render_to_response('databrowse/object_detail.html', {'object': obj, 'root_url': model_databrowse.site.root_url})
diff --git a/django/contrib/sitemaps/__init__.py b/django/contrib/sitemaps/__init__.py
index 53b375a48b..7d03ef19f5 100644
--- a/django/contrib/sitemaps/__init__.py
+++ b/django/contrib/sitemaps/__init__.py
@@ -1,7 +1,11 @@
from django.contrib.sites.models import Site
from django.core import urlresolvers, paginator
from django.core.exceptions import ImproperlyConfigured
-import urllib
+try:
+ from urllib.parse import urlencode
+ from urllib.request import urlopen
+except ImportError: # Python 2
+ from urllib import urlencode, urlopen
PING_URL = "http://www.google.com/webmasters/tools/ping"
@@ -32,8 +36,8 @@ def ping_google(sitemap_url=None, ping_url=PING_URL):
from django.contrib.sites.models import Site
current_site = Site.objects.get_current()
url = "http://%s%s" % (current_site.domain, sitemap_url)
- params = urllib.urlencode({'sitemap':url})
- urllib.urlopen("%s?%s" % (ping_url, params))
+ params = urlencode({'sitemap':url})
+ urlopen("%s?%s" % (ping_url, params))
class Sitemap(object):
# This limit is defined by Google. See the index documentation at
diff --git a/django/contrib/staticfiles/handlers.py b/django/contrib/staticfiles/handlers.py
index f475b22d9c..9067a0e75e 100644
--- a/django/contrib/staticfiles/handlers.py
+++ b/django/contrib/staticfiles/handlers.py
@@ -1,5 +1,9 @@
-import urllib
-from urlparse import urlparse
+try:
+ from urllib.parse import urlparse
+ from urllib.request import url2pathname
+except ImportError: # Python 2
+ from urllib import url2pathname
+ from urlparse import urlparse
from django.conf import settings
from django.core.handlers.wsgi import WSGIHandler
@@ -42,7 +46,7 @@ class StaticFilesHandler(WSGIHandler):
Returns the relative path to the media file on disk for the given URL.
"""
relative_url = url[len(self.base_url[2]):]
- return urllib.url2pathname(relative_url)
+ return url2pathname(relative_url)
def serve(self, request):
"""
diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py
index 47132831eb..a0133e1c6a 100644
--- a/django/contrib/staticfiles/storage.py
+++ b/django/contrib/staticfiles/storage.py
@@ -3,8 +3,11 @@ import hashlib
import os
import posixpath
import re
-from urllib import unquote
-from urlparse import urlsplit, urlunsplit, urldefrag
+try:
+ from urllib.parse import unquote, urlsplit, urlunsplit, urldefrag
+except ImportError: # Python 2
+ from urllib import unquote
+ from urlparse import urlsplit, urlunsplit, urldefrag
from django.conf import settings
from django.core.cache import (get_cache, InvalidCacheBackendError,
diff --git a/django/contrib/staticfiles/views.py b/django/contrib/staticfiles/views.py
index 1a9c166ad7..85459812ad 100644
--- a/django/contrib/staticfiles/views.py
+++ b/django/contrib/staticfiles/views.py
@@ -5,7 +5,10 @@ development, and SHOULD NOT be used in a production setting.
"""
import os
import posixpath
-import urllib
+try:
+ from urllib.parse import unquote
+except ImportError: # Python 2
+ from urllib import unquote
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
@@ -31,7 +34,7 @@ def serve(request, path, document_root=None, insecure=False, **kwargs):
raise ImproperlyConfigured("The staticfiles view can only be used in "
"debug mode or if the the --insecure "
"option of 'runserver' is used")
- normalized_path = posixpath.normpath(urllib.unquote(path)).lstrip('/')
+ normalized_path = posixpath.normpath(unquote(path)).lstrip('/')
absolute_path = finders.find(normalized_path)
if not absolute_path:
if path.endswith('/') or path == '':
diff --git a/django/core/cache/__init__.py b/django/core/cache/__init__.py
index 2a9e1a700b..f496c35e2b 100644
--- a/django/core/cache/__init__.py
+++ b/django/core/cache/__init__.py
@@ -14,7 +14,10 @@ cache class.
See docs/topics/cache.txt for information on the public API.
"""
-from urlparse import parse_qsl
+try:
+ from urllib.parse import parse_qsl
+except ImportError: # Python 2
+ from urlparse import parse_qsl
from django.conf import settings
from django.core import signals
diff --git a/django/core/files/storage.py b/django/core/files/storage.py
index ba88674dbd..5179980513 100644
--- a/django/core/files/storage.py
+++ b/django/core/files/storage.py
@@ -1,6 +1,9 @@
import os
import errno
-import urlparse
+try:
+ from urllib.parse import urljoin
+except ImportError: # Python 2
+ from urlparse import urljoin
import itertools
from datetime import datetime
@@ -252,7 +255,7 @@ class FileSystemStorage(Storage):
def url(self, name):
if self.base_url is None:
raise ValueError("This file is not accessible via a URL.")
- return urlparse.urljoin(self.base_url, filepath_to_uri(name))
+ return urljoin(self.base_url, filepath_to_uri(name))
def accessed_time(self, name):
return datetime.fromtimestamp(os.path.getatime(self.path(name)))
diff --git a/django/core/management/templates.py b/django/core/management/templates.py
index 623aa69deb..2bf2f661fd 100644
--- a/django/core/management/templates.py
+++ b/django/core/management/templates.py
@@ -8,7 +8,10 @@ import shutil
import stat
import sys
import tempfile
-import urllib
+try:
+ from urllib.request import urlretrieve
+except ImportError: # Python 2
+ from urllib import urlretrieve
from optparse import make_option
from os import path
@@ -227,8 +230,7 @@ class TemplateCommand(BaseCommand):
if self.verbosity >= 2:
self.stdout.write("Downloading %s\n" % display_url)
try:
- the_path, info = urllib.urlretrieve(url,
- path.join(tempdir, filename))
+ the_path, info = urlretrieve(url, path.join(tempdir, filename))
except IOError as e:
raise CommandError("couldn't download URL %s to %s: %s" %
(url, filename, e))
diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py
index be2962d660..f67b105397 100644
--- a/django/core/servers/basehttp.py
+++ b/django/core/servers/basehttp.py
@@ -11,8 +11,11 @@ import os
import socket
import sys
import traceback
-import urllib
-import urlparse
+try:
+ from urllib.parse import unquote, urljoin
+except ImportError: # Python 2
+ from urllib import unquote
+ from urlparse import urljoin
from SocketServer import ThreadingMixIn
from wsgiref import simple_server
from wsgiref.util import FileWrapper # for backwards compatibility
@@ -127,7 +130,7 @@ class WSGIRequestHandler(simple_server.WSGIRequestHandler, object):
def __init__(self, *args, **kwargs):
from django.conf import settings
- self.admin_static_prefix = urlparse.urljoin(settings.STATIC_URL, 'admin/')
+ self.admin_static_prefix = urljoin(settings.STATIC_URL, 'admin/')
# We set self.path to avoid crashes in log_message() on unsupported
# requests (like "OPTIONS").
self.path = ''
@@ -143,7 +146,7 @@ class WSGIRequestHandler(simple_server.WSGIRequestHandler, object):
else:
path,query = self.path,''
- env['PATH_INFO'] = urllib.unquote(path)
+ env['PATH_INFO'] = unquote(path)
env['QUERY_STRING'] = query
env['REMOTE_ADDR'] = self.client_address[0]
env['CONTENT_TYPE'] = self.headers.get('content-type', 'text/plain')
diff --git a/django/core/validators.py b/django/core/validators.py
index 47c1cbf1cd..03ff8be3bc 100644
--- a/django/core/validators.py
+++ b/django/core/validators.py
@@ -1,7 +1,10 @@
from __future__ import unicode_literals
import re
-import urlparse
+try:
+ from urllib.parse import urlsplit, urlunsplit
+except ImportError: # Python 2
+ from urlparse import urlsplit, urlunsplit
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
@@ -52,12 +55,12 @@ class URLValidator(RegexValidator):
# Trivial case failed. Try for possible IDN domain
if value:
value = smart_unicode(value)
- scheme, netloc, path, query, fragment = urlparse.urlsplit(value)
+ scheme, netloc, path, query, fragment = urlsplit(value)
try:
netloc = netloc.encode('idna') # IDN -> ACE
except UnicodeError: # invalid domain part
raise e
- url = urlparse.urlunsplit((scheme, netloc, path, query, fragment))
+ url = urlunsplit((scheme, netloc, path, query, fragment))
super(URLValidator, self).__call__(url)
else:
raise
diff --git a/django/forms/fields.py b/django/forms/fields.py
index 9c944ad0ac..c4a675da74 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -8,7 +8,10 @@ import copy
import datetime
import os
import re
-import urlparse
+try:
+ from urllib.parse import urlsplit, urlunsplit
+except ImportError: # Python 2
+ from urlparse import urlsplit, urlunsplit
from decimal import Decimal, DecimalException
from io import BytesIO
@@ -599,7 +602,7 @@ class URLField(CharField):
``ValidationError`` exception for certain).
"""
try:
- return list(urlparse.urlsplit(url))
+ return list(urlsplit(url))
except ValueError:
# urlparse.urlsplit can raise a ValueError with some
# misformatted URLs.
@@ -618,11 +621,11 @@ class URLField(CharField):
url_fields[2] = ''
# Rebuild the url_fields list, since the domain segment may now
# contain the path too.
- url_fields = split_url(urlparse.urlunsplit(url_fields))
+ url_fields = split_url(urlunsplit(url_fields))
if not url_fields[2]:
# the path portion may need to be added before query params
url_fields[2] = '/'
- value = urlparse.urlunsplit(url_fields)
+ value = urlunsplit(url_fields)
return value
class BooleanField(Field):
diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index f2446efcdf..6b1be37ec2 100644
--- a/django/forms/widgets.py
+++ b/django/forms/widgets.py
@@ -7,7 +7,10 @@ from __future__ import absolute_import, unicode_literals
import copy
import datetime
from itertools import chain
-from urlparse import urljoin
+try:
+ from urllib.parse import urljoin
+except ImportError: # Python 2
+ from urlparse import urljoin
from django.conf import settings
from django.forms.util import flatatt, to_current_timezone
diff --git a/django/http/__init__.py b/django/http/__init__.py
index 7c5184a329..da97506c8c 100644
--- a/django/http/__init__.py
+++ b/django/http/__init__.py
@@ -10,8 +10,11 @@ import warnings
from io import BytesIO
from pprint import pformat
-from urllib import urlencode, quote
-from urlparse import urljoin, parse_qsl
+try:
+ from urllib.parse import quote, parse_qsl, urlencode, urljoin
+except ImportError: # Python 2
+ from urllib import quote, urlencode
+ from urlparse import parse_qsl, urljoin
import Cookie
# Some versions of Python 2.7 and later won't need this encoding bug fix:
diff --git a/django/templatetags/static.py b/django/templatetags/static.py
index 4b2d66d521..5b0e40eba6 100644
--- a/django/templatetags/static.py
+++ b/django/templatetags/static.py
@@ -1,4 +1,8 @@
-from urlparse import urljoin
+try:
+ from urllib.parse import urljoin
+except ImportError: # Python 2
+ from urlparse import urljoin
+
from django import template
from django.template.base import Node
from django.utils.encoding import iri_to_uri
diff --git a/django/test/client.py b/django/test/client.py
index 7b6cdaa2a4..a18b7f8853 100644
--- a/django/test/client.py
+++ b/django/test/client.py
@@ -1,11 +1,14 @@
-import urllib
import sys
import os
import re
import mimetypes
from copy import copy
from io import BytesIO
-from urlparse import urlparse, urlsplit
+try:
+ from urllib.parse import unquote, urlparse, urlsplit
+except ImportError: # Python 2
+ from urllib import unquote
+ from urlparse import urlparse, urlsplit
from django.conf import settings
from django.contrib.auth import authenticate, login
@@ -222,9 +225,9 @@ class RequestFactory(object):
def _get_path(self, parsed):
# If there are parameters, add them
if parsed[3]:
- return urllib.unquote(parsed[2] + ";" + parsed[3])
+ return unquote(parsed[2] + ";" + parsed[3])
else:
- return urllib.unquote(parsed[2])
+ return unquote(parsed[2])
def get(self, path, data={}, **extra):
"Construct a GET request."
diff --git a/django/test/testcases.py b/django/test/testcases.py
index eb7bd70d12..b9aae21e8e 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -7,7 +7,10 @@ import re
import sys
from copy import copy
from functools import wraps
-from urlparse import urlsplit, urlunsplit
+try:
+ from urllib.parse import urlsplit, urlunsplit
+except ImportError: # Python 2
+ from urlparse import urlsplit, urlunsplit
from xml.dom.minidom import parseString, Node
import select
import socket
diff --git a/django/utils/encoding.py b/django/utils/encoding.py
index 789e709da5..f2295444bf 100644
--- a/django/utils/encoding.py
+++ b/django/utils/encoding.py
@@ -1,10 +1,13 @@
from __future__ import unicode_literals
-import urllib
-import locale
-import datetime
import codecs
+import datetime
from decimal import Decimal
+import locale
+try:
+ from urllib.parse import quote
+except ImportError: # Python 2
+ from urllib import quote
from django.utils.functional import Promise
from django.utils import six
@@ -165,7 +168,7 @@ def iri_to_uri(iri):
# converted.
if iri is None:
return iri
- return urllib.quote(smart_str(iri), safe=b"/#%[]=:;$&()+,!?*@'~")
+ return quote(smart_str(iri), safe=b"/#%[]=:;$&()+,!?*@'~")
def filepath_to_uri(path):
"""Convert an file system path to a URI portion that is suitable for
@@ -184,7 +187,7 @@ def filepath_to_uri(path):
return path
# I know about `os.sep` and `os.altsep` but I want to leave
# some flexibility for hardcoding separators.
- return urllib.quote(smart_str(path).replace("\\", "/"), safe=b"/~!*()'")
+ return quote(smart_str(path).replace("\\", "/"), safe=b"/~!*()'")
# The encoding of the default system locale but falls back to the
# given fallback encoding if the encoding is unsupported by python or could
diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py
index 3dc66a68c6..6498aaf57c 100644
--- a/django/utils/feedgenerator.py
+++ b/django/utils/feedgenerator.py
@@ -24,7 +24,10 @@ http://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004/
from __future__ import unicode_literals
import datetime
-import urlparse
+try:
+ from urllib.parse import urlparse
+except ImportError: # Python 2
+ from urlparse import urlparse
from django.utils.xmlutils import SimplerXMLGenerator
from django.utils.encoding import force_unicode, iri_to_uri
from django.utils import datetime_safe
@@ -67,7 +70,7 @@ def get_tag_uri(url, date):
See http://web.archive.org/web/20110514113830/http://diveintomark.org/archives/2004/05/28/howto-atom-id
"""
- bits = urlparse.urlparse(url)
+ bits = urlparse(url)
d = ''
if date is not None:
d = ',%s' % datetime_safe.new_datetime(date).strftime('%Y-%m-%d')
diff --git a/django/utils/html.py b/django/utils/html.py
index d5881996d9..7e35fdecb8 100644
--- a/django/utils/html.py
+++ b/django/utils/html.py
@@ -4,8 +4,11 @@ from __future__ import unicode_literals
import re
import string
-import urllib
-import urlparse
+try:
+ from urllib.parse import quote, urlsplit, urlunsplit
+except ImportError: # Python 2
+ from urllib import quote
+ from urlparse import urlsplit, urlunsplit
from django.utils.safestring import SafeData, mark_safe
from django.utils.encoding import smart_str, force_unicode
@@ -138,19 +141,19 @@ fix_ampersands = allow_lazy(fix_ampersands, six.text_type)
def smart_urlquote(url):
"Quotes a URL if it isn't already quoted."
# Handle IDN before quoting.
- scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
+ scheme, netloc, path, query, fragment = urlsplit(url)
try:
netloc = netloc.encode('idna') # IDN -> ACE
except UnicodeError: # invalid domain part
pass
else:
- url = urlparse.urlunsplit((scheme, netloc, path, query, fragment))
+ url = urlunsplit((scheme, netloc, path, query, fragment))
# An URL is considered unquoted if it contains no % characters or
# contains a % not followed by two hexadecimal digits. See #9655.
if '%' not in url or unquoted_percents_re.search(url):
# See http://bugs.python.org/issue2637
- url = urllib.quote(smart_str(url), safe=b'!*\'();:@&=+$,/?#[]~')
+ url = quote(smart_str(url), safe=b'!*\'();:@&=+$,/?#[]~')
return force_unicode(url)
diff --git a/django/utils/http.py b/django/utils/http.py
index ec94d62903..f3a3dce58c 100644
--- a/django/utils/http.py
+++ b/django/utils/http.py
@@ -2,8 +2,14 @@ import calendar
import datetime
import re
import sys
-import urllib
-import urlparse
+try:
+ from urllib import parse as urllib_parse
+except ImportError: # Python 2
+ import urllib as urllib_parse
+ import urlparse
+ urllib_parse.urlparse = urlparse.urlparse
+
+
from email.utils import formatdate
from django.utils.datastructures import MultiValueDict
@@ -31,7 +37,7 @@ def urlquote(url, safe='/'):
can safely be used as part of an argument to a subsequent iri_to_uri() call
without double-quoting occurring.
"""
- return force_unicode(urllib.quote(smart_str(url), smart_str(safe)))
+ return force_unicode(urllib_parse.quote(smart_str(url), smart_str(safe)))
urlquote = allow_lazy(urlquote, six.text_type)
def urlquote_plus(url, safe=''):
@@ -41,7 +47,7 @@ def urlquote_plus(url, safe=''):
returned string can safely be used as part of an argument to a subsequent
iri_to_uri() call without double-quoting occurring.
"""
- return force_unicode(urllib.quote_plus(smart_str(url), smart_str(safe)))
+ return force_unicode(urllib_parse.quote_plus(smart_str(url), smart_str(safe)))
urlquote_plus = allow_lazy(urlquote_plus, six.text_type)
def urlunquote(quoted_url):
@@ -49,7 +55,7 @@ def urlunquote(quoted_url):
A wrapper for Python's urllib.unquote() function that can operate on
the result of django.utils.http.urlquote().
"""
- return force_unicode(urllib.unquote(smart_str(quoted_url)))
+ return force_unicode(urllib_parse.unquote(smart_str(quoted_url)))
urlunquote = allow_lazy(urlunquote, six.text_type)
def urlunquote_plus(quoted_url):
@@ -57,7 +63,7 @@ def urlunquote_plus(quoted_url):
A wrapper for Python's urllib.unquote_plus() function that can operate on
the result of django.utils.http.urlquote_plus().
"""
- return force_unicode(urllib.unquote_plus(smart_str(quoted_url)))
+ return force_unicode(urllib_parse.unquote_plus(smart_str(quoted_url)))
urlunquote_plus = allow_lazy(urlunquote_plus, six.text_type)
def urlencode(query, doseq=0):
@@ -70,7 +76,7 @@ def urlencode(query, doseq=0):
query = query.lists()
elif hasattr(query, 'items'):
query = query.items()
- return urllib.urlencode(
+ return urllib_parse.urlencode(
[(smart_str(k),
[smart_str(i) for i in v] if isinstance(v, (list,tuple)) else smart_str(v))
for k, v in query],
@@ -212,5 +218,5 @@ def same_origin(url1, url2):
"""
Checks if two URLs are 'same-origin'
"""
- p1, p2 = urlparse.urlparse(url1), urlparse.urlparse(url2)
+ p1, p2 = urllib_parse.urlparse(url1), urllib_parse.urlparse(url2)
return (p1.scheme, p1.hostname, p1.port) == (p2.scheme, p2.hostname, p2.port)
diff --git a/django/views/static.py b/django/views/static.py
index 64f0b1c262..bcac9475e2 100644
--- a/django/views/static.py
+++ b/django/views/static.py
@@ -9,7 +9,10 @@ import os
import stat
import posixpath
import re
-import urllib
+try:
+ from urllib.parse import unquote
+except ImportError: # Python 2
+ from urllib import unquote
from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpResponseNotModified
from django.template import loader, Template, Context, TemplateDoesNotExist
@@ -30,7 +33,7 @@ def serve(request, path, document_root=None, show_indexes=False):
but if you'd like to override it, you can create a template called
``static/directory_index.html``.
"""
- path = posixpath.normpath(urllib.unquote(path))
+ path = posixpath.normpath(unquote(path))
path = path.lstrip('/')
newpath = ''
for part in path.split('/'):