launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #26259
[Merge] ~cjwatson/launchpad:py3-email-decode-bytes into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:py3-email-decode-bytes into launchpad:master.
Commit message:
Fix types in email payload tests
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/397707
`Message.get_payload(decode=True)` returns bytes, not text.
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:py3-email-decode-bytes into launchpad:master.
diff --git a/lib/lp/blueprints/doc/specification-notifications.txt b/lib/lp/blueprints/doc/specification-notifications.txt
index 097cf25..275dbd9 100644
--- a/lib/lp/blueprints/doc/specification-notifications.txt
+++ b/lib/lp/blueprints/doc/specification-notifications.txt
@@ -128,7 +128,7 @@ Now let's take a look at what the notification looks like:
>>> status_notification['Subject']
'[Blueprint svg-support] Support Native SVG Objects'
>>> body = status_notification.get_payload(decode=True)
- >>> print(body)
+ >>> print(body.decode('UTF-8'))
Blueprint changed by Foo Bar:
<BLANKLINE>
Definition Status: Drafting => Pending Approval
@@ -168,7 +168,7 @@ Whiteboard change:
>>> status_notification['Subject']
'[Blueprint svg-support] Support Native SVG Objects'
>>> body = status_notification.get_payload(decode=True)
- >>> print(body)
+ >>> print(body.decode('UTF-8'))
Blueprint changed by Foo Bar:
<BLANKLINE>
Whiteboard set to:
@@ -208,7 +208,7 @@ Definition status and whiteboard change:
>>> status_notification['Subject']
'[Blueprint svg-support] Support Native SVG Objects'
>>> body = status_notification.get_payload(decode=True)
- >>> print(body)
+ >>> print(body.decode('UTF-8'))
Blueprint changed by Foo Bar:
<BLANKLINE>
Definition Status: Pending Approval => Approved
@@ -248,7 +248,7 @@ Change priority:
>>> status_notification['Subject']
'[Blueprint svg-support] Support Native SVG Objects'
>>> body = status_notification.get_payload(decode=True)
- >>> print(body)
+ >>> print(body.decode('UTF-8'))
Blueprint changed by Foo Bar:
<BLANKLINE>
Priority: High => Essential
@@ -282,7 +282,7 @@ Change approver, assignee and drafter:
>>> status_notification['Subject']
'[Blueprint svg-support] Support Native SVG Objects'
>>> body = status_notification.get_payload(decode=True)
- >>> print(body)
+ >>> print(body.decode('UTF-8'))
Blueprint changed by Foo Bar:
<BLANKLINE>
Approver: Mark Shuttleworth => (none)
diff --git a/lib/lp/blueprints/model/tests/test_specification.py b/lib/lp/blueprints/model/tests/test_specification.py
index 4264e9f..73a8834 100644
--- a/lib/lp/blueprints/model/tests/test_specification.py
+++ b/lib/lp/blueprints/model/tests/test_specification.py
@@ -236,7 +236,7 @@ class TestSpecificationWorkItemsNotifications(TestCaseWithFactory):
new_work_item['status'].name)
[email] = stub.test_emails
# Actual message is part 2 of the email.
- msg = email[2]
+ msg = email[2].decode('UTF-8')
self.assertIn(rationale, msg)
def test_workitems_deleted_notification_message(self):
@@ -255,7 +255,7 @@ class TestSpecificationWorkItemsNotifications(TestCaseWithFactory):
rationale = '- %s: %s' % (wi.title, wi.status.name)
[email] = stub.test_emails
# Actual message is part 2 of the email.
- msg = email[2]
+ msg = email[2].decode('UTF-8')
self.assertIn(rationale, msg)
def test_workitems_changed_notification_message(self):
@@ -294,7 +294,7 @@ class TestSpecificationWorkItemsNotifications(TestCaseWithFactory):
new_work_item['title'], new_work_item['status'].name)
[email] = stub.test_emails
# Actual message is part 2 of the email.
- msg = email[2]
+ msg = email[2].decode('UTF-8')
self.assertIn(rationale_removed, msg)
self.assertIn(rationale_added, msg)
diff --git a/lib/lp/bugs/doc/bugnotification-sending.txt b/lib/lp/bugs/doc/bugnotification-sending.txt
index e0ed9aa..48495ac 100644
--- a/lib/lp/bugs/doc/bugnotification-sending.txt
+++ b/lib/lp/bugs/doc/bugnotification-sending.txt
@@ -31,7 +31,7 @@ easier.
... print_notification_headers(
... email_notification, extra_headers=extra_headers)
... print()
- ... print(email_notification.get_payload(decode=True))
+ ... print(six.ensure_str(email_notification.get_payload(decode=True)))
... print("-" * 70)
We'll also import a helper function to help us with database users.
@@ -273,7 +273,7 @@ lp/bugs/tests/test_bugnotification.py), and not demonstrated here.
Another thing worth noting is that there's a blank line before the
signature, and the signature marker has a trailing space.
- >>> message.get_payload(decode=True).splitlines()
+ >>> six.ensure_str(message.get_payload(decode=True)).splitlines()
[...,
'',
'-- ',
@@ -1063,26 +1063,26 @@ It's important to note that the bug title and description are wrapped
and indented correctly in verbose notifications.
>>> message = collated_messages['conciseteam@xxxxxxxxxxx'][0]
- >>> payload = message.get_payload(decode=True)
- >>> print(payload.split('\n'))
+ >>> payload = six.ensure_str(message.get_payload(decode=True))
+ >>> print(payload.splitlines())
[...
- u'Title:',
- u' In the beginning, the universe was created. This has made a lot of',
- u' people very angry and has been widely regarded as a bad move',
+ 'Title:',
+ ' In the beginning, the universe was created. This has made a lot of',
+ ' people very angry and has been widely regarded as a bad move',
...
- u'Bug description:',
- u' This is a long description of the bug, which will be automatically',
- u" wrapped by the BugNotification machinery. Ain't technology great?"...]
+ 'Bug description:',
+ ' This is a long description of the bug, which will be automatically',
+ " wrapped by the BugNotification machinery. Ain't technology great?"...]
The title is also wrapped and indented in normal notifications.
>>> message = collated_messages['verboseteam@xxxxxxxxxxx'][0]
- >>> payload = message.get_payload(decode=True)
- >>> print(payload.strip().split('\n'))
+ >>> payload = six.ensure_str(message.get_payload(decode=True))
+ >>> print(payload.strip().splitlines())
[...
- u'Title:',
- u' In the beginning, the universe was created. This has made a lot of',
- u' people very angry and has been widely regarded as a bad move'...]
+ 'Title:',
+ ' In the beginning, the universe was created. This has made a lot of',
+ ' people very angry and has been widely regarded as a bad move'...]
Self-Generated Bug Notifications
--------------------------------
diff --git a/lib/lp/bugs/doc/externalbugtracker-debbugs.txt b/lib/lp/bugs/doc/externalbugtracker-debbugs.txt
index 4353e79..3a427dd 100644
--- a/lib/lp/bugs/doc/externalbugtracker-debbugs.txt
+++ b/lib/lp/bugs/doc/externalbugtracker-debbugs.txt
@@ -319,7 +319,7 @@ description as the description.
>>> print(report['Subject'])
evolution: Multiple format string vulnerabilities in Evolution
- >>> print(report.get_payload(decode=True))
+ >>> print(six.ensure_text(report.get_payload(decode=True)))
Package: evolution
Severity: grave
Tags: security
diff --git a/lib/lp/bugs/doc/initial-bug-contacts.txt b/lib/lp/bugs/doc/initial-bug-contacts.txt
index 6e89ca6..ed95d04 100644
--- a/lib/lp/bugs/doc/initial-bug-contacts.txt
+++ b/lib/lp/bugs/doc/initial-bug-contacts.txt
@@ -198,7 +198,7 @@ of the email with the bug title and URL.
>>> msg['Subject']
'[Bug 1] [NEW] Firefox does not support SVG'
- >>> print(msg.get_payload(decode=True))
+ >>> print(six.ensure_text(msg.get_payload(decode=True)))
You have been subscribed to a public bug:
<BLANKLINE>
Firefox needs to support embedded SVG images, now that the standard has
diff --git a/lib/lp/bugs/mail/tests/test_bugnotificationbuilder.py b/lib/lp/bugs/mail/tests/test_bugnotificationbuilder.py
index 291d87f..c3063f4 100644
--- a/lib/lp/bugs/mail/tests/test_bugnotificationbuilder.py
+++ b/lib/lp/bugs/mail/tests/test_bugnotificationbuilder.py
@@ -70,7 +70,7 @@ class TestBugNotificationBuilder(TestCaseWithFactory):
message = self.builder.build(
'from', self.bug.owner, 'body', 'subject', utc_now, filters=[])
self.assertNotIn(
- "Launchpad-Notification-Type", message.get_payload(decode=True))
+ b"Launchpad-Notification-Type", message.get_payload(decode=True))
def test_mails_append_expanded_footer(self):
# Recipients with expanded_notification_footers receive an expanded
@@ -81,7 +81,7 @@ class TestBugNotificationBuilder(TestCaseWithFactory):
message = self.builder.build(
'from', self.bug.owner, 'body', 'subject', utc_now, filters=[])
self.assertIn(
- "\n-- \nLaunchpad-Notification-Type: bug\n",
+ b"\n-- \nLaunchpad-Notification-Type: bug\n",
message.get_payload(decode=True))
def test_private_team(self):
diff --git a/lib/lp/bugs/mail/tests/test_handler.py b/lib/lp/bugs/mail/tests/test_handler.py
index eeebc9f..a017d48 100644
--- a/lib/lp/bugs/mail/tests/test_handler.py
+++ b/lib/lp/bugs/mail/tests/test_handler.py
@@ -187,13 +187,13 @@ class TestMaloneHandler(TestCaseWithFactory):
big_body_text = 'This is really big.' * 10000
message = self.getFailureForMessage(
'new@xxxxxxxxxxxxxxxxxxx', body=big_body_text)
- self.assertIn("The description is too long.", message)
+ self.assertIn(b"The description is too long.", message)
def test_bug_not_found(self):
# Non-existent bug numbers result in an informative error.
message = self.getFailureForMessage('1234@xxxxxxxxxxxxxxxxxxx')
self.assertIn(
- "There is no such bug in Launchpad: 1234", message)
+ b"There is no such bug in Launchpad: 1234", message)
def test_accessible_private_bug(self):
# Private bugs are accessible by their subscribers.
@@ -216,7 +216,7 @@ class TestMaloneHandler(TestCaseWithFactory):
True, self.factory.makePerson())
message = self.getFailureForMessage('4@xxxxxxxxxxxxxxxxxxx')
self.assertIn(
- "There is no such bug in Launchpad: 4", message)
+ b"There is no such bug in Launchpad: 4", message)
class MaloneHandlerProcessTestCase(TestCaseWithFactory):
diff --git a/lib/lp/bugs/scripts/tests/test_bugnotification.py b/lib/lp/bugs/scripts/tests/test_bugnotification.py
index 7454ad4..9973981 100644
--- a/lib/lp/bugs/scripts/tests/test_bugnotification.py
+++ b/lib/lp/bugs/scripts/tests/test_bugnotification.py
@@ -690,7 +690,7 @@ class EmailNotificationTestBase(TestCaseWithFactory):
class EmailNotificationsBugMixin:
- change_class = change_name = old = new = alt = unexpected_text = None
+ change_class = change_name = old = new = alt = unexpected_bytes = None
def change(self, old, new):
self.bug.addChange(
@@ -708,7 +708,7 @@ class EmailNotificationsBugMixin:
# A smoketest.
self.change(self.old, self.new)
message, body = next(self.get_messages())
- self.assertThat(body, Contains(self.unexpected_text))
+ self.assertThat(body, Contains(self.unexpected_bytes))
def test_undone_change_sends_no_emails(self):
self.change(self.old, self.new)
@@ -720,7 +720,7 @@ class EmailNotificationsBugMixin:
self.change(self.new, self.old)
self.change_other()
message, body = next(self.get_messages())
- self.assertThat(body, Not(Contains(self.unexpected_text)))
+ self.assertThat(body, Not(Contains(self.unexpected_bytes)))
def test_multiple_undone_changes_sends_no_emails(self):
self.change(self.old, self.new)
@@ -763,7 +763,7 @@ class EmailNotificationsBugTaskMixin(EmailNotificationsBugMixin):
self.change(self.old, self.new, index=0)
self.change(self.new, self.old, index=1)
message, body = next(self.get_messages())
- self.assertThat(body, Contains(self.unexpected_text))
+ self.assertThat(body, Contains(self.unexpected_bytes))
class EmailNotificationsAddedRemovedMixin:
@@ -805,7 +805,7 @@ class TestEmailNotificationsBugTitle(
old = "Old summary"
new = "New summary"
alt = "Another summary"
- unexpected_text = '** Summary changed:'
+ unexpected_bytes = b'** Summary changed:'
class TestEmailNotificationsBugTags(
@@ -816,7 +816,7 @@ class TestEmailNotificationsBugTags(
old = ['foo', 'bar', 'baz']
new = ['foo', 'bar']
alt = ['bing', 'shazam']
- unexpected_text = '** Tags'
+ unexpected_bytes = b'** Tags'
def test_undone_ordered_set_sends_no_email(self):
# Tags use ordered sets to generate change descriptions, which we
@@ -831,7 +831,7 @@ class TestEmailNotificationsBugDuplicate(
change_class = BugDuplicateChange
change_name = "duplicateof"
- unexpected_text = 'duplicate'
+ unexpected_bytes = b'duplicate'
def _bug(self):
with lp_dbuser():
@@ -850,7 +850,7 @@ class TestEmailNotificationsBugTaskStatus(
old = BugTaskStatus.TRIAGED
new = BugTaskStatus.INPROGRESS
alt = BugTaskStatus.INVALID
- unexpected_text = 'Status: '
+ unexpected_bytes = b'Status: '
class TestEmailNotificationsBugWatch(
@@ -862,8 +862,8 @@ class TestEmailNotificationsBugWatch(
# bugwatch, so they can be handled just as a simple bugtask attribute
# change, like status.
- added_message = '** Bug watch added:'
- removed_message = '** Bug watch removed:'
+ added_message = b'** Bug watch added:'
+ removed_message = b'** Bug watch removed:'
@cachedproperty
def tracker(self):
@@ -897,8 +897,8 @@ class TestEmailNotificationsBugWatch(
class TestEmailNotificationsBranch(
EmailNotificationsAddedRemovedMixin, EmailNotificationTestBase):
- added_message = '** Branch linked:'
- removed_message = '** Branch unlinked:'
+ added_message = b'** Branch linked:'
+ removed_message = b'** Branch unlinked:'
def _branch(self):
with lp_dbuser():
@@ -923,8 +923,8 @@ class TestEmailNotificationsBranch(
class TestEmailNotificationsCVE(
EmailNotificationsAddedRemovedMixin, EmailNotificationTestBase):
- added_message = '** CVE added:'
- removed_message = '** CVE removed:'
+ added_message = b'** CVE added:'
+ removed_message = b'** CVE removed:'
def _cve(self, sequence):
with lp_dbuser():
@@ -949,8 +949,8 @@ class TestEmailNotificationsCVE(
class TestEmailNotificationsAttachments(
EmailNotificationsAddedRemovedMixin, EmailNotificationTestBase):
- added_message = '** Attachment added:'
- removed_message = '** Attachment removed:'
+ added_message = b'** Attachment added:'
+ removed_message = b'** Attachment removed:'
def _attachment(self):
with lp_dbuser():
@@ -1270,10 +1270,10 @@ class TestExpandedNotificationFooters(EmailNotificationTestBase):
payload for message, payload in self.get_messages()
if message["to"] == expected_to]
self.assertThat(payload, MatchesRegex(
- r'.*To manage notifications about this bug go to:\n'
- r'http://.*\+subscriptions\n'
- r'\n'
- r'Launchpad-Notification-Type: bug\n', re.S))
+ br'.*To manage notifications about this bug go to:\n'
+ br'http://.*\+subscriptions\n'
+ br'\n'
+ br'Launchpad-Notification-Type: bug\n', re.S))
class TestDeferredNotifications(TestCaseWithFactory):
diff --git a/lib/lp/code/doc/branch-merge-proposal-notifications.txt b/lib/lp/code/doc/branch-merge-proposal-notifications.txt
index 1cf3c56..70d15f0 100644
--- a/lib/lp/code/doc/branch-merge-proposal-notifications.txt
+++ b/lib/lp/code/doc/branch-merge-proposal-notifications.txt
@@ -140,7 +140,7 @@ An email is sent to subscribers of either branch and the default reviewer.
Subscriber
>>> print(notification['X-Launchpad-Message-For'])
source-subscriber
- >>> print(notification.get_payload(decode=True))
+ >>> print(six.ensure_text(notification.get_payload(decode=True)))
Eric has proposed merging
lp://dev/~person-name...into lp://dev/~person-name...
--
@@ -187,7 +187,8 @@ in the email.
source@xxxxxxxxxxx, Subscriber, source-subscriber
target@xxxxxxxxxxx, Subscriber, target-subscriber
>>> notification = notifications[0]
- >>> print(notification.get_payload()[0].get_payload(decode=True))
+ >>> print(six.ensure_text(
+ ... notification.get_payload()[0].get_payload(decode=True)))
Eric has proposed merging
lp://dev/~person-name...into lp://dev/~person-name...
<BLANKLINE>
diff --git a/lib/lp/code/doc/branch-notifications.txt b/lib/lp/code/doc/branch-notifications.txt
index 5869074..00696fe 100644
--- a/lib/lp/code/doc/branch-notifications.txt
+++ b/lib/lp/code/doc/branch-notifications.txt
@@ -62,7 +62,8 @@ also sends the email to the list of recipients.
Subscriber
>>> print(branch_notification['X-Launchpad-Message-For'])
name12
- >>> notification_body = branch_notification.get_payload(decode=True)
+ >>> notification_body = six.ensure_text(
+ ... branch_notification.get_payload(decode=True))
>>> print(notification_body) #doctest: -NORMALIZE_WHITESPACE
The contents.
<BLANKLINE>
@@ -196,15 +197,17 @@ to allow email filtering.
# A helper function to print out the To header and
# email body
>>> def print_to_and_body(email):
- ... attachment = ''
+ ... attachment = b''
... if email.is_multipart():
... root = email.get_payload()
... body = root[0].get_payload(decode=True)
... if len(root) > 1:
- ... attachment = '\n' + root[1].get_payload(decode=True)
+ ... attachment = b'\n' + root[1].get_payload(decode=True)
... else:
... body = email.get_payload(decode=True)
- ... print('To: %s\n%s%s' % (email['To'], body, attachment))
+ ... print('To: %s\n%s%s' % (
+ ... email['To'], six.ensure_text(body),
+ ... six.ensure_text(attachment)))
We need to create some sufficiently large diffs to compare against.
diff --git a/lib/lp/code/doc/codeimport.txt b/lib/lp/code/doc/codeimport.txt
index bed3223..354df5e 100644
--- a/lib/lp/code/doc/codeimport.txt
+++ b/lib/lp/code/doc/codeimport.txt
@@ -111,7 +111,7 @@ three members of the vcs-imports team.
Operator @vcs-imports
>>> print(message['X-Launchpad-Message-For'])
vcs-imports
- >>> print(message.get_payload(decode=True))
+ >>> print(six.ensure_text(message.get_payload(decode=True)))
A new CVS code import has been requested by Code Import Person:
http://code.launchpad.test/~import-person/widget/trunk-cvs
from
diff --git a/lib/lp/code/mail/tests/test_branch.py b/lib/lp/code/mail/tests/test_branch.py
index 9d6bdb2..69ed7dd 100644
--- a/lib/lp/code/mail/tests/test_branch.py
+++ b/lib/lp/code/mail/tests/test_branch.py
@@ -309,7 +309,7 @@ class TestBranchMailerDiffMixin:
ctrl = self.makeBobMailController(diff=u'hello \u03A3')
self.assertEqual(1, len(ctrl.attachments))
diff = ctrl.attachments[0]
- self.assertEqual('hello \xce\xa3', diff.get_payload(decode=True))
+ self.assertEqual(b'hello \xce\xa3', diff.get_payload(decode=True))
self.assertEqual('text/x-diff; charset="utf-8"', diff['Content-type'])
self.assertEqual('inline; filename="revision-diff.txt"',
diff['Content-disposition'])
diff --git a/lib/lp/code/mail/tests/test_branchmergeproposal.py b/lib/lp/code/mail/tests/test_branchmergeproposal.py
index 0a0fd9a..4bfd3db 100644
--- a/lib/lp/code/mail/tests/test_branchmergeproposal.py
+++ b/lib/lp/code/mail/tests/test_branchmergeproposal.py
@@ -9,6 +9,7 @@ from textwrap import dedent
from lazr.lifecycle.event import ObjectModifiedEvent
from lazr.lifecycle.snapshot import Snapshot
+import six
import transaction
from zope.interface import providedBy
@@ -375,7 +376,8 @@ class TestMergeProposalMailing(TestCaseWithFactory):
'text/x-diff; charset="utf-8"', attachment['Content-Type'])
self.assertEqual('inline; filename="review-diff.txt"',
attachment['Content-Disposition'])
- self.assertEqual(diff_text, attachment.get_payload(decode=True))
+ self.assertEqual(
+ diff_text.encode('UTF-8'), attachment.get_payload(decode=True))
def test_generateEmail_no_diff_for_status_only(self):
"""If the subscription is for status only, don't attach diffs."""
@@ -404,7 +406,9 @@ class TestMergeProposalMailing(TestCaseWithFactory):
'text/x-diff; charset="utf-8"', attachment['Content-Type'])
self.assertEqual('inline; filename="review-diff.txt"',
attachment['Content-Disposition'])
- self.assertEqual(diff_text[:25], attachment.get_payload(decode=True))
+ self.assertEqual(
+ diff_text.encode('UTF-8')[:25],
+ attachment.get_payload(decode=True))
warning_text = (
"The attached diff has been truncated due to its size.\n")
self.assertTrue(warning_text in ctrl.body)
@@ -544,7 +548,8 @@ class TestMergeProposalMailing(TestCaseWithFactory):
'source': bmp.source_branch.bzr_identity,
'target': bmp.target_branch.bzr_identity,
'bmp': canonical_url(bmp)}
- self.assertEqual(expected, email.get_payload(decode=True))
+ self.assertEqual(
+ expected, six.ensure_text(email.get_payload(decode=True)))
def assertRecipientsMatches(self, recipients, mailer):
"""Assert that `mailer` will send to the people in `recipients`."""
@@ -676,7 +681,8 @@ class TestBranchMergeProposalRequestReview(TestCaseWithFactory):
'source': bmp.source_branch.bzr_identity,
'target': bmp.target_branch.bzr_identity,
'bmp': canonical_url(bmp)})
- self.assertEqual(expected, sent_mail.get_payload(decode=True))
+ self.assertEqual(
+ expected, six.ensure_text(sent_mail.get_payload(decode=True)))
def test_nominateReview_emails_team_address(self):
# If a review request is made for a team, the members of the team are
diff --git a/lib/lp/code/mail/tests/test_codehandler.py b/lib/lp/code/mail/tests/test_codehandler.py
index 97feda0..197ee49 100644
--- a/lib/lp/code/mail/tests/test_codehandler.py
+++ b/lib/lp/code/mail/tests/test_codehandler.py
@@ -199,7 +199,7 @@ class TestCodeHandler(TestCaseWithFactory):
# the message, and the second is the original message.
message, original = notification.get_payload()
self.assertIn(
- "There is no merge proposal at mp+0@xxxxxxxxxxxxxxxxxxx\n",
+ b"There is no merge proposal at mp+0@xxxxxxxxxxxxxxxxxxx\n",
message.get_payload(decode=True))
def test_processBadVote(self):
@@ -239,7 +239,7 @@ class TestCodeHandler(TestCaseWithFactory):
--\x20
For more information about using Launchpad by email, see
https://help.launchpad.net/EmailInterface
- or send an email to help@xxxxxxxxxxxxx"""),
+ or send an email to help@xxxxxxxxxxxxx""").encode("UTF-8"),
message.get_payload(decode=True))
self.assertEqual(mail['From'], notification['To'])
@@ -278,8 +278,8 @@ class TestCodeHandler(TestCaseWithFactory):
# The returned message is a multipart message, the first part is
# the message, and the second is the original message.
message, original = notification.get_payload()
- self.assertTrue(
- "You are not a reviewer for the branch" in
+ self.assertIn(
+ b"You are not a reviewer for the branch",
message.get_payload(decode=True))
def test_processVote(self):
@@ -424,9 +424,9 @@ class TestCodeHandler(TestCaseWithFactory):
notification['Subject'], 'Error Creating Merge Proposal')
self.assertEqual(
notification.get_payload(decode=True),
- 'Your message did not contain a subject. Launchpad code '
- 'reviews require all\nemails to contain subject lines. '
- 'Please re-send your email including the\nsubject line.\n\n')
+ b'Your message did not contain a subject. Launchpad code '
+ b'reviews require all\nemails to contain subject lines. '
+ b'Please re-send your email including the\nsubject line.\n\n')
self.assertEqual(notification['to'],
mail['from'])
self.assertEqual(0, bmp.all_comments.count())
diff --git a/lib/lp/code/mail/tests/test_codeimport.py b/lib/lp/code/mail/tests/test_codeimport.py
index a155823..e82f466 100644
--- a/lib/lp/code/mail/tests/test_codeimport.py
+++ b/lib/lp/code/mail/tests/test_codeimport.py
@@ -8,6 +8,7 @@ from __future__ import absolute_import, print_function, unicode_literals
from email import message_from_string
import textwrap
+import six
import transaction
from lp.code.enums import (
@@ -51,7 +52,8 @@ class TestNewCodeImports(TestCaseWithFactory):
' :pserver:anonymouse@xxxxxxxxxxxxxxx:/cvsroot, a_module\n'
'\n'
'-- \nYou are getting this email because you are a member of the '
- 'vcs-imports team.\n', msg.get_payload(decode=True))
+ 'vcs-imports team.\n',
+ six.ensure_text(msg.get_payload(decode=True)))
def test_svn_to_bzr_import(self):
# Test the email for a new Subversion-to-Bazaar import.
@@ -74,7 +76,8 @@ class TestNewCodeImports(TestCaseWithFactory):
' svn://svn.example.com/fooix/trunk\n'
'\n'
'-- \nYou are getting this email because you are a member of the '
- 'vcs-imports team.\n', msg.get_payload(decode=True))
+ 'vcs-imports team.\n',
+ six.ensure_text(msg.get_payload(decode=True)))
def test_git_to_bzr_import(self):
# Test the email for a new git-to-Bazaar import.
@@ -97,7 +100,8 @@ class TestNewCodeImports(TestCaseWithFactory):
' git://git.example.com/fooix.git\n'
'\n'
'-- \nYou are getting this email because you are a member of the '
- 'vcs-imports team.\n', msg.get_payload(decode=True))
+ 'vcs-imports team.\n',
+ six.ensure_text(msg.get_payload(decode=True)))
def test_git_to_git_import(self):
# Test the email for a new git-to-git import.
@@ -122,7 +126,8 @@ class TestNewCodeImports(TestCaseWithFactory):
' git://git.example.com/fooix.git\n'
'\n'
'-- \nYou are getting this email because you are a member of the '
- 'vcs-imports team.\n', msg.get_payload(decode=True))
+ 'vcs-imports team.\n',
+ six.ensure_text(msg.get_payload(decode=True)))
def test_new_source_package_import(self):
# Test the email for a new sourcepackage import.
@@ -150,7 +155,8 @@ class TestNewCodeImports(TestCaseWithFactory):
' git://git.example.com/fooix.git\n'
'\n'
'-- \nYou are getting this email because you are a member of the '
- 'vcs-imports team.\n', msg.get_payload(decode=True))
+ 'vcs-imports team.\n',
+ six.ensure_text(msg.get_payload(decode=True)))
class TestUpdatedCodeImports(TestCaseWithFactory):
@@ -174,7 +180,7 @@ class TestUpdatedCodeImports(TestCaseWithFactory):
'details': details,
'unique_name': unique_name,
},
- msg.get_payload(decode=True))
+ six.ensure_text(msg.get_payload(decode=True)))
def assertDifferentDetailsEmail(self, old_details, new_details,
unique_name):
@@ -198,7 +204,7 @@ class TestUpdatedCodeImports(TestCaseWithFactory):
'new_details': new_details,
'unique_name': unique_name,
},
- msg.get_payload(decode=True))
+ six.ensure_text(msg.get_payload(decode=True)))
def test_cvs_to_bzr_import_same_details(self):
code_import = self.factory.makeProductCodeImport(
diff --git a/lib/lp/code/mail/tests/test_codereviewcomment.py b/lib/lp/code/mail/tests/test_codereviewcomment.py
index 712a55f..7d4ec13 100644
--- a/lib/lp/code/mail/tests/test_codereviewcomment.py
+++ b/lib/lp/code/mail/tests/test_codereviewcomment.py
@@ -351,7 +351,7 @@ class TestCodeReviewComment(TestCaseWithFactory):
person.preferredemail.email, person).makeMessage()
attachment = message.get_payload()[1]
self.assertEqual(
- 'This is a diff.', attachment.get_payload(decode=True))
+ b'This is a diff.', attachment.get_payload(decode=True))
def makeCommentAndParticipants(self):
"""Create a merge proposal and comment.
diff --git a/lib/lp/code/model/tests/test_branchjob.py b/lib/lp/code/model/tests/test_branchjob.py
index 821e3a1..2abb78a 100644
--- a/lib/lp/code/model/tests/test_branchjob.py
+++ b/lib/lp/code/model/tests/test_branchjob.py
@@ -18,6 +18,7 @@ from breezy.revision import NULL_REVISION
from breezy.transport import get_transport
from fixtures import MockPatch
import pytz
+import six
from storm.locals import Store
import transaction
from zope.component import getUtility
@@ -332,7 +333,8 @@ class TestBranchUpgradeJob(TestCaseWithFactory):
(mail,) = pop_notifications()
self.assertEqual(
'Launchpad error while upgrading a branch', mail['subject'])
- self.assertIn('Not a branch', mail.get_payload(decode=True))
+ self.assertIn(
+ 'Not a branch', six.ensure_text(mail.get_payload(decode=True)))
class TestRevisionMailJob(TestCaseWithFactory):
@@ -384,7 +386,7 @@ class TestRevisionMailJob(TestCaseWithFactory):
'url': canonical_url(branch),
'identity': branch.bzr_identity,
},
- mail.get_payload(decode=True))
+ six.ensure_text(mail.get_payload(decode=True)))
def test_revno_string(self):
"""Ensure that revnos can be strings."""
diff --git a/lib/lp/code/model/tests/test_branchmergeproposaljobs.py b/lib/lp/code/model/tests/test_branchmergeproposaljobs.py
index c2bed7f..7236b18 100644
--- a/lib/lp/code/model/tests/test_branchmergeproposaljobs.py
+++ b/lib/lp/code/model/tests/test_branchmergeproposaljobs.py
@@ -348,7 +348,7 @@ class TestUpdatePreviewDiffJob(DiffTestCase):
'The source branch of http://code.launchpad.test/~%s/%s/%s/'
'+merge/%d has no revisions.' % (
branch.owner.name, branch.target.name, branch.name, bmp.id),
- email.get_payload(decode=True))
+ six.ensure_text(email.get_payload(decode=True)))
def test_run_branches_pending_writes(self):
"""If the branches are being written, we retry but don't complain."""
@@ -738,7 +738,7 @@ class TestReviewRequestedEmailJob(TestCaseWithFactory):
(notification,) = pop_notifications()
self.assertIn(
'You have been requested to review the proposed merge',
- notification.get_payload(decode=True))
+ six.ensure_text(notification.get_payload(decode=True)))
class TestMergeProposalUpdatedEmailJob(TestCaseWithFactory):
diff --git a/lib/lp/code/model/tests/test_gitrepository.py b/lib/lp/code/model/tests/test_gitrepository.py
index ce52929..df40171 100644
--- a/lib/lp/code/model/tests/test_gitrepository.py
+++ b/lib/lp/code/model/tests/test_gitrepository.py
@@ -1297,7 +1297,7 @@ class TestGitRepositoryModificationNotifications(TestCaseWithFactory):
for from_addr, to_addrs, message in stub.test_emails:
body = email.message_from_string(message).get_payload(decode=True)
for to_addr in to_addrs:
- bodies_by_recipient[to_addr] = body
+ bodies_by_recipient[to_addr] = six.ensure_text(body)
# Both the owner and the unprivileged subscriber receive email.
self.assertContentEqual(
[owner_address, subscriber_address], bodies_by_recipient.keys())
@@ -2876,7 +2876,7 @@ class TestGitRepositoryDetectMerges(TestCaseWithFactory):
notifications = pop_notifications()
self.assertIn(
"Work in progress => Merged",
- notifications[0].get_payload(decode=True))
+ notifications[0].get_payload(decode=True).decode("UTF-8"))
self.assertEqual(
config.canonical.noreply_from_address, notifications[0]["From"])
recipients = set(msg["x-envelope-to"] for msg in notifications)
diff --git a/lib/lp/codehosting/scanner/tests/test_email.py b/lib/lp/codehosting/scanner/tests/test_email.py
index 3148e8b..26ab55f 100644
--- a/lib/lp/codehosting/scanner/tests/test_email.py
+++ b/lib/lp/codehosting/scanner/tests/test_email.py
@@ -133,7 +133,7 @@ class TestBzrSyncEmail(BzrSyncTestCase):
self.assertEqual(len(stub.test_emails), 2)
[recommit_email, uncommit_email] = stub.test_emails
uncommit_email_body = uncommit_email[2]
- expected = '1 revision was removed from the branch.'
+ expected = b'1 revision was removed from the branch.'
self.assertIn(expected, uncommit_email_body)
subject = (
'Subject: [Branch %s] Test branch' % self.db_branch.unique_name)
@@ -145,11 +145,11 @@ class TestBzrSyncEmail(BzrSyncTestCase):
subject = '[Branch %s] Rev 1: second' % self.db_branch.unique_name
self.assertEmailHeadersEqual(subject, recommit_email_msg['Subject'])
body_bits = [
- 'revno: 1',
- 'committer: %s' % author,
- 'branch nick: %s' % self.bzr_branch.nick,
- 'message:\n second',
- 'added:\n hello.txt',
+ b'revno: 1',
+ ('committer: %s' % author).encode('UTF-8'),
+ ('branch nick: %s' % self.bzr_branch.nick).encode('UTF-8'),
+ b'message:\n second',
+ b'added:\n hello.txt',
]
for bit in body_bits:
self.assertIn(bit, recommit_email_body)
diff --git a/lib/lp/codehosting/scanner/tests/test_mergedetection.py b/lib/lp/codehosting/scanner/tests/test_mergedetection.py
index 34202df..3868865 100644
--- a/lib/lp/codehosting/scanner/tests/test_mergedetection.py
+++ b/lib/lp/codehosting/scanner/tests/test_mergedetection.py
@@ -11,6 +11,7 @@ import logging
from breezy.revision import NULL_REVISION
from lazr.lifecycle.event import ObjectModifiedEvent
+import six
import transaction
from zope.component import getUtility
from zope.event import notify
@@ -298,8 +299,9 @@ class TestBranchMergeDetectionHandler(TestCaseWithFactory):
derived_job = job.makeDerived()
derived_job.run()
notifications = pop_notifications()
- self.assertIn('Work in progress => Merged',
- notifications[0].get_payload(decode=True))
+ self.assertIn(
+ 'Work in progress => Merged',
+ six.ensure_text(notifications[0].get_payload(decode=True)))
self.assertEqual(
config.canonical.noreply_from_address, notifications[0]['From'])
recipients = set(msg['x-envelope-to'] for msg in notifications)
diff --git a/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt b/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt
index 950706d..cb24bd7 100644
--- a/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt
+++ b/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt
@@ -62,7 +62,7 @@ followed by ASCII armored encrypted confirmation instructions. Ensure that
the clear text instructions contain the expected URLs pointing to more help.
>>> cipher_body = msg.get_payload(decode=True)
- >>> print(cipher_body)
+ >>> print(six.ensure_text(cipher_body))
Hello,
<BLANKLINE>
This message contains the instructions for confirming registration of an
@@ -182,13 +182,13 @@ Sample Person checks their email.
The email is not encrypted, since Sample Person didn't claim the
ability to decrypt text with this key.
- >>> '-----BEGIN PGP MESSAGE-----' in body
+ >>> b'-----BEGIN PGP MESSAGE-----' in body
False
The email does contain some information about the key, and a token URL
Sample Person should visit to verify their ownership of the key.
- >>> print(body)
+ >>> print(six.ensure_text(body))
<BLANKLINE>
Hello,
...
@@ -210,7 +210,8 @@ text which includes the date the token was generated (to avoid replay
attacks). To make this testable, we set the creation date of this
token to a fixed value:
- >>> nothing, token_value = token_url.split('http://launchpad.test/token/')
+ >>> token_value = token_url.split(
+ ... 'http://launchpad.test/token/')[1].encode('ASCII')
>>> import datetime, hashlib, pytz
>>> from lp.services.verification.model.logintoken import LoginToken
@@ -622,7 +623,7 @@ Test if the advertisement email was sent:
>>> from lp.services.mail import stub
>>> from_addr, to_addrs, raw_msg = stub.test_emails.pop()
>>> msg = email.message_from_string(raw_msg)
- >>> print(msg.get_payload(decode=True))
+ >>> print(six.ensure_text(msg.get_payload(decode=True)))
<BLANKLINE>
...
User: 'Mark Shuttleworth'
diff --git a/lib/lp/registry/tests/test_codeofconduct.py b/lib/lp/registry/tests/test_codeofconduct.py
index 5472c05..b505254 100644
--- a/lib/lp/registry/tests/test_codeofconduct.py
+++ b/lib/lp/registry/tests/test_codeofconduct.py
@@ -191,4 +191,4 @@ class TestSignedCodeOfConductSet(TestCaseWithFactory):
'user': user.display_name,
'fingerprint': gpgkey.fingerprint,
},
- notification.get_payload(decode=True))
+ notification.get_payload(decode=True).decode("UTF-8"))
diff --git a/lib/lp/services/job/tests/test_runner.py b/lib/lp/services/job/tests/test_runner.py
index 8981b66..36842b9 100644
--- a/lib/lp/services/job/tests/test_runner.py
+++ b/lib/lp/services/job/tests/test_runner.py
@@ -290,9 +290,10 @@ class TestJobRunner(StatsMixin, TestCaseWithFactory):
'Launchpad encountered an internal error during the following'
' operation: appending a string to a list. It was logged with id'
' %s. Sorry for the inconvenience.' % oops['id'],
- notification.get_payload(decode=True))
- self.assertNotIn('Fake exception. Foobar, I say!',
- notification.get_payload(decode=True))
+ notification.get_payload(decode=True).decode('UTF-8'))
+ self.assertNotIn(
+ 'Fake exception. Foobar, I say!',
+ notification.get_payload(decode=True).decode('UTF-8'))
self.assertEqual('Launchpad internal error', notification['subject'])
def test_runAll_mails_user_errors(self):
@@ -317,7 +318,7 @@ class TestJobRunner(StatsMixin, TestCaseWithFactory):
self.assertEqual([], self.oopses)
notifications = pop_notifications()
self.assertEqual(1, len(notifications))
- body = notifications[0].get_payload(decode=True)
+ body = notifications[0].get_payload(decode=True).decode('UTF-8')
self.assertEqual(
'Launchpad encountered an error during the following operation:'
' appending a string to a list. Fake exception. Foobar, I say!',
diff --git a/lib/lp/services/mail/doc/sending-mail.txt b/lib/lp/services/mail/doc/sending-mail.txt
index 88bf4c9..428f07a 100644
--- a/lib/lp/services/mail/doc/sending-mail.txt
+++ b/lib/lp/services/mail/doc/sending-mail.txt
@@ -27,8 +27,8 @@ Now let's look at the sent email:
'foo.bar@xxxxxxxxxxxxx'
>>> msg['Subject']
'Subject'
- >>> msg.get_payload(decode=True)
- 'Content'
+ >>> print(six.ensure_text(msg.get_payload(decode=True)))
+ Content
>>> # Make sure bulk headers are set for vacation programs
>>> msg['Precedence']
'bulk'
@@ -57,8 +57,8 @@ the person's name is encoded properly.
'Foo Bar <foo.bar@xxxxxxxxxxxxx>'
>>> msg['Subject']
'Subject'
- >>> msg.get_payload(decode=True)
- 'Content'
+ >>> print(six.ensure_text(msg.get_payload(decode=True)))
+ Content
>>> msg['Precedence']
'bulk'
@@ -249,8 +249,8 @@ that the precedence header was not added.
'feedback@xxxxxxxxxxxxx'
>>> msg['Subject']
'Forgot password'
- >>> msg.get_payload(decode=True)
- 'Content'
+ >>> print(six.ensure_text(msg.get_payload(decode=True)))
+ Content
>>> print(msg['Precedence'])
None
diff --git a/lib/lp/services/mail/tests/test_basemailer.py b/lib/lp/services/mail/tests/test_basemailer.py
index ac0fd62..6e6cb05 100644
--- a/lib/lp/services/mail/tests/test_basemailer.py
+++ b/lib/lp/services/mail/tests/test_basemailer.py
@@ -233,15 +233,15 @@ class TestBaseMailer(TestCaseWithFactory):
good_parts = good.get_payload()
self.assertEqual(3, len(good_parts))
self.assertEqual(
- 'attachment1', good_parts[1].get_payload(decode=True))
+ b'attachment1', good_parts[1].get_payload(decode=True))
self.assertEqual(
- 'attachment2', good_parts[2].get_payload(decode=True))
+ b'attachment2', good_parts[2].get_payload(decode=True))
# The bad email has the normal attachments stripped off and replaced
# with the text.
bad_parts = bad.get_payload()
self.assertEqual(2, len(bad_parts))
self.assertEqual(
- 'Excessively large attachments removed.',
+ b'Excessively large attachments removed.',
bad_parts[1].get_payload(decode=True))
# And no OOPS is logged.
self.assertEqual(0, len(self.oopses))
diff --git a/lib/lp/services/mail/tests/test_incoming.py b/lib/lp/services/mail/tests/test_incoming.py
index 3d2e625..a9d615a 100644
--- a/lib/lp/services/mail/tests/test_incoming.py
+++ b/lib/lp/services/mail/tests/test_incoming.py
@@ -7,6 +7,7 @@ import logging
import os
import unittest
+import six
from testtools.matchers import (
Equals,
Is,
@@ -110,7 +111,8 @@ class IncomingTestCase(TestCaseWithFactory):
handleMail()
self.assertEqual([], self.oopses)
[notification] = pop_notifications()
- body = notification.get_payload()[0].get_payload(decode=True)
+ body = six.ensure_text(
+ notification.get_payload()[0].get_payload(decode=True))
self.assertIn(
"An error occurred while processing a mail you sent to "
"Launchpad's email\ninterface.\n\n\n"
@@ -143,7 +145,8 @@ class IncomingTestCase(TestCaseWithFactory):
handleMail()
self.assertEqual([], self.oopses)
[notification] = pop_notifications()
- body = notification.get_payload()[0].get_payload(decode=True)
+ body = six.ensure_text(
+ notification.get_payload()[0].get_payload(decode=True))
self.assertIn(
"An error occurred while processing a mail you sent to "
"Launchpad's email\ninterface.\n\n\n"
@@ -176,7 +179,8 @@ class IncomingTestCase(TestCaseWithFactory):
handleMail()
self.assertEqual([], self.oopses)
[notification] = pop_notifications()
- body = notification.get_payload()[0].get_payload(decode=True)
+ body = six.ensure_text(
+ notification.get_payload()[0].get_payload(decode=True))
self.assertIn(
"An error occurred while processing a mail you sent to "
"Launchpad's email\ninterface.\n\n\n"
@@ -202,7 +206,8 @@ class IncomingTestCase(TestCaseWithFactory):
handleMail()
self.assertEqual([], self.oopses)
[notification] = pop_notifications()
- body = notification.get_payload()[0].get_payload(decode=True)
+ body = six.ensure_text(
+ notification.get_payload()[0].get_payload(decode=True))
self.assertIn("The mail you sent to Launchpad is too long.", body)
self.assertIn("was 55 MB and the limit is 10 MB.", body)
diff --git a/lib/lp/services/verification/tests/test_logintoken.py b/lib/lp/services/verification/tests/test_logintoken.py
index 14cedac..dcde2fa 100644
--- a/lib/lp/services/verification/tests/test_logintoken.py
+++ b/lib/lp/services/verification/tests/test_logintoken.py
@@ -8,6 +8,7 @@ __metaclass__ = type
import doctest
from textwrap import dedent
+import six
from testtools.matchers import DocTestMatches
from zope.component import getUtility
@@ -77,4 +78,6 @@ class TestLoginToken(TestCaseWithFactory):
""")
expected_matcher = DocTestMatches(
expected_message, doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE)
- self.assertThat(message.get_payload(decode=True), expected_matcher)
+ self.assertThat(
+ six.ensure_text(message.get_payload(decode=True)),
+ expected_matcher)
diff --git a/lib/lp/snappy/tests/test_snapbuild.py b/lib/lp/snappy/tests/test_snapbuild.py
index 77bdac0..e5dda05 100644
--- a/lib/lp/snappy/tests/test_snapbuild.py
+++ b/lib/lp/snappy/tests/test_snapbuild.py
@@ -15,6 +15,7 @@ from datetime import (
from fixtures import FakeLogger
from pymacaroons import Macaroon
import pytz
+import six
from six.moves.urllib.request import urlopen
from testtools.matchers import (
ContainsDict,
@@ -461,7 +462,8 @@ class TestSnapBuild(TestCaseWithFactory):
notification["X-Launchpad-Notification-Type"])
self.assertEqual(
"FAILEDTOBUILD", notification["X-Launchpad-Build-State"])
- body, footer = notification.get_payload(decode=True).split("\n-- \n")
+ body, footer = six.ensure_text(
+ notification.get_payload(decode=True)).split("\n-- \n")
self.assertEqual(expected_body % (build.log_url, ""), body)
self.assertEqual(
"http://launchpad.test/~person/+snap/snap-1/+build/%d\n"
diff --git a/lib/lp/snappy/tests/test_snapbuildjob.py b/lib/lp/snappy/tests/test_snapbuildjob.py
index 90bb9db..87a5528 100644
--- a/lib/lp/snappy/tests/test_snapbuildjob.py
+++ b/lib/lp/snappy/tests/test_snapbuildjob.py
@@ -10,6 +10,7 @@ __metaclass__ = type
from datetime import timedelta
from fixtures import FakeLogger
+import six
from testtools.matchers import (
Equals,
Is,
@@ -243,7 +244,8 @@ class TestSnapStoreUploadJob(TestCaseWithFactory):
self.assertEqual(
"snap-build-upload-unauthorized",
notification["X-Launchpad-Notification-Type"])
- body, footer = notification.get_payload(decode=True).split("\n-- \n")
+ body, footer = six.ensure_text(
+ notification.get_payload(decode=True)).split("\n-- \n")
self.assertIn(
"http://launchpad.test/~requester-team/+snap/test-snap/+authorize",
body)
@@ -335,7 +337,8 @@ class TestSnapStoreUploadJob(TestCaseWithFactory):
self.assertEqual(
"snap-build-upload-refresh-failed",
notification["X-Launchpad-Notification-Type"])
- body, footer = notification.get_payload(decode=True).split("\n-- \n")
+ body, footer = six.ensure_text(
+ notification.get_payload(decode=True)).split("\n-- \n")
self.assertIn(
"http://launchpad.test/~requester-team/+snap/test-snap/+authorize",
body)
@@ -385,7 +388,8 @@ class TestSnapStoreUploadJob(TestCaseWithFactory):
self.assertEqual(
"snap-build-upload-failed",
notification["X-Launchpad-Notification-Type"])
- body, footer = notification.get_payload(decode=True).split("\n-- \n")
+ body, footer = six.ensure_text(
+ notification.get_payload(decode=True)).split("\n-- \n")
self.assertIn("Failed to upload", body)
build_url = (
"http://launchpad.test/~requester-team/+snap/test-snap/+build/%d" %
@@ -488,7 +492,8 @@ class TestSnapStoreUploadJob(TestCaseWithFactory):
self.assertEqual(
"snap-build-upload-scan-failed",
notification["X-Launchpad-Notification-Type"])
- body, footer = notification.get_payload(decode=True).split("\n-- \n")
+ body, footer = six.ensure_text(
+ notification.get_payload(decode=True)).split("\n-- \n")
self.assertIn("Scan failed.", body)
self.assertEqual(
"http://launchpad.test/~requester-team/+snap/test-snap/+build/%d\n"
diff --git a/lib/lp/snappy/tests/test_snapjob.py b/lib/lp/snappy/tests/test_snapjob.py
index 00130b5..7eea223 100644
--- a/lib/lp/snappy/tests/test_snapjob.py
+++ b/lib/lp/snappy/tests/test_snapjob.py
@@ -9,6 +9,7 @@ __metaclass__ = type
from textwrap import dedent
+import six
from testtools.matchers import (
AfterPreprocessing,
ContainsDict,
@@ -201,7 +202,7 @@ class TestSnapRequestBuildsJob(TestCaseWithFactory):
self.assertEqual(
"Launchpad encountered an error during the following operation: "
"requesting builds of %s. Nonsense on stilts" % snap.name,
- notification.get_payload(decode=True))
+ six.ensure_text(notification.get_payload(decode=True)))
self.assertThat(job, MatchesStructure(
job=MatchesStructure.byEquality(status=JobStatus.FAILED),
date_created=Equals(expected_date_created),
@@ -235,7 +236,7 @@ class TestSnapRequestBuildsJob(TestCaseWithFactory):
"Launchpad encountered an error during the following operation: "
"requesting builds of %s. No such base: "
"'nonexistent'." % snap.name,
- notification.get_payload(decode=True))
+ six.ensure_text(notification.get_payload(decode=True)))
self.assertThat(job, MatchesStructure(
job=MatchesStructure.byEquality(status=JobStatus.FAILED),
date_created=Equals(expected_date_created),
diff --git a/lib/lp/soyuz/doc/build-failedtoupload-workflow.txt b/lib/lp/soyuz/doc/build-failedtoupload-workflow.txt
index 18e1b08..787a70e 100644
--- a/lib/lp/soyuz/doc/build-failedtoupload-workflow.txt
+++ b/lib/lp/soyuz/doc/build-failedtoupload-workflow.txt
@@ -78,7 +78,8 @@ Note that the generated notification contain the 'extra_info' content:
>>> build_notification['X-Creator-Recipient']
'mark@xxxxxxxxxxx'
- >>> notification_body = build_notification.get_payload(decode=True)
+ >>> notification_body = six.ensure_text(
+ ... build_notification.get_payload(decode=True))
>>> print(notification_body) #doctest: -NORMALIZE_WHITESPACE
<BLANKLINE>
* Source Package: cdrkit
diff --git a/lib/lp/soyuz/mail/tests/test_packageupload.py b/lib/lp/soyuz/mail/tests/test_packageupload.py
index 4b1bd3a..7881462 100644
--- a/lib/lp/soyuz/mail/tests/test_packageupload.py
+++ b/lib/lp/soyuz/mail/tests/test_packageupload.py
@@ -7,6 +7,7 @@
from textwrap import dedent
+import six
from testtools.matchers import (
Contains,
ContainsDict,
@@ -66,9 +67,9 @@ class TestNotificationRequiringLibrarian(TestCaseWithFactory):
notifications = pop_notifications()
self.assertEqual(2, len(notifications))
msg = notifications[1].get_payload(0)
- body = msg.get_payload(decode=True)
- self.assertIn("Changed-By: Loïc", body)
- self.assertIn("Signed-By: Stéphane", body)
+ body = six.ensure_text(msg.get_payload(decode=True))
+ self.assertIn(u"Changed-By: Loïc", body)
+ self.assertIn(u"Signed-By: Stéphane", body)
def test_calculate_subject_customfile(self):
lfa = self.factory.makeLibraryFileAlias()
@@ -225,7 +226,7 @@ class TestNotificationRequiringLibrarian(TestCaseWithFactory):
summary_text="Rejected by archive administrator.")
mailer.sendAll()
[notification] = pop_notifications()
- body = notification.get_payload(decode=True)
+ body = six.ensure_text(notification.get_payload(decode=True))
self.assertEqual('Blamer <blamer@xxxxxxxxxxx>', notification['To'])
expected_body = dedent("""\
Rejected:
diff --git a/lib/lp/soyuz/scripts/tests/test_copypackage.py b/lib/lp/soyuz/scripts/tests/test_copypackage.py
index 6a99db9..8fdf14e 100644
--- a/lib/lp/soyuz/scripts/tests/test_copypackage.py
+++ b/lib/lp/soyuz/scripts/tests/test_copypackage.py
@@ -7,6 +7,7 @@ import datetime
from textwrap import dedent
import pytz
+import six
from testtools.content import text_content
from testtools.matchers import (
Equals,
@@ -1454,7 +1455,7 @@ class TestDoDirectCopy(BaseDoCopyTests, TestCaseWithFactory):
[notification] = pop_notifications()
self.assertEqual(
target_archive.reference, notification['X-Launchpad-Archive'])
- body = notification.get_payload(decode=True)
+ body = six.ensure_text(notification.get_payload(decode=True))
expected = dedent("""\
Accepted:
OK: foo_1.0-2.dsc
diff --git a/lib/lp/soyuz/tests/test_build_notify.py b/lib/lp/soyuz/tests/test_build_notify.py
index 3c27aec..2823531 100644
--- a/lib/lp/soyuz/tests/test_build_notify.py
+++ b/lib/lp/soyuz/tests/test_build_notify.py
@@ -183,7 +183,7 @@ class TestBuildNotify(TestCaseWithFactory):
build.archive.reference, build.status.title, duration, build_log,
builder, source, "-- ", build.title, canonical_url(build)))
expected_body += "\n" + REASONS[reason] + "\n"
- self.assertEqual(expected_body, body)
+ self.assertEqual(expected_body.encode("UTF-8"), body)
def _assert_mails_are_correct(self, build, reasons, ppa=False):
notifications = pop_notifications()
diff --git a/lib/lp/soyuz/tests/test_livefsbuild.py b/lib/lp/soyuz/tests/test_livefsbuild.py
index e7436f1..8d71dd7 100644
--- a/lib/lp/soyuz/tests/test_livefsbuild.py
+++ b/lib/lp/soyuz/tests/test_livefsbuild.py
@@ -340,7 +340,8 @@ class TestLiveFSBuild(TestCaseWithFactory):
notification["X-Launchpad-Notification-Type"])
self.assertEqual(
"FAILEDTOBUILD", notification["X-Launchpad-Build-State"])
- body, footer = notification.get_payload(decode=True).split("\n-- \n")
+ body, footer = notification.get_payload(decode=True).decode(
+ "UTF-8").split("\n-- \n")
self.assertEqual(expected_body % (build.log_url, ""), body)
self.assertEqual(
"http://launchpad.test/~person/+livefs/distro/unstable/livefs-1/"
diff --git a/lib/lp/testing/mail_helpers.py b/lib/lp/testing/mail_helpers.py
index 1b405e3..1bed4dc 100644
--- a/lib/lp/testing/mail_helpers.py
+++ b/lib/lp/testing/mail_helpers.py
@@ -9,6 +9,7 @@ __metaclass__ = type
import operator
+import six
import transaction
from zope.component import getUtility
@@ -119,7 +120,7 @@ def print_emails(include_reply_to=False, group_similar=False,
print('%s: %s' % (
notification_type_header, message[notification_type_header]))
print('Subject:', message['Subject'])
- print(body)
+ print(six.ensure_text(body))
print("-" * 40)
diff --git a/lib/lp/translations/doc/pofile-verify-stats.txt b/lib/lp/translations/doc/pofile-verify-stats.txt
index 71fb3f4..d2299da 100644
--- a/lib/lp/translations/doc/pofile-verify-stats.txt
+++ b/lib/lp/translations/doc/pofile-verify-stats.txt
@@ -105,7 +105,7 @@ The Translations administrators also receive an email about the error.
>>> to_addrs
['launchpad-error-reports@xxxxxxxxxxxxxxxxxxx']
>>> in_header = True
- >>> for line in body.splitlines():
+ >>> for line in body.decode('UTF-8').splitlines():
... if in_header:
... in_header = (line != '')
... else: