← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:py3-bugs-unicode into launchpad:master

 

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

Commit message:
Port unicode() calls in lp.bugs to Python 3

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

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

This unfortunately requires some contextual clues, because `six.text_type(b'foo')` returns `u'foo'` on Python 2 but `"b'foo'"` on Python 3, while `six.ensure_text` works on bytes or text but not on other types.  Use single-argument `six.text_type` in cases where we know that the argument is not bytes, and `six.ensure_text` where we know the argument is either bytes or text.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:py3-bugs-unicode into launchpad:master.
diff --git a/lib/lp/bugs/browser/bugsubscription.py b/lib/lp/bugs/browser/bugsubscription.py
index b8a689e..999e9d1 100644
--- a/lib/lp/bugs/browser/bugsubscription.py
+++ b/lib/lp/bugs/browser/bugsubscription.py
@@ -18,6 +18,7 @@ from lazr.restful.interfaces import (
     IWebServiceClientRequest,
     )
 from simplejson import dumps
+import six
 from zope import formlib
 from zope.formlib.itemswidgets import RadioWidget
 from zope.formlib.widget import CustomWidgetFactory
@@ -77,7 +78,7 @@ class BugSubscriptionAddView(LaunchpadFormView):
             self.context.bug.subscribe(
                 person, self.user, suppress_notify=False)
         except SubscriptionPrivacyViolation as error:
-            self.setFieldError('person', unicode(error))
+            self.setFieldError('person', six.text_type(error))
         else:
             if person.is_team:
                 message = '%s team has been subscribed to this bug.'
diff --git a/lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py b/lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py
index 9454ff7..32635f6 100644
--- a/lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py
+++ b/lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py
@@ -8,6 +8,7 @@ __metaclass__ = type
 import json
 
 from lxml import html
+import six
 from six.moves.urllib.parse import urlparse
 from testtools.matchers import StartsWith
 
