← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:py3only-urllib-imports into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:py3only-urllib-imports into launchpad:master.

Commit message:
Stop using six.moves for urllib imports

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/420569

Largely mechanical, aided by `isort`.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:py3only-urllib-imports into launchpad:master.
diff --git a/lib/launchpad_loggerhead/app.py b/lib/launchpad_loggerhead/app.py
index 3e693f2..7697cc9 100644
--- a/lib/launchpad_loggerhead/app.py
+++ b/lib/launchpad_loggerhead/app.py
@@ -4,6 +4,10 @@
 import logging
 import os
 import threading
+from urllib.parse import (
+    urlencode,
+    urljoin,
+    )
 import xmlrpc.client
 
 from breezy import (
@@ -40,10 +44,6 @@ from paste.request import (
     parse_querystring,
     path_info_pop,
     )
-from six.moves.urllib.parse import (
-    urlencode,
-    urljoin,
-    )
 
 from lp.code.interfaces.codehosting import (
     BRANCH_TRANSPORT,
diff --git a/lib/launchpad_loggerhead/tests.py b/lib/launchpad_loggerhead/tests.py
index cad2ec3..52cd884 100644
--- a/lib/launchpad_loggerhead/tests.py
+++ b/lib/launchpad_loggerhead/tests.py
@@ -1,12 +1,13 @@
 # Copyright 2010-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from paste.httpexceptions import HTTPExceptionHandler
-import requests
-from six.moves.urllib_parse import (
+from urllib.parse import (
     urlencode,
     urlsplit,
     )
+
+from paste.httpexceptions import HTTPExceptionHandler
+import requests
 import soupmatchers
 from testtools.content import Content
 from testtools.content_type import UTF8_TEXT
diff --git a/lib/lp/answers/browser/faqcollection.py b/lib/lp/answers/browser/faqcollection.py
index a32ebca..a2fb420 100644
--- a/lib/lp/answers/browser/faqcollection.py
+++ b/lib/lp/answers/browser/faqcollection.py
@@ -8,7 +8,7 @@ __all__ = [
     'SearchFAQsView',
     ]
 
-from six.moves.urllib.parse import urlencode
+from urllib.parse import urlencode
 
 from lp import _
 from lp.answers.enums import (
diff --git a/lib/lp/answers/browser/questiontarget.py b/lib/lp/answers/browser/questiontarget.py
index 57d8caa..5eb0c08 100644
--- a/lib/lp/answers/browser/questiontarget.py
+++ b/lib/lp/answers/browser/questiontarget.py
@@ -19,13 +19,13 @@ __all__ = [
     ]
 
 from operator import attrgetter
+from urllib.parse import urlencode
 
 from lazr.restful.interfaces import (
     IJSONRequestCache,
     IWebServiceClientRequest,
     )
 from simplejson import dumps
-from six.moves.urllib.parse import urlencode
 from zope.browserpage import ViewPageTemplateFile
 from zope.component import (
     getMultiAdapter,
diff --git a/lib/lp/answers/browser/tests/test_questiontarget.py b/lib/lp/answers/browser/tests/test_questiontarget.py
index 307d038..386846f 100644
--- a/lib/lp/answers/browser/tests/test_questiontarget.py
+++ b/lib/lp/answers/browser/tests/test_questiontarget.py
@@ -5,12 +5,12 @@
 
 import json
 import os
+from urllib.parse import quote
 
 from lazr.restful.interfaces import (
     IJSONRequestCache,
     IWebServiceClientRequest,
     )
-from six.moves.urllib.parse import quote
 from zope.component import getUtility
 from zope.security.proxy import removeSecurityProxy
 from zope.traversing.browser import absoluteURL
diff --git a/lib/lp/app/browser/launchpad.py b/lib/lp/app/browser/launchpad.py
index 110a34a..c887a24 100644
--- a/lib/lp/app/browser/launchpad.py
+++ b/lib/lp/app/browser/launchpad.py
@@ -26,11 +26,11 @@ import operator
 import os
 import re
 import time
-
-from six.moves.urllib.parse import (
+from urllib.parse import (
     parse_qs,
     urlencode,
     )
+
 from zope import i18n
 from zope.component import (
     getGlobalSiteManager,
diff --git a/lib/lp/app/browser/tales.py b/lib/lp/app/browser/tales.py
index 304fb1b..cfe0af0 100644
--- a/lib/lp/app/browser/tales.py
+++ b/lib/lp/app/browser/tales.py
@@ -16,12 +16,12 @@ import math
 import os.path
 import sys
 from textwrap import dedent
+from urllib.parse import quote
 
 from lazr.enum import enumerated_type_registry
 from lazr.restful.utils import get_current_browser_request
 from lazr.uri import URI
 import pytz
-from six.moves.urllib.parse import quote
 from zope.browserpage import ViewPageTemplateFile
 from zope.component import (
     adapter,
diff --git a/lib/lp/app/browser/tests/test_vocabulary.py b/lib/lp/app/browser/tests/test_vocabulary.py
index 644c72d..8a04ba5 100644
--- a/lib/lp/app/browser/tests/test_vocabulary.py
+++ b/lib/lp/app/browser/tests/test_vocabulary.py
@@ -4,10 +4,10 @@
 """Test vocabulary adapters."""
 
 from datetime import datetime
+from urllib.parse import urlencode
 
 import pytz
 import simplejson
-from six.moves.urllib.parse import urlencode
 from zope.component import (
     getSiteManager,
     getUtility,
diff --git a/lib/lp/app/tests/test_services.py b/lib/lp/app/tests/test_services.py
index 0cbaee4..20f1670 100644
--- a/lib/lp/app/tests/test_services.py
+++ b/lib/lp/app/tests/test_services.py
@@ -4,10 +4,10 @@
 """Tests for core services infrastructure."""
 
 import json
+from urllib.parse import urlparse
 
 from fixtures import FakeLogger
 from lazr.restful.interfaces._rest import IHTTPResource
-from six.moves.urllib.parse import urlparse
 from zope.component import getUtility
 from zope.interface import implementer
 from zope.interface.interfaces import ComponentLookupError
diff --git a/lib/lp/app/validators/url.py b/lib/lp/app/validators/url.py
index dd29b7a..c90b4c9 100644
--- a/lib/lp/app/validators/url.py
+++ b/lib/lp/app/validators/url.py
@@ -10,8 +10,7 @@ __all__ = [
     ]
 
 from textwrap import dedent
-
-from six.moves.urllib.parse import urlsplit
+from urllib.parse import urlsplit
 
 from lp import _
 from lp.app.validators import LaunchpadValidationError
diff --git a/lib/lp/bugs/browser/buglisting.py b/lib/lp/bugs/browser/buglisting.py
index cbc365b..4fbb813 100644
--- a/lib/lp/bugs/browser/buglisting.py
+++ b/lib/lp/bugs/browser/buglisting.py
@@ -20,6 +20,12 @@ __all__ = [
     ]
 
 import os.path
+from urllib.parse import (
+    parse_qs,
+    parse_qsl,
+    quote,
+    urlencode,
+    )
 
 from lazr.delegates import delegate_to
 from lazr.restful.interfaces import IJSONRequestCache
@@ -27,12 +33,6 @@ from lazr.uri import URI
 import pystache
 from simplejson import dumps
 from simplejson.encoder import JSONEncoderForHTML
-from six.moves.urllib.parse import (
-    parse_qs,
-    parse_qsl,
-    quote,
-    urlencode,
-    )
 from zope.authentication.interfaces import IUnauthenticatedPrincipal
 from zope.browserpage import ViewPageTemplateFile
 from zope.component import (
diff --git a/lib/lp/bugs/browser/bugtarget.py b/lib/lp/bugs/browser/bugtarget.py
index cdceaea..1802a0e 100644
--- a/lib/lp/bugs/browser/bugtarget.py
+++ b/lib/lp/bugs/browser/bugtarget.py
@@ -21,15 +21,15 @@ from datetime import datetime
 from functools import partial
 import http.client
 from io import BytesIO
+from urllib.parse import (
+    quote,
+    urlencode,
+    )
 
 from lazr.restful.interface import copy_field
 from lazr.restful.interfaces import IJSONRequestCache
 from pytz import timezone
 from simplejson import dumps
-from six.moves.urllib.parse import (
-    quote,
-    urlencode,
-    )
 from zope.browserpage import ViewPageTemplateFile
 from zope.component import getUtility
 from zope.formlib.form import Fields
diff --git a/lib/lp/bugs/browser/bugtask.py b/lib/lp/bugs/browser/bugtask.py
index 6e85112..7af4f94 100644
--- a/lib/lp/bugs/browser/bugtask.py
+++ b/lib/lp/bugs/browser/bugtask.py
@@ -33,6 +33,7 @@ from datetime import (
 from itertools import groupby
 from operator import attrgetter
 import re
+from urllib.parse import quote
 
 from lazr.delegates import delegate_to
 from lazr.lifecycle.event import ObjectModifiedEvent
@@ -47,7 +48,6 @@ from lazr.restful.interfaces import (
 from lazr.restful.utils import smartquote
 from pytz import utc
 from simplejson import dumps
-from six.moves.urllib.parse import quote
 import transaction
 from zope import formlib
 from zope.browserpage import ViewPageTemplateFile
diff --git a/lib/lp/bugs/browser/person.py b/lib/lp/bugs/browser/person.py
index 4b5de77..d9bc4b6 100644
--- a/lib/lp/bugs/browser/person.py
+++ b/lib/lp/bugs/browser/person.py
@@ -16,8 +16,8 @@ __all__ = [
 
 import copy
 from operator import itemgetter
+from urllib.parse import urlencode
 
-from six.moves.urllib.parse import urlencode
 from zope.component import getUtility
 
 from lp.bugs.browser.buglisting import BugTaskSearchListingView
diff --git a/lib/lp/bugs/browser/tests/test_bugattachment_file_access.py b/lib/lp/bugs/browser/tests/test_bugattachment_file_access.py
index 3b48f29..52c2e36 100644
--- a/lib/lp/bugs/browser/tests/test_bugattachment_file_access.py
+++ b/lib/lp/bugs/browser/tests/test_bugattachment_file_access.py
@@ -2,13 +2,13 @@
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 import re
-
-import requests
-from six.moves.urllib.parse import (
+from urllib.parse import (
     parse_qs,
     urlparse,
     urlunparse,
     )
+
+import requests
 import transaction
 from zope.component import (
     getMultiAdapter,
diff --git a/lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py b/lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py
index 23f9c99..45ec289 100644
--- a/lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py
+++ b/lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py
@@ -4,9 +4,9 @@
 """Tests for bug subscription filter browser code."""
 
 import json
+from urllib.parse import urlparse
 
 from lxml import html
-from six.moves.urllib.parse import urlparse
 from testtools.matchers import StartsWith
 
 from lp.app.enums import InformationType
diff --git a/lib/lp/bugs/browser/tests/test_bugtask.py b/lib/lp/bugs/browser/tests/test_bugtask.py
index 9c13e86..4394120 100644
--- a/lib/lp/bugs/browser/tests/test_bugtask.py
+++ b/lib/lp/bugs/browser/tests/test_bugtask.py
@@ -6,12 +6,12 @@ from datetime import (
     timedelta,
     )
 import re
+from urllib.parse import urlencode
 
 from lazr.restful.interfaces import IJSONRequestCache
 from pytz import UTC
 import simplejson
 import six
-from six.moves.urllib.parse import urlencode
 import soupmatchers
 from testscenarios import (
     load_tests_apply_scenarios,
diff --git a/lib/lp/bugs/browser/tests/test_structuralsubscription.py b/lib/lp/bugs/browser/tests/test_structuralsubscription.py
index a6fd6a9..5aacbdb 100644
--- a/lib/lp/bugs/browser/tests/test_structuralsubscription.py
+++ b/lib/lp/bugs/browser/tests/test_structuralsubscription.py
@@ -3,7 +3,8 @@
 
 """Tests for structural subscription traversal."""
 
-from six.moves.urllib.parse import urlparse
+from urllib.parse import urlparse
+
 from zope.publisher.interfaces import NotFound
 
 from lp.registry.browser.distribution import DistributionNavigation
diff --git a/lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt b/lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt
index 8c76531..6e5865f 100644
--- a/lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt
+++ b/lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt
@@ -31,7 +31,7 @@ Trac to validate $token and return a Set-Cookie header.
 
     >>> import random
     >>> import re
-    >>> from six.moves.urllib_parse import (
+    >>> from urllib.parse import (
     ...     urljoin,
     ...     urlsplit,
     ...     )
diff --git a/lib/lp/bugs/doc/sourceforge-remote-products.txt b/lib/lp/bugs/doc/sourceforge-remote-products.txt
index 8f15721..edd70ce 100644
--- a/lib/lp/bugs/doc/sourceforge-remote-products.txt
+++ b/lib/lp/bugs/doc/sourceforge-remote-products.txt
@@ -41,8 +41,8 @@ Define some request mocks so that we don't try to access SourceForge.
 
     >>> import os.path
     >>> import re
+    >>> from urllib.parse import urlsplit
     >>> import responses
-    >>> from six.moves.urllib_parse import urlsplit
 
     >>> def project_callback(request):
     ...     url = urlsplit(request.url)
diff --git a/lib/lp/bugs/externalbugtracker/base.py b/lib/lp/bugs/externalbugtracker/base.py
index 6ebd4bc..8cf7f0e 100644
--- a/lib/lp/bugs/externalbugtracker/base.py
+++ b/lib/lp/bugs/externalbugtracker/base.py
@@ -26,11 +26,12 @@ __all__ = [
     ]
 
 
-import requests
-from six.moves.urllib_parse import (
+from urllib.parse import (
     urljoin,
     urlparse,
     )
+
+import requests
 from zope.interface import implementer
 
 from lp.bugs.adapters import treelookup
diff --git a/lib/lp/bugs/externalbugtracker/github.py b/lib/lp/bugs/externalbugtracker/github.py
index 4e686ee..8f45e4d 100644
--- a/lib/lp/bugs/externalbugtracker/github.py
+++ b/lib/lp/bugs/externalbugtracker/github.py
@@ -13,13 +13,13 @@ __all__ = [
 from contextlib import contextmanager
 import http.client
 import time
-
-import pytz
-import requests
-from six.moves.urllib.parse import (
+from urllib.parse import (
     urlencode,
     urlunsplit,
     )
+
+import pytz
+import requests
 from zope.component import getUtility
 from zope.interface import Interface
 
diff --git a/lib/lp/bugs/externalbugtracker/gitlab.py b/lib/lp/bugs/externalbugtracker/gitlab.py
index cc7ac40..444fcb1 100644
--- a/lib/lp/bugs/externalbugtracker/gitlab.py
+++ b/lib/lp/bugs/externalbugtracker/gitlab.py
@@ -9,14 +9,14 @@ __all__ = [
     ]
 
 import http.client
-
-import pytz
-from six.moves.urllib.parse import (
+from urllib.parse import (
     quote,
     quote_plus,
     urlunsplit,
     )
 
+import pytz
+
 from lp.bugs.externalbugtracker import (
     BugTrackerConnectError,
     ExternalBugTracker,
diff --git a/lib/lp/bugs/externalbugtracker/mantis.py b/lib/lp/bugs/externalbugtracker/mantis.py
index 40562da..bf10470 100644
--- a/lib/lp/bugs/externalbugtracker/mantis.py
+++ b/lib/lp/bugs/externalbugtracker/mantis.py
@@ -11,15 +11,15 @@ __all__ = [
 import csv
 import logging
 import re
-
-from bs4.element import Comment
-from requests.cookies import RequestsCookieJar
-from six.moves.urllib_parse import (
+from urllib.parse import (
     parse_qsl,
     urlencode,
     urlunparse,
     )
 
+from bs4.element import Comment
+from requests.cookies import RequestsCookieJar
+
 from lp.bugs.externalbugtracker import (
     BugNotFound,
     BugTrackerConnectError,
diff --git a/lib/lp/bugs/externalbugtracker/roundup.py b/lib/lp/bugs/externalbugtracker/roundup.py
index 2bd3de2..84e7967 100644
--- a/lib/lp/bugs/externalbugtracker/roundup.py
+++ b/lib/lp/bugs/externalbugtracker/roundup.py
@@ -6,9 +6,9 @@
 __all__ = ['Roundup']
 
 import csv
+from urllib.parse import quote_plus
 
 from lazr.uri import URI
-from six.moves.urllib.parse import quote_plus
 
 from lp.bugs.externalbugtracker import (
     BugNotFound,
diff --git a/lib/lp/bugs/externalbugtracker/tests/test_github.py b/lib/lp/bugs/externalbugtracker/tests/test_github.py
index 87cdafa..b7644b5 100644
--- a/lib/lp/bugs/externalbugtracker/tests/test_github.py
+++ b/lib/lp/bugs/externalbugtracker/tests/test_github.py
@@ -5,14 +5,14 @@
 
 from datetime import datetime
 import json
-
-import pytz
-import responses
-from six.moves.urllib_parse import (
+from urllib.parse import (
     parse_qs,
     urlsplit,
     urlunsplit,
     )
+
+import pytz
+import responses
 from testtools import ExpectedException
 from testtools.matchers import (
     Contains,
diff --git a/lib/lp/bugs/externalbugtracker/tests/test_gitlab.py b/lib/lp/bugs/externalbugtracker/tests/test_gitlab.py
index 9fd7351..2ed17bf 100644
--- a/lib/lp/bugs/externalbugtracker/tests/test_gitlab.py
+++ b/lib/lp/bugs/externalbugtracker/tests/test_gitlab.py
@@ -5,14 +5,14 @@
 
 from datetime import datetime
 import json
-
-import pytz
-import responses
-from six.moves.urllib_parse import (
+from urllib.parse import (
     parse_qs,
     urlsplit,
     urlunsplit,
     )
+
+import pytz
+import responses
 from testtools.matchers import (
     Contains,
     ContainsDict,
diff --git a/lib/lp/bugs/externalbugtracker/tests/test_mantis.py b/lib/lp/bugs/externalbugtracker/tests/test_mantis.py
index 99de31b..3fc3010 100644
--- a/lib/lp/bugs/externalbugtracker/tests/test_mantis.py
+++ b/lib/lp/bugs/externalbugtracker/tests/test_mantis.py
@@ -3,8 +3,9 @@
 
 """Tests for the Mantis BugTracker."""
 
+from urllib.parse import urljoin
+
 import responses
-from six.moves.urllib_parse import urljoin
 from testtools.matchers import (
     Equals,
     Is,
diff --git a/lib/lp/bugs/externalbugtracker/xmlrpc.py b/lib/lp/bugs/externalbugtracker/xmlrpc.py
index 6d63fe9..228a9de 100644
--- a/lib/lp/bugs/externalbugtracker/xmlrpc.py
+++ b/lib/lp/bugs/externalbugtracker/xmlrpc.py
@@ -9,6 +9,10 @@ __all__ = [
 
 
 from io import BytesIO
+from urllib.parse import (
+    urlparse,
+    urlunparse,
+    )
 from xmlrpc.client import (
     ProtocolError,
     Transport,
@@ -18,10 +22,6 @@ from defusedxml.xmlrpc import monkey_patch
 import requests
 from requests.cookies import RequestsCookieJar
 import six
-from six.moves.urllib.parse import (
-    urlparse,
-    urlunparse,
-    )
 
 from lp.bugs.externalbugtracker.base import repost_on_redirect_hook
 from lp.services.config import config
diff --git a/lib/lp/bugs/model/bugtracker.py b/lib/lp/bugs/model/bugtracker.py
index a8070ae..9106ffe 100644
--- a/lib/lp/bugs/model/bugtracker.py
+++ b/lib/lp/bugs/model/bugtracker.py
@@ -12,15 +12,15 @@ __all__ = [
 
 from datetime import datetime
 from itertools import chain
-
-from lazr.uri import URI
-from pytz import timezone
-import six
-from six.moves.urllib.parse import (
+from urllib.parse import (
     quote,
     urlsplit,
     urlunsplit,
     )
+
+from lazr.uri import URI
+from pytz import timezone
+import six
 from storm.expr import (
     Count,
     Desc,
diff --git a/lib/lp/bugs/stories/bug-also-affects/xx-upstream-bugtracker-links.txt b/lib/lp/bugs/stories/bug-also-affects/xx-upstream-bugtracker-links.txt
index 1d29a68..d3656ca 100644
--- a/lib/lp/bugs/stories/bug-also-affects/xx-upstream-bugtracker-links.txt
+++ b/lib/lp/bugs/stories/bug-also-affects/xx-upstream-bugtracker-links.txt
@@ -74,7 +74,7 @@ will be displayed.
 The description given in the link to the bug filing form contains a
 link back to bug 13, the place where it was originally filed.
 
-    >>> from six.moves.urllib.parse import (
+    >>> from urllib.parse import (
     ...     parse_qs,
     ...     urlparse,
     ...     )
diff --git a/lib/lp/bugs/stories/bugs/xx-bugs-advanced-search-upstream-status.txt b/lib/lp/bugs/stories/bugs/xx-bugs-advanced-search-upstream-status.txt
index bf2bed7..2211cbc 100644
--- a/lib/lp/bugs/stories/bugs/xx-bugs-advanced-search-upstream-status.txt
+++ b/lib/lp/bugs/stories/bugs/xx-bugs-advanced-search-upstream-status.txt
@@ -144,7 +144,7 @@ status. Bookmarks of such searches work nevertheless.
 
 The user opens a bookmark for "upstream status doesn't matter"
 
-    >>> from six.moves.urllib.parse import urlencode
+    >>> from urllib.parse import urlencode
     >>> bookmark_params = {
     ...     'field.status_upstream': '',
     ...     'field.status_upstream-empty-marker': '1',
diff --git a/lib/lp/bugs/stories/bugtask-searches/xx-old-urls-still-work.txt b/lib/lp/bugs/stories/bugtask-searches/xx-old-urls-still-work.txt
index 2992c0b..9bf67e9 100644
--- a/lib/lp/bugs/stories/bugtask-searches/xx-old-urls-still-work.txt
+++ b/lib/lp/bugs/stories/bugtask-searches/xx-old-urls-still-work.txt
@@ -22,7 +22,7 @@ The user is redirected to a new url to make the change explicit, and
 to allow user agents (and users) to update bookmarks, etc.
 
     >>> def print_query_changes(query_string_before, query_string_after):
-    ...     from six.moves.urllib.parse import parse_qsl
+    ...     from urllib.parse import parse_qsl
     ...     query_before = parse_qsl(
     ...         query_string_before, keep_blank_values=True)
     ...     query_after = parse_qsl(
diff --git a/lib/lp/bugs/stories/webservice/xx-bug.txt b/lib/lp/bugs/stories/webservice/xx-bug.txt
index e19ef0f..718e63c 100644
--- a/lib/lp/bugs/stories/webservice/xx-bug.txt
+++ b/lib/lp/bugs/stories/webservice/xx-bug.txt
@@ -1335,7 +1335,7 @@ we must follow to download the data.
     Location: http://.../numbers.txt
     ...
 
-    >>> from six.moves.urllib.request import urlopen
+    >>> from urllib.request import urlopen
 
     >>> data = None
     >>> conn = urlopen(data_response.getHeader('Location'))
diff --git a/lib/lp/bugs/tests/externalbugtracker.py b/lib/lp/bugs/tests/externalbugtracker.py
index a7706d7..11dcaab 100644
--- a/lib/lp/bugs/tests/externalbugtracker.py
+++ b/lib/lp/bugs/tests/externalbugtracker.py
@@ -14,14 +14,14 @@ import os
 import random
 import re
 import time
-import xmlrpc.client
-
-import responses
-from six.moves.urllib_parse import (
+from urllib.parse import (
     parse_qs,
     urljoin,
     urlsplit,
     )
+import xmlrpc.client
+
+import responses
 from zope.component import getUtility
 from zope.security.proxy import removeSecurityProxy
 
diff --git a/lib/lp/bugs/tests/test_bugtracker.py b/lib/lp/bugs/tests/test_bugtracker.py
index 59f4e7d..d4a3e28 100644
--- a/lib/lp/bugs/tests/test_bugtracker.py
+++ b/lib/lp/bugs/tests/test_bugtracker.py
@@ -11,11 +11,11 @@ from doctest import (
     NORMALIZE_WHITESPACE,
     )
 import unittest
+from urllib.parse import urlencode
 
 from lazr.lifecycle.snapshot import Snapshot
 from pytz import utc
 import responses
-from six.moves.urllib_parse import urlencode
 from testtools.matchers import (
     Equals,
     MatchesListwise,
diff --git a/lib/lp/bugs/tests/test_bugwatch.py b/lib/lp/bugs/tests/test_bugwatch.py
index 402253b..9a363d5 100644
--- a/lib/lp/bugs/tests/test_bugwatch.py
+++ b/lib/lp/bugs/tests/test_bugwatch.py
@@ -8,10 +8,10 @@ from datetime import (
     timedelta,
     )
 import re
+from urllib.parse import urlunsplit
 
 from lazr.lifecycle.snapshot import Snapshot
 from pytz import utc
-from six.moves.urllib.parse import urlunsplit
 from storm.store import Store
 from testscenarios import (
     load_tests_apply_scenarios,
diff --git a/lib/lp/buildmaster/interactor.py b/lib/lp/buildmaster/interactor.py
index 679d5c6..eed2b23 100644
--- a/lib/lp/buildmaster/interactor.py
+++ b/lib/lp/buildmaster/interactor.py
@@ -14,10 +14,10 @@ import logging
 import os.path
 import sys
 import traceback
+from urllib.parse import urlparse
 
 from ampoule.pool import ProcessPool
 import six
-from six.moves.urllib.parse import urlparse
 import transaction
 from twisted.internet import (
     defer,
diff --git a/lib/lp/buildmaster/tests/builderproxy.py b/lib/lp/buildmaster/tests/builderproxy.py
index 82197ed..356bc0f 100644
--- a/lib/lp/buildmaster/tests/builderproxy.py
+++ b/lib/lp/buildmaster/tests/builderproxy.py
@@ -6,10 +6,10 @@
 from datetime import datetime
 import json
 from textwrap import dedent
+from urllib.parse import urlsplit
 import uuid
 
 import fixtures
-from six.moves.urllib_parse import urlsplit
 from testtools.matchers import (
     Equals,
     HasLength,
diff --git a/lib/lp/charms/tests/test_charmrecipebuildbehaviour.py b/lib/lp/charms/tests/test_charmrecipebuildbehaviour.py
index 6cd8791..a473487 100644
--- a/lib/lp/charms/tests/test_charmrecipebuildbehaviour.py
+++ b/lib/lp/charms/tests/test_charmrecipebuildbehaviour.py
@@ -7,11 +7,11 @@ import base64
 from datetime import datetime
 import os.path
 import time
+from urllib.parse import urlsplit
 import uuid
 
 from fixtures import MockPatch
 from pymacaroons import Macaroon
-from six.moves.urllib_parse import urlsplit
 from testtools import ExpectedException
 from testtools.matchers import (
     ContainsDict,
diff --git a/lib/lp/code/browser/branchlisting.py b/lib/lp/code/browser/branchlisting.py
index 56e26b2..eee45b8 100644
--- a/lib/lp/code/browser/branchlisting.py
+++ b/lib/lp/code/browser/branchlisting.py
@@ -25,13 +25,13 @@ __all__ = [
     ]
 
 from operator import attrgetter
+from urllib.parse import parse_qs
 
 from lazr.delegates import delegate_to
 from lazr.enum import (
     EnumeratedType,
     Item,
     )
-from six.moves.urllib.parse import parse_qs
 from storm.expr import Desc
 from zope.browserpage import ViewPageTemplateFile
 from zope.component import getUtility
diff --git a/lib/lp/code/browser/branchmergeproposal.py b/lib/lp/code/browser/branchmergeproposal.py
index 4e89019..fcaddeb 100644
--- a/lib/lp/code/browser/branchmergeproposal.py
+++ b/lib/lp/code/browser/branchmergeproposal.py
@@ -26,6 +26,10 @@ __all__ = [
 
 from functools import wraps
 import operator
+from urllib.parse import (
+    urlsplit,
+    urlunsplit,
+    )
 
 from lazr.delegates import delegate_to
 from lazr.restful.interface import copy_field
@@ -34,10 +38,6 @@ from lazr.restful.interfaces import (
     IWebServiceClientRequest,
     )
 import simplejson
-from six.moves.urllib_parse import (
-    urlsplit,
-    urlunsplit,
-    )
 from zope.component import (
     adapter,
     getMultiAdapter,
diff --git a/lib/lp/code/browser/codeimport.py b/lib/lp/code/browser/codeimport.py
index 5ecf7d4..33a2cd4 100644
--- a/lib/lp/code/browser/codeimport.py
+++ b/lib/lp/code/browser/codeimport.py
@@ -18,12 +18,12 @@ __all__ = [
     ]
 
 from textwrap import dedent
+from urllib.parse import urlparse
 
 from lazr.restful.interface import (
     copy_field,
     use_template,
     )
-from six.moves.urllib.parse import urlparse
 from zope.component import (
     getUtility,
     queryAdapter,
diff --git a/lib/lp/code/browser/gitref.py b/lib/lp/code/browser/gitref.py
index fedff3e..bc72f3a 100644
--- a/lib/lp/code/browser/gitref.py
+++ b/lib/lp/code/browser/gitref.py
@@ -10,14 +10,14 @@ __all__ = [
     ]
 
 import json
-
-from breezy import urlutils
-from lazr.restful.interface import copy_field
-from six.moves.urllib_parse import (
+from urllib.parse import (
     quote_plus,
     urlsplit,
     urlunsplit,
     )
+
+from breezy import urlutils
+from lazr.restful.interface import copy_field
 from zope.component import getUtility
 from zope.formlib.widget import CustomWidgetFactory
 from zope.formlib.widgets import TextAreaWidget
diff --git a/lib/lp/code/browser/gitrepository.py b/lib/lp/code/browser/gitrepository.py
index 072f626..96a6ce0 100644
--- a/lib/lp/code/browser/gitrepository.py
+++ b/lib/lp/code/browser/gitrepository.py
@@ -23,6 +23,10 @@ __all__ = [
 import base64
 import binascii
 from collections import defaultdict
+from urllib.parse import (
+    urlsplit,
+    urlunsplit,
+    )
 
 from breezy import urlutils
 from lazr.lifecycle.event import ObjectModifiedEvent
@@ -31,10 +35,6 @@ from lazr.restful.interface import (
     copy_field,
     use_template,
     )
-from six.moves.urllib_parse import (
-    urlsplit,
-    urlunsplit,
-    )
 from zope.component import getUtility
 from zope.event import notify
 from zope.formlib import form
diff --git a/lib/lp/code/browser/tests/test_gitsubscription.py b/lib/lp/code/browser/tests/test_gitsubscription.py
index 1fb5fb7..6f2a5a6 100644
--- a/lib/lp/code/browser/tests/test_gitsubscription.py
+++ b/lib/lp/code/browser/tests/test_gitsubscription.py
@@ -3,8 +3,9 @@
 
 """Unit tests for GitSubscriptions."""
 
+from urllib.parse import urlencode
+
 from fixtures import FakeLogger
-from six.moves.urllib.parse import urlencode
 from testtools.matchers import MatchesStructure
 from zope.security.interfaces import Unauthorized
 from zope.testbrowser.browser import LinkNotFoundError
diff --git a/lib/lp/code/interfaces/codehosting.py b/lib/lp/code/interfaces/codehosting.py
index 91bce70..07a9411 100644
--- a/lib/lp/code/interfaces/codehosting.py
+++ b/lib/lp/code/interfaces/codehosting.py
@@ -21,10 +21,10 @@ __all__ = [
     ]
 
 import os.path
+from urllib.parse import quote
 
 from lazr.uri import URI
 import six
-from six.moves.urllib.parse import quote
 from zope.interface import Interface
 
 from lp.app.validators.name import valid_name
diff --git a/lib/lp/code/model/branch.py b/lib/lp/code/model/branch.py
index fc7da1a..2b940ba 100644
--- a/lib/lp/code/model/branch.py
+++ b/lib/lp/code/model/branch.py
@@ -11,6 +11,7 @@ from datetime import datetime
 from functools import partial
 import operator
 import os.path
+from urllib.parse import urlsplit
 
 from breezy import urlutils
 from breezy.revision import NULL_REVISION
@@ -18,7 +19,6 @@ from breezy.url_policy_open import open_only_scheme
 from lazr.lifecycle.event import ObjectCreatedEvent
 import pytz
 import six
-from six.moves.urllib_parse import urlsplit
 from storm.expr import (
     And,
     Coalesce,
diff --git a/lib/lp/code/model/branchhosting.py b/lib/lp/code/model/branchhosting.py
index 3911c16..c585df2 100644
--- a/lib/lp/code/model/branchhosting.py
+++ b/lib/lp/code/model/branchhosting.py
@@ -9,13 +9,13 @@ __all__ = [
 
 import json
 import sys
-
-from lazr.restful.utils import get_current_browser_request
-import requests
-from six.moves.urllib_parse import (
+from urllib.parse import (
     quote,
     urljoin,
     )
+
+from lazr.restful.utils import get_current_browser_request
+import requests
 from zope.interface import implementer
 
 from lp.code.errors import (
diff --git a/lib/lp/code/model/githosting.py b/lib/lp/code/model/githosting.py
index c5ade39..675b1eb 100644
--- a/lib/lp/code/model/githosting.py
+++ b/lib/lp/code/model/githosting.py
@@ -11,14 +11,14 @@ __all__ = [
 import base64
 import json
 import sys
+from urllib.parse import (
+    quote,
+    urljoin,
+    )
 
 from lazr.restful.utils import get_current_browser_request
 import requests
 from six import ensure_text
-from six.moves.urllib.parse import (
-    quote,
-    urljoin,
-    )
 from zope.interface import implementer
 
 from lp.code.errors import (
diff --git a/lib/lp/code/model/gitref.py b/lib/lp/code/model/gitref.py
index a3ef756..f91d1e5 100644
--- a/lib/lp/code/model/gitref.py
+++ b/lib/lp/code/model/gitref.py
@@ -10,16 +10,16 @@ __all__ = [
 
 from functools import partial
 import re
+from urllib.parse import (
+    quote,
+    quote_plus,
+    urlsplit,
+    )
 
 from lazr.lifecycle.event import ObjectCreatedEvent
 import pytz
 import requests
 import six
-from six.moves.urllib.parse import (
-    quote,
-    quote_plus,
-    urlsplit,
-    )
 from storm.expr import And
 from storm.locals import (
     DateTime,
diff --git a/lib/lp/code/model/gitrepository.py b/lib/lp/code/model/gitrepository.py
index f1a9dfa..39ffda1 100644
--- a/lib/lp/code/model/gitrepository.py
+++ b/lib/lp/code/model/gitrepository.py
@@ -25,6 +25,11 @@ from itertools import (
     )
 import logging
 from operator import attrgetter
+from urllib.parse import (
+    quote_plus,
+    urlsplit,
+    urlunsplit,
+    )
 
 from breezy import urlutils
 from lazr.enum import DBItem
@@ -32,11 +37,6 @@ from lazr.lifecycle.event import ObjectModifiedEvent
 from lazr.lifecycle.snapshot import Snapshot
 import pytz
 import six
-from six.moves.urllib.parse import (
-    quote_plus,
-    urlsplit,
-    urlunsplit,
-    )
 from storm.databases.postgres import Returning
 from storm.expr import (
     And,
diff --git a/lib/lp/code/model/tests/test_githosting.py b/lib/lp/code/model/tests/test_githosting.py
index ea1ebbd..ef7802c 100644
--- a/lib/lp/code/model/tests/test_githosting.py
+++ b/lib/lp/code/model/tests/test_githosting.py
@@ -11,13 +11,13 @@ import base64
 from contextlib import contextmanager
 import json
 import re
-
-from lazr.restful.utils import get_current_browser_request
-import responses
-from six.moves.urllib.parse import (
+from urllib.parse import (
     parse_qsl,
     urlsplit,
     )
+
+from lazr.restful.utils import get_current_browser_request
+import responses
 from testtools.matchers import (
     AfterPreprocessing,
     Equals,
diff --git a/lib/lp/code/stories/branches/xx-private-branch-listings.txt b/lib/lp/code/stories/branches/xx-private-branch-listings.txt
index c775877..3e7fa21 100644
--- a/lib/lp/code/stories/branches/xx-private-branch-listings.txt
+++ b/lib/lp/code/stories/branches/xx-private-branch-listings.txt
@@ -145,7 +145,7 @@ Person code listing pages
 The person code listings is the other obvious place to filter out the
 viewable branches.
 
-    >>> from six.moves.urllib.parse import urlencode
+    >>> from urllib.parse import urlencode
     >>> def print_person_code_listing(browser, category=None):
     ...     params = {'batch': '15'}
     ...     if category is not None:
diff --git a/lib/lp/code/stories/branches/xx-subscribing-branches.txt b/lib/lp/code/stories/branches/xx-subscribing-branches.txt
index 1974c42..5db15a2 100644
--- a/lib/lp/code/stories/branches/xx-subscribing-branches.txt
+++ b/lib/lp/code/stories/branches/xx-subscribing-branches.txt
@@ -120,7 +120,7 @@ shown to the user.
 Clicking the back button and then clicking on either Change or
 Unsubscribe will give a message that we are not subscribed.
 
-    >>> from six.moves.urllib.parse import urlencode
+    >>> from urllib.parse import urlencode
     >>> browser.addHeader('Referer', 'https://launchpad.test/')
     >>> browser.open(
     ...     form_url,
diff --git a/lib/lp/code/xmlrpc/git.py b/lib/lp/code/xmlrpc/git.py
index 23c67a2..6221845 100644
--- a/lib/lp/code/xmlrpc/git.py
+++ b/lib/lp/code/xmlrpc/git.py
@@ -9,12 +9,12 @@ __all__ = [
 
 import logging
 import sys
+from urllib.parse import quote
 import uuid
 import xmlrpc.client
 
 from pymacaroons import Macaroon
 import six
-from six.moves.urllib.parse import quote
 import transaction
 from zope.component import getUtility
 from zope.error.interfaces import IErrorReportingUtility
diff --git a/lib/lp/code/xmlrpc/tests/test_git.py b/lib/lp/code/xmlrpc/tests/test_git.py
index 1f2b52a..131b803 100644
--- a/lib/lp/code/xmlrpc/tests/test_git.py
+++ b/lib/lp/code/xmlrpc/tests/test_git.py
@@ -5,6 +5,7 @@
 
 from datetime import datetime
 import hashlib
+from urllib.parse import quote
 import uuid
 import xmlrpc.client
 
@@ -12,7 +13,6 @@ from fixtures import FakeLogger
 from pymacaroons import Macaroon
 import pytz
 import six
-from six.moves.urllib.parse import quote
 from storm.store import Store
 from testtools.matchers import (
     Equals,
diff --git a/lib/lp/codehosting/puller/tests/test_errors.py b/lib/lp/codehosting/puller/tests/test_errors.py
index f06ca00..4ec9a75 100644
--- a/lib/lp/codehosting/puller/tests/test_errors.py
+++ b/lib/lp/codehosting/puller/tests/test_errors.py
@@ -7,6 +7,7 @@ import http.client
 import os
 import socket
 import tempfile
+from urllib.error import HTTPError
 
 from breezy.errors import (
     BzrError,
@@ -20,7 +21,6 @@ from breezy.url_policy_open import (
     BranchReferenceForbidden,
     )
 from lazr.uri import InvalidURIError
-from six.moves.urllib.error import HTTPError
 
 from lp.code.enums import BranchType
 from lp.codehosting.puller.worker import (
diff --git a/lib/lp/codehosting/puller/worker.py b/lib/lp/codehosting/puller/worker.py
index 5f4e58d..be4cb8c 100644
--- a/lib/lp/codehosting/puller/worker.py
+++ b/lib/lp/codehosting/puller/worker.py
@@ -9,6 +9,8 @@ import sys
 # line below this comment.
 import lp.codehosting  # noqa: F401  # isort: split
 
+from urllib.error import HTTPError
+
 from breezy import (
     errors,
     urlutils,
@@ -39,7 +41,6 @@ from lazr.uri import (
     URI,
     )
 import six
-from six.moves.urllib.error import HTTPError
 
 from lp.code.bzr import (
     BranchFormat,
diff --git a/lib/lp/codehosting/scanner/buglinks.py b/lib/lp/codehosting/scanner/buglinks.py
index 33a18ed..f7fcfd5 100644
--- a/lib/lp/codehosting/scanner/buglinks.py
+++ b/lib/lp/codehosting/scanner/buglinks.py
@@ -7,8 +7,9 @@ __all__ = [
     'BugBranchLinker',
     ]
 
+from urllib.parse import urlsplit
+
 from breezy.bugtracker import InvalidBugStatus
-from six.moves.urllib.parse import urlsplit
 from zope.component import getUtility
 
 from lp.app.errors import NotFoundError
diff --git a/lib/lp/codehosting/sshserver/session.py b/lib/lp/codehosting/sshserver/session.py
index 9dc9a5d..4f0d549 100644
--- a/lib/lp/codehosting/sshserver/session.py
+++ b/lib/lp/codehosting/sshserver/session.py
@@ -8,11 +8,11 @@ __all__ = [
     ]
 
 import os
+from urllib.parse import urlparse
 
 from lazr.sshserver.events import AvatarEvent
 from lazr.sshserver.session import DoNothingSession
 import six
-from six.moves.urllib.parse import urlparse
 from twisted.internet import process
 from twisted.python import log
 from zope.event import notify
diff --git a/lib/lp/codehosting/tests/test_acceptance.py b/lib/lp/codehosting/tests/test_acceptance.py
index 0beee84..835b4d8 100644
--- a/lib/lp/codehosting/tests/test_acceptance.py
+++ b/lib/lp/codehosting/tests/test_acceptance.py
@@ -5,6 +5,7 @@
 
 import os
 import re
+from urllib.request import urlopen
 import xmlrpc.client
 
 import breezy.branch
@@ -13,7 +14,6 @@ from breezy.tests.per_repository import all_repository_format_scenarios
 from breezy.urlutils import local_path_from_url
 from breezy.workingtree import WorkingTree
 import six
-from six.moves.urllib.request import urlopen
 from testscenarios import (
     load_tests_apply_scenarios,
     WithScenarios,
diff --git a/lib/lp/oci/browser/tests/test_ocirecipe.py b/lib/lp/oci/browser/tests/test_ocirecipe.py
index 9b17ee7..97fc3c9 100644
--- a/lib/lp/oci/browser/tests/test_ocirecipe.py
+++ b/lib/lp/oci/browser/tests/test_ocirecipe.py
@@ -8,10 +8,10 @@ from datetime import (
     timedelta,
     )
 from operator import attrgetter
+from urllib.parse import quote
 
 from fixtures import FakeLogger
 import pytz
-from six.moves.urllib.parse import quote
 import soupmatchers
 from storm.locals import Store
 from testtools.matchers import (
diff --git a/lib/lp/oci/model/ociregistryclient.py b/lib/lp/oci/model/ociregistryclient.py
index e04a17a..1b71e33 100644
--- a/lib/lp/oci/model/ociregistryclient.py
+++ b/lib/lp/oci/model/ociregistryclient.py
@@ -16,6 +16,7 @@ import json
 import logging
 import re
 import tarfile
+from urllib.parse import urlparse
 
 import boto3
 from botocore.config import Config
@@ -24,7 +25,6 @@ from requests.exceptions import (
     HTTPError,
     )
 from requests.utils import parse_dict_header
-from six.moves.urllib.parse import urlparse
 from tenacity import (
     before_log,
     retry,
diff --git a/lib/lp/oci/tests/test_ocirecipebuild.py b/lib/lp/oci/tests/test_ocirecipebuild.py
index 8a9c33b..3a1b83d 100644
--- a/lib/lp/oci/tests/test_ocirecipebuild.py
+++ b/lib/lp/oci/tests/test_ocirecipebuild.py
@@ -7,11 +7,11 @@ from datetime import (
     datetime,
     timedelta,
     )
+from urllib.request import urlopen
 
 from fixtures import FakeLogger
 from pymacaroons import Macaroon
 import pytz
-from six.moves.urllib.request import urlopen
 from testtools.matchers import (
     ContainsDict,
     Equals,
diff --git a/lib/lp/oci/tests/test_ocirecipebuildbehaviour.py b/lib/lp/oci/tests/test_ocirecipebuildbehaviour.py
index 890a916..e4b0fa7 100644
--- a/lib/lp/oci/tests/test_ocirecipebuildbehaviour.py
+++ b/lib/lp/oci/tests/test_ocirecipebuildbehaviour.py
@@ -10,6 +10,7 @@ import os
 import shutil
 import tempfile
 import time
+from urllib.parse import urlsplit
 import uuid
 
 import fixtures
@@ -17,7 +18,6 @@ from fixtures import MockPatch
 from pymacaroons import Macaroon
 import pytz
 import six
-from six.moves.urllib_parse import urlsplit
 from testtools import ExpectedException
 from testtools.matchers import (
     AfterPreprocessing,
diff --git a/lib/lp/oci/vocabularies.py b/lib/lp/oci/vocabularies.py
index e8e60df..84b680b 100644
--- a/lib/lp/oci/vocabularies.py
+++ b/lib/lp/oci/vocabularies.py
@@ -5,10 +5,11 @@
 
 __all__ = []
 
-from six.moves.urllib.parse import (
+from urllib.parse import (
     quote,
     unquote,
     )
+
 from zope.component import getUtility
 from zope.interface import implementer
 from zope.schema.vocabulary import SimpleTerm
diff --git a/lib/lp/registry/browser/mailinglists.py b/lib/lp/registry/browser/mailinglists.py
index bbc26a2..be1e872 100644
--- a/lib/lp/registry/browser/mailinglists.py
+++ b/lib/lp/registry/browser/mailinglists.py
@@ -10,8 +10,8 @@ __all__ = [
 
 
 from textwrap import TextWrapper
+from urllib.parse import quote
 
-from six.moves.urllib.parse import quote
 from zope.component import getUtility
 
 from lp.app.browser.tales import PersonFormatterAPI
diff --git a/lib/lp/registry/browser/ociproject.py b/lib/lp/registry/browser/ociproject.py
index 85a1c00..00e8024 100644
--- a/lib/lp/registry/browser/ociproject.py
+++ b/lib/lp/registry/browser/ociproject.py
@@ -12,11 +12,12 @@ __all__ = [
     'OCIProjectURL',
     ]
 
-from breezy import urlutils
-from six.moves.urllib.parse import (
+from urllib.parse import (
     urlsplit,
     urlunsplit,
     )
+
+from breezy import urlutils
 from zope.component import getUtility
 from zope.interface import implementer
 
diff --git a/lib/lp/registry/browser/person.py b/lib/lp/registry/browser/person.py
index ccd09c7..99526b7 100644
--- a/lib/lp/registry/browser/person.py
+++ b/lib/lp/registry/browser/person.py
@@ -57,6 +57,10 @@ from operator import (
     itemgetter,
     )
 from textwrap import dedent
+from urllib.parse import (
+    quote,
+    urlencode,
+    )
 
 from lazr.config import as_timedelta
 from lazr.delegates import delegate_to
@@ -65,10 +69,6 @@ from lazr.restful.interfaces import IWebServiceClientRequest
 from lazr.restful.utils import smartquote
 from lazr.uri import URI
 import pytz
-from six.moves.urllib.parse import (
-    quote,
-    urlencode,
-    )
 from storm.zope.interfaces import IResultSet
 from zope.browserpage import ViewPageTemplateFile
 from zope.component import (
diff --git a/lib/lp/registry/browser/product.py b/lib/lp/registry/browser/product.py
index faea1f8..9001fdb 100644
--- a/lib/lp/registry/browser/product.py
+++ b/lib/lp/registry/browser/product.py
@@ -40,6 +40,7 @@ __all__ = [
 
 
 from operator import attrgetter
+from urllib.parse import urlunsplit
 
 from breezy import urlutils
 from breezy.revision import NULL_REVISION
@@ -49,7 +50,6 @@ from lazr.restful.interface import (
     use_template,
     )
 from lazr.restful.interfaces import IJSONRequestCache
-from six.moves.urllib.parse import urlunsplit
 from zope.browserpage import ViewPageTemplateFile
 from zope.component import getUtility
 from zope.event import notify
diff --git a/lib/lp/registry/browser/sourcepackage.py b/lib/lp/registry/browser/sourcepackage.py
index 43e6fb7..6eb7d3b 100644
--- a/lib/lp/registry/browser/sourcepackage.py
+++ b/lib/lp/registry/browser/sourcepackage.py
@@ -16,6 +16,7 @@ __all__ = [
     ]
 
 import string
+from urllib.parse import urlencode
 
 from apt_pkg import (
     upstream_version,
@@ -26,7 +27,6 @@ from lazr.enum import (
     Item,
     )
 from lazr.restful.interface import copy_field
-from six.moves.urllib.parse import urlencode
 from zope.browserpage import ViewPageTemplateFile
 from zope.component import (
     adapter,
diff --git a/lib/lp/registry/browser/team.py b/lib/lp/registry/browser/team.py
index c37bbf0..c0e0be1 100644
--- a/lib/lp/registry/browser/team.py
+++ b/lib/lp/registry/browser/team.py
@@ -36,13 +36,13 @@ from datetime import (
     timedelta,
     )
 import math
+from urllib.parse import unquote
 
 from lazr.restful.interface import copy_field
 from lazr.restful.interfaces import IJSONRequestCache
 from lazr.restful.utils import smartquote
 import pytz
 import simplejson
-from six.moves.urllib.parse import unquote
 from zope.browserpage import ViewPageTemplateFile
 from zope.component import getUtility
 from zope.formlib.form import (
diff --git a/lib/lp/registry/browser/tests/test_distroseries.py b/lib/lp/registry/browser/tests/test_distroseries.py
index 326bbfd..505d2aa 100644
--- a/lib/lp/registry/browser/tests/test_distroseries.py
+++ b/lib/lp/registry/browser/tests/test_distroseries.py
@@ -7,15 +7,15 @@ from datetime import timedelta
 import difflib
 import re
 from textwrap import TextWrapper
+from urllib.parse import (
+    urlencode,
+    urlparse,
+    )
 
 from fixtures import FakeLogger
 from lazr.restful.interfaces import IJSONRequestCache
 from lxml import html
 import six
-from six.moves.urllib.parse import (
-    urlencode,
-    urlparse,
-    )
 import soupmatchers
 from storm.zope.interfaces import IResultSet
 from testtools.content import (
diff --git a/lib/lp/registry/browser/tests/test_person.py b/lib/lp/registry/browser/tests/test_person.py
index 1a1624f..2f5eb23 100644
--- a/lib/lp/registry/browser/tests/test_person.py
+++ b/lib/lp/registry/browser/tests/test_person.py
@@ -6,10 +6,10 @@ import email
 from operator import attrgetter
 import re
 from textwrap import dedent
+from urllib.parse import urljoin
 
 from fixtures import FakeLogger
 import six
-from six.moves.urllib.parse import urljoin
 import soupmatchers
 from storm.store import Store
 from testscenarios import (
diff --git a/lib/lp/registry/browser/tests/test_product.py b/lib/lp/registry/browser/tests/test_product.py
index c79cbd1..fadb04a 100644
--- a/lib/lp/registry/browser/tests/test_product.py
+++ b/lib/lp/registry/browser/tests/test_product.py
@@ -7,16 +7,16 @@ __all__ = ['make_product_form']
 
 import re
 from textwrap import dedent
+from urllib.parse import (
+    urlencode,
+    urlsplit,
+    )
 
 from lazr.restful.fields import Reference
 from lazr.restful.interfaces import (
     IFieldMarshaller,
     IJSONRequestCache,
     )
-from six.moves.urllib.parse import (
-    urlencode,
-    urlsplit,
-    )
 from soupmatchers import (
     HTMLContains,
     Tag,
diff --git a/lib/lp/registry/browser/tests/test_sourcepackage_views.py b/lib/lp/registry/browser/tests/test_sourcepackage_views.py
index dcb66d0..2e4d2f7 100644
--- a/lib/lp/registry/browser/tests/test_sourcepackage_views.py
+++ b/lib/lp/registry/browser/tests/test_sourcepackage_views.py
@@ -3,10 +3,11 @@
 
 """Tests for SourcePackage view code."""
 
-from six.moves.urllib.parse import (
+from urllib.parse import (
     parse_qsl,
     splitquery,
     )
+
 from soupmatchers import (
     HTMLContains,
     Tag,
diff --git a/lib/lp/registry/scripts/distributionmirror_prober.py b/lib/lp/registry/scripts/distributionmirror_prober.py
index acd384d..00e1389 100644
--- a/lib/lp/registry/scripts/distributionmirror_prober.py
+++ b/lib/lp/registry/scripts/distributionmirror_prober.py
@@ -11,6 +11,12 @@ import io
 import itertools
 import logging
 import os.path
+from urllib.parse import (
+    unquote,
+    urljoin,
+    urlparse,
+    urlunparse,
+    )
 
 import OpenSSL
 from OpenSSL.SSL import (
@@ -19,12 +25,6 @@ from OpenSSL.SSL import (
     )
 import requests
 import six
-from six.moves.urllib.parse import (
-    unquote,
-    urljoin,
-    urlparse,
-    urlunparse,
-    )
 from treq.client import HTTPClient as TreqHTTPClient
 from twisted.internet import (
     defer,
diff --git a/lib/lp/registry/scripts/productreleasefinder/finder.py b/lib/lp/registry/scripts/productreleasefinder/finder.py
index df79137..5d51c0c 100644
--- a/lib/lp/registry/scripts/productreleasefinder/finder.py
+++ b/lib/lp/registry/scripts/productreleasefinder/finder.py
@@ -11,10 +11,10 @@ import mimetypes
 import os
 import re
 import tempfile
+from urllib.parse import urlsplit
 
 import pytz
 import requests
-from six.moves.urllib.parse import urlsplit
 from zope.component import getUtility
 
 from lp.app.validators.name import invalid_name_pattern
diff --git a/lib/lp/registry/scripts/productreleasefinder/walker.py b/lib/lp/registry/scripts/productreleasefinder/walker.py
index a7ee116..908dfd5 100644
--- a/lib/lp/registry/scripts/productreleasefinder/walker.py
+++ b/lib/lp/registry/scripts/productreleasefinder/walker.py
@@ -13,17 +13,17 @@ __all__ = [
 
 import ftplib
 import os
+from urllib.parse import (
+    unquote_plus,
+    urljoin,
+    urlsplit,
+    )
 
 from lazr.uri import (
     InvalidURIError,
     URI,
     )
 import requests
-from six.moves.urllib.parse import (
-    unquote_plus,
-    urljoin,
-    urlsplit,
-    )
 
 from lp.registry.scripts.productreleasefinder import log
 from lp.registry.scripts.productreleasefinder.path import (
diff --git a/lib/lp/registry/stories/product/xx-product-files.txt b/lib/lp/registry/stories/product/xx-product-files.txt
index cb82bc6..34dd7cd 100644
--- a/lib/lp/registry/stories/product/xx-product-files.txt
+++ b/lib/lp/registry/stories/product/xx-product-files.txt
@@ -401,8 +401,8 @@ Downloading and deleting files
 
 Download one of the files.
 
-    >>> from six.moves.urllib.parse import urlparse
-    >>> from six.moves.urllib.request import urlopen
+    >>> from urllib.parse import urlparse
+    >>> from urllib.request import urlopen
 
 XXX Downloading via the testbrowser does not work
 XXX unless the file is served by the Zope publisher.
diff --git a/lib/lp/services/feeds/feed.py b/lib/lp/services/feeds/feed.py
index 9798bc0..b7e1467 100644
--- a/lib/lp/services/feeds/feed.py
+++ b/lib/lp/services/feeds/feed.py
@@ -18,8 +18,8 @@ __all__ = [
 import operator
 import os
 import time
+from urllib.parse import urljoin
 
-from six.moves.urllib.parse import urljoin
 from zope.browserpage import ViewPageTemplateFile
 from zope.component import getUtility
 from zope.datetime import rfc1123_date
diff --git a/lib/lp/services/gpg/handler.py b/lib/lp/services/gpg/handler.py
index 005ca79..7dd60c9 100644
--- a/lib/lp/services/gpg/handler.py
+++ b/lib/lp/services/gpg/handler.py
@@ -18,13 +18,13 @@ import shutil
 import subprocess
 import sys
 import tempfile
+from urllib.parse import urlencode
 
 import gpgme
 from lazr.restful.utils import get_current_browser_request
 import pytz
 import requests
 import six
-from six.moves.urllib.parse import urlencode
 from zope.component import getUtility
 from zope.interface import implementer
 from zope.security.proxy import removeSecurityProxy
diff --git a/lib/lp/services/librarian/client.py b/lib/lp/services/librarian/client.py
index a011bc3..0ef6028 100644
--- a/lib/lp/services/librarian/client.py
+++ b/lib/lp/services/librarian/client.py
@@ -21,20 +21,20 @@ from socket import (
     )
 import threading
 import time
-
-from lazr.restful.utils import get_current_browser_request
-import six
-from six.moves.urllib.error import (
+from urllib.error import (
     HTTPError,
     URLError,
     )
-from six.moves.urllib.parse import (
+from urllib.parse import (
     quote,
     urljoin,
     urlparse,
     urlunparse,
     )
-from six.moves.urllib.request import urlopen
+from urllib.request import urlopen
+
+from lazr.restful.utils import get_current_browser_request
+import six
 from storm.store import Store
 from zope.interface import implementer
 
diff --git a/lib/lp/services/librarian/doc/librarian.txt b/lib/lp/services/librarian/doc/librarian.txt
index 6c41957..b5c3daf 100644
--- a/lib/lp/services/librarian/doc/librarian.txt
+++ b/lib/lp/services/librarian/doc/librarian.txt
@@ -252,7 +252,7 @@ the client until it begins a new transaction.
     >>> print(url)
     http://.../text.txt
 
-    >>> from six.moves.urllib.request import urlopen
+    >>> from urllib.request import urlopen
     >>> six.ensure_str(urlopen(url).read())
     'This is some data'
 
diff --git a/lib/lp/services/librarian/model.py b/lib/lp/services/librarian/model.py
index 6b0ea19..bf27020 100644
--- a/lib/lp/services/librarian/model.py
+++ b/lib/lp/services/librarian/model.py
@@ -12,10 +12,10 @@ __all__ = [
 
 from datetime import datetime
 import hashlib
+from urllib.parse import urlparse
 
 from lazr.delegates import delegate_to
 import pytz
-from six.moves.urllib.parse import urlparse
 from storm.locals import (
     Date,
     Desc,
diff --git a/lib/lp/services/librarian/smoketest.py b/lib/lp/services/librarian/smoketest.py
index 5fd3a2b..8b4ba38 100644
--- a/lib/lp/services/librarian/smoketest.py
+++ b/lib/lp/services/librarian/smoketest.py
@@ -9,9 +9,9 @@
 import datetime
 import io
 import sys
+from urllib.request import urlopen
 
 import pytz
-from six.moves.urllib.request import urlopen
 import transaction
 from zope.component import getUtility
 
diff --git a/lib/lp/services/librarian/tests/test_client.py b/lib/lp/services/librarian/tests/test_client.py
index 6bef538..2fef0cf 100644
--- a/lib/lp/services/librarian/tests/test_client.py
+++ b/lib/lp/services/librarian/tests/test_client.py
@@ -10,16 +10,16 @@ import socket
 import textwrap
 import threading
 import unittest
+from urllib.error import (
+    HTTPError,
+    URLError,
+    )
+from urllib.request import urlopen
 
 from fixtures import (
     EnvironmentVariable,
     TempDir,
     )
-from six.moves.urllib.error import (
-    HTTPError,
-    URLError,
-    )
-from six.moves.urllib.request import urlopen
 from testtools.testcase import ExpectedException
 import transaction
 
diff --git a/lib/lp/services/librarianserver/db.py b/lib/lp/services/librarianserver/db.py
index 4ed2901..3c0d9d0 100644
--- a/lib/lp/services/librarianserver/db.py
+++ b/lib/lp/services/librarianserver/db.py
@@ -8,13 +8,13 @@ __all__ = [
     ]
 
 import hashlib
-from xmlrpc.client import Fault
-
-from pymacaroons import Macaroon
-from six.moves.urllib.parse import (
+from urllib.parse import (
     quote,
     unquote,
     )
+from xmlrpc.client import Fault
+
+from pymacaroons import Macaroon
 from storm.expr import (
     And,
     SQL,
diff --git a/lib/lp/services/librarianserver/swift.py b/lib/lp/services/librarianserver/swift.py
index bd22a1e..87bee7b 100644
--- a/lib/lp/services/librarianserver/swift.py
+++ b/lib/lp/services/librarianserver/swift.py
@@ -19,8 +19,8 @@ import hashlib
 import os.path
 import re
 import time
+from urllib.parse import quote
 
-from six.moves.urllib.parse import quote
 from swiftclient import client as swiftclient
 
 from lp.services.config import config
diff --git a/lib/lp/services/librarianserver/testing/fake.py b/lib/lp/services/librarianserver/testing/fake.py
index b18f9a9..59ed31b 100644
--- a/lib/lp/services/librarianserver/testing/fake.py
+++ b/lib/lp/services/librarianserver/testing/fake.py
@@ -16,9 +16,9 @@ __all__ = [
 
 import hashlib
 import io
+from urllib.parse import urljoin
 
 from fixtures import Fixture
-from six.moves.urllib.parse import urljoin
 import transaction
 from transaction.interfaces import ISynchronizer
 import zope.component
diff --git a/lib/lp/services/librarianserver/testing/tests/test_server_fixture.py b/lib/lp/services/librarianserver/testing/tests/test_server_fixture.py
index 86a6619..bd617e9 100644
--- a/lib/lp/services/librarianserver/testing/tests/test_server_fixture.py
+++ b/lib/lp/services/librarianserver/testing/tests/test_server_fixture.py
@@ -6,8 +6,7 @@
 import os
 import socket
 from textwrap import dedent
-
-from six.moves.urllib.request import urlopen
+from urllib.request import urlopen
 
 from lp.services.config import config
 from lp.services.config.fixture import ConfigFixture
diff --git a/lib/lp/services/librarianserver/tests/test_db_outage.py b/lib/lp/services/librarianserver/tests/test_db_outage.py
index 5709cd9..7887632 100644
--- a/lib/lp/services/librarianserver/tests/test_db_outage.py
+++ b/lib/lp/services/librarianserver/tests/test_db_outage.py
@@ -6,10 +6,10 @@
 Database outages happen by accident and during fastdowntime deployments."""
 
 import io
+from urllib.error import HTTPError
+from urllib.request import urlopen
 
 from fixtures import Fixture
-from six.moves.urllib.error import HTTPError
-from six.moves.urllib.request import urlopen
 
 from lp.services.librarian.client import LibrarianClient
 from lp.services.librarianserver.testing.server import LibrarianServerFixture
diff --git a/lib/lp/services/librarianserver/tests/test_gc.py b/lib/lp/services/librarianserver/tests/test_gc.py
index 7e1eedb..850f9ae 100644
--- a/lib/lp/services/librarianserver/tests/test_gc.py
+++ b/lib/lp/services/librarianserver/tests/test_gc.py
@@ -19,11 +19,11 @@ from subprocess import (
     STDOUT,
     )
 import tempfile
+from urllib.parse import urljoin
 
 from fixtures import MockPatchObject
 import pytz
 import requests
-from six.moves.urllib.parse import urljoin
 from storm.store import Store
 from swiftclient import client as swiftclient
 from testtools.matchers import (
diff --git a/lib/lp/services/librarianserver/tests/test_web.py b/lib/lp/services/librarianserver/tests/test_web.py
index 5800724..1fe9c22 100644
--- a/lib/lp/services/librarianserver/tests/test_web.py
+++ b/lib/lp/services/librarianserver/tests/test_web.py
@@ -8,11 +8,11 @@ import http.client
 from io import BytesIO
 import os
 import unittest
+from urllib.parse import urlparse
 
 from lazr.uri import URI
 import pytz
 import requests
-from six.moves.urllib.parse import urlparse
 from storm.expr import SQL
 from testtools.matchers import EndsWith
 import transaction
diff --git a/lib/lp/services/librarianserver/web.py b/lib/lp/services/librarianserver/web.py
index b40536f..989e043 100644
--- a/lib/lp/services/librarianserver/web.py
+++ b/lib/lp/services/librarianserver/web.py
@@ -3,10 +3,10 @@
 
 from datetime import datetime
 import time
+from urllib.parse import urlparse
 
 from pymacaroons import Macaroon
 import six
-from six.moves.urllib.parse import urlparse
 from storm.exceptions import DisconnectionError
 from twisted.internet import (
     abstract,
diff --git a/lib/lp/services/oauth/stories/access-token.txt b/lib/lp/services/oauth/stories/access-token.txt
index a56ee3c..86c5241 100644
--- a/lib/lp/services/oauth/stories/access-token.txt
+++ b/lib/lp/services/oauth/stories/access-token.txt
@@ -19,7 +19,7 @@ access token.
     >>> token.review(salgado, OAuthPermission.WRITE_PUBLIC)
     >>> logout()
 
-    >>> from six.moves.urllib.parse import urlencode
+    >>> from urllib.parse import urlencode
     >>> data = dict(
     ...     oauth_consumer_key='foobar123451432',
     ...     oauth_version='1.0',
diff --git a/lib/lp/services/oauth/stories/authorize-token.txt b/lib/lp/services/oauth/stories/authorize-token.txt
index 6634a7a..ecd2e7a 100644
--- a/lib/lp/services/oauth/stories/authorize-token.txt
+++ b/lib/lp/services/oauth/stories/authorize-token.txt
@@ -31,7 +31,7 @@ The +authorize-token page is restricted to logged in users, so users will
 first be asked to log in. (We won't show the actual login process because
 it involves OpenID, which would complicate this test quite a bit.)
 
-    >>> from six.moves.urllib.parse import urlencode
+    >>> from urllib.parse import urlencode
     >>> params = dict(
     ...     oauth_token=token.key, oauth_callback='http://launchpad.test/bzr')
     >>> url = "http://launchpad.test/+authorize-token?%s"; % urlencode(params)
diff --git a/lib/lp/services/oauth/stories/request-token.txt b/lib/lp/services/oauth/stories/request-token.txt
index 3e9b4cb..dc1b001 100644
--- a/lib/lp/services/oauth/stories/request-token.txt
+++ b/lib/lp/services/oauth/stories/request-token.txt
@@ -4,7 +4,7 @@ Asking for a request token
 Our sample consumer (whose key is 'foobar123451432') asks Launchpad for
 a request token which may later be exchanged for an access token.
 
-    >>> from six.moves.urllib.parse import urlencode
+    >>> from urllib.parse import urlencode
     >>> data = dict(
     ...     oauth_consumer_key='foobar123451432',
     ...     oauth_version='1.0',
diff --git a/lib/lp/services/openid/fetcher.py b/lib/lp/services/openid/fetcher.py
index 88343a1..a32e0f7 100644
--- a/lib/lp/services/openid/fetcher.py
+++ b/lib/lp/services/openid/fetcher.py
@@ -9,12 +9,12 @@ __all__ = [
 
 from functools import partial
 import os.path
+from urllib.request import urlopen
 
 from openid.fetchers import (
     setDefaultFetcher,
     Urllib2Fetcher,
     )
-from six.moves.urllib.request import urlopen
 
 from lp.services.config import config
 from lp.services.encoding import wsgi_native_string
diff --git a/lib/lp/services/scripts/base.py b/lib/lp/services/scripts/base.py
index 9abdbb2..62dc799 100644
--- a/lib/lp/services/scripts/base.py
+++ b/lib/lp/services/scripts/base.py
@@ -19,6 +19,10 @@ import logging
 from optparse import OptionParser
 import os.path
 import sys
+from urllib.parse import (
+    urlparse,
+    urlunparse,
+    )
 
 from contrib.glock import (
     GlobalLock,
@@ -26,10 +30,6 @@ from contrib.glock import (
     )
 import pytz
 import requests
-from six.moves.urllib.parse import (
-    urlparse,
-    urlunparse,
-    )
 import transaction
 from zope.component import getUtility
 
diff --git a/lib/lp/services/signing/proxy.py b/lib/lp/services/signing/proxy.py
index 0e5fded..5bd23ba 100644
--- a/lib/lp/services/signing/proxy.py
+++ b/lib/lp/services/signing/proxy.py
@@ -5,6 +5,7 @@
 
 import base64
 import json
+from urllib.parse import urljoin
 
 from lazr.restful.utils import get_current_browser_request
 from nacl.encoding import Base64Encoder
@@ -14,7 +15,6 @@ from nacl.public import (
     PublicKey,
     )
 from nacl.utils import random
-from six.moves.urllib.parse import urljoin
 from zope.interface import implementer
 
 from lp.services.config import config
diff --git a/lib/lp/services/sitesearch/__init__.py b/lib/lp/services/sitesearch/__init__.py
index 074c1a1..9c04b05 100644
--- a/lib/lp/services/sitesearch/__init__.py
+++ b/lib/lp/services/sitesearch/__init__.py
@@ -9,14 +9,15 @@ __all__ = [
     'PageMatches',
     ]
 
-from lazr.restful.utils import get_current_browser_request
-from lazr.uri import URI
-import requests
-from six.moves.urllib.parse import (
+from urllib.parse import (
     parse_qsl,
     urlencode,
     urlunparse,
     )
+
+from lazr.restful.utils import get_current_browser_request
+from lazr.uri import URI
+import requests
 from zope.interface import implementer
 
 from lp.services.config import config
diff --git a/lib/lp/services/verification/browser/logintoken.py b/lib/lp/services/verification/browser/logintoken.py
index 8d13422..a9004d4 100644
--- a/lib/lp/services/verification/browser/logintoken.py
+++ b/lib/lp/services/verification/browser/logintoken.py
@@ -13,10 +13,11 @@ __all__ = [
     'ValidateGPGKeyView',
     ]
 
-from six.moves.urllib.parse import (
+from urllib.parse import (
     urlencode,
     urljoin,
     )
+
 from zope.component import getUtility
 from zope.formlib.widget import CustomWidgetFactory
 from zope.formlib.widgets import TextAreaWidget
diff --git a/lib/lp/services/webapp/doc/webapp-publication.txt b/lib/lp/services/webapp/doc/webapp-publication.txt
index d7f8dcc..430ead9 100644
--- a/lib/lp/services/webapp/doc/webapp-publication.txt
+++ b/lib/lp/services/webapp/doc/webapp-publication.txt
@@ -507,7 +507,7 @@ python 'in' operator.
 
     >>> from lp.services.webapp.servers import (
     ...     LaunchpadBrowserRequest)
-    >>> from six.moves.urllib.parse import urlencode
+    >>> from urllib.parse import urlencode
     >>> environment = {'QUERY_STRING': urlencode({
     ...     'a_field': 'a_value',
     ...     'items_field': [1, 2, 3]}, doseq=True)}
diff --git a/lib/lp/services/webapp/errorlog.py b/lib/lp/services/webapp/errorlog.py
index 7327c8f..82e698f 100644
--- a/lib/lp/services/webapp/errorlog.py
+++ b/lib/lp/services/webapp/errorlog.py
@@ -7,6 +7,7 @@ import contextlib
 from itertools import repeat
 import operator
 import re
+from urllib.parse import urlparse
 
 from lazr.restful.utils import get_current_browser_request
 import oops.createhooks
@@ -15,7 +16,6 @@ from oops_datedir_repo import DateDirRepo
 import oops_timeline
 import pytz
 import six
-from six.moves.urllib.parse import urlparse
 from talisker.logs import logging_context
 from zope.component import getUtility
 from zope.error.interfaces import IErrorReportingUtility
diff --git a/lib/lp/services/webapp/login.py b/lib/lp/services/webapp/login.py
index 08e693a..0060ab7 100644
--- a/lib/lp/services/webapp/login.py
+++ b/lib/lp/services/webapp/login.py
@@ -6,6 +6,7 @@ from datetime import (
     datetime,
     timedelta,
     )
+from urllib.parse import urlencode
 
 from openid.consumer.consumer import (
     CANCEL,
@@ -22,7 +23,6 @@ from paste.httpexceptions import (
     HTTPException,
     )
 import six
-from six.moves.urllib.parse import urlencode
 import transaction
 from zope.authentication.interfaces import IUnauthenticatedPrincipal
 from zope.browserpage import ViewPageTemplateFile
diff --git a/lib/lp/services/webapp/publication.py b/lib/lp/services/webapp/publication.py
index 37cd383..6f2690d 100644
--- a/lib/lp/services/webapp/publication.py
+++ b/lib/lp/services/webapp/publication.py
@@ -11,13 +11,13 @@ import sys
 import threading
 import time
 import traceback
+from urllib.parse import quote
 
 from lazr.uri import (
     InvalidURIError,
     URI,
     )
 from psycopg2.extensions import TransactionRollbackError
-from six.moves.urllib.parse import quote
 from storm.database import STATE_DISCONNECTED
 from storm.exceptions import (
     DisconnectionError,
diff --git a/lib/lp/services/webapp/publisher.py b/lib/lp/services/webapp/publisher.py
index 2f5960d..397c873 100644
--- a/lib/lp/services/webapp/publisher.py
+++ b/lib/lp/services/webapp/publisher.py
@@ -28,6 +28,7 @@ __all__ = [
 from cgi import FieldStorage
 import http.client
 import re
+from urllib.parse import urlparse
 from wsgiref.headers import Headers
 
 from lazr.restful import (
@@ -41,7 +42,6 @@ from lazr.restful.tales import WebLayerAPI
 from lazr.restful.utils import get_current_browser_request
 import simplejson
 import six
-from six.moves.urllib.parse import urlparse
 from zope.app.publisher.xmlrpc import IMethodPublisher
 from zope.component import (
     getUtility,
diff --git a/lib/lp/services/webapp/servers.py b/lib/lp/services/webapp/servers.py
index e644e05..79888bd 100644
--- a/lib/lp/services/webapp/servers.py
+++ b/lib/lp/services/webapp/servers.py
@@ -4,6 +4,7 @@
 """Definition of the internet servers that Launchpad uses."""
 
 import threading
+from urllib.parse import parse_qs
 import xmlrpc.client
 
 from lazr.restful.interfaces import (
@@ -18,7 +19,6 @@ from lazr.restful.publisher import (
 from lazr.restful.utils import get_current_browser_request
 from lazr.uri import URI
 import six
-from six.moves.urllib.parse import parse_qs
 from talisker.logs import logging_context
 import transaction
 from transaction.interfaces import ISynchronizer
diff --git a/lib/lp/services/webapp/tests/test_error.py b/lib/lp/services/webapp/tests/test_error.py
index 2081b14..eae2756 100644
--- a/lib/lp/services/webapp/tests/test_error.py
+++ b/lib/lp/services/webapp/tests/test_error.py
@@ -7,10 +7,10 @@ import http.client
 import logging
 import socket
 import time
+from urllib.error import HTTPError
 
 from fixtures import FakeLogger
 import psycopg2
-from six.moves.urllib.error import HTTPError
 from storm.exceptions import (
     DisconnectionError,
     OperationalError,
diff --git a/lib/lp/services/webapp/tests/test_login.py b/lib/lp/services/webapp/tests/test_login.py
index 61357d4..1cfec2d 100644
--- a/lib/lp/services/webapp/tests/test_login.py
+++ b/lib/lp/services/webapp/tests/test_login.py
@@ -17,6 +17,12 @@ from datetime import (
     )
 import http.client
 import unittest
+from urllib.error import HTTPError
+from urllib.parse import (
+    parse_qsl,
+    quote,
+    urlsplit,
+    )
 
 from openid.consumer.consumer import (
     FAILURE,
@@ -27,12 +33,6 @@ from openid.extensions import (
     sreg,
     )
 from openid.yadis.discover import DiscoveryFailure
-from six.moves.urllib.error import HTTPError
-from six.moves.urllib.parse import (
-    parse_qsl,
-    quote,
-    urlsplit,
-    )
 from testtools.matchers import (
     Contains,
     ContainsDict,
diff --git a/lib/lp/services/webapp/tests/test_login_account.py b/lib/lp/services/webapp/tests/test_login_account.py
index 6d6f535..550a7ae 100644
--- a/lib/lp/services/webapp/tests/test_login_account.py
+++ b/lib/lp/services/webapp/tests/test_login_account.py
@@ -2,9 +2,9 @@
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 from datetime import datetime
+from urllib.parse import parse_qs
 
 import lazr.uri
-from six.moves.urllib.parse import parse_qs
 from zope.component import getUtility
 from zope.event import notify
 from zope.session.interfaces import ISession
diff --git a/lib/lp/services/webapp/url.py b/lib/lp/services/webapp/url.py
index a6f15b5..e3932d5 100644
--- a/lib/lp/services/webapp/url.py
+++ b/lib/lp/services/webapp/url.py
@@ -5,8 +5,8 @@
 
 __all__ = ['urlappend', 'urlparse', 'urlsplit']
 
-import six.moves.urllib.parse as urlparse_module
-from six.moves.urllib.parse import (
+import urllib.parse as urlparse_module
+from urllib.parse import (
     urljoin,
     urlparse as original_urlparse,
     urlsplit as original_urlsplit,
diff --git a/lib/lp/services/webhooks/model.py b/lib/lp/services/webhooks/model.py
index aed49ae..e8518db 100644
--- a/lib/lp/services/webhooks/model.py
+++ b/lib/lp/services/webhooks/model.py
@@ -15,6 +15,7 @@ from datetime import (
 import ipaddress
 import re
 import socket
+from urllib.parse import urlsplit
 
 import iso8601
 from lazr.delegates import delegate_to
@@ -24,7 +25,6 @@ from lazr.enum import (
     )
 import psutil
 from pytz import utc
-from six.moves.urllib.parse import urlsplit
 from storm.expr import Desc
 from storm.properties import (
     Bool,
diff --git a/lib/lp/services/webservice/wadl.py b/lib/lp/services/webservice/wadl.py
index 5432f26..bcbf3bf 100644
--- a/lib/lp/services/webservice/wadl.py
+++ b/lib/lp/services/webservice/wadl.py
@@ -7,9 +7,9 @@ try:
     from importlib import resources
 except ImportError:
     import importlib_resources as resources
-import subprocess
 
-from six.moves.urllib.parse import urljoin
+import subprocess
+from urllib.parse import urljoin
 
 from lp.services.webapp.interaction import (
     ANONYMOUS,
diff --git a/lib/lp/snappy/browser/snap.py b/lib/lp/snappy/browser/snap.py
index 0fc63ca..eccbcd8 100644
--- a/lib/lp/snappy/browser/snap.py
+++ b/lib/lp/snappy/browser/snap.py
@@ -15,12 +15,13 @@ __all__ = [
     'SnapView',
     ]
 
+from urllib.parse import urlencode
+
 from lazr.restful.fields import Reference
 from lazr.restful.interface import (
     copy_field,
     use_template,
     )
-from six.moves.urllib.parse import urlencode
 from zope.component import getUtility
 from zope.error.interfaces import IErrorReportingUtility
 from zope.formlib.widget import CustomWidgetFactory
diff --git a/lib/lp/snappy/browser/tests/test_snap.py b/lib/lp/snappy/browser/tests/test_snap.py
index c513111..bbc0be7 100644
--- a/lib/lp/snappy/browser/tests/test_snap.py
+++ b/lib/lp/snappy/browser/tests/test_snap.py
@@ -9,15 +9,15 @@ from datetime import (
     )
 import json
 import re
+from urllib.parse import (
+    parse_qs,
+    urlsplit,
+    )
 
 from fixtures import FakeLogger
 from pymacaroons import Macaroon
 import pytz
 import responses
-from six.moves.urllib.parse import (
-    parse_qs,
-    urlsplit,
-    )
 import soupmatchers
 from testtools.matchers import (
     AfterPreprocessing,
diff --git a/lib/lp/snappy/model/snap.py b/lib/lp/snappy/model/snap.py
index 1a2bf68..16bbfed 100644
--- a/lib/lp/snappy/model/snap.py
+++ b/lib/lp/snappy/model/snap.py
@@ -13,13 +13,13 @@ from datetime import (
     timedelta,
     )
 from operator import attrgetter
+from urllib.parse import urlsplit
 
 from breezy import urlutils
 from lazr.lifecycle.event import ObjectCreatedEvent
 from pymacaroons import Macaroon
 import pytz
 import six
-from six.moves.urllib.parse import urlsplit
 from storm.expr import (
     And,
     Coalesce,
diff --git a/lib/lp/snappy/model/snapstoreclient.py b/lib/lp/snappy/model/snapstoreclient.py
index e5900fc..b56f5b6 100644
--- a/lib/lp/snappy/model/snapstoreclient.py
+++ b/lib/lp/snappy/model/snapstoreclient.py
@@ -11,13 +11,13 @@ import base64
 import json
 import string
 import time
+from urllib.parse import urlsplit
 
 from lazr.restful.utils import get_current_browser_request
 from pymacaroons import Macaroon
 import requests
 from requests_toolbelt import MultipartEncoder
 import six
-from six.moves.urllib.parse import urlsplit
 from zope.component import getUtility
 from zope.interface import implementer
 from zope.security.proxy import removeSecurityProxy
diff --git a/lib/lp/snappy/tests/test_snap.py b/lib/lp/snappy/tests/test_snap.py
index 7d8d45e..0dae2d5 100644
--- a/lib/lp/snappy/tests/test_snap.py
+++ b/lib/lp/snappy/tests/test_snap.py
@@ -11,6 +11,7 @@ from datetime import (
 import json
 from operator import attrgetter
 from textwrap import dedent
+from urllib.parse import urlsplit
 
 from fixtures import (
     FakeLogger,
@@ -21,7 +22,6 @@ from nacl.public import PrivateKey
 from pymacaroons import Macaroon
 import pytz
 import responses
-from six.moves.urllib.parse import urlsplit
 from storm.exceptions import LostObjectError
 from storm.locals import Store
 from testtools.matchers import (
diff --git a/lib/lp/snappy/tests/test_snapbuild.py b/lib/lp/snappy/tests/test_snapbuild.py
index 0cf70ac..f11a097 100644
--- a/lib/lp/snappy/tests/test_snapbuild.py
+++ b/lib/lp/snappy/tests/test_snapbuild.py
@@ -7,12 +7,12 @@ from datetime import (
     datetime,
     timedelta,
     )
+from urllib.request import urlopen
 
 from fixtures import FakeLogger
 from pymacaroons import Macaroon
 import pytz
 import six
-from six.moves.urllib.request import urlopen
 from testtools.matchers import (
     ContainsDict,
     Equals,
diff --git a/lib/lp/snappy/tests/test_snapbuildbehaviour.py b/lib/lp/snappy/tests/test_snapbuildbehaviour.py
index d1836e1..db202cb 100644
--- a/lib/lp/snappy/tests/test_snapbuildbehaviour.py
+++ b/lib/lp/snappy/tests/test_snapbuildbehaviour.py
@@ -8,13 +8,13 @@ from datetime import datetime
 import os.path
 from textwrap import dedent
 import time
+from urllib.parse import urlsplit
 import uuid
 
 from aptsources.sourceslist import SourceEntry
 import fixtures
 from pymacaroons import Macaroon
 import pytz
-from six.moves.urllib_parse import urlsplit
 from testtools import ExpectedException
 from testtools.matchers import (
     AfterPreprocessing,
diff --git a/lib/lp/soyuz/browser/widgets/archive.py b/lib/lp/soyuz/browser/widgets/archive.py
index 17d0947..73a279f 100644
--- a/lib/lp/soyuz/browser/widgets/archive.py
+++ b/lib/lp/soyuz/browser/widgets/archive.py
@@ -7,7 +7,7 @@ __all__ = [
     'PPANameWidget',
     ]
 
-from six.moves.urllib.parse import urljoin
+from urllib.parse import urljoin
 
 from lp.app.widgets.textwidgets import URIComponentWidget
 from lp.services.config import config
diff --git a/lib/lp/soyuz/interfaces/archive.py b/lib/lp/soyuz/interfaces/archive.py
index da4b948..e011591 100644
--- a/lib/lp/soyuz/interfaces/archive.py
+++ b/lib/lp/soyuz/interfaces/archive.py
@@ -54,6 +54,7 @@ __all__ = [
 
 import http.client
 import re
+from urllib.parse import urlparse
 
 from lazr.restful.declarations import (
     call_with,
@@ -78,7 +79,6 @@ from lazr.restful.fields import (
     CollectionField,
     Reference,
     )
-from six.moves.urllib.parse import urlparse
 from zope.interface import (
     Attribute,
     Interface,
diff --git a/lib/lp/soyuz/scripts/ppa_apache_log_parser.py b/lib/lp/soyuz/scripts/ppa_apache_log_parser.py
index 64bfcd1..c8c1e58 100644
--- a/lib/lp/soyuz/scripts/ppa_apache_log_parser.py
+++ b/lib/lp/soyuz/scripts/ppa_apache_log_parser.py
@@ -4,8 +4,7 @@
 __all__ = ['DBUSER', 'get_ppa_file_key']
 
 import os.path
-
-from six.moves.urllib.parse import unquote
+from urllib.parse import unquote
 
 from lp.archiveuploader.utils import re_isadeb
 
diff --git a/lib/lp/soyuz/tests/test_archive.py b/lib/lp/soyuz/tests/test_archive.py
index cbc40ac..a02d75d 100644
--- a/lib/lp/soyuz/tests/test_archive.py
+++ b/lib/lp/soyuz/tests/test_archive.py
@@ -11,11 +11,11 @@ from datetime import (
 import doctest
 import http.client
 import os.path
+from urllib.parse import urlsplit
 
 from aptsources.sourceslist import SourceEntry
 from pytz import UTC
 import responses
-from six.moves.urllib.parse import urlsplit
 from storm.store import Store
 from testtools.matchers import (
     AfterPreprocessing,
diff --git a/lib/lp/soyuz/tests/test_livefsbuild.py b/lib/lp/soyuz/tests/test_livefsbuild.py
index d448344..f642bcd 100644
--- a/lib/lp/soyuz/tests/test_livefsbuild.py
+++ b/lib/lp/soyuz/tests/test_livefsbuild.py
@@ -7,12 +7,12 @@ from datetime import (
     datetime,
     timedelta,
     )
+from urllib.parse import urlsplit
+from urllib.request import urlopen
 
 from fixtures import FakeLogger
 from pymacaroons import Macaroon
 import pytz
-from six.moves.urllib.parse import urlsplit
-from six.moves.urllib.request import urlopen
 from testtools.matchers import (
     ContainsDict,
     Equals,
diff --git a/lib/lp/soyuz/tests/test_packageupload.py b/lib/lp/soyuz/tests/test_packageupload.py
index 24d21ca..3e88b0e 100644
--- a/lib/lp/soyuz/tests/test_packageupload.py
+++ b/lib/lp/soyuz/tests/test_packageupload.py
@@ -7,13 +7,13 @@ from datetime import timedelta
 import io
 import os.path
 import shutil
+from urllib.request import urlopen
 
 from debian.deb822 import Changes
 from lazr.restfulclient.errors import (
     BadRequest,
     Unauthorized,
     )
-from six.moves.urllib.request import urlopen
 from testtools.matchers import (
     Equals,
     MatchesListwise,
diff --git a/lib/lp/testing/keyserver/tests/test_harness.py b/lib/lp/testing/keyserver/tests/test_harness.py
index 18b5ac0..e0727f4 100644
--- a/lib/lp/testing/keyserver/tests/test_harness.py
+++ b/lib/lp/testing/keyserver/tests/test_harness.py
@@ -1,7 +1,7 @@
 # Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from six.moves.urllib.request import urlopen
+from urllib.request import urlopen
 
 from lp.services.config import config
 from lp.testing import TestCase
diff --git a/lib/lp/testing/layers.py b/lib/lp/testing/layers.py
index 94c5dcd..6af3146 100644
--- a/lib/lp/testing/layers.py
+++ b/lib/lp/testing/layers.py
@@ -65,6 +65,12 @@ from unittest import (
     TestCase,
     TestResult,
     )
+from urllib.error import (
+    HTTPError,
+    URLError,
+    )
+from urllib.parse import urlparse
+from urllib.request import urlopen
 
 from fixtures import (
     Fixture,
@@ -73,12 +79,6 @@ from fixtures import (
 import psycopg2
 from requests import Session
 from requests.adapters import HTTPAdapter
-from six.moves.urllib.error import (
-    HTTPError,
-    URLError,
-    )
-from six.moves.urllib.parse import urlparse
-from six.moves.urllib.request import urlopen
 from storm.uri import URI
 from talisker.context import Context
 import transaction
diff --git a/lib/lp/testing/pages.py b/lib/lp/testing/pages.py
index 0772e0c..c706ab8 100644
--- a/lib/lp/testing/pages.py
+++ b/lib/lp/testing/pages.py
@@ -11,6 +11,7 @@ from itertools import chain
 import os
 import re
 import unittest
+from urllib.parse import urljoin
 
 from bs4.element import (
     CData,
@@ -25,7 +26,6 @@ from bs4.element import (
 from lazr.restful.testing.webservice import WebServiceCaller
 from oauthlib import oauth1
 import six
-from six.moves.urllib.parse import urljoin
 from soupsieve import escape as css_escape
 import transaction
 from webtest import TestRequest
diff --git a/lib/lp/testing/publication.py b/lib/lp/testing/publication.py
index 74b350f..a0f6d55 100644
--- a/lib/lp/testing/publication.py
+++ b/lib/lp/testing/publication.py
@@ -10,11 +10,11 @@ __all__ = [
     ]
 
 import io
-
-from six.moves.urllib_parse import (
+from urllib.parse import (
     unquote,
     urljoin,
     )
+
 from zope.app.publication.requestpublicationregistry import factoryRegistry
 from zope.authentication.interfaces import IUnauthenticatedPrincipal
 from zope.component import (
diff --git a/lib/lp/testing/tests/test_layers_functional.py b/lib/lp/testing/tests/test_layers_functional.py
index 212701a..0a665dc 100644
--- a/lib/lp/testing/tests/test_layers_functional.py
+++ b/lib/lp/testing/tests/test_layers_functional.py
@@ -10,6 +10,8 @@ to confirm that the environment hasn't been corrupted by tests
 import io
 import os
 import signal
+from urllib.error import HTTPError
+from urllib.request import urlopen
 
 import amqp
 from fixtures import (
@@ -18,8 +20,6 @@ from fixtures import (
     TestWithFixtures,
     )
 import six
-from six.moves.urllib.error import HTTPError
-from six.moves.urllib.request import urlopen
 from zope.component import getUtility
 from zope.interface.interfaces import ComponentLookupError
 
diff --git a/lib/lp/testing/tests/test_publication.py b/lib/lp/testing/tests/test_publication.py
index 606ae31..a748c39 100644
--- a/lib/lp/testing/tests/test_publication.py
+++ b/lib/lp/testing/tests/test_publication.py
@@ -3,9 +3,10 @@
 
 """Tests for the helpers in `lp.testing.publication`."""
 
+from urllib.parse import quote
+
 from lazr.restful import EntryResource
 from lazr.restful.utils import get_current_browser_request
-from six.moves.urllib_parse import quote
 from zope.browserpage.simpleviewclass import simple
 from zope.component import (
     getSiteManager,
diff --git a/lib/lp/testopenid/stories/basics.txt b/lib/lp/testopenid/stories/basics.txt
index 380bb7d..0543953 100644
--- a/lib/lp/testopenid/stories/basics.txt
+++ b/lib/lp/testopenid/stories/basics.txt
@@ -29,7 +29,7 @@ After determining the URL of the OpenID server, the next thing a consumer
 needs to do is associate with the server and get a shared secret via a
 POST request.
 
-    >>> from six.moves.urllib.parse import urlencode
+    >>> from urllib.parse import urlencode
     >>> anon_browser.open(
     ...     'http://testopenid.test/+openid', data=urlencode({
     ...         'openid.mode': 'associate',
diff --git a/lib/lp/testopenid/testing/helpers.py b/lib/lp/testopenid/testing/helpers.py
index 4d189e4..bcbe038 100644
--- a/lib/lp/testopenid/testing/helpers.py
+++ b/lib/lp/testopenid/testing/helpers.py
@@ -11,13 +11,13 @@ __all__ = [
     ]
 
 import io
+from urllib.error import HTTPError
 
 from openid import fetchers
 from openid.consumer.discover import (
     OPENID_IDP_2_0_TYPE,
     OpenIDServiceEndpoint,
     )
-from six.moves.urllib.error import HTTPError
 from zope.testbrowser.wsgi import Browser
 
 from lp.services.encoding import wsgi_native_string
diff --git a/lib/lp/translations/browser/person.py b/lib/lp/translations/browser/person.py
index 2dd8d81..ec90dde 100644
--- a/lib/lp/translations/browser/person.py
+++ b/lib/lp/translations/browser/person.py
@@ -14,9 +14,9 @@ from datetime import (
     timedelta,
     )
 from itertools import islice
+from urllib.parse import urlencode
 
 import pytz
-from six.moves.urllib.parse import urlencode
 from zope.browserpage import ViewPageTemplateFile
 from zope.component import getUtility
 from zope.formlib.widget import CustomWidgetFactory
diff --git a/lib/lp/translations/browser/pofile.py b/lib/lp/translations/browser/pofile.py
index 1e85b3e..e636631 100644
--- a/lib/lp/translations/browser/pofile.py
+++ b/lib/lp/translations/browser/pofile.py
@@ -15,10 +15,10 @@ __all__ = [
 
 import os.path
 import re
+from urllib.parse import urlencode
 
 from lazr.restful.utils import smartquote
 import six
-from six.moves.urllib.parse import urlencode
 from zope.component import getUtility
 from zope.publisher.browser import FileUpload
 
diff --git a/lib/lp/translations/browser/tests/test_persontranslationview.py b/lib/lp/translations/browser/tests/test_persontranslationview.py
index e3c1251..aa0d873 100644
--- a/lib/lp/translations/browser/tests/test_persontranslationview.py
+++ b/lib/lp/translations/browser/tests/test_persontranslationview.py
@@ -1,7 +1,8 @@
 # Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from six.moves.urllib.parse import urlencode
+from urllib.parse import urlencode
+
 from zope.security.proxy import removeSecurityProxy
 
 from lp.app.enums import ServiceUsage
diff --git a/lib/lp/translations/browser/translationmessage.py b/lib/lp/translations/browser/translationmessage.py
index 4f904d9..105ad46 100644
--- a/lib/lp/translations/browser/translationmessage.py
+++ b/lib/lp/translations/browser/translationmessage.py
@@ -19,12 +19,12 @@ __all__ = [
 import datetime
 import operator
 import re
-
-import pytz
-from six.moves.urllib.parse import (
+from urllib.parse import (
     parse_qsl,
     urlencode,
     )
+
+import pytz
 from zope import datetime as zope_datetime
 from zope.browserpage import ViewPageTemplateFile
 from zope.component import getUtility
diff --git a/lib/lp/translations/doc/poexport-request-productseries.txt b/lib/lp/translations/doc/poexport-request-productseries.txt
index a762411..45aa763 100644
--- a/lib/lp/translations/doc/poexport-request-productseries.txt
+++ b/lib/lp/translations/doc/poexport-request-productseries.txt
@@ -84,7 +84,7 @@ The email contains a URL linking to where the exported file can be downloaded.
 
 Let's download it and make sure the contents look ok.
 
-    >>> from six.moves.urllib.request import urlopen
+    >>> from urllib.request import urlopen
     >>> from lp.services.helpers import bytes_to_tarfile
     >>> tarball = bytes_to_tarfile(urlopen(url).read())
     >>> for name in sorted(tarball.getnames()):
diff --git a/lib/lp/translations/doc/poexport-request.txt b/lib/lp/translations/doc/poexport-request.txt
index 18d685d..5aee787 100644
--- a/lib/lp/translations/doc/poexport-request.txt
+++ b/lib/lp/translations/doc/poexport-request.txt
@@ -85,7 +85,7 @@ The email contains a URL linking to where the exported file can be downloaded.
 
 Let's download it and make sure the contents look ok.
 
-    >>> from six.moves.urllib.request import urlopen
+    >>> from urllib.request import urlopen
     >>> from lp.services.helpers import bytes_to_tarfile
     >>> tarball = bytes_to_tarfile(urlopen(url).read())
     >>> for name in sorted(tarball.getnames()):
diff --git a/lib/lp/translations/stories/importqueue/xx-translation-import-queue.txt b/lib/lp/translations/stories/importqueue/xx-translation-import-queue.txt
index 0dcbd93..2279d03 100644
--- a/lib/lp/translations/stories/importqueue/xx-translation-import-queue.txt
+++ b/lib/lp/translations/stories/importqueue/xx-translation-import-queue.txt
@@ -209,7 +209,7 @@ There is an option to remove entries from the queue.
 
 No Privileges Person tries to remove entries but to no effect.
 
-    >>> from six.moves.urllib.parse import urlencode
+    >>> from urllib.parse import urlencode
     >>> post_data = urlencode(
     ...     {
     ...         'field.filter_target': 'all',
diff --git a/utilities/paste b/utilities/paste
index 2787a3a..fa461f0 100755
--- a/utilities/paste
+++ b/utilities/paste
@@ -9,11 +9,11 @@ from optparse import OptionParser
 import os
 import pwd
 import sys
+from urllib.parse import urljoin
 import webbrowser
 
 from fixtures import MonkeyPatch
 from six.moves.http_cookiejar import Cookie
-from six.moves.urllib.parse import urljoin
 from zope.testbrowser.browser import Browser
 
 
@@ -118,8 +118,7 @@ def main():
     # Remove the check for robots.txt, since the one on
     # pastebin.ubuntu.com doesn't allow us to open the page. We're not
     # really a robot.
-    with MonkeyPatch(
-            'six.moves.urllib.robotparser.RobotFileParser.allow_all', True):
+    with MonkeyPatch('urllib.robotparser.RobotFileParser.allow_all', True):
         browser.open(urljoin('https://' + paste_host, PASTE_PATH))
 
     if parser.options.private:
diff --git a/utilities/roundup-sniffer.py b/utilities/roundup-sniffer.py
index 5fbfb26..16bebbe 100755
--- a/utilities/roundup-sniffer.py
+++ b/utilities/roundup-sniffer.py
@@ -44,9 +44,8 @@ from os.path import (
 from pprint import pprint
 import sys
 from time import sleep
-
-from six.moves.urllib.parse import urlencode
-from six.moves.urllib.request import urlopen
+from urllib.parse import urlencode
+from urllib.request import urlopen
 
 from lp.services.beautifulsoup import BeautifulSoup