← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:remove-deprecations into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:remove-deprecations into launchpad:master.

Commit message:
Fix several [Pending]DeprecationWarnings

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

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

Noticed while working on upgrading zope.testing/zope.testrunner.  There are more, but this is a start.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:remove-deprecations into launchpad:master.
diff --git a/lib/contrib/oauth.py b/lib/contrib/oauth.py
index 26e69f4..47a821d 100644
--- a/lib/contrib/oauth.py
+++ b/lib/contrib/oauth.py
@@ -1,10 +1,16 @@
-import cgi
-import urllib
-import time
-import random
-import urlparse
-import hmac
 import base64
+import hmac
+import random
+import time
+
+from six.moves.urllib.parse import (
+    parse_qs,
+    quote,
+    unquote,
+    urlencode,
+    urlparse,
+    )
+
 
 VERSION = '1.0' # Hi Blaine!
 HTTP_METHOD = 'GET'
@@ -22,7 +28,7 @@ def build_authenticate_header(realm=''):
 # url escape
 def escape(s):
     # escape '/' too
-    return urllib.quote(s, safe='~')
+    return quote(s, safe='~')
 
 # util function: current timestamp
 # seconds since epoch (UTC)
@@ -60,13 +66,13 @@ class OAuthToken(object):
         self.secret = secret
 
     def to_string(self):
-        return urllib.urlencode({'oauth_token': self.key, 'oauth_token_secret': self.secret})
+        return urlencode({'oauth_token': self.key, 'oauth_token_secret': self.secret})
 
     # return a token from something like:
     # oauth_token_secret=digg&oauth_token=digg
     @staticmethod   
     def from_string(s):
-        params = cgi.parse_qs(s, keep_blank_values=False)
+        params = parse_qs(s, keep_blank_values=False)
         key = params['oauth_token'][0]
         secret = params['oauth_token_secret'][0]
         return OAuthToken(key, secret)
@@ -155,7 +161,7 @@ class OAuthRequest(object):
 
     # parses the url and rebuilds it to be scheme://host/path
     def get_normalized_http_url(self):
-        parts = urlparse.urlparse(self.http_url)
+        parts = urlparse(self.http_url)
         url_string = '%s://%s%s' % (parts[0], parts[1], parts[2]) # scheme, netloc, path
         return url_string
         
@@ -197,7 +203,7 @@ class OAuthRequest(object):
 
         # from the url string
         elif http_method == 'GET':
-            param_str = urlparse.urlparse(http_url).query
+            param_str = urlparse(http_url).query
             parameters = OAuthRequest._split_url_string(param_str)
 
         if parameters:
@@ -256,15 +262,15 @@ class OAuthRequest(object):
                 # section 3.4.1.3.1.
                 continue
             # remove quotes and unescape the value
-            params[param_parts[0]] = urllib.unquote(param_parts[1].strip('\"'))
+            params[param_parts[0]] = unquote(param_parts[1].strip('\"'))
         return params
     
     # util function: turn url string into parameters, has to do some unescaping
     @staticmethod
     def _split_url_string(param_str):
-        parameters = cgi.parse_qs(param_str, keep_blank_values=False)
+        parameters = parse_qs(param_str, keep_blank_values=False)
         for k, v in parameters.iteritems():
-            parameters[k] = urllib.unquote(v[0])
+            parameters[k] = unquote(v[0])
         return parameters
 
 # OAuthServer is a worker to check a requests validity against a data store
diff --git a/lib/lp/app/browser/launchpad.py b/lib/lp/app/browser/launchpad.py
index 5d2d6d6..50ccd6c 100644
--- a/lib/lp/app/browser/launchpad.py
+++ b/lib/lp/app/browser/launchpad.py
@@ -22,7 +22,6 @@ __all__ = [
     ]
 
 
-import cgi
 from datetime import timedelta
 import operator
 import os
@@ -30,6 +29,7 @@ import re
 import time
 import urllib
 
+from six.moves.urllib.parse import parse_qs
 from zope import i18n
 from zope.component import (
     getGlobalSiteManager,
@@ -631,7 +631,7 @@ class LoginStatus:
         # If we have a query string, remove some things we don't want, and
         # keep it around.
         if query_string:
-            query_dict = cgi.parse_qs(query_string, keep_blank_values=True)
+            query_dict = parse_qs(query_string, keep_blank_values=True)
             query_dict.pop('loggingout', None)
             query_string = urllib.urlencode(
                 sorted(query_dict.items()), doseq=True)
diff --git a/lib/lp/bugs/browser/buglisting.py b/lib/lp/bugs/browser/buglisting.py
index f2fc8ab..2468f2f 100644
--- a/lib/lp/bugs/browser/buglisting.py
+++ b/lib/lp/bugs/browser/buglisting.py
@@ -1,4 +1,4 @@
-# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """IBugTask-related browser views."""
@@ -21,10 +21,8 @@ __all__ = [
     'TextualBugTaskSearchListingView',
     ]
 
-import cgi
 import os.path
 import urllib
-import urlparse
 
 from lazr.delegates import delegate_to
 from lazr.restful.interfaces import IJSONRequestCache
@@ -32,6 +30,10 @@ 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,
+    )
 from z3c.pt.pagetemplate import ViewPageTemplateFile
 from zope.authentication.interfaces import IUnauthenticatedPrincipal
 from zope.component import (
@@ -231,7 +233,7 @@ def rewrite_old_bugtask_status_query_string(query_string):
     corrected query string for the search, else return the original
     query string.
     """
-    query_elements = cgi.parse_qsl(
+    query_elements = parse_qsl(
         query_string, keep_blank_values=True, strict_parsing=False)
     query_elements_mapped = []
 
@@ -766,7 +768,7 @@ class BugListingBatchNavigator(TableBatchNavigator):
         # field/value pairs.
         if cookie is None:
             return
-        for field, value in urlparse.parse_qsl(cookie):
+        for field, value in parse_qsl(cookie):
             # Skip unsupported fields (from old cookies).
             if field not in self.field_visibility:
                 continue
@@ -1129,7 +1131,7 @@ class BugTaskSearchListingView(LaunchpadFormView, FeedsMixin, BugsInfoMixin):
     @property
     def template(self):
         query_string = self.request.get('QUERY_STRING') or ''
-        query_params = urlparse.parse_qs(query_string)
+        query_params = parse_qs(query_string)
         if 'batch_request' in query_params:
             return self.bugtask_table_template
         else:
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 0ab4524..9cc69fc 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
@@ -73,8 +73,10 @@ 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 cgi import parse_qs
-    >>> from urlparse import urlparse
+    >>> from six.moves.urllib.parse import (
+    ...     parse_qs,
+    ...     urlparse,
+    ...     )
 
     >>> url = user_browser.getLink(text=u'bug filing form').url
     >>> scheme, netloc, path, params, query, fragment = urlparse(url)
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 0968c21..99d8893 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
@@ -21,7 +21,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 cgi import parse_qsl
+    ...     from six.moves.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/registry/browser/tests/test_sourcepackage_views.py b/lib/lp/registry/browser/tests/test_sourcepackage_views.py
index bc5a3f7..3893d1e 100644
--- a/lib/lp/registry/browser/tests/test_sourcepackage_views.py
+++ b/lib/lp/registry/browser/tests/test_sourcepackage_views.py
@@ -1,13 +1,13 @@
-# Copyright 2010-2016 Canonical Ltd.  This software is licensed under the
+# Copyright 2010-2019 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Tests for SourcePackage view code."""
 
 __metaclass__ = type
 
-import cgi
 import urllib
 
+from six.moves.urllib.parse import parse_qsl
 from soupmatchers import (
     HTMLContains,
     Tag,
@@ -61,7 +61,7 @@ class TestSourcePackageViewHelpers(TestCaseWithFactory):
 
     def assertInQueryString(self, url, field, value):
         base, query = urllib.splitquery(url)
-        params = cgi.parse_qsl(query)
+        params = parse_qsl(query)
         self.assertTrue((field, value) in params)
 
     def test_get_register_upstream_url_fields(self):
@@ -74,7 +74,7 @@ class TestSourcePackageViewHelpers(TestCaseWithFactory):
         url = get_register_upstream_url(source_package)
         base, query = urllib.splitquery(url)
         self.assertEqual('/projects/+new', base)
-        params = cgi.parse_qsl(query)
+        params = parse_qsl(query)
         expected_params = [
             ('_return_url',
              'http://launchpad.test/zoobuntu/walrus/'
diff --git a/lib/lp/registry/tests/test_distributionsourcepackage.py b/lib/lp/registry/tests/test_distributionsourcepackage.py
index 992e6c4..15da65e 100644
--- a/lib/lp/registry/tests/test_distributionsourcepackage.py
+++ b/lib/lp/registry/tests/test_distributionsourcepackage.py
@@ -1,4 +1,4 @@
-# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Tests for DistributionSourcePackage."""
@@ -298,7 +298,7 @@ class TestDistributionSourcePackageInDatabase(TestCaseWithFactory):
         DistributionSourcePackageInDatabase._cache["Frank"] = "Sinatra"
         transaction.abort()
         self.assertEqual(
-            {}, DistributionSourcePackageInDatabase._cache.items())
+            {}, DistributionSourcePackageInDatabase._cache.as_dict())
 
     def test_mapping_cache_cleared_on_commit(self):
         # DistributionSourcePackageInDatabase._cache is cleared when a
@@ -306,7 +306,7 @@ class TestDistributionSourcePackageInDatabase(TestCaseWithFactory):
         DistributionSourcePackageInDatabase._cache["Frank"] = "Sinatra"
         transaction.commit()
         self.assertEqual(
-            {}, DistributionSourcePackageInDatabase._cache.items())
+            {}, DistributionSourcePackageInDatabase._cache.as_dict())
 
     def test_new(self):
         # DistributionSourcePackageInDatabase.new() creates a new DSP, adds it
@@ -318,7 +318,7 @@ class TestDistributionSourcePackageInDatabase(TestCaseWithFactory):
         self.assertIs(Store.of(distribution), Store.of(dsp))
         self.assertEqual(
             {(distribution.id, sourcepackagename.id): dsp.id},
-            DistributionSourcePackageInDatabase._cache.items())
+            DistributionSourcePackageInDatabase._cache.as_dict())
 
     def test_getDirect_not_found(self):
         # DistributionSourcePackageInDatabase.getDirect() returns None if a
@@ -333,7 +333,7 @@ class TestDistributionSourcePackageInDatabase(TestCaseWithFactory):
             self.assertIs(None, dsp)
         self.assertThat(recorder, HasQueryCount(Equals(1)))
         self.assertEqual(
-            {}, DistributionSourcePackageInDatabase._cache.items())
+            {}, DistributionSourcePackageInDatabase._cache.as_dict())
 
     def test_getDirect_found(self):
         # DistributionSourcePackageInDatabase.getDirect() returns the