@@ -67,7 +68,7 @@ class TestBugSubscriptionFilterNavigation(
 
     def test_navigation(self):
         request = LaunchpadTestRequest()
-        request.setTraversalStack([unicode(self.subscription_filter.id)])
+        request.setTraversalStack([six.text_type(self.subscription_filter.id)])
         navigation = StructuralSubscriptionNavigation(
             self.subscription, request)
         view = navigation.publishTraverse(request, '+filter')
diff --git a/lib/lp/bugs/doc/bugactivity.txt b/lib/lp/bugs/doc/bugactivity.txt
index 03828c5..79d54d6 100644
--- a/lib/lp/bugs/doc/bugactivity.txt
+++ b/lib/lp/bugs/doc/bugactivity.txt
@@ -21,6 +21,7 @@ authenticated user--let's login:
 Bug activity tracking is done using event subscribers. The handlers
 are simple little functions.
 
+    >>> import six
     >>> from lp.bugs.interfaces.bugtask import IBugTaskSet
     >>> from lp.registry.interfaces.product import IProductSet
     >>> from lp.services.webapp.snapshot import notify_modified
@@ -147,7 +148,7 @@ Bug report is marked as a duplicate of another bug report
     u'marked as duplicate'
     >>> latest_activity.oldvalue is None
     True
-    >>> latest_activity.newvalue == unicode(latest_bug.id)
+    >>> latest_activity.newvalue == six.text_type(latest_bug.id)
     True
 
 
@@ -163,9 +164,9 @@ Bug report has its duplicate marker changed to another bug report
     >>> latest_activity = bug.activity[-1]
     >>> latest_activity.whatchanged
     u'changed duplicate marker'
-    >>> latest_activity.oldvalue == unicode(latest_bug.id)
+    >>> latest_activity.oldvalue == six.text_type(latest_bug.id)
     True
-    >>> latest_activity.newvalue == unicode(another_bug.id)
+    >>> latest_activity.newvalue == six.text_type(another_bug.id)
     True
 
 
@@ -180,7 +181,7 @@ The bug report is un-duplicated
     >>> latest_activity = bug.activity[-1]
     >>> latest_activity.whatchanged
     u'removed duplicate marker'
-    >>> latest_activity.oldvalue == unicode(another_bug.id)
+    >>> latest_activity.oldvalue == six.text_type(another_bug.id)
     True
     >>> latest_activity.newvalue is None
     True
@@ -214,16 +215,16 @@ final_bug as their master bug.
     >>> latest_activity = dupe_one.activity[-1]
     >>> print(latest_activity.whatchanged)
     changed duplicate marker
-    >>> latest_activity.oldvalue == unicode(initial_bug.id)
+    >>> latest_activity.oldvalue == six.text_type(initial_bug.id)
     True
-    >>> latest_activity.newvalue == unicode(final_bug.id)
+    >>> latest_activity.newvalue == six.text_type(final_bug.id)
     True
     >>> latest_activity = dupe_two.activity[-1]
     >>> print(latest_activity.whatchanged)
     changed duplicate marker
-    >>> latest_activity.oldvalue == unicode(initial_bug.id)
+    >>> latest_activity.oldvalue == six.text_type(initial_bug.id)
     True
-    >>> latest_activity.newvalue == unicode(final_bug.id)
+    >>> latest_activity.newvalue == six.text_type(final_bug.id)
     True
 
 
diff --git a/lib/lp/bugs/mail/commands.py b/lib/lp/bugs/mail/commands.py
index 651a062..b22723b 100644
--- a/lib/lp/bugs/mail/commands.py
+++ b/lib/lp/bugs/mail/commands.py
@@ -588,7 +588,8 @@ class AffectsEmailCommand(EmailCommand):
         try:
             bug_target = self.getBugTarget(path)
         except BugTargetNotFound as error:
-            raise EmailProcessingError(unicode(error), stop_processing=True)
+            raise EmailProcessingError(
+                six.text_type(error), stop_processing=True)
         event = None
 
         if isinstance(bug, CreateBugParams):
diff --git a/lib/lp/bugs/model/bug.py b/lib/lp/bugs/model/bug.py
index e352e4b..d52869a 100644
--- a/lib/lp/bugs/model/bug.py
+++ b/lib/lp/bugs/model/bug.py
@@ -29,6 +29,7 @@ import re
 from lazr.lifecycle.event import ObjectCreatedEvent
 from lazr.lifecycle.snapshot import Snapshot
 import pytz
+import six
 from six.moves.collections_abc import (
     Iterable,
     Set,
@@ -384,7 +385,7 @@ class Bug(SQLBase, InformationTypeMixin):
         from lp.bugs.model.cve import Cve
         xref_cve_sequences = [
             sequence for _, sequence in getUtility(IXRefSet).findFrom(
-                (u'bug', unicode(self.id)), types=[u'cve'])]
+                (u'bug', six.text_type(self.id)), types=[u'cve'])]
         expr = Cve.sequence.is_in(xref_cve_sequences)
         return list(sorted(
             IStore(Cve).find(Cve, expr), key=operator.attrgetter('sequence')))
@@ -394,7 +395,7 @@ class Bug(SQLBase, InformationTypeMixin):
         from lp.answers.model.question import Question
         question_ids = [
             int(id) for _, id in getUtility(IXRefSet).findFrom(
-                (u'bug', unicode(self.id)), types=[u'question'])]
+                (u'bug', six.text_type(self.id)), types=[u'question'])]
         return list(sorted(
             bulk.load(Question, question_ids), key=operator.attrgetter('id')))
 
@@ -403,7 +404,7 @@ class Bug(SQLBase, InformationTypeMixin):
         from lp.blueprints.model.specification import Specification
         spec_ids = [
             int(id) for _, id in getUtility(IXRefSet).findFrom(
-                (u'bug', unicode(self.id)), types=[u'specification'])]
+                (u'bug', six.text_type(self.id)), types=[u'specification'])]
         return list(sorted(
             bulk.load(Specification, spec_ids), key=operator.attrgetter('id')))
 
