diff --git a/wagtail/wagtailadmin/templatetags/gravatar.py b/wagtail/wagtailadmin/templatetags/gravatar.py
index 5c69f4fd2..15c161015 100644
--- a/wagtail/wagtailadmin/templatetags/gravatar.py
+++ b/wagtail/wagtailadmin/templatetags/gravatar.py
@@ -8,9 +8,10 @@
###
### just make sure to update the "default" image path below
-import urllib
import hashlib
+from six.moves.urllib.parse import urlencode
+
from django import template
register = template.Library()
@@ -31,7 +32,7 @@ class GravatarUrlNode(template.Node):
size = int(self.size) * 2 # requested at retina size by default and scaled down at point of use with css
gravatar_url = "//www.gravatar.com/avatar/" + hashlib.md5(email.lower()).hexdigest() + "?"
- gravatar_url += urllib.urlencode({'s': str(size), 'd': default})
+ gravatar_url += urlencode({'s': str(size), 'd': default})
return gravatar_url
diff --git a/wagtail/wagtailcore/models.py b/wagtail/wagtailcore/models.py
index 95730e334..77691e1b9 100644
--- a/wagtail/wagtailcore/models.py
+++ b/wagtail/wagtailcore/models.py
@@ -1,7 +1,8 @@
-from StringIO import StringIO
-from urlparse import urlparse
import warnings
+from six import StringIO
+from six.moves.urllib.parse import urlparse
+
from modelcluster.models import ClusterableModel
from django.db import models, connection, transaction
diff --git a/wagtail/wagtailcore/tests/test_management_commands.py b/wagtail/wagtailcore/tests/test_management_commands.py
index ae19167c2..1e3ff28e1 100644
--- a/wagtail/wagtailcore/tests/test_management_commands.py
+++ b/wagtail/wagtailcore/tests/test_management_commands.py
@@ -1,6 +1,7 @@
-from StringIO import StringIO
from datetime import timedelta
+from six import StringIO
+
from django.test import TestCase, Client
from django.http import HttpRequest, Http404
from django.core import management
diff --git a/wagtail/wagtailcore/tests/test_page_model.py b/wagtail/wagtailcore/tests/test_page_model.py
index 4cbdd9993..58c359d72 100644
--- a/wagtail/wagtailcore/tests/test_page_model.py
+++ b/wagtail/wagtailcore/tests/test_page_model.py
@@ -1,4 +1,4 @@
-from StringIO import StringIO
+from six import StringIO
from django.test import TestCase, Client
from django.http import HttpRequest, Http404
diff --git a/wagtail/wagtailcore/tests/test_page_permissions.py b/wagtail/wagtailcore/tests/test_page_permissions.py
index 111b059e6..eb2fe3257 100644
--- a/wagtail/wagtailcore/tests/test_page_permissions.py
+++ b/wagtail/wagtailcore/tests/test_page_permissions.py
@@ -1,4 +1,4 @@
-from StringIO import StringIO
+from six import StringIO
from django.test import TestCase, Client
from django.http import HttpRequest, Http404
diff --git a/wagtail/wagtailcore/tests/test_page_queryset.py b/wagtail/wagtailcore/tests/test_page_queryset.py
index 57599173c..2c4e46c9c 100644
--- a/wagtail/wagtailcore/tests/test_page_queryset.py
+++ b/wagtail/wagtailcore/tests/test_page_queryset.py
@@ -1,4 +1,4 @@
-from StringIO import StringIO
+from six import StringIO
from django.test import TestCase, Client
from django.http import HttpRequest, Http404
diff --git a/wagtail/wagtailcore/whitelist.py b/wagtail/wagtailcore/whitelist.py
index 9a5f67cf1..d82a2b2cd 100644
--- a/wagtail/wagtailcore/whitelist.py
+++ b/wagtail/wagtailcore/whitelist.py
@@ -2,8 +2,9 @@
A generic HTML whitelisting engine, designed to accommodate subclassing to override
specific rules.
"""
+from six.moves.urllib.parse import urlparse
+
from bs4 import BeautifulSoup, NavigableString, Tag
-from urlparse import urlparse
ALLOWED_URL_SCHEMES = ['', 'http', 'https', 'ftp', 'mailto', 'tel']
diff --git a/wagtail/wagtailembeds/embeds.py b/wagtail/wagtailembeds/embeds.py
index 2ec974d8a..ebc3e1491 100644
--- a/wagtail/wagtailembeds/embeds.py
+++ b/wagtail/wagtailembeds/embeds.py
@@ -1,4 +1,5 @@
import sys
+from datetime import datetime
try:
from importlib import import_module
@@ -6,13 +7,16 @@ except ImportError:
# for Python 2.6, fall back on django.utils.importlib (deprecated as of Django 1.7)
from django.utils.importlib import import_module
+from six.moves.urllib.request import urlopen, Request
+from six.moves.urllib.error import URLError
+from six.moves.urllib.parse import urlencode
+
from django.conf import settings
-from datetime import datetime
from django.utils import six
+
from wagtail.wagtailembeds.oembed_providers import get_oembed_provider
from wagtail.wagtailembeds.models import Embed
-import urllib2, urllib
-import json
+
class EmbedNotFoundException(Exception): pass
@@ -99,11 +103,11 @@ def oembed(url, max_width=None):
params['maxwidth'] = max_width
# Perform request
- request = urllib2.Request(provider + '?' + urllib.urlencode(params))
+ request = Request(provider + '?' + urlencode(params))
request.add_header('User-agent', 'Mozilla/5.0')
try:
- r = urllib2.urlopen(request)
- except urllib2.URLError:
+ r = urlopen(request)
+ except URLError:
raise EmbedNotFoundException
oembed = json.loads(r.read())
diff --git a/wagtail/wagtailembeds/tests.py b/wagtail/wagtailembeds/tests.py
index 405566981..cc67e6b9b 100644
--- a/wagtail/wagtailembeds/tests.py
+++ b/wagtail/wagtailembeds/tests.py
@@ -1,5 +1,6 @@
+from six.moves.urllib.request import urlopen
+
from mock import patch
-import urllib2
try:
import embedly
@@ -222,7 +223,7 @@ class TestOembed(TestCase):
self.assertRaises(EmbedNotFoundException, wagtail_oembed,
"http://www.youtube.com/watch/")
- @patch('urllib2.urlopen')
+ @patch('six.moves.urllib.request.urlopen')
@patch('json.loads')
def test_oembed_photo_request(self, loads, urlopen) :
urlopen.return_value = self.dummy_response
@@ -233,7 +234,7 @@ class TestOembed(TestCase):
self.assertEqual(result['html'], '
')
loads.assert_called_with("foo")
- @patch('urllib2.urlopen')
+ @patch('six.moves.urllib.request.urlopen')
@patch('json.loads')
def test_oembed_return_values(self, loads, urlopen):
urlopen.return_value = self.dummy_response
@@ -268,7 +269,7 @@ class TestEmbedFilter(TestCase):
return "foo"
self.dummy_response = DummyResponse()
- @patch('urllib2.urlopen')
+ @patch('six.moves.urllib.request.urlopen')
@patch('json.loads')
def test_valid_embed(self, loads, urlopen):
urlopen.return_value = self.dummy_response
@@ -277,7 +278,7 @@ class TestEmbedFilter(TestCase):
result = embed_filter('http://www.youtube.com/watch/')
self.assertEqual(result, '
')
- @patch('urllib2.urlopen')
+ @patch('six.moves.urllib.request.urlopenn')
@patch('json.loads')
def test_render_filter(self, loads, urlopen):
urlopen.return_value = self.dummy_response
@@ -288,7 +289,7 @@ class TestEmbedFilter(TestCase):
result = temp.render(context)
self.assertEqual(result, '
')
- @patch('urllib2.urlopen')
+ @patch('six.moves.urllib.request.urlopen')
@patch('json.loads')
def test_render_filter_nonexistent_type(self, loads, urlopen):
urlopen.return_value = self.dummy_response
@@ -307,7 +308,7 @@ class TestEmbedlyFilter(TestEmbedFilter):
return "foo"
self.dummy_response = DummyResponse()
- @patch('urllib2.urlopen')
+ @patch('six.moves.urllib.request.urlopen')
@patch('json.loads')
def test_valid_embed(self, loads, urlopen):
urlopen.return_value = self.dummy_response
@@ -316,7 +317,7 @@ class TestEmbedlyFilter(TestEmbedFilter):
result = embedly_filter('http://www.youtube.com/watch/')
self.assertEqual(result, '
')
- @patch('urllib2.urlopen')
+ @patch('six.moves.urllib.request.urlopen')
@patch('json.loads')
def test_render_filter(self, loads, urlopen):
urlopen.return_value = self.dummy_response
@@ -327,7 +328,7 @@ class TestEmbedlyFilter(TestEmbedFilter):
result = temp.render(context)
self.assertEqual(result, '
')
- @patch('urllib2.urlopen')
+ @patch('six.moves.urllib.request.urlopen')
@patch('json.loads')
def test_render_filter_nonexistent_type(self, loads, urlopen):
urlopen.return_value = self.dummy_response
diff --git a/wagtail/wagtailimages/models.py b/wagtail/wagtailimages/models.py
index 3ff2f9782..fe898b4d6 100644
--- a/wagtail/wagtailimages/models.py
+++ b/wagtail/wagtailimages/models.py
@@ -1,7 +1,8 @@
-import StringIO
import os.path
import re
+from six import BytesIO
+
from taggit.managers import TaggableManager
from django.core.files import File
@@ -208,7 +209,7 @@ class Filter(models.Model):
image = method(image, self.method_arg)
- output = StringIO.StringIO()
+ output = BytesIO()
backend.save_image(image, output, file_format)
# and then close the input file
diff --git a/wagtail/wagtailimages/tests.py b/wagtail/wagtailimages/tests.py
index 5b7b2fd14..af4f305e7 100644
--- a/wagtail/wagtailimages/tests.py
+++ b/wagtail/wagtailimages/tests.py
@@ -18,11 +18,11 @@ from wagtail.wagtailimages.backends import get_image_backend
from wagtail.wagtailimages.backends.pillow import PillowBackend
def get_test_image_file():
- from StringIO import StringIO
+ from six import BytesIO
from PIL import Image
from django.core.files.images import ImageFile
- f = StringIO()
+ f = BytesIO()
image = Image.new('RGB', (640, 480), 'white')
image.save(f, 'PNG')
return ImageFile(f, name='test.png')
diff --git a/wagtail/wagtailredirects/models.py b/wagtail/wagtailredirects/models.py
index 6440ad383..d04b4911e 100644
--- a/wagtail/wagtailredirects/models.py
+++ b/wagtail/wagtailredirects/models.py
@@ -3,7 +3,7 @@ from django.utils.translation import ugettext_lazy as _
from wagtail.wagtailadmin.edit_handlers import FieldPanel, MultiFieldPanel, PageChooserPanel
-from urlparse import urlparse
+from six.moves.urllib.parse import urlparse
class Redirect(models.Model):
diff --git a/wagtail/wagtailsearch/tests/test_backends.py b/wagtail/wagtailsearch/tests/test_backends.py
index fa7b4d9fa..e8a175f21 100644
--- a/wagtail/wagtailsearch/tests/test_backends.py
+++ b/wagtail/wagtailsearch/tests/test_backends.py
@@ -1,12 +1,14 @@
+from six import StringIO
+
from django.test import TestCase
from django.test.utils import override_settings
from django.conf import settings
from django.core import management
+
from wagtail.tests.utils import unittest
from wagtail.wagtailsearch import models, get_search_backend
from wagtail.wagtailsearch.backends.db import DBSearch
from wagtail.wagtailsearch.backends import InvalidSearchBackendError
-from StringIO import StringIO
# Register wagtailsearch signal handlers
diff --git a/wagtail/wagtailsearch/tests/test_queries.py b/wagtail/wagtailsearch/tests/test_queries.py
index fb47478a2..10785187e 100644
--- a/wagtail/wagtailsearch/tests/test_queries.py
+++ b/wagtail/wagtailsearch/tests/test_queries.py
@@ -1,4 +1,4 @@
-from StringIO import StringIO
+from six import StringIO
from django.test import TestCase
from django.core import management