← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:py3-services-basestring into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:py3-services-basestring into launchpad:master.

Commit message:
Replace basestring with six.string_types in lp.services

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/389208
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:py3-services-basestring into launchpad:master.
diff --git a/lib/lp/services/database/postgresql.py b/lib/lp/services/database/postgresql.py
index e6f8c38..967a5a8 100644
--- a/lib/lp/services/database/postgresql.py
+++ b/lib/lp/services/database/postgresql.py
@@ -12,6 +12,8 @@ __metaclass__ = type
 
 import re
 
+import six
+
 from lp.services.database.sqlbase import (
     quote,
     quoteIdentifier,
@@ -406,7 +408,7 @@ def drop_tables(cur, tables):
     """
     if tables is None or len(tables) == 0:
         return
-    if isinstance(tables, basestring):
+    if isinstance(tables, six.string_types):
         tables = [tables]
 
     # This syntax requires postgres 8.2 or better
diff --git a/lib/lp/services/database/sqlbase.py b/lib/lp/services/database/sqlbase.py
index ca35d9f..57fd27c 100644
--- a/lib/lp/services/database/sqlbase.py
+++ b/lib/lp/services/database/sqlbase.py
@@ -41,6 +41,7 @@ from psycopg2.extensions import (
     ISOLATION_LEVEL_SERIALIZABLE,
     )
 import pytz
+import six
 from sqlobject.sqlbuilder import sqlrepr
 import storm
 from storm.databases.postgres import compile as postgres_compile
@@ -371,7 +372,7 @@ def quote_like(x):
     TypeError: Not a string (<type 'int'>)
 
     """
-    if not isinstance(x, basestring):
+    if not isinstance(x, six.string_types):
         raise TypeError('Not a string (%s)' % type(x))
     return quote(x.replace('%', r'\%').replace('_', r'\_'))
 
diff --git a/lib/lp/services/helpers.py b/lib/lp/services/helpers.py
index 888c31e..33f2e23 100644
--- a/lib/lp/services/helpers.py
+++ b/lib/lp/services/helpers.py
@@ -327,7 +327,7 @@ def ensure_unicode(string):
     ensure_unicode() should eventually be removed.
 
     This differs from the builtin unicode() function, as a TypeError
-    exception will be raised if the parameter is not a basestring or if
+    exception will be raised if the parameter is not a string type or if
     a raw string is not ASCII.
 
     >>> ensure_unicode(u'hello')
@@ -344,7 +344,7 @@ def ensure_unicode(string):
     >>> ensure_unicode(42)
     Traceback (most recent call last):
     ...
-    TypeError: 42 is not a basestring (<type 'int'>)
+    TypeError: 42 is not a string type (<type 'int'>)
 
     >>> ensure_unicode(None) is None
     True
@@ -360,4 +360,4 @@ def ensure_unicode(string):
             raise TypeError("%s is not US-ASCII" % repr(string))
     else:
         raise TypeError(
-            "%r is not a basestring (%r)" % (string, type(string)))
+            "%r is not a string type (%r)" % (string, type(string)))
diff --git a/lib/lp/services/log/logger.py b/lib/lp/services/log/logger.py
index 4451a04..ea1f61e 100644
--- a/lib/lp/services/log/logger.py
+++ b/lib/lp/services/log/logger.py
@@ -110,7 +110,7 @@ class FakeLogger:
         return self.loglevel
 
     def _format_message(self, msg, *args):
-        if not isinstance(msg, basestring):
+        if not isinstance(msg, six.string_types):
             msg = str(msg)
         # To avoid type errors when the msg has % values and args is empty,
         # don't expand the string with empty args.
diff --git a/lib/lp/services/mail/notificationrecipientset.py b/lib/lp/services/mail/notificationrecipientset.py
index 62e9391..d08a804 100644
--- a/lib/lp/services/mail/notificationrecipientset.py
+++ b/lib/lp/services/mail/notificationrecipientset.py
@@ -87,7 +87,7 @@ class NotificationRecipientSet:
 
     def getReason(self, person_or_email):
         """See `INotificationRecipientSet`."""