@@ -351,7 +351,7 @@ class TestDistributionSourcePackageInDatabase(TestCaseWithFactory):
         self.assertThat(recorder, HasQueryCount(Equals(1)))
         self.assertEqual(
             {(distribution.id, sourcepackagename.id): dsp.id},
-            DistributionSourcePackageInDatabase._cache.items())
+            DistributionSourcePackageInDatabase._cache.as_dict())
 
     def test_get_not_cached_and_not_found(self):
         # DistributionSourcePackageInDatabase.get() returns None if a DSP does
@@ -366,7 +366,7 @@ class TestDistributionSourcePackageInDatabase(TestCaseWithFactory):
             self.assertIs(None, dsp)
         self.assertThat(recorder, HasQueryCount(Equals(1)))
         self.assertEqual(
-            {}, DistributionSourcePackageInDatabase._cache.items())
+            {}, DistributionSourcePackageInDatabase._cache.as_dict())
 
     def test_get_cached_and_not_found(self):
         # DistributionSourcePackageInDatabase.get() returns None if a DSP does
@@ -451,7 +451,7 @@ class TestDistributionSourcePackageInDatabase(TestCaseWithFactory):
         self.assertThat(recorder, HasQueryCount(Equals(1)))
         self.assertEqual(
             {(distribution.id, sourcepackagename.id): dsp.id},
-            DistributionSourcePackageInDatabase._cache.items())
+            DistributionSourcePackageInDatabase._cache.as_dict())
 
     def test_get_cached_and_found(self):
         # DistributionSourcePackageInDatabase.get() returns the DSP if it's
diff --git a/lib/lp/scripts/utilities/js/combo.py b/lib/lp/scripts/utilities/js/combo.py
index 470a5f6..4d27293 100644
--- a/lib/lp/scripts/utilities/js/combo.py
+++ b/lib/lp/scripts/utilities/js/combo.py
@@ -1,12 +1,13 @@
-# Copyright 2011-2012 Canonical Ltd.  This software is licensed under the
+# Copyright 2011-2019 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 __metaclass__ = type
 
-import cgi
 import os
 import urlparse
 