@@ -1410,7 +1411,7 @@ class Bug(SQLBase, InformationTypeMixin):
         from lp.code.model.branchmergeproposal import BranchMergeProposal
         merge_proposal_ids = [
             int(id) for _, id in getUtility(IXRefSet).findFrom(
-                (u'bug', unicode(self.id)), types=[u'merge_proposal'])]
+                (u'bug', six.text_type(self.id)), types=[u'merge_proposal'])]
         return list(sorted(
             bulk.load(BranchMergeProposal, merge_proposal_ids),
             key=operator.attrgetter('id')))
diff --git a/lib/lp/bugs/model/bugtask.py b/lib/lp/bugs/model/bugtask.py
index fe7d366..82caf37 100644
--- a/lib/lp/bugs/model/bugtask.py
+++ b/lib/lp/bugs/model/bugtask.py
@@ -1390,7 +1390,7 @@ class BugTaskSet:
         bug_ids = set(bugtask.bugID for bugtask in bugtasks)
         bug_ids_with_specifications = set(
             int(id) for _, id in getUtility(IXRefSet).findFromMany(
-                [(u'bug', unicode(bug_id)) for bug_id in bug_ids],
+                [(u'bug', six.text_type(bug_id)) for bug_id in bug_ids],
                 types=[u'specification']).keys())
         bug_ids_with_branches = set(IStore(BugBranch).find(
                 BugBranch.bug_id, BugBranch.bug_id.is_in(bug_ids)))
diff --git a/lib/lp/bugs/model/bugwatch.py b/lib/lp/bugs/model/bugwatch.py
index 847fc50..3336576 100644
--- a/lib/lp/bugs/model/bugwatch.py
+++ b/lib/lp/bugs/model/bugwatch.py
@@ -307,9 +307,9 @@ class BugWatch(SQLBase):
         else:
             activity.result = result
         if message is not None:
-            activity.message = unicode(message)
+            activity.message = six.ensure_text(message)
         if oops_id is not None:
-            activity.oops_id = unicode(oops_id)
+            activity.oops_id = six.ensure_text(oops_id)
         store = IStore(BugWatchActivity)
         store.add(activity)
 
diff --git a/lib/lp/bugs/utilities/filebugdataparser.py b/lib/lp/bugs/utilities/filebugdataparser.py
index 7ab6540..ce16707 100644
--- a/lib/lp/bugs/utilities/filebugdataparser.py
+++ b/lib/lp/bugs/utilities/filebugdataparser.py
@@ -11,6 +11,8 @@ __all__ = [
 from email import message_from_string
 import tempfile
 
+import six
+
 from lp.bugs.model.bug import FileBugData
 
 
@@ -71,9 +73,9 @@ class FileBugDataParser:
     def _setDataFromHeaders(self, data, headers):
         """Set the data attributes from the message headers."""
         if 'Subject' in headers:
-            data.initial_summary = unicode(headers['Subject'])
+            data.initial_summary = six.ensure_text(headers['Subject'])
         if 'Tags' in headers:
-            tags_string = unicode(headers['Tags'])
+            tags_string = six.ensure_text(headers['Tags'])
             data.initial_tags = tags_string.lower().split()
         if 'Private' in headers:
             private = headers['Private']
@@ -86,7 +88,7 @@ class FileBugDataParser:
                 # ignore it as we cannot currently give the user an error
                 pass
         if 'Subscribers' in headers:
-            subscribers_string = unicode(headers['Subscribers'])
+            subscribers_string = six.ensure_text(headers['Subscribers'])
             data.subscribers = subscribers_string.lower().split()
 
     def parse(self):
@@ -147,11 +149,12 @@ class FileBugDataParser:
                     data.comments.append(inline_content)
             elif disposition == 'attachment':
                 attachment = dict(
-                    filename=unicode(part_headers.get_filename().strip("'")),
-                    content_type=unicode(part_headers['Content-type']),
+                    filename=six.ensure_text(
+                        part_headers.get_filename().strip("'")),
+                    content_type=six.ensure_text(part_headers['Content-type']),
                     content=part_file)
                 if 'Content-Description' in part_headers:
-                    attachment['description'] = unicode(
+                    attachment['description'] = six.ensure_text(
                         part_headers['Content-Description'])
                 else:
                     attachment['description'] = attachment['filename']