← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:py3-unicode-delimited-list-widget into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:py3-unicode-delimited-list-widget into launchpad:master.

Commit message:
Use six.text_type in DelimitedListWidget.split

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/391065
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:py3-unicode-delimited-list-widget into launchpad:master.
diff --git a/lib/lp/answers/model/faq.py b/lib/lp/answers/model/faq.py
index 0ff0d1b..bc69e39 100644
--- a/lib/lp/answers/model/faq.py
+++ b/lib/lp/answers/model/faq.py
@@ -12,6 +12,7 @@ __all__ = [
     ]
 
 from lazr.lifecycle.event import ObjectCreatedEvent
+import six
 from sqlobject import (
     ForeignKey,
     SQLMultipleJoin,
@@ -188,7 +189,7 @@ class FAQSearch:
         :param projectgroup: The project group in which to search for FAQs.
         """
         if search_text is not None:
-            assert isinstance(search_text, basestring), (
+            assert isinstance(search_text, six.string_types), (
                 'search_text should be a string, not %s' % type(search_text))
             self.search_text = search_text
 
diff --git a/lib/lp/answers/testing.py b/lib/lp/answers/testing.py
index 23ce85a..2a76ad6 100644
--- a/lib/lp/answers/testing.py
+++ b/lib/lp/answers/testing.py
@@ -10,6 +10,7 @@ __all__ = [
     'QuestionFactory',
     ]
 
+import six
 from zope.component import getUtility
 
 from lp.answers.interfaces.questiontarget import IQuestionTarget
@@ -27,7 +28,7 @@ class QuestionFactory:
         It returns the pillar with the target_name and makes sure it
         provides `IQuestionTarget`.
         """
-        assert isinstance(target_name, basestring), (
+        assert isinstance(target_name, six.string_types), (
             "expected a project name: %r", target_name)
         target = getUtility(IPillarNameSet).getByName(target_name)
         assert target is not None, (
diff --git a/lib/lp/app/browser/lazrjs.py b/lib/lp/app/browser/lazrjs.py
index 3c3f0a8..8288bf3 100644
--- a/lib/lp/app/browser/lazrjs.py
+++ b/lib/lp/app/browser/lazrjs.py
@@ -23,6 +23,7 @@ from lazr.restful.utils import (
     safe_hasattr,
     )
 import simplejson
+import six
 from zope.browserpage import ViewPageTemplateFile
 from zope.component import getUtility
 from zope.schema.interfaces import (
@@ -502,7 +503,7 @@ class InlineMultiCheckboxWidget(WidgetBase):
             else:
                 vocabulary = exported_field.vocabularyName
 
-        if isinstance(vocabulary, basestring):
+        if isinstance(vocabulary, six.string_types):
             vocabulary = getVocabularyRegistry().get(context, vocabulary)
 
         # Construct checkbox data dict for each item in the vocabulary.
diff --git a/lib/lp/app/widgets/popup.py b/lib/lp/app/widgets/popup.py
index 9e8fb73..100c48b 100644
--- a/lib/lp/app/widgets/popup.py
+++ b/lib/lp/app/widgets/popup.py
@@ -16,6 +16,7 @@ __all__ = [
 
 from lazr.restful.utils import safe_hasattr
 import simplejson
+import six
 from zope.browserpage import ViewPageTemplateFile
 from zope.component import getUtility
 from zope.formlib.interfaces import ConversionError
@@ -84,7 +85,7 @@ class VocabularyPickerWidget(SingleDataHelper, ItemsWidgetBase):
         vocab = self.vocabulary
         # Special case - if the entered value is valid, it is an object
         # rather than a string (I think this is a bug somewhere)
-        if not isinstance(formValue, basestring):
+        if not isinstance(formValue, six.string_types):
             return [vocab.getTerm(formValue)]
 
         search_results = vocab.searchForTerms(formValue)
@@ -101,7 +102,7 @@ class VocabularyPickerWidget(SingleDataHelper, ItemsWidgetBase):
         val = self._getFormValue()
 
         # We have a valid object - return the corresponding token
-        if not isinstance(val, basestring):
+        if not isinstance(val, six.string_types):
             return self.vocabulary.getTerm(val).token
 
         # Just return the existing invalid token
diff --git a/lib/lp/app/widgets/textwidgets.py b/lib/lp/app/widgets/textwidgets.py
index ff28a1e..ad4cf43 100644
--- a/lib/lp/app/widgets/textwidgets.py
+++ b/lib/lp/app/widgets/textwidgets.py
@@ -5,6 +5,7 @@ import datetime
 import re
 
 import pytz
+import six
 from zope.browserpage import ViewPageTemplateFile
 from zope.datetime import (
     DateTimeError,
@@ -199,7 +200,7 @@ class DelimitedListWidget(TextAreaWidget):
     # The default splitting function, which splits on
     # white-space. Subclasses can override this if different
     # delimiting rules are needed.
-    split = staticmethod(unicode.split)
+    split = staticmethod(six.text_type.split)
 
     # The default joining function, which simply separates each list
     # item with a newline. Subclasses can override this if different
diff --git a/lib/lp/blueprints/model/specificationsearch.py b/lib/lp/blueprints/model/specificationsearch.py
index 4f68ba6..b8449d8 100644
--- a/lib/lp/blueprints/model/specificationsearch.py
+++ b/lib/lp/blueprints/model/specificationsearch.py
@@ -14,6 +14,7 @@ __all__ = [
 from collections import defaultdict
 from functools import reduce
 
+import six
 from storm.expr import (
     And,
     Coalesce,
@@ -264,7 +265,7 @@ def get_specification_filters(filter, goalstatus=True):
             SpecificationDefinitionStatus.SUPERSEDED])))
     # Filter for specification text.
     for constraint in filter:
-        if isinstance(constraint, basestring):
+        if isinstance(constraint, six.string_types):
             # A string in the filter is a text search filter.
             clauses.append(fti_search(Specification, constraint))
     return clauses
diff --git a/lib/lp/bugs/browser/bug.py b/lib/lp/bugs/browser/bug.py
index 48749dc..255b9ab 100644
--- a/lib/lp/bugs/browser/bug.py
+++ b/lib/lp/bugs/browser/bug.py
@@ -42,6 +42,7 @@ from lazr.restful import (
 from lazr.restful.interface import copy_field
 from lazr.restful.interfaces import IJSONRequestCache
 from simplejson import dumps
+import six
 from zope import formlib
 from zope.component import (
     getMultiAdapter,
@@ -407,7 +408,7 @@ class MaloneView(LaunchpadFormView):
 
     def _redirectToBug(self, bug_id):
         """Redirect to the specified bug id."""
-        if not isinstance(bug_id, basestring):
+        if not isinstance(bug_id, six.string_types):
             self.error_message = "Bug %r is not registered." % bug_id
             return
         if bug_id.startswith("#"):
diff --git a/lib/lp/bugs/browser/widgets/bugtask.py b/lib/lp/bugs/browser/widgets/bugtask.py
index 2f086b2..5169abc 100644
--- a/lib/lp/bugs/browser/widgets/bugtask.py
+++ b/lib/lp/bugs/browser/widgets/bugtask.py
@@ -17,6 +17,7 @@ __all__ = [
     "NewLineToSpacesWidget",
     ]
 
+import six
 from zope.browserpage import ViewPageTemplateFile
 from zope.component import getUtility
 from zope.formlib.interfaces import (
@@ -373,7 +374,7 @@ class BugTaskBugWatchWidget(RadioWidget):
         #      value instead of a valid field value.
         if value == self._missing:
             value = self.context.missing_value
-        elif (isinstance(value, basestring) and
+        elif (isinstance(value, six.string_types) and
               value != self._new_bugwatch_value):
             value = self._toFieldValue(value)
         # check if we want to select first item, the previously selected item
diff --git a/lib/lp/bugs/subscribers/bugactivity.py b/lib/lp/bugs/subscribers/bugactivity.py
index 799f8e4..9655239 100644
--- a/lib/lp/bugs/subscribers/bugactivity.py
+++ b/lib/lp/bugs/subscribers/bugactivity.py
@@ -4,6 +4,7 @@
 __metaclass__ = type
 
 from lazr.enum import BaseItem
+import six
 from zope.component import getUtility
 from zope.proxy import isProxy
 from zope.schema.interfaces import IField
@@ -56,7 +57,7 @@ def get_string_representation(obj):
         return obj.name
     elif isinstance(obj, BaseItem):
         return obj.title
-    elif isinstance(obj, basestring):
+    elif isinstance(obj, six.string_types):
         return obj
     elif isinstance(obj, bool):
         return str(obj)
diff --git a/lib/lp/code/mail/tests/test_branchmergeproposal.py b/lib/lp/code/mail/tests/test_branchmergeproposal.py
index 3a3e887..c6c0fdc 100644
--- a/lib/lp/code/mail/tests/test_branchmergeproposal.py
+++ b/lib/lp/code/mail/tests/test_branchmergeproposal.py
@@ -77,8 +77,8 @@ class TestMergeProposalMailing(TestCaseWithFactory):
             initial_comment=initial_comment, reviewer=reviewer)
         if diff_text:
             PreviewDiff.create(
-                bmp, diff_text, unicode(self.factory.getUniqueString('revid')),
-                unicode(self.factory.getUniqueString('revid')), None, None)
+                bmp, diff_text, self.factory.getUniqueUnicode('revid'),
+                self.factory.getUniqueUnicode('revid'), None, None)
             transaction.commit()
         subscriber = self.factory.makePerson(displayname='Baz Quxx',
             email='baz.quxx@xxxxxxxxxxx')
@@ -442,8 +442,8 @@ class TestMergeProposalMailing(TestCaseWithFactory):
             merge_proposal, providing=providedBy(merge_proposal))
         merge_proposal.updatePreviewDiff(
             ''.join(unified_diff('', 'Fake diff')),
-            unicode(self.factory.getUniqueString('revid')),
-            unicode(self.factory.getUniqueString('revid')))
+            self.factory.getUniqueUnicode('revid'),
+            self.factory.getUniqueUnicode('revid'))
         event = ObjectModifiedEvent(
             merge_proposal, old_merge_proposal, [], merge_proposal.registrant)
         merge_proposal_modified(merge_proposal, event)
diff --git a/lib/lp/code/model/branch.py b/lib/lp/code/model/branch.py
index b214c86..5e756d0 100644
--- a/lib/lp/code/model/branch.py
+++ b/lib/lp/code/model/branch.py
@@ -1136,7 +1136,7 @@ class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
 
     def removeBranchRevisions(self, revision_ids):
         """See `IBranch`."""
-        if isinstance(revision_ids, basestring):
+        if isinstance(revision_ids, six.string_types):
             revision_ids = [revision_ids]
         IMasterStore(BranchRevision).find(
             BranchRevision,
diff --git a/lib/lp/code/model/gitrepository.py b/lib/lp/code/model/gitrepository.py
index 77a4bbd..3d2408e 100644
--- a/lib/lp/code/model/gitrepository.py
+++ b/lib/lp/code/model/gitrepository.py
@@ -652,7 +652,8 @@ class GitRepository(StormBase, WebhookTargetMixin, GitIdentityMixin):
             raise ValueError('ref info object does not contain "sha1" key')
         if "type" not in obj:
             raise ValueError('ref info object does not contain "type" key')
-        if not isinstance(obj["sha1"], basestring) or len(obj["sha1"]) != 40:
+        if (not isinstance(obj["sha1"], six.string_types) or
+                len(obj["sha1"]) != 40):
             raise ValueError('ref info sha1 is not a 40-character string')
         if obj["type"] not in object_type_map:
             raise ValueError('ref info type is not a recognised object type')
diff --git a/lib/lp/code/tests/helpers.py b/lib/lp/code/tests/helpers.py
index 0e784f0..a4f8416 100644
--- a/lib/lp/code/tests/helpers.py
+++ b/lib/lp/code/tests/helpers.py
@@ -28,6 +28,7 @@ from itertools import count
 
 from breezy.plugins.builder.recipe import RecipeParser
 import fixtures
+import six
 import transaction
 from zope.component import getUtility
 from zope.security.proxy import (
@@ -170,7 +171,7 @@ def make_package_branches(factory, series, sourcepackagename, branch_count,
     Make `branch_count` branches, and make `official_count` of those
     official branches.
     """
-    if zisinstance(sourcepackagename, basestring):
+    if zisinstance(sourcepackagename, six.string_types):
         sourcepackagename = factory.getOrMakeSourcePackageName(
             sourcepackagename)
     # Make the branches created in the past in order.
diff --git a/lib/lp/registry/browser/distributionsourcepackage.py b/lib/lp/registry/browser/distributionsourcepackage.py
index 55fabee..d70467b 100644
--- a/lib/lp/registry/browser/distributionsourcepackage.py
+++ b/lib/lp/registry/browser/distributionsourcepackage.py
@@ -21,6 +21,7 @@ import itertools
 import operator
 
 from lazr.delegates import delegate_to
+import six
 from zope.component import getUtility
 from zope.interface import (
     implementer,
@@ -264,7 +265,7 @@ class DistributionSourcePackageBaseView(LaunchpadView):
 
         def not_empty(text):
             return (
-                text is not None and isinstance(text, basestring)
+                text is not None and isinstance(text, six.string_types)
                 and len(text.strip()) > 0)
 
         def decorate(dspr_pubs):
diff --git a/lib/lp/registry/model/distribution.py b/lib/lp/registry/model/distribution.py
index 9a19a4c..b9baba7 100644
--- a/lib/lp/registry/model/distribution.py
+++ b/lib/lp/registry/model/distribution.py
@@ -13,6 +13,7 @@ from collections import defaultdict
 import itertools
 from operator import itemgetter
 
+import six
 from sqlobject import (
     BoolCol,
     ForeignKey,
@@ -1140,7 +1141,7 @@ class Distribution(SQLBase, BugTargetBase, MakesAnnouncements,
 
     def guessPublishedSourcePackageName(self, pkgname):
         """See `IDistribution`"""
-        assert isinstance(pkgname, basestring), (
+        assert isinstance(pkgname, six.string_types), (
             "Expected string. Got: %r" % pkgname)
 
         pkgname = pkgname.strip().lower()
diff --git a/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py b/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py
index 84f9f74..3825fa0 100644
--- a/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py
+++ b/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py
@@ -117,7 +117,7 @@ class TestFindLatestSourcePackageReleases(TestCaseWithFactory, FactoryHelper):
     def test_baseline(self):
         distroseries = self.factory.makeDistroSeries()
         query = compose_sql_find_latest_source_package_releases(distroseries)
-        self.assertIsInstance(query, basestring)
+        self.assertIsInstance(query, six.string_types)
 
     def test_finds_nothing_for_empty_distroseries(self):
         distroseries = self.factory.makeDistroSeries()
@@ -219,7 +219,7 @@ class TestFindDifferences(TestCaseWithFactory, FactoryHelper):
         dsp = self.makeDerivedDistroSeries()
         query = compose_sql_find_differences(
             dsp.derived_series, dsp.parent_series)
-        self.assertIsInstance(query, basestring)
+        self.assertIsInstance(query, six.string_types)
 
     def test_finds_nothing_for_empty_distroseries(self):
         dsp = self.makeDerivedDistroSeries()
@@ -403,7 +403,7 @@ class TestDifferenceTypeExpression(TestCaseWithFactory):
 
     def test_baseline(self):
         query = compose_sql_difference_type()
-        self.assertIsInstance(query, basestring)
+        self.assertIsInstance(query, six.string_types)
 
     def test_no_parent_version_means_unique_to_derived_series(self):
         expected = DistroSeriesDifferenceType.UNIQUE_TO_DERIVED_SERIES
@@ -461,7 +461,7 @@ class TestPopulateDistroSeriesDiff(TestCaseWithFactory, FactoryHelper):
         dsp = self.factory.makeDistroSeriesParent()
         query = compose_sql_populate_distroseriesdiff(
             dsp.derived_series, dsp.parent_series, "tmp")
-        self.assertIsInstance(query, basestring)
+        self.assertIsInstance(query, six.string_types)
 
     def test_creates_distroseriesdifference(self):
         dsp = self.makeDerivedDistroSeries()
diff --git a/lib/lp/soyuz/model/archive.py b/lib/lp/soyuz/model/archive.py
index 0d58e56..dd80d33 100644
--- a/lib/lp/soyuz/model/archive.py
+++ b/lib/lp/soyuz/model/archive.py
@@ -1175,7 +1175,7 @@ class Archive(SQLBase):
 
     def _addArchiveDependency(self, dependency, pocket, component=None):
         """See `IArchive`."""
-        if isinstance(component, basestring):
+        if isinstance(component, six.string_types):
             try:
                 component = getUtility(IComponentSet)[component]
             except NotFoundError as e:
@@ -1430,9 +1430,9 @@ class Archive(SQLBase):
     def _checkUpload(self, person, distroseries, sourcepackagename, component,
                     pocket, strict_component=True):
         """See `IArchive`."""
-        if isinstance(component, basestring):
+        if isinstance(component, six.string_types):
             component = getUtility(IComponentSet)[component]
-        if isinstance(sourcepackagename, basestring):
+        if isinstance(sourcepackagename, six.string_types):
             sourcepackagename = getUtility(
                 ISourcePackageNameSet)[sourcepackagename]
         reason = self.checkUpload(person, distroseries, sourcepackagename,
@@ -1547,7 +1547,7 @@ class Archive(SQLBase):
         if self.is_ppa:
             if IComponent.providedBy(component_name):
                 name = component_name.name
-            elif isinstance(component_name, basestring):
+            elif isinstance(component_name, six.string_types):
                 name = component_name
             else:
                 name = None
diff --git a/lib/lp/soyuz/model/archivepermission.py b/lib/lp/soyuz/model/archivepermission.py
index d18a587..cef8196 100644
--- a/lib/lp/soyuz/model/archivepermission.py
+++ b/lib/lp/soyuz/model/archivepermission.py
@@ -14,6 +14,7 @@ from operator import attrgetter
 
 from lazr.enum import DBItem
 import pytz
+import six
 from storm.expr import Exists
 from storm.locals import (
     And,
@@ -203,7 +204,7 @@ class ArchivePermissionSet:
     def _nameToComponent(self, component):
         """Helper to convert a possible string component to IComponent"""
         try:
-            if isinstance(component, basestring):
+            if isinstance(component, six.string_types):
                 component = getUtility(IComponentSet)[component]
             return component
         except NotFoundError:
@@ -211,7 +212,7 @@ class ArchivePermissionSet:
 
     def _nameToSourcePackageName(self, sourcepackagename):
         """Helper to convert a possible string name to ISourcePackageName."""
-        if isinstance(sourcepackagename, basestring):
+        if isinstance(sourcepackagename, six.string_types):
             sourcepackagename = getUtility(
                 ISourcePackageNameSet)[sourcepackagename]
         return sourcepackagename
diff --git a/lib/lp/soyuz/model/packageset.py b/lib/lp/soyuz/model/packageset.py
index 9aebcc5..7bf5204 100644
--- a/lib/lp/soyuz/model/packageset.py
+++ b/lib/lp/soyuz/model/packageset.py
@@ -301,7 +301,7 @@ class Packageset(Storm):
 
     def addSources(self, names):
         """See `IPackageset`."""
-        if isinstance(names, basestring):
+        if isinstance(names, six.string_types):
             names = [ensure_unicode(names)]
         clauses = (SourcePackageName, SourcePackageName.name.is_in(names))
         self._api_add_or_remove(clauses, self._addSourcePackageNames)
@@ -419,7 +419,7 @@ class PackagesetSet:
 
     def _nameToSourcePackageName(self, source_name):
         """Helper to convert a possible string name to ISourcePackageName."""
-        if isinstance(source_name, basestring):
+        if isinstance(source_name, six.string_types):
             source_name = getUtility(ISourcePackageNameSet)[source_name]
         return source_name
 
diff --git a/lib/lp/soyuz/model/publishing.py b/lib/lp/soyuz/model/publishing.py
index 52ffae4..33390b5 100644
--- a/lib/lp/soyuz/model/publishing.py
+++ b/lib/lp/soyuz/model/publishing.py
@@ -489,11 +489,11 @@ class SourcePackagePublishingHistory(SQLBase, ArchivePublisherBase):
         # Check there is a change to make
         if new_component is None:
             new_component = self.component
-        elif isinstance(new_component, basestring):
+        elif isinstance(new_component, six.string_types):
             new_component = getUtility(IComponentSet)[new_component]
         if new_section is None:
             new_section = self.section
-        elif isinstance(new_section, basestring):
+        elif isinstance(new_section, six.string_types):
             new_section = getUtility(ISectionSet)[new_section]
 
         if new_component == self.component and new_section == self.section:
@@ -828,15 +828,15 @@ class BinaryPackagePublishingHistory(SQLBase, ArchivePublisherBase):
         # Check there is a change to make
         if new_component is None:
             new_component = self.component
-        elif isinstance(new_component, basestring):
+        elif isinstance(new_component, six.string_types):
             new_component = getUtility(IComponentSet)[new_component]
         if new_section is None:
             new_section = self.section
-        elif isinstance(new_section, basestring):
+        elif isinstance(new_section, six.string_types):
             new_section = getUtility(ISectionSet)[new_section]
         if new_priority is None:
             new_priority = self.priority
-        elif isinstance(new_priority, basestring):
+        elif isinstance(new_priority, six.string_types):
             new_priority = name_priority_map[new_priority]
         if new_phased_update_percentage is None:
             new_phased_update_percentage = self.phased_update_percentage
diff --git a/lib/lp/soyuz/model/queue.py b/lib/lp/soyuz/model/queue.py
index 6465bd8..c3452e2 100644
--- a/lib/lp/soyuz/model/queue.py
+++ b/lib/lp/soyuz/model/queue.py
@@ -17,6 +17,7 @@ from itertools import chain
 from operator import attrgetter
 
 import pytz
+import six
 from sqlobject import (
     ForeignKey,
     SQLMultipleJoin,
@@ -972,7 +973,7 @@ class PackageUpload(SQLBase):
     def _nameToComponent(self, component):
         """Helper to convert a possible string component to IComponent."""
         try:
-            if isinstance(component, basestring):
+            if isinstance(component, six.string_types):
                 component = getUtility(IComponentSet)[component]
             return component
         except NotFoundError:
@@ -981,7 +982,7 @@ class PackageUpload(SQLBase):
     def _nameToSection(self, section):
         """Helper to convert a possible string section to ISection."""
         try:
-            if isinstance(section, basestring):
+            if isinstance(section, six.string_types):
                 section = getUtility(ISectionSet)[section]
             return section
         except NotFoundError:
@@ -990,7 +991,7 @@ class PackageUpload(SQLBase):
     def _nameToPriority(self, priority):
         """Helper to convert a possible string priority to its enum."""
         try:
-            if isinstance(priority, basestring):
+            if isinstance(priority, six.string_types):
                 priority = name_priority_map[priority]
             return priority
         except KeyError:
diff --git a/lib/lp/soyuz/scripts/populate_archive.py b/lib/lp/soyuz/scripts/populate_archive.py
index c35063b..b853d49 100644
--- a/lib/lp/soyuz/scripts/populate_archive.py
+++ b/lib/lp/soyuz/scripts/populate_archive.py
@@ -9,7 +9,7 @@ __all__ = [
     'ArchivePopulator',
     ]
 
-
+import six
 from zope.component import getUtility
 
 from lp.app.errors import NotFoundError
@@ -38,7 +38,7 @@ def specified(option):
     """
     if option is None:
         return False
-    if isinstance(option, basestring) and option.strip() == '':
+    if isinstance(option, six.string_types) and option.strip() == '':
         return False
     return True
 
diff --git a/lib/lp/soyuz/tests/test_build_depwait.py b/lib/lp/soyuz/tests/test_build_depwait.py
index c961dd4..83b9186 100644
--- a/lib/lp/soyuz/tests/test_build_depwait.py
+++ b/lib/lp/soyuz/tests/test_build_depwait.py
@@ -56,12 +56,11 @@ class TestBuildDepWait(TestCaseWithFactory):
             version="%s.1" % self.factory.getUniqueInteger(),
             distroseries=self.distroseries, archive=self.archive)
         [build] = spph.createMissingBuilds()
-        spn = self.factory.getUniqueString()
+        spn = self.factory.getUniqueUnicode()
         version = "%s.1" % self.factory.getUniqueInteger()
         with person_logged_in(self.admin):
             build.updateStatus(
-                BuildStatus.MANUALDEPWAIT,
-                slave_status={'dependencies': unicode(spn)})
+                BuildStatus.MANUALDEPWAIT, slave_status={'dependencies': spn})
             [bpph] = self.publisher.getPubBinaries(
                 binaryname=spn, distroseries=self.distroseries,
                 version=version, builder=self.builder, archive=self.archive,
@@ -79,12 +78,11 @@ class TestBuildDepWait(TestCaseWithFactory):
             version="%s.1" % self.factory.getUniqueInteger(),
             distroseries=self.distroseries, archive=self.archive)
         [build] = spph.createMissingBuilds()
-        spn = self.factory.getUniqueString()
+        spn = self.factory.getUniqueUnicode()
         version = "%s.1" % self.factory.getUniqueInteger()
         with person_logged_in(self.admin):
             build.updateStatus(
-                BuildStatus.MANUALDEPWAIT,
-                slave_status={'dependencies': unicode(spn)})
+                BuildStatus.MANUALDEPWAIT,slave_status={'dependencies': spn})
             [bpph] = self.publisher.getPubBinaries(
                 binaryname=spn, distroseries=self.distroseries,
                 version=version, builder=self.builder, archive=self.archive,
@@ -94,7 +92,7 @@ class TestBuildDepWait(TestCaseWithFactory):
             transaction.commit()
         build.updateDependencies()
         # Since the dependency is in universe, we still can't see it.
-        self.assertEqual(unicode(spn), build.dependencies)
+        self.assertEqual(spn, build.dependencies)
         with person_logged_in(self.admin):
             bpph.component = getUtility(IComponentSet)['main']
             transaction.commit()
diff --git a/lib/lp/testing/__init__.py b/lib/lp/testing/__init__.py
index 8b43a1c..1fa039a 100644
--- a/lib/lp/testing/__init__.py
+++ b/lib/lp/testing/__init__.py
@@ -889,7 +889,7 @@ class TestCaseWithFactory(TestCase):
         :param branch_url: The URL to create the branch at.
         :param format: The format of branch to create.
         """
-        if format is not None and isinstance(format, basestring):
+        if format is not None and isinstance(format, six.string_types):
             format = format_registry.get(format)()
         return ControlDir.create_branch_convenience(branch_url, format=format)
 
diff --git a/lib/lp/testing/_login.py b/lib/lp/testing/_login.py
index 1cdd05b..552eea5 100644
--- a/lib/lp/testing/_login.py
+++ b/lib/lp/testing/_login.py
@@ -23,6 +23,7 @@ __all__ = [
 
 from contextlib import contextmanager
 
+import six
 from zope.component import getUtility
 from zope.security.management import (
     endInteraction,
@@ -70,7 +71,7 @@ def login(email, participation=None):
     setPrincipal(), otherwise it must allow setting its principal attribute.
     """
 
-    if not isinstance(email, basestring):
+    if not isinstance(email, six.string_types):
         raise ValueError("Expected email parameter to be a string.")
     participation = _test_login_impl(participation)
     setupInteractionByEmail(email, participation)
diff --git a/lib/lp/testing/_webservice.py b/lib/lp/testing/_webservice.py
index 6427960..95ec423 100644
--- a/lib/lp/testing/_webservice.py
+++ b/lib/lp/testing/_webservice.py
@@ -60,15 +60,15 @@ def oauth_access_token_for(consumer_name, person, permission, context=None):
 
     :return: A tuple of an OAuthAccessToken object and its secret.
     """
-    if isinstance(person, basestring):
+    if isinstance(person, six.string_types):
         # Look up a person by name.
         person = getUtility(IPersonSet).getByName(person)
-    if isinstance(context, basestring):
+    if isinstance(context, six.string_types):
         # Turn an OAuth context string into the corresponding object.
         # Avoid an import loop by importing from launchpad.browser here.
         from lp.services.oauth.browser import lookup_oauth_context
         context = lookup_oauth_context(context)
-    if isinstance(permission, basestring):
+    if isinstance(permission, six.string_types):
         # Look up a permission by its token string.
         permission = OAuthPermission.items[permission]
 
diff --git a/lib/lp/testing/factory.py b/lib/lp/testing/factory.py
index c109014..b7dc38f 100644
--- a/lib/lp/testing/factory.py
+++ b/lib/lp/testing/factory.py
@@ -831,7 +831,7 @@ class BareLaunchpadObjectFactory(ObjectFactory):
         """
         if owner is None:
             owner = self.makePerson()
-        elif isinstance(owner, basestring):
+        elif isinstance(owner, six.string_types):
             owner = getUtility(IPersonSet).getByName(owner)
         else:
             pass
@@ -2132,7 +2132,7 @@ class BareLaunchpadObjectFactory(ObjectFactory):
         """
         if bug is None:
             bug = self.makeBug()
-        elif isinstance(bug, (six.integer_types, basestring)):
+        elif isinstance(bug, (six.integer_types, six.string_types)):
             bug = getUtility(IBugSet).getByNameOrID(str(bug))
         if owner is None:
             owner = self.makePerson()
@@ -2167,7 +2167,7 @@ class BareLaunchpadObjectFactory(ObjectFactory):
         """
         if bug is None:
             bug = self.makeBug()
-        elif isinstance(bug, (six.integer_types, basestring)):
+        elif isinstance(bug, (six.integer_types, six.string_types)):
             bug = getUtility(IBugSet).getByNameOrID(str(bug))
         if owner is None:
             owner = self.makePerson()
@@ -2919,7 +2919,7 @@ class BareLaunchpadObjectFactory(ObjectFactory):
         """
         if purpose is None:
             purpose = ArchivePurpose.PPA
-        elif isinstance(purpose, basestring):
+        elif isinstance(purpose, six.string_types):
             purpose = ArchivePurpose.items[purpose.upper()]
 
         if distribution is None:
@@ -3602,7 +3602,7 @@ class BareLaunchpadObjectFactory(ObjectFactory):
         """
         # Make sure we have a real sourcepackagename object.
         if (sourcepackagename is None or
-            isinstance(sourcepackagename, basestring)):
+            isinstance(sourcepackagename, six.string_types)):
             sourcepackagename = self.getOrMakeSourcePackageName(
                 sourcepackagename)
         if distroseries is None:
@@ -3762,16 +3762,16 @@ class BareLaunchpadObjectFactory(ObjectFactory):
             archive = distroseries.main_archive
 
         if (sourcepackagename is None or
-            isinstance(sourcepackagename, basestring)):
+            isinstance(sourcepackagename, six.string_types)):
             sourcepackagename = self.getOrMakeSourcePackageName(
                 sourcepackagename)
 
-        if (component is None or isinstance(component, basestring)):
+        if (component is None or isinstance(component, six.string_types)):
             component = self.makeComponent(component)
 
         if urgency is None:
             urgency = self.getAnySourcePackageUrgency()
-        elif isinstance(urgency, basestring):
+        elif isinstance(urgency, six.string_types):
             urgency = SourcePackageUrgency.items[urgency.upper()]
 
         section = self.makeSection(name=section_name)
@@ -3878,7 +3878,7 @@ class BareLaunchpadObjectFactory(ObjectFactory):
                 archive = source_package_release.upload_archive
         if pocket is None:
             pocket = PackagePublishingPocket.RELEASE
-        elif isinstance(pocket, basestring):
+        elif isinstance(pocket, six.string_types):
             pocket = PackagePublishingPocket.items[pocket.upper()]
 
         if source_package_release is None:
@@ -3958,12 +3958,12 @@ class BareLaunchpadObjectFactory(ObjectFactory):
 
         if pocket is None:
             pocket = self.getAnyPocket()
-        elif isinstance(pocket, basestring):
+        elif isinstance(pocket, six.string_types):
             pocket = PackagePublishingPocket.items[pocket.upper()]
 
         if status is None:
             status = PackagePublishingStatus.PENDING
-        elif isinstance(status, basestring):
+        elif isinstance(status, six.string_types):
             status = PackagePublishingStatus.items[status.upper()]
 
         if sourcepackagerelease is None:
@@ -4163,7 +4163,7 @@ class BareLaunchpadObjectFactory(ObjectFactory):
         if build is None:
             build = self.makeBinaryPackageBuild()
         if (binarypackagename is None or
-            isinstance(binarypackagename, basestring)):
+            isinstance(binarypackagename, six.string_types)):
             binarypackagename = self.getOrMakeBinaryPackageName(
                 binarypackagename)
         if version is None:
@@ -4174,7 +4174,7 @@ class BareLaunchpadObjectFactory(ObjectFactory):
             component = build.source_package_release.component
         elif isinstance(component, six.text_type):
             component = getUtility(IComponentSet)[component]
-        if isinstance(section_name, basestring):
+        if isinstance(section_name, six.string_types):
             section_name = self.makeSection(section_name)
         section = section_name or build.source_package_release.section
         if priority is None:
@@ -4287,7 +4287,7 @@ class BareLaunchpadObjectFactory(ObjectFactory):
             pocket = self.getAnyPocket()
         # Make sure we have a real sourcepackagename object.
         if (sourcepackagename is None or
-            isinstance(sourcepackagename, basestring)):
+            isinstance(sourcepackagename, six.string_types)):
             sourcepackagename = self.getOrMakeSourcePackageName(
                 sourcepackagename)
         return ProxyFactory(
@@ -4297,7 +4297,7 @@ class BareLaunchpadObjectFactory(ObjectFactory):
                                       distribution=None, with_db=False):
         # Make sure we have a real sourcepackagename object.
         if (sourcepackagename is None or
-            isinstance(sourcepackagename, basestring)):
+            isinstance(sourcepackagename, six.string_types)):
             sourcepackagename = self.getOrMakeSourcePackageName(
                 sourcepackagename)
         if distribution is None:
diff --git a/lib/lp/translations/model/pofile.py b/lib/lp/translations/model/pofile.py
index a975b67..112a86d 100644
--- a/lib/lp/translations/model/pofile.py
+++ b/lib/lp/translations/model/pofile.py
@@ -255,7 +255,7 @@ class POFileMixIn(RosettaStats):
         Orders the result by TranslationTemplateItem.sequence which must
         be among `origin_tables`.
         """
-        if isinstance(query, basestring):
+        if isinstance(query, six.string_types):
             query = SQL(query)
         results = IMasterStore(POTMsgSet).using(origin_tables).find(
             POTMsgSet, query)
diff --git a/lib/lp/translations/scripts/remove_translations.py b/lib/lp/translations/scripts/remove_translations.py
index 6c5ebdf..4b8040c 100644
--- a/lib/lp/translations/scripts/remove_translations.py
+++ b/lib/lp/translations/scripts/remove_translations.py
@@ -16,6 +16,7 @@ from optparse import (
     OptionValueError,
     )
 
+import six
 from zope.component import getUtility
 
 from lp.registry.interfaces.person import IPersonSet
@@ -64,7 +65,7 @@ def get_id(identifier, lookup_function=None):
     """
     if identifier is None or identifier == '':
         return None
-    elif isinstance(identifier, basestring) and identifier == '':
+    elif isinstance(identifier, six.string_types) and identifier == '':
         return None
     elif isinstance(identifier, int):
         return identifier
diff --git a/lib/lp/translations/scripts/tests/test_remove_translations.py b/lib/lp/translations/scripts/tests/test_remove_translations.py
index 411c7f9..46a59e9 100644
--- a/lib/lp/translations/scripts/tests/test_remove_translations.py
+++ b/lib/lp/translations/scripts/tests/test_remove_translations.py
@@ -14,6 +14,7 @@ from optparse import (
     )
 from unittest import TestLoader
 
+import six
 from storm.store import Store
 from testtools.matchers import MatchesStructure
 from zope.component import getUtility
@@ -45,7 +46,7 @@ from lp.translations.scripts.remove_translations import (
 
 def make_script(args=None):
     """Create a `RemoveTranslations` script with given options."""
-    if isinstance(args, basestring):
+    if isinstance(args, six.string_types):
         args = [args]
     script = RemoveTranslations(
         'remove-translations-test', test_args=args, logger=DevNullLogger())
@@ -157,7 +158,7 @@ class OptionChecker(OptionParser):
 
 def parse_opts(opts):
     """Simulate options being parsed by `LaunchpadScript`."""
-    if isinstance(opts, basestring):
+    if isinstance(opts, six.string_types):
         opts = [opts]
 
     parser = OptionChecker()