+from six.moves.urllib.parse import parse_qsl
+
 from jsbuild import (
     CSSComboFile,
     JSComboFile,
@@ -27,7 +28,7 @@ def parse_qs(query):
 
     Returns the list of arguments in the original order.
     """
-    params = cgi.parse_qsl(query, keep_blank_values=True)
+    params = parse_qsl(query, keep_blank_values=True)
     return tuple([param for param, value in params])
 
 
diff --git a/lib/lp/services/webapp/login.py b/lib/lp/services/webapp/login.py
index 8dc179f..0dcb795 100644
--- a/lib/lp/services/webapp/login.py
+++ b/lib/lp/services/webapp/login.py
@@ -1,4 +1,4 @@
-# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 """Stuff to do with logging in and logging out."""
 
@@ -414,7 +414,7 @@ class OpenIDCallbackView(OpenIDLogin):
                 return self.processPositiveAssertion()
             except HTTPException as error:
                 return OpenIDLoginErrorView(
-                    self.context, self.request, login_error=error.message)()
+                    self.context, self.request, login_error=str(error))()
 
         if self.account is not None:
             # The authentication failed (or was canceled), but the user is
diff --git a/lib/lp/services/webapp/servers.py b/lib/lp/services/webapp/servers.py
index 506f705..c9fc0e6 100644
--- a/lib/lp/services/webapp/servers.py
+++ b/lib/lp/services/webapp/servers.py
@@ -5,7 +5,6 @@
 
 __metaclass__ = type
 
-import cgi
 import threading
 import xmlrpclib
 
@@ -21,6 +20,7 @@ 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
 import transaction
 from transaction.interfaces import ISynchronizer
 from zc.zservertracelog.tracelog import Server as ZServerTracelogServer
@@ -525,7 +525,7 @@ def get_query_string_params(request):
     if query_string is None:
         query_string = ''
 
-    parsed_qs = cgi.parse_qs(query_string, keep_blank_values=True)
+    parsed_qs = parse_qs(query_string, keep_blank_values=True)
     # Use BrowserRequest._decode() for decoding the received parameters.
     decoded_qs = {}
     for key, values in parsed_qs.iteritems():
diff --git a/lib/lp/services/webapp/tests/test_login_account.py b/lib/lp/services/webapp/tests/test_login_account.py
index af72f47..6d6f535 100644
--- a/lib/lp/services/webapp/tests/test_login_account.py
+++ b/lib/lp/services/webapp/tests/test_login_account.py
@@ -1,10 +1,10 @@
-# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-import cgi
 from datetime import datetime
 
 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
@@ -133,7 +133,7 @@ class TestLoginAndLogout(TestCaseWithFactory):
         # which we provide in our query string.  See
         # launchpad_loggerhead.tests.TestLogout for the pertinent tests.
 
-        query = cgi.parse_qs(location.query)
+        query = parse_qs(location.query)
         self.assertEqual(query['next_to'][0], 'http://testopenid.test/+logout')
 
     def test_logging_in_and_logging_out_the_old_way(self):
diff --git a/lib/lp/testing/swift/tests/test_fixture.py b/lib/lp/testing/swift/tests/test_fixture.py
index ddcfc81..e3a5a31 100644
--- a/lib/lp/testing/swift/tests/test_fixture.py
+++ b/lib/lp/testing/swift/tests/test_fixture.py
@@ -1,4 +1,4 @@
-# Copyright 2013-2017 Canonical Ltd.  This software is licensed under the
+# Copyright 2013-2019 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Testing the mock Swift test fixture."""
@@ -68,7 +68,7 @@ class TestSwiftFixture(TestCase):
         self.assertEqual(
             'Authorization Failure. '
             'Authorization Failed: Forbidden (HTTP 403)',
-            exc.message)
+            str(exc))
 
     def test_put(self):
         client = self.swift_fixture.connect()
diff --git a/lib/lp/translations/browser/translationmessage.py b/lib/lp/translations/browser/translationmessage.py
index 693ca47..7442198 100644
--- a/lib/lp/translations/browser/translationmessage.py
+++ b/lib/lp/translations/browser/translationmessage.py
@@ -1,4 +1,4 @@
-# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """View classes for ITranslationMessage interface."""
@@ -18,13 +18,13 @@ __all__ = [
     'TranslationMessageSuggestions',
     ]
 
-import cgi
 import datetime
 import operator
 import re
 import urllib
 
 import pytz
+from six.moves.urllib.parse import parse_qsl
 from z3c.ptcompat import ViewPageTemplateFile
 from zope import datetime as zope_datetime
 from zope.component import getUtility
@@ -851,8 +851,7 @@ class BaseTranslationView(LaunchpadView):
         if '?' in new_url:
             # Get current query string
             base_url, old_query_string = new_url.split('?')
-            query_parts = cgi.parse_qsl(
-                old_query_string, strict_parsing=False)
+            query_parts = parse_qsl(old_query_string, strict_parsing=False)
 
             # Combine parameters provided by _buildRedirectParams with those
             # that came with our page request.  The latter take precedence.