-        if zope_isinstance(person_or_email, basestring):
+        if zope_isinstance(person_or_email, six.string_types):
             try:
                 person = self._emailToPerson[person_or_email]
             except KeyError:
diff --git a/lib/lp/services/mail/sendmail.py b/lib/lp/services/mail/sendmail.py
index 7cd0739..d54a764 100644
--- a/lib/lp/services/mail/sendmail.py
+++ b/lib/lp/services/mail/sendmail.py
@@ -82,9 +82,11 @@ def do_paranoid_email_content_validation(from_addr, to_addrs, subject, body):
     # XXX StuartBishop 2005-03-19:
     # These checks need to be migrated upstream if this bug
     # still exists in modern Z3.
-    assert zisinstance(from_addr, basestring), 'Invalid From: %r' % from_addr
-    assert zisinstance(subject, basestring), 'Invalid Subject: %r' % subject
-    assert zisinstance(body, basestring), 'Invalid body: %r' % body
+    assert zisinstance(from_addr, six.string_types), \
+        'Invalid From: %r' % from_addr
+    assert zisinstance(subject, six.string_types), \
+        'Invalid Subject: %r' % subject
+    assert zisinstance(body, six.string_types), 'Invalid body: %r' % body
 
 
 def do_paranoid_envelope_to_validation(to_addrs):
@@ -98,7 +100,7 @@ def do_paranoid_envelope_to_validation(to_addrs):
     assert (zisinstance(to_addrs, (list, tuple, set))
             and len(to_addrs) > 0), 'Invalid To: %r' % (to_addrs,)
     for addr in to_addrs:
-        assert zisinstance(addr, basestring) and bool(addr), \
+        assert zisinstance(addr, six.string_types) and bool(addr), \
                 'Invalid recipient: %r in %r' % (addr, to_addrs)
         assert '\n' not in addr, (
             "Address contains carriage returns: %r" % (addr,))
@@ -204,7 +206,7 @@ class MailController(object):
     def __init__(self, from_addr, to_addrs, subject, body, headers=None,
                  envelope_to=None, bulk=True):
         self.from_addr = from_addr
-        if zisinstance(to_addrs, basestring):
+        if zisinstance(to_addrs, six.string_types):
             to_addrs = [to_addrs]
         self.to_addrs = to_addrs
         self.envelope_to = envelope_to
@@ -448,7 +450,7 @@ def sendmail(message, to_addrs=None, bulk=True):
 
     raw_message = message.as_string()
     message_detail = message['Subject']
-    if not isinstance(message_detail, basestring):
+    if not isinstance(message_detail, six.string_types):
         # Might be a Header object; can be squashed.
         message_detail = unicode(message_detail)
     if _immediate_mail_delivery:
@@ -509,7 +511,8 @@ def raw_sendmail(from_addr, to_addrs, raw_message, message_detail):
     :param message_detail: String of detail about the message
         to be recorded to help with debugging, eg the message subject.
     """
-    assert not isinstance(to_addrs, basestring), 'to_addrs must be a sequence'
+    assert not isinstance(to_addrs, six.string_types), \
+        'to_addrs must be a sequence'
     assert isinstance(raw_message, str), 'Not a plain string'
     assert raw_message.decode('ascii'), 'Not ASCII - badly encoded message'
     mailer = getUtility(IMailDelivery, 'Mail')
diff --git a/lib/lp/services/mail/tests/test_sendmail.py b/lib/lp/services/mail/tests/test_sendmail.py
index 24f1512..8206ad7 100644
--- a/lib/lp/services/mail/tests/test_sendmail.py
+++ b/lib/lp/services/mail/tests/test_sendmail.py
@@ -8,6 +8,7 @@ import email.header
 from email.message import Message
 import unittest
 
+import six
 from zope.interface import implementer
 from zope.sendmail.interfaces import IMailDelivery
 
@@ -300,7 +301,7 @@ class TestMailController(TestCase):
         a0 = actions[0]
         self.assertEqual(a0.category, 'sendmail')
         self.assertEqual(a0.detail, subject)
-        self.assertIsInstance(a0.detail, basestring)
+        self.assertIsInstance(a0.detail, six.string_types)
 
 
 @implementer(IMailDelivery)
diff --git a/lib/lp/services/messages/doc/message.txt b/lib/lp/services/messages/doc/message.txt
index 8e7ee4c..53994b5 100644
--- a/lib/lp/services/messages/doc/message.txt
+++ b/lib/lp/services/messages/doc/message.txt
@@ -37,7 +37,8 @@ Messages always have a message id, which is used when notifications
 of this message are sent out. The message id is generated by the system
 if not provided
 
-    >>> isinstance(msg.rfc822msgid, basestring)
+    >>> import six
+    >>> isinstance(msg.rfc822msgid, six.string_types)
     True
     >>> bool(msg.rfc822msgid)
     True
diff --git a/lib/lp/services/propertycache.py b/lib/lp/services/propertycache.py
index 4495419..77b5b89 100644
--- a/lib/lp/services/propertycache.py
+++ b/lib/lp/services/propertycache.py
@@ -17,6 +17,7 @@ __all__ = [
 
 from functools import partial
 
+import six
 from zope.interface import (
     implementer,
     Interface,
@@ -134,7 +135,7 @@ def cachedproperty(name_or_function):
 
     See `doc/propertycache.txt` for usage.
     """
-    if isinstance(name_or_function, basestring):
+    if isinstance(name_or_function, six.string_types):
         name = name_or_function
         return partial(CachedProperty, name=name)
     else:
diff --git a/lib/lp/services/timeout.py b/lib/lp/services/timeout.py
index c06a703..a44040c 100644
--- a/lib/lp/services/timeout.py
+++ b/lib/lp/services/timeout.py
@@ -37,6 +37,7 @@ from requests.adapters import (
     )
 from requests_file import FileAdapter
 from requests_toolbelt.downloadutils import stream
+import six
 from six import reraise
 from six.moves.xmlrpc_client import (
     SafeTransport,
@@ -190,7 +191,7 @@ class with_timeout:
         """
         # If the cleanup function is specified by name, the function but be a
         # method, so defined in a class definition context.
-        if isinstance(cleanup, basestring):
+        if isinstance(cleanup, six.string_types):
             frame = sys._getframe(1)
             f_locals = frame.f_locals
 
@@ -206,7 +207,7 @@ class with_timeout:
         """Wraps the method."""
         def cleanup(t, args):
             if self.cleanup is not None:
-                if isinstance(self.cleanup, basestring):
+                if isinstance(self.cleanup, six.string_types):
                     # 'self' will be first positional argument.
                     getattr(args[0], self.cleanup)()
                 else:
diff --git a/lib/lp/services/utils.py b/lib/lp/services/utils.py
index 56e5468..d3def35 100644
--- a/lib/lp/services/utils.py
+++ b/lib/lp/services/utils.py
@@ -381,7 +381,7 @@ def obfuscate_structure(o):
         elements, and dict keys and values have undergone obfuscate_email
         recursively.
     """
-    if isinstance(o, basestring):
+    if isinstance(o, six.string_types):
         return obfuscate_email(o)
     elif isinstance(o, (list, tuple)):
         return [obfuscate_structure(value) for value in o]
diff --git a/lib/lp/services/webapp/errorlog.py b/lib/lp/services/webapp/errorlog.py
index a64ce43..df20c1d 100644
--- a/lib/lp/services/webapp/errorlog.py
+++ b/lib/lp/services/webapp/errorlog.py
@@ -19,6 +19,7 @@ import oops_amqp
 from oops_datedir_repo import DateDirRepo
 import oops_timeline
 import pytz
+import six
 from six.moves.urllib.parse import urlparse
 from zope.component.interfaces import ObjectEvent
 from zope.error.interfaces import IErrorReportingUtility
@@ -112,7 +113,7 @@ def attach_exc_info(report, context):
         return
     report['type'] = getattr(info[0], '__name__', info[0])
     report['value'] = oops.createhooks.safe_unicode(info[1])
-    if not isinstance(info[2], basestring):
+    if not isinstance(info[2], six.string_types):
         tb_text = ''.join(format_exception(*info,
                                            **{'as_html': False}))
     else:
@@ -204,7 +205,7 @@ def attach_http_request(report, context):
     for key, value in request.items():
         if _is_sensitive(request, key):
             value = '<hidden>'
-        if not isinstance(value, basestring):
+        if not isinstance(value, six.string_types):
             value = oops.createhooks.safe_unicode(value)
         # keys need to be unicode objects. The form items (a subset of
         # request.items) are generally just the url query_string url decoded,
diff --git a/lib/lp/services/webapp/servers.py b/lib/lp/services/webapp/servers.py
index 1f77b76..ab9764b 100644
--- a/lib/lp/services/webapp/servers.py
+++ b/lib/lp/services/webapp/servers.py
@@ -1224,7 +1224,7 @@ class WebServicePublication(WebServicePublicationMixin,
                 pageid += ':' + collection_identifier
         op = (view.request.get('ws.op')
             or view.request.query_string_params.get('ws.op'))
-        if op and isinstance(op, basestring):
+        if op and isinstance(op, six.string_types):
             pageid += ':' + op
         return pageid
 
diff --git a/lib/lp/services/webapp/tests/test_statementtracer.py b/lib/lp/services/webapp/tests/test_statementtracer.py
index bb2c6d0..51ae1cf 100644
--- a/lib/lp/services/webapp/tests/test_statementtracer.py
+++ b/lib/lp/services/webapp/tests/test_statementtracer.py
@@ -72,7 +72,7 @@ class StubCursor:
         # most types, but we can't use psycopg2's mogrify without a real
         # connection.
         mangled_params = tuple(
-            repr(p) if isinstance(p, basestring) else p for p in params)
+            repr(p) if isinstance(p, six.string_types) else p for p in params)
         return statement % tuple(mangled_params)
 
 
diff --git a/lib/lp/services/webapp/vocabulary.py b/lib/lp/services/webapp/vocabulary.py
index 40ad2ea..8ccb7b2 100644
--- a/lib/lp/services/webapp/vocabulary.py
+++ b/lib/lp/services/webapp/vocabulary.py
@@ -27,6 +27,7 @@ __all__ = [
 from collections import namedtuple
 
 from lazr.restful.utils import safe_hasattr
+import six
 from sqlobject import (
     AND,
     CONTAINSSTRING,
@@ -263,7 +264,7 @@ class FilteredVocabularyBase:
                     or func.__name__ == 'search')):
             def do_search(
                     query=None, vocab_filter=None, *args, **kwargs):
-                if isinstance(vocab_filter, basestring):
+                if isinstance(vocab_filter, six.string_types):
                     for filter in self.supportedFilters():
                         if filter.name == vocab_filter:
                             vocab_filter = filter
diff --git a/lib/lp/services/webhooks/model.py b/lib/lp/services/webhooks/model.py
index 461129d..d2ae96f 100644
--- a/lib/lp/services/webhooks/model.py
+++ b/lib/lp/services/webhooks/model.py
@@ -175,7 +175,7 @@ class Webhook(StormBase):
         # The correctness of the values is also checked by zope.schema,
         # but best to be safe.
         assert isinstance(event_types, (list, tuple))
-        assert all(isinstance(v, basestring) for v in event_types)
+        assert all(isinstance(v, six.string_types) for v in event_types)
         updated_data['event_types'] = event_types
         self.json_data = updated_data
 
diff --git a/lib/lp/services/worlddata/model/language.py b/lib/lp/services/worlddata/model/language.py
index 2325683..800b219 100644
--- a/lib/lp/services/worlddata/model/language.py
+++ b/lib/lp/services/worlddata/model/language.py
@@ -8,7 +8,7 @@ __all__ = [
     'LanguageSet',
     ]
 
-
+import six
 from sqlobject import (
     BoolCol,
     IntCol,
@@ -270,7 +270,7 @@ class LanguageSet:
 
     def getLanguageByCode(self, code):
         """See `ILanguageSet`."""
-        assert isinstance(code, basestring), (
+        assert isinstance(code, six.string_types), (
             "%s is not a valid type for 'code'" % type(code))
         try:
             return Language.byCode(code)