Merge ~cjwatson/launchpad:reduce-ensure-str into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 84ad29369c11fcaef75eff96df0fe73a56ad855f
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:reduce-ensure-str
Merge into: launchpad:master
Diff against target: 1607 lines (+153/-211)
57 files modified
lib/launchpad_loggerhead/app.py (+1/-2)
lib/lp/answers/stories/question-obfuscation.txt (+2/-2)
lib/lp/app/doc/displaying-paragraphs-of-text.txt (+7/-12)
lib/lp/app/doc/launchpadform.txt (+1/-1)
lib/lp/app/doc/launchpadview.txt (+2/-2)
lib/lp/app/doc/menus.txt (+1/-1)
lib/lp/app/doc/textformatting.txt (+2/-2)
lib/lp/app/widgets/doc/announcement-date-widget.txt (+1/-1)
lib/lp/app/widgets/doc/noneable-text-widgets.txt (+1/-1)
lib/lp/app/widgets/doc/project-scope-widget.txt (+1/-2)
lib/lp/app/widgets/doc/stripped-text-widget.txt (+1/-1)
lib/lp/blueprints/browser/sprint.py (+0/-7)
lib/lp/blueprints/stories/blueprints/xx-editing.txt (+2/-2)
lib/lp/blueprints/stories/blueprints/xx-productseries.txt (+5/-6)
lib/lp/blueprints/stories/standalone/subscribing.txt (+10/-14)
lib/lp/bugs/model/tests/test_bugtasksearch.py (+4/-7)
lib/lp/bugs/stories/bug-also-affects/xx-bug-also-affects.txt (+2/-2)
lib/lp/bugs/stories/bug-tags/xx-tags-on-bug-page.txt (+3/-3)
lib/lp/bugs/stories/bugattachments/xx-bugattachments.txt (+5/-5)
lib/lp/bugs/stories/bugs/xx-bug-edit.txt (+2/-2)
lib/lp/bugs/stories/bugs/xx-bug-index.txt (+2/-2)
lib/lp/bugs/stories/bugs/xx-bug-obfuscation.txt (+1/-1)
lib/lp/bugs/stories/bugs/xx-bug-text-pages.txt (+1/-1)
lib/lp/bugs/stories/bugwatches/xx-edit-bugwatch.txt (+2/-3)
lib/lp/code/browser/tests/test_codereviewcomment.py (+1/-1)
lib/lp/code/model/branch.py (+1/-1)
lib/lp/coop/answersbugs/visibility.py (+1/-3)
lib/lp/registry/browser/tests/person-admin-views.txt (+3/-3)
lib/lp/registry/browser/tests/test_announcements.py (+1/-2)
lib/lp/registry/doc/person-account.txt (+3/-3)
lib/lp/registry/scripts/tests/test_closeaccount.py (+33/-34)
lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt (+2/-2)
lib/lp/services/database/doc/enumcol.txt (+1/-1)
lib/lp/services/database/doc/textsearching.txt (+2/-2)
lib/lp/services/doc/limitedlist.txt (+1/-1)
lib/lp/services/gpg/doc/gpg-encryption.txt (+4/-4)
lib/lp/services/gpg/handler.py (+1/-2)
lib/lp/services/gpg/tests/test_gpghandler.py (+2/-2)
lib/lp/services/librarian/model.py (+1/-2)
lib/lp/services/mail/doc/notification-recipient-set.txt (+1/-1)
lib/lp/services/webapp/breadcrumb.py (+1/-6)
lib/lp/services/webapp/doc/canonical_url.txt (+1/-2)
lib/lp/services/webapp/doc/menus.txt (+1/-2)
lib/lp/services/webapp/doc/test_adapter.txt (+2/-2)
lib/lp/services/webapp/publication.py (+1/-5)
lib/lp/services/webapp/publisher.py (+3/-5)
lib/lp/services/webapp/servers.py (+1/-3)
lib/lp/services/webservice/doc/launchpadlib.txt (+1/-3)
lib/lp/soyuz/scripts/gina/packages.py (+2/-6)
lib/lp/soyuz/scripts/ppareport.py (+2/-3)
lib/lp/soyuz/stories/soyuz/xx-builds-pages.txt (+1/-2)
lib/lp/translations/model/pomsgid.py (+1/-1)
lib/lp/translations/model/potranslation.py (+1/-1)
lib/lp/translations/stories/standalone/xx-language.txt (+2/-3)
lib/lp/translations/stories/standalone/xx-translationmessage-translate.txt (+5/-6)
lib/lp/translations/stories/translations/xx-translations.txt (+10/-12)
scripts/list-team-members (+1/-3)
Reviewer Review Type Date Requested Status
Guruprasad Approve
Review via email: mp+415902@code.launchpad.net

Commit message

Remove simple uses of six.ensure_str

Description of the change

These were clearly no-ops on Python 3, but missed by pyupgrade for various reasons, such as being in doctests.

To post a comment you must log in.
Revision history for this message
Guruprasad (lgp171188) wrote :

LGTM 👍

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/lib/launchpad_loggerhead/app.py b/lib/launchpad_loggerhead/app.py
index 7ada98a..3e693f2 100644
--- a/lib/launchpad_loggerhead/app.py
+++ b/lib/launchpad_loggerhead/app.py
@@ -40,7 +40,6 @@ from paste.request import (
40 parse_querystring,40 parse_querystring,
41 path_info_pop,41 path_info_pop,
42 )42 )
43import six
44from six.moves.urllib.parse import (43from six.moves.urllib.parse import (
45 urlencode,44 urlencode,
46 urljoin,45 urljoin,
@@ -256,7 +255,7 @@ class RootApp:
256 self.log.info('Using branch: %s', branch_name)255 self.log.info('Using branch: %s', branch_name)
257 if trail and not trail.startswith('/'):256 if trail and not trail.startswith('/'):
258 trail = '/' + trail257 trail = '/' + trail
259 environ['PATH_INFO'] = six.ensure_str(trail)258 environ['PATH_INFO'] = trail
260 environ['SCRIPT_NAME'] += consumed.rstrip('/')259 environ['SCRIPT_NAME'] += consumed.rstrip('/')
261 branch_url = lp_server.get_url() + branch_name260 branch_url = lp_server.get_url() + branch_name
262 branch_link = urljoin(261 branch_link = urljoin(
diff --git a/lib/lp/answers/stories/question-obfuscation.txt b/lib/lp/answers/stories/question-obfuscation.txt
index f6a23c9..1f082fd 100644
--- a/lib/lp/answers/stories/question-obfuscation.txt
+++ b/lib/lp/answers/stories/question-obfuscation.txt
@@ -96,7 +96,7 @@ Anonymous cannot see the email address anywhere on the Answers front
96page.96page.
9797
98 >>> anon_browser.open('http://answers.launchpad.test/')98 >>> anon_browser.open('http://answers.launchpad.test/')
99 >>> six.ensure_str('user@domain.com') in anon_browser.contents99 >>> 'user@domain.com' in anon_browser.contents
100 False100 False
101101
102 >>> question_portlet = find_tag_by_id(102 >>> question_portlet = find_tag_by_id(
@@ -132,7 +132,7 @@ They cannot see the address reading the question either.
132 link ...132 link ...
133133
134 >>> anon_browser.getLink('mailto: problem in webpage').click()134 >>> anon_browser.getLink('mailto: problem in webpage').click()
135 >>> six.ensure_str('user@domain.com') in anon_browser.contents135 >>> 'user@domain.com' in anon_browser.contents
136 False136 False
137137
138 >>> description = find_main_content(anon_browser.contents).p138 >>> description = find_main_content(anon_browser.contents).p
diff --git a/lib/lp/app/doc/displaying-paragraphs-of-text.txt b/lib/lp/app/doc/displaying-paragraphs-of-text.txt
index 94171e0..c50955a 100644
--- a/lib/lp/app/doc/displaying-paragraphs-of-text.txt
+++ b/lib/lp/app/doc/displaying-paragraphs-of-text.txt
@@ -494,7 +494,7 @@ we want to replace a variable number of spaces with the same number of
494494
495 >>> from lp.app.browser.stringformatter import FormattersAPI495 >>> from lp.app.browser.stringformatter import FormattersAPI
496 >>> import re496 >>> import re
497 >>> matchobj = re.match('foo(.*)bar', six.ensure_str('fooX Ybar'))497 >>> matchobj = re.match('foo(.*)bar', 'fooX Ybar')
498 >>> matchobj.groups()498 >>> matchobj.groups()
499 ('X Y',)499 ('X Y',)
500 >>> FormattersAPI._substitute_matchgroup_for_spaces(matchobj)500 >>> FormattersAPI._substitute_matchgroup_for_spaces(matchobj)
@@ -508,10 +508,9 @@ First, let's try a match of nothing it understands. This is a bug, so we get
508an AssertionError.508an AssertionError.
509509
510 >>> matchobj = re.match(510 >>> matchobj = re.match(
511 ... six.ensure_str(511 ... '(?P<bug>xxx)?(?P<faq>www)?(?P<url>yyy)?(?P<oops>zzz)?'
512 ... '(?P<bug>xxx)?(?P<faq>www)?(?P<url>yyy)?(?P<oops>zzz)?'512 ... '(?P<lpbranchurl>www)?(?P<clbug>vvv)?',
513 ... '(?P<lpbranchurl>www)?(?P<clbug>vvv)?'),513 ... 'fish')
514 ... six.ensure_str('fish'))
515 >>> sorted(matchobj.groupdict().items())514 >>> sorted(matchobj.groupdict().items())
516 [('bug', None),515 [('bug', None),
517 ('clbug', None),516 ('clbug', None),
@@ -527,9 +526,7 @@ an AssertionError.
527When we have a URL, the URL is made into a link. A quote is added to the526When we have a URL, the URL is made into a link. A quote is added to the
528url to demonstrate quoting in the HTML attribute.527url to demonstrate quoting in the HTML attribute.
529528
530 >>> matchobj = re.match(529 >>> matchobj = re.match('(?P<bug>xxx)?(?P<url>y"y)?', 'y"y')
531 ... six.ensure_str('(?P<bug>xxx)?(?P<url>y"y)?'),
532 ... six.ensure_str('y"y'))
533 >>> sorted(matchobj.groupdict().items())530 >>> sorted(matchobj.groupdict().items())
534 [('bug', None), ('url', 'y"y')]531 [('bug', None), ('url', 'y"y')]
535 >>> print(FormattersAPI._linkify_substitution(matchobj))532 >>> print(FormattersAPI._linkify_substitution(matchobj))
@@ -539,8 +536,7 @@ When we have a bug reference, the 'bug' group is used as the text of the link,
539and the 'bugnum' is used to look up the bug.536and the 'bugnum' is used to look up the bug.
540537
541 >>> matchobj = re.match(538 >>> matchobj = re.match(
542 ... six.ensure_str('(?P<bug>xxxx)?(?P<bugnum>2)?(?P<url>yyy)?'),539 ... '(?P<bug>xxxx)?(?P<bugnum>2)?(?P<url>yyy)?', 'xxxx2')
543 ... six.ensure_str('xxxx2'))
544 >>> sorted(matchobj.groupdict().items())540 >>> sorted(matchobj.groupdict().items())
545 [('bug', 'xxxx'), ('bugnum', '2'), ('url', None)]541 [('bug', 'xxxx'), ('bugnum', '2'), ('url', None)]
546 >>> FormattersAPI._linkify_substitution(matchobj)542 >>> FormattersAPI._linkify_substitution(matchobj)
@@ -550,8 +546,7 @@ When the bugnum doesn't match any bug, we still get a link, but get a message
550in the link's title.546in the link's title.
551547
552 >>> matchobj = re.match(548 >>> matchobj = re.match(
553 ... six.ensure_str('(?P<bug>xxxx)?(?P<bugnum>2000)?(?P<url>yyy)?'),549 ... '(?P<bug>xxxx)?(?P<bugnum>2000)?(?P<url>yyy)?', 'xxxx2000')
554 ... six.ensure_str('xxxx2000'))
555 >>> sorted(matchobj.groupdict().items())550 >>> sorted(matchobj.groupdict().items())
556 [('bug', 'xxxx'), ('bugnum', '2000'), ('url', None)]551 [('bug', 'xxxx'), ('bugnum', '2000'), ('url', None)]
557 >>> FormattersAPI._linkify_substitution(matchobj)552 >>> FormattersAPI._linkify_substitution(matchobj)
diff --git a/lib/lp/app/doc/launchpadform.txt b/lib/lp/app/doc/launchpadform.txt
index db59937..6fa4e8e 100644
--- a/lib/lp/app/doc/launchpadform.txt
+++ b/lib/lp/app/doc/launchpadform.txt
@@ -229,7 +229,7 @@ setFieldError() method (for errors specific to a field):
229 ... self.addError('your password may not be the same '229 ... self.addError('your password may not be the same '
230 ... 'as your name')230 ... 'as your name')
231 ... if data.get('password') == 'password':231 ... if data.get('password') == 'password':
232 ... self.setFieldError(six.ensure_str('password'),232 ... self.setFieldError('password',
233 ... 'your password must not be "password"')233 ... 'your password must not be "password"')
234234
235 >>> context = FormTest()235 >>> context = FormTest()
diff --git a/lib/lp/app/doc/launchpadview.txt b/lib/lp/app/doc/launchpadview.txt
index f49c1ef..2951085 100644
--- a/lib/lp/app/doc/launchpadview.txt
+++ b/lib/lp/app/doc/launchpadview.txt
@@ -62,7 +62,7 @@ an IStructuredString implementation.
62 >>> print(view.info_message)62 >>> print(view.info_message)
63 None63 None
6464
65 >>> view.error_message = six.ensure_str('A simple string.')65 >>> view.error_message = 'A simple string.'
66 Traceback (most recent call last):66 Traceback (most recent call last):
67 ...67 ...
68 ValueError: <... 'str'> is not a valid value for error_message,68 ValueError: <... 'str'> is not a valid value for error_message,
@@ -70,7 +70,7 @@ an IStructuredString implementation.
70 >>> print(view.error_message)70 >>> print(view.error_message)
71 None71 None
7272
73 >>> view.info_message = six.ensure_str('A simple string.')73 >>> view.info_message = 'A simple string.'
74 Traceback (most recent call last):74 Traceback (most recent call last):
75 ...75 ...
76 ValueError: <... 'str'> is not a valid value for info_message,76 ValueError: <... 'str'> is not a valid value for info_message,
diff --git a/lib/lp/app/doc/menus.txt b/lib/lp/app/doc/menus.txt
index c76ac01..001eac8 100644
--- a/lib/lp/app/doc/menus.txt
+++ b/lib/lp/app/doc/menus.txt
@@ -33,7 +33,7 @@ later, implementations having facets and menus will be defined.
3333
34 >>> import sys34 >>> import sys
35 >>> import types35 >>> import types
36 >>> cookingexample = types.ModuleType(six.ensure_str('cookingexample'))36 >>> cookingexample = types.ModuleType('cookingexample')
37 >>> sys.modules['lp.app.cookingexample'] = cookingexample37 >>> sys.modules['lp.app.cookingexample'] = cookingexample
3838
39 >>> cookingexample.ICookbook = ICookbook39 >>> cookingexample.ICookbook = ICookbook
diff --git a/lib/lp/app/doc/textformatting.txt b/lib/lp/app/doc/textformatting.txt
index 3d9dd40..faee73c 100644
--- a/lib/lp/app/doc/textformatting.txt
+++ b/lib/lp/app/doc/textformatting.txt
@@ -230,14 +230,14 @@ The line endings are normalized to \n, so if we get a text with
230dos-style line endings, we get the following result:230dos-style line endings, we get the following result:
231231
232 >>> mailwrapper = MailWrapper(width=56)232 >>> mailwrapper = MailWrapper(width=56)
233 >>> dos_style_comment = six.ensure_str(233 >>> dos_style_comment = (
234 ... "This paragraph is longer than 56 characters, so it should"234 ... "This paragraph is longer than 56 characters, so it should"
235 ... " be wrapped even though the paragraphs are separated with"235 ... " be wrapped even though the paragraphs are separated with"
236 ... " dos-style line endings."236 ... " dos-style line endings."
237 ... "\r\n\r\n"237 ... "\r\n\r\n"
238 ... "Here's the second paragraph.")238 ... "Here's the second paragraph.")
239 >>> wrapped_text = mailwrapper.format(dos_style_comment)239 >>> wrapped_text = mailwrapper.format(dos_style_comment)
240 >>> wrapped_text.split(six.ensure_str('\n'))240 >>> wrapped_text.split('\n')
241 ['This paragraph is longer than 56 characters, so it',241 ['This paragraph is longer than 56 characters, so it',
242 'should be wrapped even though the paragraphs are',242 'should be wrapped even though the paragraphs are',
243 'separated with dos-style line endings.',243 'separated with dos-style line endings.',
diff --git a/lib/lp/app/widgets/doc/announcement-date-widget.txt b/lib/lp/app/widgets/doc/announcement-date-widget.txt
index d90250c..3b901ce 100644
--- a/lib/lp/app/widgets/doc/announcement-date-widget.txt
+++ b/lib/lp/app/widgets/doc/announcement-date-widget.txt
@@ -9,7 +9,7 @@ future, or to manually publish it later.
9 >>> from lp.testing.pages import extract_text9 >>> from lp.testing.pages import extract_text
10 >>> from lp.services.webapp.servers import LaunchpadTestRequest10 >>> from lp.services.webapp.servers import LaunchpadTestRequest
11 >>> from lp.app.widgets.announcementdate import AnnouncementDateWidget11 >>> from lp.app.widgets.announcementdate import AnnouncementDateWidget
12 >>> field = Field(__name__=six.ensure_str('foo'), title=u'Foo')12 >>> field = Field(__name__='foo', title='Foo')
13 >>> widget = AnnouncementDateWidget(field, LaunchpadTestRequest())13 >>> widget = AnnouncementDateWidget(field, LaunchpadTestRequest())
14 >>> print(extract_text(widget()))14 >>> print(extract_text(widget()))
15 Publish this announcement:15 Publish this announcement:
diff --git a/lib/lp/app/widgets/doc/noneable-text-widgets.txt b/lib/lp/app/widgets/doc/noneable-text-widgets.txt
index 85ca174..6f79a1c 100644
--- a/lib/lp/app/widgets/doc/noneable-text-widgets.txt
+++ b/lib/lp/app/widgets/doc/noneable-text-widgets.txt
@@ -65,5 +65,5 @@ Excess whitespace is stripped, but newlines are preserved.
65 >>> request = LaunchpadTestRequest(65 >>> request = LaunchpadTestRequest(
66 ... form={'field.summary' : ' flower \n grass '})66 ... form={'field.summary' : ' flower \n grass '})
67 >>> widget = NoneableDescriptionWidget(field, request)67 >>> widget = NoneableDescriptionWidget(field, request)
68 >>> six.ensure_str(widget.getInputValue())68 >>> widget.getInputValue()
69 'flower \n grass'69 'flower \n grass'
diff --git a/lib/lp/app/widgets/doc/project-scope-widget.txt b/lib/lp/app/widgets/doc/project-scope-widget.txt
index 366a4bd..1871412 100644
--- a/lib/lp/app/widgets/doc/project-scope-widget.txt
+++ b/lib/lp/app/widgets/doc/project-scope-widget.txt
@@ -15,8 +15,7 @@ selected.
1515
16 >>> empty_request = LaunchpadTestRequest()16 >>> empty_request = LaunchpadTestRequest()
17 >>> scope_field = Choice(17 >>> scope_field = Choice(
18 ... __name__=six.ensure_str('scope'), vocabulary='ProjectGroup',18 ... __name__='scope', vocabulary='ProjectGroup', required=False)
19 ... required=False)
20 >>> scope_field = scope_field.bind(object())19 >>> scope_field = scope_field.bind(object())
21 >>> widget = ProjectScopeWidget(20 >>> widget = ProjectScopeWidget(
22 ... scope_field, scope_field.vocabulary, empty_request)21 ... scope_field, scope_field.vocabulary, empty_request)
diff --git a/lib/lp/app/widgets/doc/stripped-text-widget.txt b/lib/lp/app/widgets/doc/stripped-text-widget.txt
index 3343cd7..c4612d1 100644
--- a/lib/lp/app/widgets/doc/stripped-text-widget.txt
+++ b/lib/lp/app/widgets/doc/stripped-text-widget.txt
@@ -57,7 +57,7 @@ provided.
57 True57 True
5858
59 >>> required_field = StrippedTextLine(59 >>> required_field = StrippedTextLine(
60 ... __name__=six.ensure_str('field'), title=u'Title', required=True)60 ... __name__='field', title=u'Title', required=True)
61 >>> request = LaunchpadTestRequest(form={'field.field':' \n '})61 >>> request = LaunchpadTestRequest(form={'field.field':' \n '})
62 >>> widget = StrippedTextWidget(required_field, request)62 >>> widget = StrippedTextWidget(required_field, request)
63 >>> widget.getInputValue()63 >>> widget.getInputValue()
diff --git a/lib/lp/blueprints/browser/sprint.py b/lib/lp/blueprints/browser/sprint.py
index 84ac65e..95bf105 100644
--- a/lib/lp/blueprints/browser/sprint.py
+++ b/lib/lp/blueprints/browser/sprint.py
@@ -612,13 +612,6 @@ class SprintAttendeesCsvExportView(LaunchpadView):
612 attendance.time_starts.strftime('%Y-%m-%dT%H:%M:%SZ'),612 attendance.time_starts.strftime('%Y-%m-%dT%H:%M:%SZ'),
613 attendance.time_ends.strftime('%Y-%m-%dT%H:%M:%SZ'),613 attendance.time_ends.strftime('%Y-%m-%dT%H:%M:%SZ'),
614 str(attendance.is_physical)))614 str(attendance.is_physical)))
615 # On Python 2, CSV can't handle unicode, so we encode everything as
616 # UTF-8. Note that none of the columns constructed above can ever
617 # be None, so it's safe to use six.ensure_str here (which will raise
618 # TypeError if given None).
619 rows = [[six.ensure_str(column)
620 for column in row]
621 for row in rows]
622 self.request.response.setHeader(615 self.request.response.setHeader(
623 'Content-type', 'text/csv;charset="utf-8"')616 'Content-type', 'text/csv;charset="utf-8"')
624 self.request.response.setHeader(617 self.request.response.setHeader(
diff --git a/lib/lp/blueprints/stories/blueprints/xx-editing.txt b/lib/lp/blueprints/stories/blueprints/xx-editing.txt
index b5b3e2c..fd1a89a 100644
--- a/lib/lp/blueprints/stories/blueprints/xx-editing.txt
+++ b/lib/lp/blueprints/stories/blueprints/xx-editing.txt
@@ -26,7 +26,7 @@ Launchpad won't let us use an URL already used in another blueprint.
26 >>> browser.getControl('Specification URL').value = url26 >>> browser.getControl('Specification URL').value = url
27 >>> browser.getControl('Change').click()27 >>> browser.getControl('Change').click()
2828
29 >>> message = six.ensure_str(29 >>> message = (
30 ... 'https://wiki.ubuntu.com/MediaIntegrityCheck is already '30 ... 'https://wiki.ubuntu.com/MediaIntegrityCheck is already '
31 ... 'registered by')31 ... 'registered by')
32 >>> message in browser.contents32 >>> message in browser.contents
@@ -40,7 +40,7 @@ product.
40 >>> browser.getControl('Specification URL').value = url40 >>> browser.getControl('Specification URL').value = url
41 >>> browser.getControl('Change').click()41 >>> browser.getControl('Change').click()
4242
43 >>> message = six.ensure_str('e4x is already in use by another blueprint')43 >>> message = 'e4x is already in use by another blueprint'
44 >>> message in browser.contents44 >>> message in browser.contents
45 True45 True
4646
diff --git a/lib/lp/blueprints/stories/blueprints/xx-productseries.txt b/lib/lp/blueprints/stories/blueprints/xx-productseries.txt
index 309a17f..4b3f4a3 100644
--- a/lib/lp/blueprints/stories/blueprints/xx-productseries.txt
+++ b/lib/lp/blueprints/stories/blueprints/xx-productseries.txt
@@ -153,8 +153,7 @@ there are none left in the queue.
153 ... 'http://blueprints.launchpad.test/firefox/1.0/+setgoals')153 ... 'http://blueprints.launchpad.test/firefox/1.0/+setgoals')
154 >>> driver_browser.getControl('Support E4X').selected = True154 >>> driver_browser.getControl('Support E4X').selected = True
155 >>> driver_browser.getControl('Decline').click()155 >>> driver_browser.getControl('Decline').click()
156 >>> six.ensure_str('Declined 1 specification(s)') in (156 >>> 'Declined 1 specification(s)' in driver_browser.contents
157 ... driver_browser.contents)
158 True157 True
159158
160The accepted item should show up in the list of specs for this series:159The accepted item should show up in the list of specs for this series:
@@ -216,9 +215,9 @@ OK, lets see if it was immediately accepted:
216215
217 >>> anon_browser.open(216 >>> anon_browser.open(
218 ... 'http://launchpad.test/firefox/+spec/svg-support')217 ... 'http://launchpad.test/firefox/+spec/svg-support')
219 >>> six.ensure_str('firefox/trunk') in anon_browser.contents218 >>> 'firefox/trunk' in anon_browser.contents
220 True219 True
221 >>> six.ensure_str('Accepted') in anon_browser.contents220 >>> 'Accepted' in anon_browser.contents
222 True221 True
223222
224And lets put it back:223And lets put it back:
@@ -258,7 +257,7 @@ And again, it should be accepted automatically.
258257
259 >>> anon_browser.open(258 >>> anon_browser.open(
260 ... 'http://launchpad.test/firefox/+spec/svg-support')259 ... 'http://launchpad.test/firefox/+spec/svg-support')
261 >>> six.ensure_str('firefox/1.0') in anon_browser.contents260 >>> 'firefox/1.0' in anon_browser.contents
262 True261 True
263 >>> six.ensure_str('Accepted') in anon_browser.contents262 >>> 'Accepted' in anon_browser.contents
264 True263 True
diff --git a/lib/lp/blueprints/stories/standalone/subscribing.txt b/lib/lp/blueprints/stories/standalone/subscribing.txt
index beab847..f8289a0 100644
--- a/lib/lp/blueprints/stories/standalone/subscribing.txt
+++ b/lib/lp/blueprints/stories/standalone/subscribing.txt
@@ -52,11 +52,10 @@ Now, we'll POST the form. We should see a message that we have just
52subscribed.52subscribed.
5353
54 >>> browser.getControl('Subscribe').click()54 >>> browser.getControl('Subscribe').click()
55 >>> six.ensure_str('You have subscribed to this blueprint') in (55 >>> 'You have subscribed to this blueprint' in browser.contents
56 ... browser.contents)
57 True56 True
5857
59 >>> six.ensure_str('subscriber-essential') in browser.contents58 >>> 'subscriber-essential' in browser.contents
60 True59 True
6160
62Now the link should say "Update subscription" in the actions menu.61Now the link should say "Update subscription" in the actions menu.
@@ -77,11 +76,10 @@ We will unset the essential flag and resubmit:
7776
78 >>> essential.selected = False77 >>> essential.selected = False
79 >>> browser.getControl('Change').click()78 >>> browser.getControl('Change').click()
80 >>> six.ensure_str('Your subscription has been updated') in (79 >>> 'Your subscription has been updated' in browser.contents
81 ... browser.contents)
82 True80 True
8381
84 >>> six.ensure_str('subscriber-inessential') in browser.contents82 >>> 'subscriber-inessential' in browser.contents
85 True83 True
8684
87It's also possible to change the essential flag clicking on the star85It's also possible to change the essential flag clicking on the star
@@ -93,7 +91,7 @@ icon in the Subscribers portlet.
93 >>> browser.url91 >>> browser.url
94 'http://blueprints.launchpad.test/firefox/+spec/e4x'92 'http://blueprints.launchpad.test/firefox/+spec/e4x'
9593
96 >>> six.ensure_str('subscriber-essential') in browser.contents94 >>> 'subscriber-essential' in browser.contents
97 True95 True
9896
99We don't really want to be subscribed, so lets unsubscribe from that97We don't really want to be subscribed, so lets unsubscribe from that
@@ -104,14 +102,13 @@ unsubscribe confirmation page loads.
104 >>> unsubit.click()102 >>> unsubit.click()
105 >>> confirm = browser.getControl('Unsubscribe')103 >>> confirm = browser.getControl('Unsubscribe')
106 >>> confirm.click()104 >>> confirm.click()
107 >>> six.ensure_str('You have unsubscribed from this blueprint.') in (105 >>> 'You have unsubscribed from this blueprint.' in browser.contents
108 ... browser.contents)
109 True106 True
110107
111 >>> six.ensure_str('subscriber-inessential') in browser.contents108 >>> 'subscriber-inessential' in browser.contents
112 False109 False
113110
114 >>> six.ensure_str('subscriber-essential') in browser.contents111 >>> 'subscriber-essential' in browser.contents
115 False112 False
116113
117114
@@ -128,8 +125,7 @@ When we want other users to track a specification we can subscribe them.
128125
129 >>> browser.getControl('Subscriber').value = 'stub'126 >>> browser.getControl('Subscriber').value = 'stub'
130 >>> browser.getControl('Subscribe').click()127 >>> browser.getControl('Subscribe').click()
131 >>> msg = six.ensure_str(128 >>> msg = "Stuart Bishop has been subscribed to this blueprint."
132 ... "Stuart Bishop has been subscribed to this blueprint.")
133 >>> msg in browser.contents129 >>> msg in browser.contents
134 True130 True
135131
@@ -280,7 +276,7 @@ list, and now the unsubscribe confirmation page loads.
280 >>> unsubit.click()276 >>> unsubit.click()
281 >>> confirm = browser.getControl('Unsubscribe')277 >>> confirm = browser.getControl('Unsubscribe')
282 >>> confirm.click()278 >>> confirm.click()
283 >>> msg = six.ensure_str(279 >>> msg = (
284 ... "Launchpad Administrators has been unsubscribed from this "280 ... "Launchpad Administrators has been unsubscribed from this "
285 ... "blueprint.")281 ... "blueprint.")
286 >>> msg in browser.contents282 >>> msg in browser.contents
diff --git a/lib/lp/bugs/model/tests/test_bugtasksearch.py b/lib/lp/bugs/model/tests/test_bugtasksearch.py
index a8bd7a7..c19503e 100644
--- a/lib/lp/bugs/model/tests/test_bugtasksearch.py
+++ b/lib/lp/bugs/model/tests/test_bugtasksearch.py
@@ -9,7 +9,6 @@ from operator import attrgetter
9import unittest9import unittest
1010
11import pytz11import pytz
12import six
13from storm.expr import Or12from storm.expr import Or
14from testtools.matchers import Equals13from testtools.matchers import Equals
15from testtools.testcase import ExpectedException14from testtools.testcase import ExpectedException
@@ -2460,8 +2459,7 @@ def test_suite():
2460 loader = unittest.TestLoader()2459 loader = unittest.TestLoader()
2461 for bug_target_search_type_class in (2460 for bug_target_search_type_class in (
2462 PreloadBugtaskTargets, NoPreloadBugtaskTargets, QueryBugIDs):2461 PreloadBugtaskTargets, NoPreloadBugtaskTargets, QueryBugIDs):
2463 class_name = six.ensure_str(2462 class_name = 'Test%s' % bug_target_search_type_class.__name__
2464 'Test%s' % bug_target_search_type_class.__name__)
2465 class_bases = (2463 class_bases = (
2466 bug_target_search_type_class, ProductTarget, OnceTests,2464 bug_target_search_type_class, ProductTarget, OnceTests,
2467 SearchTestBase, TestCaseWithFactory)2465 SearchTestBase, TestCaseWithFactory)
@@ -2469,10 +2467,9 @@ def test_suite():
2469 suite.addTest(loader.loadTestsFromTestCase(test_class))2467 suite.addTest(loader.loadTestsFromTestCase(test_class))
24702468
2471 for target_mixin in bug_targets_mixins:2469 for target_mixin in bug_targets_mixins:
2472 class_name = six.ensure_str(2470 class_name = 'Test%s%s' % (
2473 'Test%s%s' % (2471 bug_target_search_type_class.__name__,
2474 bug_target_search_type_class.__name__,2472 target_mixin.__name__)
2475 target_mixin.__name__))
2476 mixins = [2473 mixins = [
2477 target_mixin, bug_target_search_type_class]2474 target_mixin, bug_target_search_type_class]
2478 class_bases = (2475 class_bases = (
diff --git a/lib/lp/bugs/stories/bug-also-affects/xx-bug-also-affects.txt b/lib/lp/bugs/stories/bug-also-affects/xx-bug-also-affects.txt
index d58193d..7a7ebf8 100644
--- a/lib/lp/bugs/stories/bug-also-affects/xx-bug-also-affects.txt
+++ b/lib/lp/bugs/stories/bug-also-affects/xx-bug-also-affects.txt
@@ -704,7 +704,7 @@ confirmation.
704 mailto:dark-master-o-bugs@mylittlepony.com704 mailto:dark-master-o-bugs@mylittlepony.com
705705
706 >>> user_browser.contents.count(706 >>> user_browser.contents.count(
707 ... six.ensure_str('mailto:dark-master-o-bugs@mylittlepony.com'))707 ... 'mailto:dark-master-o-bugs@mylittlepony.com')
708 3708 3
709709
710To evade harvesting, the email address above is obfuscated if you're not710To evade harvesting, the email address above is obfuscated if you're not
@@ -720,5 +720,5 @@ logged in.
720 auto-dark-master-o-bugs720 auto-dark-master-o-bugs
721721
722 >>> anon_browser.contents.count(722 >>> anon_browser.contents.count(
723 ... six.ensure_str('mailto:dark-master-o-bugs@mylittlepony.com'))723 ... 'mailto:dark-master-o-bugs@mylittlepony.com')
724 0724 0
diff --git a/lib/lp/bugs/stories/bug-tags/xx-tags-on-bug-page.txt b/lib/lp/bugs/stories/bug-tags/xx-tags-on-bug-page.txt
index 918cf50..e4b2e8d 100644
--- a/lib/lp/bugs/stories/bug-tags/xx-tags-on-bug-page.txt
+++ b/lib/lp/bugs/stories/bug-tags/xx-tags-on-bug-page.txt
@@ -34,11 +34,11 @@ Let's specify two valid tags.
3434
35Now the tags will be displayed on the bug page:35Now the tags will be displayed on the bug page:
3636
37 >>> six.ensure_str('Tags:') in user_browser.contents37 >>> 'Tags:' in user_browser.contents
38 True38 True
39 >>> six.ensure_str('foo') in user_browser.contents39 >>> 'foo' in user_browser.contents
40 True40 True
41 >>> six.ensure_str('bar') in user_browser.contents41 >>> 'bar' in user_browser.contents
42 True42 True
4343
44Simply changing the ordering of the bug tags won't cause anything to44Simply changing the ordering of the bug tags won't cause anything to
diff --git a/lib/lp/bugs/stories/bugattachments/xx-bugattachments.txt b/lib/lp/bugs/stories/bugattachments/xx-bugattachments.txt
index ec8e157..ae6db94 100644
--- a/lib/lp/bugs/stories/bugattachments/xx-bugattachments.txt
+++ b/lib/lp/bugs/stories/bugattachments/xx-bugattachments.txt
@@ -44,14 +44,14 @@ We can check that the attachment is there
44 >>> link.url44 >>> link.url
45 'http://bugs.launchpad.test/firefox/+bug/1/+attachment/.../+files/foo.txt'45 'http://bugs.launchpad.test/firefox/+bug/1/+attachment/.../+files/foo.txt'
4646
47 >>> six.ensure_str('Added some information') in user_browser.contents47 >>> 'Added some information' in user_browser.contents
48 True48 True
4949
50And that we stripped the leading and trailing whitespace correctly50And that we stripped the leading and trailing whitespace correctly
5151
52 >>> six.ensure_str(' Some information ') in user_browser.contents52 >>> ' Some information ' in user_browser.contents
53 False53 False
54 >>> six.ensure_str('Some information') in user_browser.contents54 >>> 'Some information' in user_browser.contents
55 True55 True
5656
57If no description is given it gets set to the attachment filename. It's57If no description is given it gets set to the attachment filename. It's
@@ -265,7 +265,7 @@ We can also edit the attachment details, let's navigate to that page.
265 >>> user_browser.url265 >>> user_browser.url
266 'http://bugs.launchpad.test/firefox/+bug/1/+attachment/...'266 'http://bugs.launchpad.test/firefox/+bug/1/+attachment/...'
267267
268 >>> six.ensure_str('Edit attachment') in user_browser.contents268 >>> 'Edit attachment' in user_browser.contents
269 True269 True
270270
271There's also an option to cancel, which takes you back to the bug271There's also an option to cancel, which takes you back to the bug
@@ -286,7 +286,7 @@ whitespace to test that's correctly stripped)...
286 >>> user_browser.url286 >>> user_browser.url
287 'http://bugs.launchpad.test/firefox/+bug/1'287 'http://bugs.launchpad.test/firefox/+bug/1'
288288
289 >>> six.ensure_str('Another title') in user_browser.contents289 >>> 'Another title' in user_browser.contents
290 True290 True
291291
292We can edit the attachment to be a patch.292We can edit the attachment to be a patch.
diff --git a/lib/lp/bugs/stories/bugs/xx-bug-edit.txt b/lib/lp/bugs/stories/bugs/xx-bug-edit.txt
index 7700e4a..2456c33 100644
--- a/lib/lp/bugs/stories/bugs/xx-bug-edit.txt
+++ b/lib/lp/bugs/stories/bugs/xx-bug-edit.txt
@@ -73,9 +73,9 @@ Now we are back at the bug page, and the tag has been added.
7373
74 >>> user_browser.url74 >>> user_browser.url
75 'http://bugs.launchpad.test/firefox/+bug/1'75 'http://bugs.launchpad.test/firefox/+bug/1'
76 >>> six.ensure_str('layout-test') in user_browser.contents76 >>> 'layout-test' in user_browser.contents
77 True77 True
78 >>> six.ensure_str('new-tag') in user_browser.contents78 >>> 'new-tag' in user_browser.contents
79 False79 False
8080
81Now, let's add 'new-tag' again, and confirm it this time.81Now, let's add 'new-tag' again, and confirm it this time.
diff --git a/lib/lp/bugs/stories/bugs/xx-bug-index.txt b/lib/lp/bugs/stories/bugs/xx-bug-index.txt
index 590df67..540000e 100644
--- a/lib/lp/bugs/stories/bugs/xx-bug-index.txt
+++ b/lib/lp/bugs/stories/bugs/xx-bug-index.txt
@@ -43,7 +43,7 @@ highlighted.
43 ...<tr>43 ...<tr>
44 ...mozilla-firefox (Ubuntu)...44 ...mozilla-firefox (Ubuntu)...
45 ...45 ...
46 >>> anon_browser.contents.count(six.ensure_str('<tr class="highlight"'))46 >>> anon_browser.contents.count('<tr class="highlight"')
47 147 1
4848
49 >>> anon_browser.open(49 >>> anon_browser.open(
@@ -60,7 +60,7 @@ highlighted.
60 ...<tr>60 ...<tr>
61 ...mozilla-firefox (Ubuntu)...61 ...mozilla-firefox (Ubuntu)...
62 ...62 ...
63 >>> anon_browser.contents.count(six.ensure_str('<tr class="highlight"'))63 >>> anon_browser.contents.count('<tr class="highlight"')
64 164 1
6565
66If the context is a distribution package, the package name has a66If the context is a distribution package, the package name has a
diff --git a/lib/lp/bugs/stories/bugs/xx-bug-obfuscation.txt b/lib/lp/bugs/stories/bugs/xx-bug-obfuscation.txt
index a7dc948..7864052 100644
--- a/lib/lp/bugs/stories/bugs/xx-bug-obfuscation.txt
+++ b/lib/lp/bugs/stories/bugs/xx-bug-obfuscation.txt
@@ -29,7 +29,7 @@ An anonymous cannot see the email address anywhere in the page.
29 >>> print(anon_browser.title)29 >>> print(anon_browser.title)
30 Bug #3 ...30 Bug #3 ...
3131
32 >>> six.ensure_str('user@domain.org') in anon_browser.contents32 >>> 'user@domain.org' in anon_browser.contents
33 False33 False
3434
35 >>> description = find_tag_by_id(35 >>> description = find_tag_by_id(
diff --git a/lib/lp/bugs/stories/bugs/xx-bug-text-pages.txt b/lib/lp/bugs/stories/bugs/xx-bug-text-pages.txt
index f4e5a39..f25404c 100644
--- a/lib/lp/bugs/stories/bugs/xx-bug-text-pages.txt
+++ b/lib/lp/bugs/stories/bugs/xx-bug-text-pages.txt
@@ -127,7 +127,7 @@ are replaced by a single space.
127127
128 >>> attachments_text = text_bug[text_bug.find('attachments:'):]128 >>> attachments_text = text_bug[text_bug.find('attachments:'):]
129 >>> attachment_2 = attachments_text.split('\n')[2]129 >>> attachment_2 = attachments_text.split('\n')[2]
130 >>> six.ensure_str(attachment_2)130 >>> attachment_2
131 ' http://bugs.launchpad.test/.../file%20with%20space.txt text/plain;131 ' http://bugs.launchpad.test/.../file%20with%20space.txt text/plain;
132 name="file with space.txt"'132 name="file with space.txt"'
133133
diff --git a/lib/lp/bugs/stories/bugwatches/xx-edit-bugwatch.txt b/lib/lp/bugs/stories/bugwatches/xx-edit-bugwatch.txt
index 2488478..d86a58d 100644
--- a/lib/lp/bugs/stories/bugwatches/xx-edit-bugwatch.txt
+++ b/lib/lp/bugs/stories/bugwatches/xx-edit-bugwatch.txt
@@ -10,9 +10,8 @@ After a bug watch is recorded, it is possible to go back and change it.
10 >>> admin_browser.getControl('Change').click()10 >>> admin_browser.getControl('Change').click()
11 >>> admin_browser.url11 >>> admin_browser.url
12 'http://bugs.launchpad.test/firefox/+bug/1'12 'http://bugs.launchpad.test/firefox/+bug/1'
13 >>> six.ensure_str(13 >>> 'https://bugzilla.mozilla.org/show_bug.cgi?id=1000' in (
14 ... 'https://bugzilla.mozilla.org/show_bug.cgi?id=1000') in (14 ... admin_browser.contents)
15 ... admin_browser.contents)
16 True15 True
1716
18The URL supplied must be a valid bug tracker URL and must point to a17The URL supplied must be a valid bug tracker URL and must point to a
diff --git a/lib/lp/code/browser/tests/test_codereviewcomment.py b/lib/lp/code/browser/tests/test_codereviewcomment.py
index 458f67a..ac402fe 100644
--- a/lib/lp/code/browser/tests/test_codereviewcomment.py
+++ b/lib/lp/code/browser/tests/test_codereviewcomment.py
@@ -207,7 +207,7 @@ class TestCodeReviewCommentHtmlMixin:
207 contents = 'test-comment'207 contents = 'test-comment'
208 comment = self.makeCodeReviewComment(body=contents)208 comment = self.makeCodeReviewComment(body=contents)
209 browser = self.getViewBrowser(comment, view_name='+reply')209 browser = self.getViewBrowser(comment, view_name='+reply')
210 self.assertIn(six.ensure_str(contents), browser.contents)210 self.assertIn(contents, browser.contents)
211211
212 def test_footer_for_mergeable_and_admin(self):212 def test_footer_for_mergeable_and_admin(self):
213 """An admin sees Hide/Reply links for a comment on a mergeable MP."""213 """An admin sees Hide/Reply links for a comment on a mergeable MP."""
diff --git a/lib/lp/code/model/branch.py b/lib/lp/code/model/branch.py
index 98952be..f86f754 100644
--- a/lib/lp/code/model/branch.py
+++ b/lib/lp/code/model/branch.py
@@ -743,7 +743,7 @@ class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
743743
744 def getInternalBzrUrl(self):744 def getInternalBzrUrl(self):
745 """See `IBranch`."""745 """See `IBranch`."""
746 return six.ensure_str('lp-internal:///' + self.unique_name)746 return 'lp-internal:///' + self.unique_name
747747
748 def getBzrBranch(self):748 def getBzrBranch(self):
749 """See `IBranch`."""749 """See `IBranch`."""
diff --git a/lib/lp/coop/answersbugs/visibility.py b/lib/lp/coop/answersbugs/visibility.py
index b167ef2..cbb3815 100644
--- a/lib/lp/coop/answersbugs/visibility.py
+++ b/lib/lp/coop/answersbugs/visibility.py
@@ -8,8 +8,6 @@ __all__ = [
8 'TestMessageVisibilityMixin',8 'TestMessageVisibilityMixin',
9 ]9 ]
1010
11import six
12
13from lp.services.webapp.escaping import html_escape11from lp.services.webapp.escaping import html_escape
14from lp.testing.pages import find_tag_by_id12from lp.testing.pages import find_tag_by_id
1513
@@ -17,7 +15,7 @@ from lp.testing.pages import find_tag_by_id
17class TestMessageVisibilityMixin:15class TestMessageVisibilityMixin:
1816
19 comment_text = "You can't see me."17 comment_text = "You can't see me."
20 html_comment_text = six.ensure_str(html_escape(comment_text))18 html_comment_text = html_escape(comment_text)
2119
22 def makeHiddenMessage(self):20 def makeHiddenMessage(self):
23 """To be overwridden by subclasses.21 """To be overwridden by subclasses.
diff --git a/lib/lp/registry/browser/tests/person-admin-views.txt b/lib/lp/registry/browser/tests/person-admin-views.txt
index 9e4d33d..34d0d8f 100644
--- a/lib/lp/registry/browser/tests/person-admin-views.txt
+++ b/lib/lp/registry/browser/tests/person-admin-views.txt
@@ -129,7 +129,7 @@ an account is suspended, the preferred email address is disabled.
129 >>> transaction.commit()129 >>> transaction.commit()
130 >>> user.account_status130 >>> user.account_status
131 <DBItem AccountStatus.SUSPENDED, ...>131 <DBItem AccountStatus.SUSPENDED, ...>
132 >>> six.ensure_str(user.account_status_history)132 >>> user.account_status_history
133 '... name16: Active -> Suspended: Wanted by the galactic police.\n'133 '... name16: Active -> Suspended: Wanted by the galactic police.\n'
134 >>> print(user.preferredemail)134 >>> print(user.preferredemail)
135 None135 None
@@ -161,7 +161,7 @@ user must log in to restore the email addresses using the reactivate step.
161 []161 []
162 >>> user.account_status162 >>> user.account_status
163 <DBItem AccountStatus.DEACTIVATED, ...>163 <DBItem AccountStatus.DEACTIVATED, ...>
164 >>> six.ensure_str(user.account_status_history)164 >>> user.account_status_history
165 "... name16: Active -> Suspended: Wanted by the galactic police.\n...165 "... name16: Active -> Suspended: Wanted by the galactic police.\n...
166 name16: Suspended -> Deactivated: Zaphod's a hoopy frood.\n"166 name16: Suspended -> Deactivated: Zaphod's a hoopy frood.\n"
167 >>> print(user.preferredemail)167 >>> print(user.preferredemail)
@@ -180,7 +180,7 @@ An admin can mark an account as belonging to a user who has died.
180 []180 []
181 >>> user.account_status181 >>> user.account_status
182 <DBItem AccountStatus.DECEASED, ...>182 <DBItem AccountStatus.DECEASED, ...>
183 >>> six.ensure_str(user.account_status_history)183 >>> user.account_status_history
184 "... name16: Active -> Suspended: Wanted by the galactic police.\n...184 "... name16: Active -> Suspended: Wanted by the galactic police.\n...
185 name16: Suspended -> Deactivated: Zaphod's a hoopy frood.\n...185 name16: Suspended -> Deactivated: Zaphod's a hoopy frood.\n...
186 name16: Deactivated -> Deceased: In memoriam.\n"186 name16: Deactivated -> Deceased: In memoriam.\n"
diff --git a/lib/lp/registry/browser/tests/test_announcements.py b/lib/lp/registry/browser/tests/test_announcements.py
index 5f005c6..af459b4 100644
--- a/lib/lp/registry/browser/tests/test_announcements.py
+++ b/lib/lp/registry/browser/tests/test_announcements.py
@@ -7,7 +7,6 @@ from datetime import datetime
77
8from lxml import html8from lxml import html
9from pytz import utc9from pytz import utc
10import six
11from zope.component import getUtility10from zope.component import getUtility
12from zope.security.proxy import removeSecurityProxy11from zope.security.proxy import removeSecurityProxy
1312
@@ -107,7 +106,7 @@ class TestAnnouncementPage(BrowserTestCase):
107 removeSecurityProxy(inactive_product).active = False106 removeSecurityProxy(inactive_product).active = False
108107
109 browser = self.getViewBrowser(context, view_name, user=user)108 browser = self.getViewBrowser(context, view_name, user=user)
110 contents = six.ensure_str(browser.contents, "utf-8")109 contents = browser.contents
111110
112 self.assertIn(first_announcement.title, contents)111 self.assertIn(first_announcement.title, contents)
113 self.assertIn(first_announcement.summary, contents)112 self.assertIn(first_announcement.summary, contents)
diff --git a/lib/lp/registry/doc/person-account.txt b/lib/lp/registry/doc/person-account.txt
index 576ab7d..0ed70c6 100644
--- a/lib/lp/registry/doc/person-account.txt
+++ b/lib/lp/registry/doc/person-account.txt
@@ -49,7 +49,7 @@ Matsubara can.
49 True49 True
50 >>> matsubara.account.status50 >>> matsubara.account.status
51 <DBItem AccountStatus.ACTIVE, ...>51 <DBItem AccountStatus.ACTIVE, ...>
52 >>> six.ensure_str(removeSecurityProxy(matsubara.account).status_history)52 >>> removeSecurityProxy(matsubara.account).status_history
53 '...: Unactivated -> Active: test\n'53 '...: Unactivated -> Active: test\n'
54 >>> print(removeSecurityProxy(matsubara.preferredemail).email)54 >>> print(removeSecurityProxy(matsubara.preferredemail).email)
55 matsubara@async.com.br55 matsubara@async.com.br
@@ -156,7 +156,7 @@ adds a '-deactivatedaccount' suffix to the person's name...
156 >>> foobar.account.status156 >>> foobar.account.status
157 <DBItem AccountStatus.DEACTIVATED...157 <DBItem AccountStatus.DEACTIVATED...
158158
159 >>> six.ensure_str(removeSecurityProxy(foobar.account).status_history)159 >>> removeSecurityProxy(foobar.account).status_history
160 "... name16: Active -> Deactivated:160 "... name16: Active -> Deactivated:
161 I'm a person who doesn't want to be listed as a Launchpad user.\n"161 I'm a person who doesn't want to be listed as a Launchpad user.\n"
162162
@@ -232,7 +232,7 @@ Accounts can be reactivated.
232 >>> foobar.account.status232 >>> foobar.account.status
233 <DBItem AccountStatus.ACTIVE...233 <DBItem AccountStatus.ACTIVE...
234234
235 >>> six.ensure_str(removeSecurityProxy(foobar.account).status_history)235 >>> removeSecurityProxy(foobar.account).status_history
236 "... name16: Active -> Deactivated: I'm a person236 "... name16: Active -> Deactivated: I'm a person
237 who doesn't want to be listed as a Launchpad user.\n...:237 who doesn't want to be listed as a Launchpad user.\n...:
238 Deactivated -> Active:238 Deactivated -> Active:
diff --git a/lib/lp/registry/scripts/tests/test_closeaccount.py b/lib/lp/registry/scripts/tests/test_closeaccount.py
index ada1dd5..66277ea 100644
--- a/lib/lp/registry/scripts/tests/test_closeaccount.py
+++ b/lib/lp/registry/scripts/tests/test_closeaccount.py
@@ -3,7 +3,6 @@
33
4"""Test the close-account script."""4"""Test the close-account script."""
55
6import six
7from storm.store import Store6from storm.store import Store
8from testtools.matchers import (7from testtools.matchers import (
9 MatchesSetwise,8 MatchesSetwise,
@@ -178,7 +177,7 @@ class TestCloseAccount(TestCaseWithFactory):
178 person_id = person.id177 person_id = person.id
179 account_id = person.account.id178 account_id = person.account.id
180 self.factory.makeProduct(owner=person)179 self.factory.makeProduct(owner=person)
181 script = self.makeScript([six.ensure_str(person.name)])180 script = self.makeScript([person.name])
182 with dbuser('launchpad'):181 with dbuser('launchpad'):
183 self.assertRaisesWithContent(182 self.assertRaisesWithContent(
184 LaunchpadScriptFailure,183 LaunchpadScriptFailure,
@@ -192,7 +191,7 @@ class TestCloseAccount(TestCaseWithFactory):
192191
193 def test_dry_run(self):192 def test_dry_run(self):
194 person, person_id, account_id = self.makePopulatedUser()193 person, person_id, account_id = self.makePopulatedUser()
195 script = self.makeScript(['--dry-run', six.ensure_str(person.name)])194 script = self.makeScript(['--dry-run', person.name])
196 with dbuser('launchpad'):195 with dbuser('launchpad'):
197 self.runScript(script)196 self.runScript(script)
198 self.assertIn(197 self.assertIn(
@@ -201,14 +200,14 @@ class TestCloseAccount(TestCaseWithFactory):
201200
202 def test_single_by_name(self):201 def test_single_by_name(self):
203 person, person_id, account_id = self.makePopulatedUser()202 person, person_id, account_id = self.makePopulatedUser()
204 script = self.makeScript([six.ensure_str(person.name)])203 script = self.makeScript([person.name])
205 with dbuser('launchpad'):204 with dbuser('launchpad'):
206 self.runScript(script)205 self.runScript(script)
207 self.assertRemoved(account_id, person_id)206 self.assertRemoved(account_id, person_id)
208207
209 def test_single_by_email(self):208 def test_single_by_email(self):
210 person, person_id, account_id = self.makePopulatedUser()209 person, person_id, account_id = self.makePopulatedUser()
211 script = self.makeScript([six.ensure_str(person.preferredemail.email)])210 script = self.makeScript([person.preferredemail.email])
212 with dbuser('launchpad'):211 with dbuser('launchpad'):
213 self.runScript(script)212 self.runScript(script)
214 self.assertRemoved(account_id, person_id)213 self.assertRemoved(account_id, person_id)
@@ -227,7 +226,7 @@ class TestCloseAccount(TestCaseWithFactory):
227 def test_multiple_email_addresses(self):226 def test_multiple_email_addresses(self):
228 person, person_id, account_id = self.makePopulatedUser()227 person, person_id, account_id = self.makePopulatedUser()
229 self.factory.makeEmail('%s@another-domain.test' % person.name, person)228 self.factory.makeEmail('%s@another-domain.test' % person.name, person)
230 script = self.makeScript([six.ensure_str(person.name)])229 script = self.makeScript([person.name])
231 with dbuser('launchpad'):230 with dbuser('launchpad'):
232 self.runScript(script)231 self.runScript(script)
233 self.assertRemoved(account_id, person_id)232 self.assertRemoved(account_id, person_id)
@@ -251,7 +250,7 @@ class TestCloseAccount(TestCaseWithFactory):
251 snap = self.factory.makeSnap()250 snap = self.factory.makeSnap()
252 snap_build = self.factory.makeSnapBuild(requester=person, snap=snap)251 snap_build = self.factory.makeSnapBuild(requester=person, snap=snap)
253 specification = self.factory.makeSpecification(drafter=person)252 specification = self.factory.makeSpecification(drafter=person)
254 script = self.makeScript([six.ensure_str(person.name)])253 script = self.makeScript([person.name])
255 with dbuser('launchpad'):254 with dbuser('launchpad'):
256 self.runScript(script)255 self.runScript(script)
257 self.assertRemoved(account_id, person_id)256 self.assertRemoved(account_id, person_id)
@@ -271,7 +270,7 @@ class TestCloseAccount(TestCaseWithFactory):
271 question.addComment(person, "comment")270 question.addComment(person, "comment")
272 removeSecurityProxy(question).status = status271 removeSecurityProxy(question).status = status
273 questions.append(question)272 questions.append(question)
274 script = self.makeScript([six.ensure_str(person.name)])273 script = self.makeScript([person.name])
275 with dbuser('launchpad'):274 with dbuser('launchpad'):
276 self.runScript(script)275 self.runScript(script)
277 self.assertRemoved(account_id, person_id)276 self.assertRemoved(account_id, person_id)
@@ -293,7 +292,7 @@ class TestCloseAccount(TestCaseWithFactory):
293 question.addComment(person, "comment")292 question.addComment(person, "comment")
294 removeSecurityProxy(question).status = status293 removeSecurityProxy(question).status = status
295 questions[status] = question294 questions[status] = question
296 script = self.makeScript([six.ensure_str(person.name)])295 script = self.makeScript([person.name])
297 with dbuser('launchpad'):296 with dbuser('launchpad'):
298 self.runScript(script)297 self.runScript(script)
299 self.assertRemoved(account_id, person_id)298 self.assertRemoved(account_id, person_id)
@@ -308,7 +307,7 @@ class TestCloseAccount(TestCaseWithFactory):
308 spec = self.factory.makeSpecification()307 spec = self.factory.makeSpecification()
309 branch = self.factory.makeAnyBranch()308 branch = self.factory.makeAnyBranch()
310 spec.linkBranch(branch, person)309 spec.linkBranch(branch, person)
311 script = self.makeScript([six.ensure_str(person.name)])310 script = self.makeScript([person.name])
312 with dbuser('launchpad'):311 with dbuser('launchpad'):
313 self.runScript(script)312 self.runScript(script)
314 self.assertRemoved(account_id, person_id)313 self.assertRemoved(account_id, person_id)
@@ -331,7 +330,7 @@ class TestCloseAccount(TestCaseWithFactory):
331 while not job.isDone():330 while not job.isDone():
332 job(chunk_size=100)331 job(chunk_size=100)
333 self.assertTrue(person.hasMaintainedPackages())332 self.assertTrue(person.hasMaintainedPackages())
334 script = self.makeScript([six.ensure_str(person.name)])333 script = self.makeScript([person.name])
335 with dbuser('launchpad'):334 with dbuser('launchpad'):
336 self.runScript(script)335 self.runScript(script)
337 self.assertRemoved(account_id, person_id)336 self.assertRemoved(account_id, person_id)
@@ -345,7 +344,7 @@ class TestCloseAccount(TestCaseWithFactory):
345 bugtask = self.factory.makeBugTask(bug=bug, owner=person)344 bugtask = self.factory.makeBugTask(bug=bug, owner=person)
346 person_id = person.id345 person_id = person.id
347 account_id = person.account.id346 account_id = person.account.id
348 script = self.makeScript([six.ensure_str(person.name)])347 script = self.makeScript([person.name])
349 with dbuser('launchpad'):348 with dbuser('launchpad'):
350 self.runScript(script)349 self.runScript(script)
351 self.assertRemoved(account_id, person_id)350 self.assertRemoved(account_id, person_id)
@@ -358,7 +357,7 @@ class TestCloseAccount(TestCaseWithFactory):
358 self.factory.makeBugWatch(owner=person)357 self.factory.makeBugWatch(owner=person)
359 person_id = person.id358 person_id = person.id
360 account_id = person.account.id359 account_id = person.account.id
361 script = self.makeScript([six.ensure_str(person.name)])360 script = self.makeScript([person.name])
362 with dbuser('launchpad'):361 with dbuser('launchpad'):
363 self.runScript(script)362 self.runScript(script)
364 self.assertRemoved(account_id, person_id)363 self.assertRemoved(account_id, person_id)
@@ -370,7 +369,7 @@ class TestCloseAccount(TestCaseWithFactory):
370 self.assertTrue(bug.isUserAffected(person))369 self.assertTrue(bug.isUserAffected(person))
371 person_id = person.id370 person_id = person.id
372 account_id = person.account.id371 account_id = person.account.id
373 script = self.makeScript([six.ensure_str(person.name)])372 script = self.makeScript([person.name])
374 with dbuser('launchpad'):373 with dbuser('launchpad'):
375 self.runScript(script)374 self.runScript(script)
376 self.assertRemoved(account_id, person_id)375 self.assertRemoved(account_id, person_id)
@@ -382,7 +381,7 @@ class TestCloseAccount(TestCaseWithFactory):
382 translations_person.translations_relicensing_agreement = True381 translations_person.translations_relicensing_agreement = True
383 person_id = person.id382 person_id = person.id
384 account_id = person.account.id383 account_id = person.account.id
385 script = self.makeScript([six.ensure_str(person.name)])384 script = self.makeScript([person.name])
386 with dbuser('launchpad'):385 with dbuser('launchpad'):
387 self.runScript(script)386 self.runScript(script)
388 self.assertRemoved(account_id, person_id)387 self.assertRemoved(account_id, person_id)
@@ -399,7 +398,7 @@ class TestCloseAccount(TestCaseWithFactory):
399 person, pofile))398 person, pofile))
400 person_id = person.id399 person_id = person.id
401 account_id = person.account.id400 account_id = person.account.id
402 script = self.makeScript([six.ensure_str(person.name)])401 script = self.makeScript([person.name])
403 with dbuser('launchpad'):402 with dbuser('launchpad'):
404 self.runScript(script)403 self.runScript(script)
405 self.assertRemoved(account_id, person_id)404 self.assertRemoved(account_id, person_id)
@@ -413,7 +412,7 @@ class TestCloseAccount(TestCaseWithFactory):
413 pofile.owner = person412 pofile.owner = person
414 person_id = person.id413 person_id = person.id
415 account_id = person.account.id414 account_id = person.account.id
416 script = self.makeScript([six.ensure_str(person.name)])415 script = self.makeScript([person.name])
417 with dbuser('launchpad'):416 with dbuser('launchpad'):
418 self.runScript(script)417 self.runScript(script)
419 self.assertRemoved(account_id, person_id)418 self.assertRemoved(account_id, person_id)
@@ -429,7 +428,7 @@ class TestCloseAccount(TestCaseWithFactory):
429 self.assertIsNotNone(ppa.getAuthToken(person))428 self.assertIsNotNone(ppa.getAuthToken(person))
430 person_id = person.id429 person_id = person.id
431 account_id = person.account.id430 account_id = person.account.id
432 script = self.makeScript([six.ensure_str(person.name)])431 script = self.makeScript([person.name])
433 with dbuser('launchpad'):432 with dbuser('launchpad'):
434 now = get_transaction_timestamp(Store.of(person))433 now = get_transaction_timestamp(Store.of(person))
435 self.runScript(script)434 self.runScript(script)
@@ -557,7 +556,7 @@ class TestCloseAccount(TestCaseWithFactory):
557 submission_ids[0], get_submission_by_submission_key(keys[0]))556 submission_ids[0], get_submission_by_submission_key(keys[0]))
558 person_id = person.id557 person_id = person.id
559 account_id = person.account.id558 account_id = person.account.id
560 script = self.makeScript([six.ensure_str(person.name)])559 script = self.makeScript([person.name])
561 with dbuser('launchpad'):560 with dbuser('launchpad'):
562 self.runScript(script)561 self.runScript(script)
563 self.assertRemoved(account_id, person_id)562 self.assertRemoved(account_id, person_id)
@@ -584,7 +583,7 @@ class TestCloseAccount(TestCaseWithFactory):
584 MatchesStructure.byEquality(count=1, viewed_by=other_person)))583 MatchesStructure.byEquality(count=1, viewed_by=other_person)))
585 person_id = person.id584 person_id = person.id
586 account_id = person.account.id585 account_id = person.account.id
587 script = self.makeScript([six.ensure_str(person.name)])586 script = self.makeScript([person.name])
588 with dbuser('launchpad'):587 with dbuser('launchpad'):
589 self.runScript(script)588 self.runScript(script)
590 self.assertRemoved(account_id, person_id)589 self.assertRemoved(account_id, person_id)
@@ -620,7 +619,7 @@ class TestCloseAccount(TestCaseWithFactory):
620 MatchesStructure.byEquality(owner=other_person)))619 MatchesStructure.byEquality(owner=other_person)))
621 person_id = person.id620 person_id = person.id
622 account_id = person.account.id621 account_id = person.account.id
623 script = self.makeScript([six.ensure_str(person.name)])622 script = self.makeScript([person.name])
624 with dbuser('launchpad'):623 with dbuser('launchpad'):
625 self.runScript(script)624 self.runScript(script)
626 self.assertRemoved(account_id, person_id)625 self.assertRemoved(account_id, person_id)
@@ -634,7 +633,7 @@ class TestCloseAccount(TestCaseWithFactory):
634 product.active = False633 product.active = False
635 person_id = person.id634 person_id = person.id
636 account_id = person.account.id635 account_id = person.account.id
637 script = self.makeScript([six.ensure_str(person.name)])636 script = self.makeScript([person.name])
638 with dbuser('launchpad'):637 with dbuser('launchpad'):
639 self.runScript(script)638 self.runScript(script)
640 self.assertRemoved(account_id, person_id)639 self.assertRemoved(account_id, person_id)
@@ -652,7 +651,7 @@ class TestCloseAccount(TestCaseWithFactory):
652 TargetRevisionControlSystems.GIT)]651 TargetRevisionControlSystems.GIT)]
653 person_id = person.id652 person_id = person.id
654 account_id = person.account.id653 account_id = person.account.id
655 script = self.makeScript([six.ensure_str(person.name)])654 script = self.makeScript([person.name])
656 with dbuser('launchpad'):655 with dbuser('launchpad'):
657 self.runScript(script)656 self.runScript(script)
658 self.assertRemoved(account_id, person_id)657 self.assertRemoved(account_id, person_id)
@@ -680,7 +679,7 @@ class TestCloseAccount(TestCaseWithFactory):
680 result_status=CodeImportResultStatus.SUCCESS)679 result_status=CodeImportResultStatus.SUCCESS)
681 person_id = person.id680 person_id = person.id
682 account_id = person.account.id681 account_id = person.account.id
683 script = self.makeScript([six.ensure_str(person.name)])682 script = self.makeScript([person.name])
684 with dbuser('launchpad'):683 with dbuser('launchpad'):
685 self.runScript(script)684 self.runScript(script)
686 self.assertRemoved(account_id, person_id)685 self.assertRemoved(account_id, person_id)
@@ -708,7 +707,7 @@ class TestCloseAccount(TestCaseWithFactory):
708 removeSecurityProxy(ppa).owner = other_person707 removeSecurityProxy(ppa).owner = other_person
709 person_id = person.id708 person_id = person.id
710 account_id = person.account.id709 account_id = person.account.id
711 script = self.makeScript([six.ensure_str(person.name)])710 script = self.makeScript([person.name])
712 with dbuser('launchpad'):711 with dbuser('launchpad'):
713 self.runScript(script)712 self.runScript(script)
714 self.assertRemoved(account_id, person_id)713 self.assertRemoved(account_id, person_id)
@@ -719,7 +718,7 @@ class TestCloseAccount(TestCaseWithFactory):
719 person_id = person.id718 person_id = person.id
720 account_id = person.account.id719 account_id = person.account.id
721 specification = self.factory.makeSpecification(owner=person)720 specification = self.factory.makeSpecification(owner=person)
722 script = self.makeScript([six.ensure_str(person.name)])721 script = self.makeScript([person.name])
723 with dbuser('launchpad'):722 with dbuser('launchpad'):
724 self.runScript(script)723 self.runScript(script)
725 self.assertRemoved(account_id, person_id)724 self.assertRemoved(account_id, person_id)
@@ -738,7 +737,7 @@ class TestCloseAccount(TestCaseWithFactory):
738737
739 person_id = member.id738 person_id = member.id
740 account_id = member.account.id739 account_id = member.account.id
741 script = self.makeScript([six.ensure_str(member.name)])740 script = self.makeScript([member.name])
742 with dbuser('launchpad'):741 with dbuser('launchpad'):
743 self.runScript(script)742 self.runScript(script)
744 self.assertRemoved(account_id, person_id)743 self.assertRemoved(account_id, person_id)
@@ -751,7 +750,7 @@ class TestCloseAccount(TestCaseWithFactory):
751 owned_team2 = self.factory.makeTeam(name='target2', owner=person)750 owned_team2 = self.factory.makeTeam(name='target2', owner=person)
752 person_id = person.id751 person_id = person.id
753 account_id = person.account.id752 account_id = person.account.id
754 script = self.makeScript([six.ensure_str(person.name)])753 script = self.makeScript([person.name])
755754
756 # Closing account fails as the user still owns team2755 # Closing account fails as the user still owns team2
757 with dbuser('launchpad'):756 with dbuser('launchpad'):
@@ -776,7 +775,7 @@ class TestCloseAccount(TestCaseWithFactory):
776 self.assertEqual(token, login_token_set[plaintext_token])775 self.assertEqual(token, login_token_set[plaintext_token])
777 person_id = person.id776 person_id = person.id
778 account_id = person.account.id777 account_id = person.account.id
779 script = self.makeScript([six.ensure_str(person.name)])778 script = self.makeScript([person.name])
780 with dbuser('launchpad'):779 with dbuser('launchpad'):
781 self.runScript(script)780 self.runScript(script)
782 self.assertRemoved(account_id, person_id)781 self.assertRemoved(account_id, person_id)
@@ -794,7 +793,7 @@ class TestCloseAccount(TestCaseWithFactory):
794 [other_request_token], other_person.oauth_request_tokens)793 [other_request_token], other_person.oauth_request_tokens)
795 person_id = person.id794 person_id = person.id
796 account_id = person.account.id795 account_id = person.account.id
797 script = self.makeScript([six.ensure_str(person.name)])796 script = self.makeScript([person.name])
798 with dbuser('launchpad'):797 with dbuser('launchpad'):
799 self.runScript(script)798 self.runScript(script)
800 self.assertRemoved(account_id, person_id)799 self.assertRemoved(account_id, person_id)
@@ -813,7 +812,7 @@ class TestCloseAccount(TestCaseWithFactory):
813 [other_access_token], other_person.oauth_access_tokens)812 [other_access_token], other_person.oauth_access_tokens)
814 person_id = person.id813 person_id = person.id
815 account_id = person.account.id814 account_id = person.account.id
816 script = self.makeScript([six.ensure_str(person.name)])815 script = self.makeScript([person.name])
817 with dbuser('launchpad'):816 with dbuser('launchpad'):
818 self.runScript(script)817 self.runScript(script)
819 self.assertRemoved(account_id, person_id)818 self.assertRemoved(account_id, person_id)
@@ -828,7 +827,7 @@ class TestCloseAccount(TestCaseWithFactory):
828 ppa.setProcessors(procs)827 ppa.setProcessors(procs)
829 person_id = person.id828 person_id = person.id
830 account_id = person.account.id829 account_id = person.account.id
831 script = self.makeScript([six.ensure_str(person.name)])830 script = self.makeScript([person.name])
832 with dbuser('launchpad'):831 with dbuser('launchpad'):
833 self.assertRaisesWithContent(832 self.assertRaisesWithContent(
834 LaunchpadScriptFailure,833 LaunchpadScriptFailure,
@@ -851,7 +850,7 @@ class TestCloseAccount(TestCaseWithFactory):
851 DevNullLogger(), getPubConfig(ppa), None, ppa).deleteArchive()850 DevNullLogger(), getPubConfig(ppa), None, ppa).deleteArchive()
852 person_id = person.id851 person_id = person.id
853 account_id = person.account.id852 account_id = person.account.id
854 script = self.makeScript([six.ensure_str(person.name)])853 script = self.makeScript([person.name])
855 with dbuser('launchpad'):854 with dbuser('launchpad'):
856 self.assertRaisesWithContent(855 self.assertRaisesWithContent(
857 LaunchpadScriptFailure,856 LaunchpadScriptFailure,
@@ -873,7 +872,7 @@ class TestCloseAccount(TestCaseWithFactory):
873 store = Store.of(ppa)872 store = Store.of(ppa)
874 person_id = person.id873 person_id = person.id
875 account_id = person.account.id874 account_id = person.account.id
876 script = self.makeScript([six.ensure_str(person.name)])875 script = self.makeScript([person.name])
877 with dbuser('launchpad'):876 with dbuser('launchpad'):
878 self.runScript(script)877 self.runScript(script)
879 self.assertRemoved(account_id, person_id)878 self.assertRemoved(account_id, person_id)
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 1b81c27..d9c465e 100644
--- a/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt
+++ b/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt
@@ -111,7 +111,7 @@ Import the secret keys needed for this test:
111access the current IGpghandler instance to access this key and decrypt the111access the current IGpghandler instance to access this key and decrypt the
112message.112message.
113113
114 >>> body = decrypt_content(cipher_body, six.ensure_str('test'))114 >>> body = decrypt_content(cipher_body, 'test')
115115
116Extract the token URL from the email:116Extract the token URL from the email:
117117
@@ -514,7 +514,7 @@ Get the token from the body of the email sent.
514 >>> from_addr, to_addrs, raw_msg = stub.test_emails.pop()514 >>> from_addr, to_addrs, raw_msg = stub.test_emails.pop()
515 >>> msg = email.message_from_bytes(raw_msg)515 >>> msg = email.message_from_bytes(raw_msg)
516 >>> cipher_body = msg.get_payload(decode=1)516 >>> cipher_body = msg.get_payload(decode=1)
517 >>> body = decrypt_content(cipher_body, six.ensure_str('test'))517 >>> body = decrypt_content(cipher_body, 'test')
518 >>> link = get_token_url_from_bytes(body)518 >>> link = get_token_url_from_bytes(body)
519 >>> token = re.sub(r'.*token/', '', link)519 >>> token = re.sub(r'.*token/', '', link)
520 >>> token_url = 'http://launchpad.test/token/%s' % token520 >>> token_url = 'http://launchpad.test/token/%s' % token
diff --git a/lib/lp/services/database/doc/enumcol.txt b/lib/lp/services/database/doc/enumcol.txt
index 4685182..9cb728b 100644
--- a/lib/lp/services/database/doc/enumcol.txt
+++ b/lib/lp/services/database/doc/enumcol.txt
@@ -85,7 +85,7 @@ You cannot use integers or strings as DBEnum values:
85 ...85 ...
86 TypeError: Not a DBItem: 286 TypeError: Not a DBItem: 2
8787
88 >>> t.foo = six.ensure_str("TWO")88 >>> t.foo = "TWO"
89 Traceback (most recent call last):89 Traceback (most recent call last):
90 ...90 ...
91 TypeError: Not a DBItem: 'TWO'91 TypeError: Not a DBItem: 'TWO'
diff --git a/lib/lp/services/database/doc/textsearching.txt b/lib/lp/services/database/doc/textsearching.txt
index 6aa25a7..5ced23b 100644
--- a/lib/lp/services/database/doc/textsearching.txt
+++ b/lib/lp/services/database/doc/textsearching.txt
@@ -121,7 +121,7 @@ The following examples show the text version of the query using
121 ... "SELECT to_tsvector(%s) @@ ftq(%s)",121 ... "SELECT to_tsvector(%s) @@ ftq(%s)",
122 ... (text_to_search, search_phrase))122 ... (text_to_search, search_phrase))
123 ... match = result.get_all()[0][0]123 ... match = result.get_all()[0][0]
124 ... return six.ensure_str("FTI data: %s query: %s match: %s") % (124 ... return "FTI data: %s query: %s match: %s" % (
125 ... ts_vector, ts_query, str(match))125 ... ts_vector, ts_query, str(match))
126 >>>126 >>>
127 >>> def search_same(text):127 >>> def search_same(text):
@@ -248,7 +248,7 @@ Punctuation is handled consistently. If a string containing punctuation
248appears in an FTI, it can also be passed to ftq(),and a search for this248appears in an FTI, it can also be passed to ftq(),and a search for this
249string finds the indexed text.249string finds the indexed text.
250250
251 >>> punctuation = six.ensure_str('\'"#$%*+,./:;<=>?@[\]^`{}~')251 >>> punctuation = '\'"#$%*+,./:;<=>?@[\]^`{}~'
252 >>> for symbol in punctuation:252 >>> for symbol in punctuation:
253 ... print(repr(symbol), search_same('foo%sbar' % symbol))253 ... print(repr(symbol), search_same('foo%sbar' % symbol))
254 "'" FTI data: 'bar':2 'foo':1 query: 'foo' & 'bar' match: True254 "'" FTI data: 'bar':2 'foo':1 query: 'foo' & 'bar' match: True
diff --git a/lib/lp/services/doc/limitedlist.txt b/lib/lp/services/doc/limitedlist.txt
index e8bdf08..10f1fed 100644
--- a/lib/lp/services/doc/limitedlist.txt
+++ b/lib/lp/services/doc/limitedlist.txt
@@ -22,7 +22,7 @@ We can optionally specify the initial content of the sequence. Note that
22only the last N elements of the second parameter are stored, where N is22only the last N elements of the second parameter are stored, where N is
23the given maximum size of the LimitedList.23the given maximum size of the LimitedList.
2424
25 >>> LimitedList(3, (0, six.ensure_str('one'), 2, 3))25 >>> LimitedList(3, (0, 'one', 2, 3))
26 <LimitedList(3, ['one', 2, 3])>26 <LimitedList(3, ['one', 2, 3])>
2727
28If the initial content has more elements than the given maximum length,28If the initial content has more elements than the given maximum length,
diff --git a/lib/lp/services/gpg/doc/gpg-encryption.txt b/lib/lp/services/gpg/doc/gpg-encryption.txt
index b1a1b0c..21da208 100644
--- a/lib/lp/services/gpg/doc/gpg-encryption.txt
+++ b/lib/lp/services/gpg/doc/gpg-encryption.txt
@@ -57,7 +57,7 @@ cipher constains the encrypted content.
57Storing the raw password may compromise the security, but is the57Storing the raw password may compromise the security, but is the
58only way we can decrypt the cipher content.58only way we can decrypt the cipher content.
5959
60 >>> password = six.ensure_str('test')60 >>> password = 'test'
61 >>> plain = decrypt_content(cipher, password)61 >>> plain = decrypt_content(cipher, password)
6262
63voilá, the same content shows up again.63voilá, the same content shows up again.
@@ -69,7 +69,7 @@ Verify if the encrytion process support passing another charset string
6969
70 >>> content = u'a\xe7ucar'70 >>> content = u'a\xe7ucar'
71 >>> cipher = gpghandler.encryptContent(content.encode('iso-8859-1'), key)71 >>> cipher = gpghandler.encryptContent(content.encode('iso-8859-1'), key)
72 >>> plain = decrypt_content(cipher, six.ensure_str('test'))72 >>> plain = decrypt_content(cipher, 'test')
73 >>> print(backslashreplace(plain.decode('iso-8859-1')))73 >>> print(backslashreplace(plain.decode('iso-8859-1')))
74 a\xe7ucar74 a\xe7ucar
7575
@@ -85,7 +85,7 @@ Decrypt a unicode content:
85 >>> content = u'a\xe7ucar'85 >>> content = u'a\xe7ucar'
86 >>> cipher = gpghandler.encryptContent(content.encode('iso-8859-1'), key)86 >>> cipher = gpghandler.encryptContent(content.encode('iso-8859-1'), key)
87 >>> cipher = six.ensure_text(cipher)87 >>> cipher = six.ensure_text(cipher)
88 >>> plain = decrypt_content(cipher, six.ensure_str('test'))88 >>> plain = decrypt_content(cipher, 'test')
89 Traceback (most recent call last):89 Traceback (most recent call last):
90 ...90 ...
91 TypeError: Content must be bytes.91 TypeError: Content must be bytes.
@@ -113,7 +113,7 @@ What about a message encrypted for an unknown key.
113 ... =LQK5113 ... =LQK5
114 ... -----END PGP MESSAGE-----114 ... -----END PGP MESSAGE-----
115 ... """115 ... """
116 >>> plain = decrypt_content(cipher, six.ensure_str('test'))116 >>> plain = decrypt_content(cipher, 'test')
117 >>> plain is None117 >>> plain is None
118 True118 True
119119
diff --git a/lib/lp/services/gpg/handler.py b/lib/lp/services/gpg/handler.py
index bad85f1..005ca79 100644
--- a/lib/lp/services/gpg/handler.py
+++ b/lib/lp/services/gpg/handler.py
@@ -341,8 +341,7 @@ class GPGHandler:
341 # See more information at:341 # See more information at:
342 # http://pyme.sourceforge.net/doc/gpgme/Generating-Keys.html342 # http://pyme.sourceforge.net/doc/gpgme/Generating-Keys.html
343 with gpgme_timeline("genkey", name):343 with gpgme_timeline("genkey", name):
344 result = context.genkey(344 result = context.genkey(signing_only_param % {'name': name})
345 six.ensure_str(signing_only_param % {'name': name}))
346345
347 # Right, it might seem paranoid to have this many assertions,346 # Right, it might seem paranoid to have this many assertions,
348 # but we have to take key generation very seriously.347 # but we have to take key generation very seriously.
diff --git a/lib/lp/services/gpg/tests/test_gpghandler.py b/lib/lp/services/gpg/tests/test_gpghandler.py
index 6dba52c..4072646 100644
--- a/lib/lp/services/gpg/tests/test_gpghandler.py
+++ b/lib/lp/services/gpg/tests/test_gpghandler.py
@@ -77,9 +77,9 @@ class FakeGenerateKey(Fixture):
77 self.secret_key)77 self.secret_key)
7878
79 # Fail if the key generation parameters aren't what we expect.79 # Fail if the key generation parameters aren't what we expect.
80 expected_params = six.ensure_str(signing_only_param % {80 expected_params = signing_only_param % {
81 "name": imported_key.uids[0].name,81 "name": imported_key.uids[0].name,
82 })82 }
83 if params != expected_params:83 if params != expected_params:
84 raise ValueError(84 raise ValueError(
85 "Got params %r, expected %r" % (params, expected_params))85 "Got params %r, expected %r" % (params, expected_params))
diff --git a/lib/lp/services/librarian/model.py b/lib/lp/services/librarian/model.py
index 10a387e..6b0ea19 100644
--- a/lib/lp/services/librarian/model.py
+++ b/lib/lp/services/librarian/model.py
@@ -15,7 +15,6 @@ import hashlib
1515
16from lazr.delegates import delegate_to16from lazr.delegates import delegate_to
17import pytz17import pytz
18import six
19from six.moves.urllib.parse import urlparse18from six.moves.urllib.parse import urlparse
20from storm.locals import (19from storm.locals import (
21 Date,20 Date,
@@ -358,7 +357,7 @@ class TimeLimitedToken(StormBase):
358 # allocation the external librarian must be able to serve the file357 # allocation the external librarian must be able to serve the file
359 # immediately.358 # immediately.
360 store.commit()359 store.commit()
361 return six.ensure_str(token)360 return token
362361
363 @staticmethod362 @staticmethod
364 def url_to_token_path(url):363 def url_to_token_path(url):
diff --git a/lib/lp/services/mail/doc/notification-recipient-set.txt b/lib/lp/services/mail/doc/notification-recipient-set.txt
index d06e7c4..6ed6b2c 100644
--- a/lib/lp/services/mail/doc/notification-recipient-set.txt
+++ b/lib/lp/services/mail/doc/notification-recipient-set.txt
@@ -120,7 +120,7 @@ UnknownRecipientError:
120 ...120 ...
121 lp.services.mail.interfaces.UnknownRecipientError: ...121 lp.services.mail.interfaces.UnknownRecipientError: ...
122122
123 >>> recipients.getReason(six.ensure_str('no-priv@canonical.com'))123 >>> recipients.getReason('no-priv@canonical.com')
124 Traceback (most recent call last):124 Traceback (most recent call last):
125 ...125 ...
126 lp.services.mail.interfaces.UnknownRecipientError: 'no-priv@canonical.com'126 lp.services.mail.interfaces.UnknownRecipientError: 'no-priv@canonical.com'
diff --git a/lib/lp/services/webapp/breadcrumb.py b/lib/lp/services/webapp/breadcrumb.py
index 1281fe2..eae2074 100644
--- a/lib/lp/services/webapp/breadcrumb.py
+++ b/lib/lp/services/webapp/breadcrumb.py
@@ -10,7 +10,6 @@ __all__ = [
10 'TitleBreadcrumb',10 'TitleBreadcrumb',
11 ]11 ]
1212
13import six
14from zope.interface import implementer13from zope.interface import implementer
1514
16from lp.services.webapp import canonical_url15from lp.services.webapp import canonical_url
@@ -77,12 +76,8 @@ class Breadcrumb:
77 return self._detail or self.text76 return self._detail or self.text
7877
79 def __repr__(self):78 def __repr__(self):
80 # XXX: salgado, 2009-10-14, http://bugs.python.org/issue5876: In
81 # python 2.5-2.7, the return value of __repr__() may be forced into a
82 # type(str), so we can't include unicode here.
83 text = six.ensure_str(self.text, 'raw-unicode-escape')
84 return "<%s url='%s' text='%s'>" % (79 return "<%s url='%s' text='%s'>" % (
85 self.__class__.__name__, self.url, text)80 self.__class__.__name__, self.url, self.text)
8681
8782
88class NameBreadcrumb(Breadcrumb):83class NameBreadcrumb(Breadcrumb):
diff --git a/lib/lp/services/webapp/doc/canonical_url.txt b/lib/lp/services/webapp/doc/canonical_url.txt
index 90d4df5..60f824a 100644
--- a/lib/lp/services/webapp/doc/canonical_url.txt
+++ b/lib/lp/services/webapp/doc/canonical_url.txt
@@ -18,8 +18,7 @@ will put in a temporary module.
18 >>> from lp.services.webapp.interfaces import ICanonicalUrlData18 >>> from lp.services.webapp.interfaces import ICanonicalUrlData
19 >>> from zope.interface import Interface, Attribute, implementer19 >>> from zope.interface import Interface, Attribute, implementer
2020
21 >>> module = types.ModuleType(21 >>> module = types.ModuleType(factory.getUniqueString().replace('-', '_'))
22 ... six.ensure_str(factory.getUniqueString().replace('-', '_')))
23 >>> sys.modules[module.__name__] = module22 >>> sys.modules[module.__name__] = module
2423
25 >>> class ICountrySet(Interface):24 >>> class ICountrySet(Interface):
diff --git a/lib/lp/services/webapp/doc/menus.txt b/lib/lp/services/webapp/doc/menus.txt
index c1cf9b4..7f910c8 100644
--- a/lib/lp/services/webapp/doc/menus.txt
+++ b/lib/lp/services/webapp/doc/menus.txt
@@ -561,8 +561,7 @@ First, we define a couple of interfaces, and put them in a temporary module.
561 >>> import sys561 >>> import sys
562 >>> import types562 >>> import types
563563
564 >>> module = types.ModuleType(564 >>> module = types.ModuleType(factory.getUniqueString().replace('-', '_'))
565 ... six.ensure_str(factory.getUniqueString().replace('-', '_')))
566 >>> sys.modules[module.__name__] = module565 >>> sys.modules[module.__name__] = module
567566
568 >>> class IThingHavingFacets(Interface):567 >>> class IThingHavingFacets(Interface):
diff --git a/lib/lp/services/webapp/doc/test_adapter.txt b/lib/lp/services/webapp/doc/test_adapter.txt
index abe5036..04378eb 100644
--- a/lib/lp/services/webapp/doc/test_adapter.txt
+++ b/lib/lp/services/webapp/doc/test_adapter.txt
@@ -211,7 +211,7 @@ timeout by sleeping for 200ms with a 100ms statement timeout:
211 >>> set_request_started()211 >>> set_request_started()
212 >>> print(current_statement_timeout(store))212 >>> print(current_statement_timeout(store))
213 100ms213 100ms
214 >>> store.execute(six.ensure_str('SELECT pg_sleep(0.200)'), noresult=True)214 >>> store.execute('SELECT pg_sleep(0.200)', noresult=True)
215 Traceback (most recent call last):215 Traceback (most recent call last):
216 ...216 ...
217 lp.services.webapp.adapter.LaunchpadTimeoutError:217 lp.services.webapp.adapter.LaunchpadTimeoutError:
@@ -285,7 +285,7 @@ issuing the SQL command as we have exceeded the precision period:
285This final invokation, we will actually sleep to ensure that the285This final invokation, we will actually sleep to ensure that the
286timeout being reported by PostgreSQL is actually working:286timeout being reported by PostgreSQL is actually working:
287287
288 >>> store.execute(six.ensure_str('SELECT pg_sleep(0.2)'), noresult=True)288 >>> store.execute('SELECT pg_sleep(0.2)', noresult=True)
289 Traceback (most recent call last):289 Traceback (most recent call last):
290 ...290 ...
291 lp.services.webapp.adapter.LaunchpadTimeoutError:291 lp.services.webapp.adapter.LaunchpadTimeoutError:
diff --git a/lib/lp/services/webapp/publication.py b/lib/lp/services/webapp/publication.py
index 80effc1..37cd383 100644
--- a/lib/lp/services/webapp/publication.py
+++ b/lib/lp/services/webapp/publication.py
@@ -17,7 +17,6 @@ from lazr.uri import (
17 URI,17 URI,
18 )18 )
19from psycopg2.extensions import TransactionRollbackError19from psycopg2.extensions import TransactionRollbackError
20import six
21from six.moves.urllib.parse import quote20from six.moves.urllib.parse import quote
22from storm.database import STATE_DISCONNECTED21from storm.database import STATE_DISCONNECTED
23from storm.exceptions import (22from storm.exceptions import (
@@ -422,10 +421,7 @@ class LaunchpadBrowserPublication(
422 return self.constructPageID(context, context.context, names)421 return self.constructPageID(context, context.context, names)
423 view_names = ':'.join(names)422 view_names = ':'.join(names)
424 pageid = '%s:%s' % (context_name, view_names)423 pageid = '%s:%s' % (context_name, view_names)
425 # The view name used in the pageid usually comes from ZCML and so it424 return pageid
426 # will be a Unicode string, but we want a native string. On Python
427 # 2, to avoid problems we encode it into ASCII.
428 return six.ensure_str(pageid, 'US-ASCII')
429425
430 def callObject(self, request, ob):426 def callObject(self, request, ob):
431 """See `zope.publisher.interfaces.IPublication`.427 """See `zope.publisher.interfaces.IPublication`.
diff --git a/lib/lp/services/webapp/publisher.py b/lib/lp/services/webapp/publisher.py
index c0f00aa..2f5960d 100644
--- a/lib/lp/services/webapp/publisher.py
+++ b/lib/lp/services/webapp/publisher.py
@@ -504,8 +504,7 @@ class LaunchpadView(UserAttributeCache):
504 """See IBrowserPublisher."""504 """See IBrowserPublisher."""
505 # By default, a LaunchpadView cannot be traversed through.505 # By default, a LaunchpadView cannot be traversed through.
506 # Those that can be must override this method.506 # Those that can be must override this method.
507 raise NotFound(507 raise NotFound(self, name, request=request)
508 self, six.ensure_str(name, errors='replace'), request=request)
509508
510 @property509 @property
511 def recommended_canonical_url(self):510 def recommended_canonical_url(self):
@@ -964,8 +963,7 @@ class Navigation:
964 """963 """
965 # Avoid circular imports.964 # Avoid circular imports.
966 if nextobj is None:965 if nextobj is None:
967 raise NotFound(966 raise NotFound(self.context, name)
968 self.context, six.ensure_str(name, errors='replace'))
969 elif isinstance(nextobj, redirection):967 elif isinstance(nextobj, redirection):
970 return RedirectionView(968 return RedirectionView(
971 nextobj.name, request, status=nextobj.status)969 nextobj.name, request, status=nextobj.status)
@@ -1185,7 +1183,7 @@ class RenamedView:
11851183
1186 def publishTraverse(self, request, name):1184 def publishTraverse(self, request, name):
1187 """See zope.publisher.interfaces.browser.IBrowserPublisher."""1185 """See zope.publisher.interfaces.browser.IBrowserPublisher."""
1188 raise NotFound(self.context, six.ensure_str(name, errors='replace'))1186 raise NotFound(self.context, name)
11891187
1190 def browserDefault(self, request):1188 def browserDefault(self, request):
1191 """See zope.publisher.interfaces.browser.IBrowserPublisher."""1189 """See zope.publisher.interfaces.browser.IBrowserPublisher."""
diff --git a/lib/lp/services/webapp/servers.py b/lib/lp/services/webapp/servers.py
index 32ebf7f..e644e05 100644
--- a/lib/lp/services/webapp/servers.py
+++ b/lib/lp/services/webapp/servers.py
@@ -870,9 +870,7 @@ class LaunchpadBrowserResponse(NotificationResponse, BrowserResponse):
870 status = 307870 status = 307
871 else:871 else:
872 status = 303872 status = 303
873 super().redirect(873 super().redirect(str(location), status=status, trusted=trusted)
874 six.ensure_str(str(location)),
875 status=status, trusted=trusted)
876874
877875
878def adaptResponseToSession(response):876def adaptResponseToSession(response):
diff --git a/lib/lp/services/webservice/doc/launchpadlib.txt b/lib/lp/services/webservice/doc/launchpadlib.txt
index 25d2e0b..20288ba 100644
--- a/lib/lp/services/webservice/doc/launchpadlib.txt
+++ b/lib/lp/services/webservice/doc/launchpadlib.txt
@@ -5,9 +5,7 @@ Just to show that we're actually talking to the appserver, first check to see
5if a specific user exists...5if a specific user exists...
66
7 >>> browser = Browser()7 >>> browser = Browser()
8 >>> browser.addHeader(8 >>> browser.addHeader('Authorization', 'Basic foo.bar@canonical.com:test')
9 ... 'Authorization',
10 ... six.ensure_str('Basic foo.bar@canonical.com:test'))
11 >>> from lp.testing.layers import BaseLayer9 >>> from lp.testing.layers import BaseLayer
12 >>> root_url = BaseLayer.appserver_root_url()10 >>> root_url = BaseLayer.appserver_root_url()
13 >>> browser.open(root_url)11 >>> browser.open(root_url)
diff --git a/lib/lp/soyuz/scripts/gina/packages.py b/lib/lp/soyuz/scripts/gina/packages.py
index e8b6dae..15b4a45 100644
--- a/lib/lp/soyuz/scripts/gina/packages.py
+++ b/lib/lp/soyuz/scripts/gina/packages.py
@@ -110,9 +110,7 @@ def unpack_dsc(package, version, component, distro_name, archive_root):
110 extract_dpkg_source(dsc_path, ".", vendor=distro_name)110 extract_dpkg_source(dsc_path, ".", vendor=distro_name)
111 except DpkgSourceError as e:111 except DpkgSourceError as e:
112 if os.path.isdir(source_dir):112 if os.path.isdir(source_dir):
113 # Coerce to str to avoid https://bugs.python.org/issue24672 on113 shutil.rmtree(source_dir)
114 # Python 2.
115 shutil.rmtree(six.ensure_str(source_dir))
116 raise ExecutionError("Error %d unpacking source" % e.result)114 raise ExecutionError("Error %d unpacking source" % e.result)
117115
118 return source_dir, dsc_path116 return source_dir, dsc_path
@@ -149,9 +147,7 @@ def read_dsc(package, version, component, distro_name, archive_root):
149 "No copyright file found for %s in %s" % (package, source_dir))147 "No copyright file found for %s in %s" % (package, source_dir))
150 copyright = b''148 copyright = b''
151 finally:149 finally:
152 # Coerce to str to avoid https://bugs.python.org/issue24672 on150 shutil.rmtree(source_dir)
153 # Python 2.
154 shutil.rmtree(six.ensure_str(source_dir))
155151
156 return dsc, changelog, copyright152 return dsc, changelog, copyright
157153
diff --git a/lib/lp/soyuz/scripts/ppareport.py b/lib/lp/soyuz/scripts/ppareport.py
index c9e106c..e93c85a 100644
--- a/lib/lp/soyuz/scripts/ppareport.py
+++ b/lib/lp/soyuz/scripts/ppareport.py
@@ -15,7 +15,6 @@ import operator
15import os15import os
16import sys16import sys
1717
18import six
19from storm.locals import Join18from storm.locals import Join
20from storm.store import Store19from storm.store import Store
21from zope.component import getUtility20from zope.component import getUtility
@@ -175,7 +174,7 @@ class PPAReportScript(LaunchpadScript):
175 if size <= (threshold * limit):174 if size <= (threshold * limit):
176 continue175 continue
177 line = "%s | %d | %d\n" % (canonical_url(ppa), limit, size)176 line = "%s | %d | %d\n" % (canonical_url(ppa), limit, size)
178 self.output.write(six.ensure_str(line))177 self.output.write(line)
179 self.output.write('\n')178 self.output.write('\n')
180179
181 def reportUserEmails(self):180 def reportUserEmails(self):
@@ -188,7 +187,7 @@ class PPAReportScript(LaunchpadScript):
188 for user in sorted_people_to_email:187 for user in sorted_people_to_email:
189 line = "%s | %s | %s\n" % (188 line = "%s | %s | %s\n" % (
190 user.name, user.displayname, user.preferredemail.email)189 user.name, user.displayname, user.preferredemail.email)
191 self.output.write(six.ensure_str(line))190 self.output.write(line)
192 self.output.write('\n')191 self.output.write('\n')
193192
194 @cachedproperty193 @cachedproperty
diff --git a/lib/lp/soyuz/stories/soyuz/xx-builds-pages.txt b/lib/lp/soyuz/stories/soyuz/xx-builds-pages.txt
index 6b1ab8c..4c49953 100644
--- a/lib/lp/soyuz/stories/soyuz/xx-builds-pages.txt
+++ b/lib/lp/soyuz/stories/soyuz/xx-builds-pages.txt
@@ -21,8 +21,7 @@ according to the selected buildstate, by default All.
21 ... provide only part of the required arguments to enable filter by21 ... provide only part of the required arguments to enable filter by
22 ... name.22 ... name.
23 ... """23 ... """
24 ... assert six.ensure_str(24 ... assert '<input type="submit" value="Filter" />' in contents
25 ... '<input type="submit" value="Filter" />') in contents
26 ...25 ...
27 ... field_state = find_tag_by_id(contents, 'build_state') is not None26 ... field_state = find_tag_by_id(contents, 'build_state') is not None
28 ... field_name = find_tag_by_id(contents, 'build_text') is not None27 ... field_name = find_tag_by_id(contents, 'build_text') is not None
diff --git a/lib/lp/translations/model/pomsgid.py b/lib/lp/translations/model/pomsgid.py
index 85bcd87..5f38c08 100644
--- a/lib/lp/translations/model/pomsgid.py
+++ b/lib/lp/translations/model/pomsgid.py
@@ -50,5 +50,5 @@ class POMsgID(StormBase):
50 Func('sha1', POMsgID.msgid) ==50 Func('sha1', POMsgID.msgid) ==
51 Func('sha1', six.ensure_text(key))).one()51 Func('sha1', six.ensure_text(key))).one()
52 if r is None:52 if r is None:
53 raise NotFoundError(six.ensure_str(key, errors='replace'))53 raise NotFoundError(key)
54 return r54 return r
diff --git a/lib/lp/translations/model/potranslation.py b/lib/lp/translations/model/potranslation.py
index b342098..9c01c45 100644
--- a/lib/lp/translations/model/potranslation.py
+++ b/lib/lp/translations/model/potranslation.py
@@ -51,7 +51,7 @@ class POTranslation(StormBase):
51 if r is not None:51 if r is not None:
52 return r52 return r
53 else:53 else:
54 raise NotFoundError(six.ensure_str(key, errors='replace'))54 raise NotFoundError(key)
5555
56 @classmethod56 @classmethod
57 def getOrCreateTranslation(cls, key):57 def getOrCreateTranslation(cls, key):
diff --git a/lib/lp/translations/stories/standalone/xx-language.txt b/lib/lp/translations/stories/standalone/xx-language.txt
index 438f687..0476573 100644
--- a/lib/lp/translations/stories/standalone/xx-language.txt
+++ b/lib/lp/translations/stories/standalone/xx-language.txt
@@ -274,9 +274,8 @@ Changing values to correct content works:
274 >>> admin_browser.getControl('ISO 639').value = 'bars'274 >>> admin_browser.getControl('ISO 639').value = 'bars'
275 >>> admin_browser.getControl('English name').value = 'Changed field'275 >>> admin_browser.getControl('English name').value = 'Changed field'
276 >>> spokenin_control = admin_browser.getControl(name='field.countries')276 >>> spokenin_control = admin_browser.getControl(name='field.countries')
277 >>> spokenin_control.getControl(277 >>> spokenin_control.getControl('Argentina').selected = False
278 ... six.ensure_str('Argentina')).selected = False278 >>> spokenin_control.getControl('France').selected = True
279 >>> spokenin_control.getControl(six.ensure_str('France')).selected = True
280 >>> admin_browser.getControl('Admin Language').click()279 >>> admin_browser.getControl('Admin Language').click()
281 >>> print(admin_browser.url)280 >>> print(admin_browser.url)
282 http://translations.launchpad.test/+languages/bars281 http://translations.launchpad.test/+languages/bars
diff --git a/lib/lp/translations/stories/standalone/xx-translationmessage-translate.txt b/lib/lp/translations/stories/standalone/xx-translationmessage-translate.txt
index c049b94..804cd1c 100644
--- a/lib/lp/translations/stories/standalone/xx-translationmessage-translate.txt
+++ b/lib/lp/translations/stories/standalone/xx-translationmessage-translate.txt
@@ -331,7 +331,7 @@ Now, we will check suggestions in this form.
331331
332Check that suggestions come in from other contexts:332Check that suggestions come in from other contexts:
333333
334 >>> six.ensure_str("Suggested in") in browser.contents334 >>> "Suggested in" in browser.contents
335 True335 True
336336
337 >>> find_tag_by_id(browser.contents, 'msgset_143_es_suggestion_697_0')337 >>> find_tag_by_id(browser.contents, 'msgset_143_es_suggestion_697_0')
@@ -340,16 +340,15 @@ Check that suggestions come in from other contexts:
340Check that no other suggestions are presented (since no others are340Check that no other suggestions are presented (since no others are
341relevant for this message):341relevant for this message):
342342
343 >>> six.ensure_str("Suggested by") in browser.contents343 >>> "Suggested by" in browser.contents
344 False344 False
345345
346 >>> six.ensure_str("Used in") in browser.contents346 >>> "Used in" in browser.contents
347 False347 False
348348
349Check for the translator note:349Check for the translator note:
350350
351 >>> note = six.ensure_str(351 >>> note = "This is an example of commenttext for a multiline"
352 ... "This is an example of commenttext for a multiline")
353 >>> note in browser.contents352 >>> note in browser.contents
354 True353 True
355354
@@ -410,7 +409,7 @@ And submit it.
410Now, we check that the translation we are going to add is not yet in the409Now, we check that the translation we are going to add is not yet in the
411form, so we can check later that it's added as a suggestion:410form, so we can check later that it's added as a suggestion:
412411
413 >>> six.ensure_str('foo!!') in fast_submission.contents412 >>> 'foo!!' in fast_submission.contents
414 False413 False
415414
416Now, we update the translation in slow_submission.415Now, we update the translation in slow_submission.
diff --git a/lib/lp/translations/stories/translations/xx-translations.txt b/lib/lp/translations/stories/translations/xx-translations.txt
index 9c26cb1..ee8309a 100644
--- a/lib/lp/translations/stories/translations/xx-translations.txt
+++ b/lib/lp/translations/stories/translations/xx-translations.txt
@@ -94,7 +94,7 @@ page, and that it has all the data we are expecting, in terms of languages.
94 >>> from lp.testing.pages import extract_url_parameter94 >>> from lp.testing.pages import extract_url_parameter
95 >>> browser.open('http://translations.launchpad.test/ubuntu/hoary/'95 >>> browser.open('http://translations.launchpad.test/ubuntu/hoary/'
96 ... '+translations')96 ... '+translations')
97 >>> six.ensure_str('Translation status by language') in browser.contents97 >>> 'Translation status by language' in browser.contents
98 True98 True
99 >>> print(browser.getLink('Catalan').url)99 >>> print(browser.getLink('Catalan').url)
100 http://translations.launchpad.test/ubuntu/hoary/+lang/ca100 http://translations.launchpad.test/ubuntu/hoary/+lang/ca
@@ -113,7 +113,7 @@ put Afrihili into the list of "preferred languages".
113 >>> browser.addHeader('Accept-Language', 'en-us,en;q=0.7,afh;q=0.3')113 >>> browser.addHeader('Accept-Language', 'en-us,en;q=0.7,afh;q=0.3')
114 >>> browser.open('http://translations.launchpad.test/ubuntu/hoary/'114 >>> browser.open('http://translations.launchpad.test/ubuntu/hoary/'
115 ... '+translations')115 ... '+translations')
116 >>> six.ensure_str('Translation status by language') in browser.contents116 >>> 'Translation status by language' in browser.contents
117 True117 True
118 >>> print(browser.getLink('Catalan').url)118 >>> print(browser.getLink('Catalan').url)
119 http://translations.launchpad.test/ubuntu/hoary/+lang/ca119 http://translations.launchpad.test/ubuntu/hoary/+lang/ca
@@ -130,9 +130,9 @@ pofile) for evolution-2.2
130 >>> browser.open(130 >>> browser.open(
131 ... 'http://translations.launchpad.test/ubuntu/hoary/+lang/hr'131 ... 'http://translations.launchpad.test/ubuntu/hoary/+lang/hr'
132 ... '?batch=2')132 ... '?batch=2')
133 >>> six.ensure_str('Croatian') in browser.contents133 >>> 'Croatian' in browser.contents
134 True134 True
135 >>> six.ensure_str('Translatable templates') in browser.contents135 >>> 'Translatable templates' in browser.contents
136 True136 True
137 >>> print(browser.getLink('evolution-2.2').url) # noqa137 >>> print(browser.getLink('evolution-2.2').url) # noqa
138 http://translations.launchpad.test/ubuntu/hoary/+source/evolution/+pots/evolution-2.2/hr/+translate138 http://translations.launchpad.test/ubuntu/hoary/+source/evolution/+pots/evolution-2.2/hr/+translate
@@ -173,7 +173,7 @@ And finally, we will get pmount.
173173
174With its latest translator.174With its latest translator.
175175
176 >>> six.ensure_str('Edgar Bursic') in browser.contents176 >>> 'Edgar Bursic' in browser.contents
177 True177 True
178178
179Last translator179Last translator
@@ -213,7 +213,7 @@ file):
213 batch=10213 batch=10
214 >>> print(extract_url_parameter(browser.url, 'show'))214 >>> print(extract_url_parameter(browser.url, 'show'))
215 show=untranslated215 show=untranslated
216 >>> six.ensure_str('10.') in browser.contents216 >>> '10.' in browser.contents
217 True217 True
218218
219If everything works out ok, that means that DummyPOFile has actually219If everything works out ok, that means that DummyPOFile has actually
@@ -225,9 +225,7 @@ Finally, lets also check that translated entries show up as well.
225 >>> browser.getControl('Change').click()225 >>> browser.getControl('Change').click()
226 >>> print(extract_url_parameter(browser.url, 'show'))226 >>> print(extract_url_parameter(browser.url, 'show'))
227 show=translated227 show=translated
228 >>> six.ensure_str(228 >>> "There are no messages that match this filtering." in browser.contents
229 ... "There are no messages that match this filtering.") in (
230 ... browser.contents)
231 True229 True
232230
233Links to filtered pages231Links to filtered pages
@@ -386,20 +384,20 @@ should see Catalan in the list.
386 >>> browser.open(384 >>> browser.open(
387 ... 'http://translations.launchpad.test/ubuntu/hoary/+source/'385 ... 'http://translations.launchpad.test/ubuntu/hoary/+source/'
388 ... 'evolution/+translations')386 ... 'evolution/+translations')
389 >>> six.ensure_str('Catalan') in browser.contents387 >>> 'Catalan' in browser.contents
390 True388 True
391389
392But also, he doesn't want to see other languages in the list. So, he390But also, he doesn't want to see other languages in the list. So, he
393shouldn't see eg. Japanese.391shouldn't see eg. Japanese.
394392
395 >>> six.ensure_str('Japanese') in browser.contents393 >>> 'Japanese' in browser.contents
396 False394 False
397395
398Next, if he chooses to view all the languages, he should see Japanese396Next, if he chooses to view all the languages, he should see Japanese
399among the languages on the page.397among the languages on the page.
400398
401 >>> browser.getLink('View template & all languages...').click()399 >>> browser.getLink('View template & all languages...').click()
402 >>> six.ensure_str('Japanese') in browser.contents400 >>> 'Japanese' in browser.contents
403 True401 True
404402
405So, everything is fine, and Carlos can sleep calmly.403So, everything is fine, and Carlos can sleep calmly.
diff --git a/scripts/list-team-members b/scripts/list-team-members
index 507d590..b7a7e61 100755
--- a/scripts/list-team-members
+++ b/scripts/list-team-members
@@ -8,8 +8,6 @@ import _pythonpath # noqa: F401
8import logging8import logging
9import sys9import sys
1010
11import six
12
13from lp.registry.scripts.listteammembers import (11from lp.registry.scripts.listteammembers import (
14 NoSuchTeamError,12 NoSuchTeamError,
15 process_team,13 process_team,
@@ -55,7 +53,7 @@ class ListTeamMembersScript(LaunchpadScript):
55 except NoSuchTeamError:53 except NoSuchTeamError:
56 raise LaunchpadScriptFailure("No such team: %s" % teamname)54 raise LaunchpadScriptFailure("No such team: %s" % teamname)
57 for detail in sorted(member_details):55 for detail in sorted(member_details):
58 print(six.ensure_str(detail))56 print(detail)
5957
6058
61if __name__ == '__main__':59if __name__ == '__main__':

Subscribers

People subscribed via source and target branches

to status/vote changes: