Merge ~cjwatson/launchpad:registry-pagetests-future-imports into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 9ccfa7a9b9ef5c361399b27bd03c0fffa5264c99
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:registry-pagetests-future-imports
Merge into: launchpad:master
Diff against target: 8387 lines (+1213/-1207)
102 files modified
lib/lp/registry/stories/announcements/xx-announcements.txt (+47/-47)
lib/lp/registry/stories/distribution/xx-distribution-launchpad-usage.txt (+23/-23)
lib/lp/registry/stories/distribution/xx-distribution-overview.txt (+15/-15)
lib/lp/registry/stories/distributionmirror/xx-distribution-countrymirrors.txt (+6/-6)
lib/lp/registry/stories/distributionmirror/xx-distribution-mirrors.txt (+3/-3)
lib/lp/registry/stories/distroseries/distroseries-admin.txt (+12/-12)
lib/lp/registry/stories/distroseries/xx-distroseries-index.txt (+15/-15)
lib/lp/registry/stories/distroseries/xx-show-distroseries-packaging.txt (+12/-12)
lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt (+26/-26)
lib/lp/registry/stories/gpg-coc/xx-ubuntu-codeofconduct-signer.txt (+5/-5)
lib/lp/registry/stories/location/personlocation-edit.txt (+1/-1)
lib/lp/registry/stories/mailinglists/hosted-email-address.txt (+5/-5)
lib/lp/registry/stories/mailinglists/lifecycle.txt (+33/-33)
lib/lp/registry/stories/mailinglists/subscriptions.txt (+43/-43)
lib/lp/registry/stories/mailinglists/welcome-message.txt (+3/-3)
lib/lp/registry/stories/milestone/object-milestones.txt (+33/-33)
lib/lp/registry/stories/milestone/xx-create-milestone-on-distribution.txt (+2/-2)
lib/lp/registry/stories/milestone/xx-milestone-add-and-edit.txt (+11/-11)
lib/lp/registry/stories/milestone/xx-milestone-description.txt (+4/-4)
lib/lp/registry/stories/object/xx-karmacontext-topcontributors.txt (+3/-3)
lib/lp/registry/stories/packaging/xx-distributionsourcepackage-packaging-concurrent-deletion.txt (+4/-4)
lib/lp/registry/stories/packaging/xx-distributionsourcepackage-packaging.txt (+6/-6)
lib/lp/registry/stories/packaging/xx-sourcepackage-packaging.txt (+24/-24)
lib/lp/registry/stories/person/xx-add-sshkey.txt (+22/-22)
lib/lp/registry/stories/person/xx-admin-person-review.txt (+8/-8)
lib/lp/registry/stories/person/xx-approve-members.txt (+4/-4)
lib/lp/registry/stories/person/xx-deactivate-account.txt (+4/-4)
lib/lp/registry/stories/person/xx-people-index.txt (+2/-2)
lib/lp/registry/stories/person/xx-people-search.txt (+6/-6)
lib/lp/registry/stories/person/xx-person-claim-merge.txt (+1/-1)
lib/lp/registry/stories/person/xx-person-edit-jabber-ids.txt (+3/-3)
lib/lp/registry/stories/person/xx-person-edit.txt (+2/-2)
lib/lp/registry/stories/person/xx-person-editgpgkeys-invalid-key.txt (+4/-4)
lib/lp/registry/stories/person/xx-person-home.txt (+39/-39)
lib/lp/registry/stories/person/xx-person-karma.txt (+8/-8)
lib/lp/registry/stories/person/xx-person-projects.txt (+6/-6)
lib/lp/registry/stories/person/xx-person-rdf.txt (+6/-6)
lib/lp/registry/stories/person/xx-person-subscriptions.txt (+25/-25)
lib/lp/registry/stories/person/xx-person-working-on.txt (+2/-2)
lib/lp/registry/stories/person/xx-user-to-user.txt (+8/-8)
lib/lp/registry/stories/pillar/xx-pillar-deactivation.txt (+6/-4)
lib/lp/registry/stories/pillar/xx-pillar-sprints.txt (+1/-1)
lib/lp/registry/stories/product/xx-launchpad-project-search.txt (+10/-10)
lib/lp/registry/stories/product/xx-product-add.txt (+20/-20)
lib/lp/registry/stories/product/xx-product-code-trunk.txt (+10/-10)
lib/lp/registry/stories/product/xx-product-edit-sourceforge-project.txt (+1/-1)
lib/lp/registry/stories/product/xx-product-edit.txt (+26/-26)
lib/lp/registry/stories/product/xx-product-files.txt (+26/-26)
lib/lp/registry/stories/product/xx-product-index.txt (+30/-30)
lib/lp/registry/stories/product/xx-product-package-pages.txt (+13/-13)
lib/lp/registry/stories/product/xx-product-rdf.txt (+2/-2)
lib/lp/registry/stories/product/xx-product-reassignment-and-milestones.txt (+2/-2)
lib/lp/registry/stories/product/xx-productset.txt (+6/-6)
lib/lp/registry/stories/productrelease/xx-productrelease-basics.txt (+14/-14)
lib/lp/registry/stories/productrelease/xx-productrelease-delete.txt (+9/-9)
lib/lp/registry/stories/productrelease/xx-productrelease-rdf.txt (+2/-2)
lib/lp/registry/stories/productrelease/xx-productrelease-view.txt (+6/-6)
lib/lp/registry/stories/productseries/xx-productseries-add-and-edit.txt (+8/-8)
lib/lp/registry/stories/productseries/xx-productseries-delete.txt (+17/-17)
lib/lp/registry/stories/productseries/xx-productseries-driver.txt (+5/-5)
lib/lp/registry/stories/productseries/xx-productseries-index.txt (+15/-15)
lib/lp/registry/stories/productseries/xx-productseries-rdf.txt (+2/-2)
lib/lp/registry/stories/productseries/xx-productseries-review.txt (+4/-4)
lib/lp/registry/stories/productseries/xx-productseries-series.txt (+7/-7)
lib/lp/registry/stories/productseries/xx-productseries-set-branch.txt (+7/-7)
lib/lp/registry/stories/project/xx-project-add-product.txt (+3/-3)
lib/lp/registry/stories/project/xx-project-add.txt (+1/-1)
lib/lp/registry/stories/project/xx-project-driver.txt (+2/-2)
lib/lp/registry/stories/project/xx-project-edit.txt (+17/-17)
lib/lp/registry/stories/project/xx-project-index.txt (+7/-7)
lib/lp/registry/stories/project/xx-project-rdf.txt (+2/-2)
lib/lp/registry/stories/project/xx-reassign-project.txt (+8/-8)
lib/lp/registry/stories/team-polls/create-poll-options.txt (+2/-2)
lib/lp/registry/stories/team-polls/edit-options.txt (+3/-2)
lib/lp/registry/stories/team-polls/edit-poll.txt (+4/-4)
lib/lp/registry/stories/team-polls/vote-poll.txt (+15/-15)
lib/lp/registry/stories/team-polls/xx-poll-condorcet-voting.txt (+20/-20)
lib/lp/registry/stories/team-polls/xx-poll-confirm-vote.txt (+8/-8)
lib/lp/registry/stories/team-polls/xx-poll-results.txt (+3/-3)
lib/lp/registry/stories/team/xx-team-add-my-teams.txt (+12/-12)
lib/lp/registry/stories/team/xx-team-claim.txt (+4/-4)
lib/lp/registry/stories/team/xx-team-contactemail-xss.txt (+3/-3)
lib/lp/registry/stories/team/xx-team-home.txt (+54/-54)
lib/lp/registry/stories/team/xx-team-membership.txt (+19/-19)
lib/lp/registry/stories/teammembership/private-team.txt (+1/-1)
lib/lp/registry/stories/teammembership/xx-add-member.txt (+11/-11)
lib/lp/registry/stories/teammembership/xx-member-renewed-membership.txt (+10/-10)
lib/lp/registry/stories/teammembership/xx-renew-subscription.txt (+4/-4)
lib/lp/registry/stories/teammembership/xx-team-leave.txt (+8/-8)
lib/lp/registry/stories/teammembership/xx-teammembership.txt (+21/-21)
lib/lp/registry/stories/webservice/xx-derivedistroseries.txt (+5/-5)
lib/lp/registry/stories/webservice/xx-distribution-mirror.txt (+6/-6)
lib/lp/registry/stories/webservice/xx-distribution-source-package.txt (+7/-7)
lib/lp/registry/stories/webservice/xx-distribution.txt (+13/-13)
lib/lp/registry/stories/webservice/xx-distroseries.txt (+7/-7)
lib/lp/registry/stories/webservice/xx-person.txt (+59/-59)
lib/lp/registry/stories/webservice/xx-personlocation.txt (+8/-8)
lib/lp/registry/stories/webservice/xx-private-team.txt (+25/-25)
lib/lp/registry/stories/webservice/xx-project-registry.txt (+78/-78)
lib/lp/registry/stories/webservice/xx-source-package.txt (+8/-8)
lib/lp/registry/stories/webservice/xx-structuralsubscription.txt (+16/-16)
lib/lp/registry/tests/test_doc.py (+4/-1)
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Review via email: mp+392377@code.launchpad.net

Commit message

Convert lp.registry pagetests to preferred __future__ imports

Description of the change

This is very large, but with the exception of the change to lib/lp/registry/tests/test_doc.py it consists entirely of mechanical print function conversions.

To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) wrote :

This is sufficiently large and mechanical that it isn't likely to be worth anyone else's time to review - I'm going to self-approve it since it's in line with other previous similar conversions.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/registry/stories/announcements/xx-announcements.txt b/lib/lp/registry/stories/announcements/xx-announcements.txt
2index e0ffc0b..9a12076 100644
3--- a/lib/lp/registry/stories/announcements/xx-announcements.txt
4+++ b/lib/lp/registry/stories/announcements/xx-announcements.txt
5@@ -83,22 +83,22 @@ pillar.
6 >>> priv_browser = setupBrowser(auth="Basic mark@example.com:test")
7 >>> priv_browser.open('http://launchpad.test/ubuntu')
8 >>> link = priv_browser.getLink('Make announcement')
9- >>> print link.text
10+ >>> print(link.text)
11 Make announcement
12
13 >>> priv_browser.getLink('Read all announcements').click()
14 >>> link = priv_browser.getLink('Make announcement')
15- >>> print link.text
16+ >>> print(link.text)
17 Make announcement
18
19 >>> priv_browser.open('http://launchpad.test/firefox')
20 >>> link = priv_browser.getLink('Make announcement')
21- >>> print link.text
22+ >>> print(link.text)
23 Make announcement
24
25 >>> priv_browser.getLink('Read all announcements').click()
26 >>> link = priv_browser.getLink('Make announcement')
27- >>> print link.text
28+ >>> print(link.text)
29 Make announcement
30
31
32@@ -118,9 +118,9 @@ announcement:
33 Making the announcement takes the user back to the main page for the
34 project.
35
36- >>> print priv_browser.url
37+ >>> print(priv_browser.url)
38 http://launchpad.test/apache
39- >>> print priv_browser.title
40+ >>> print(priv_browser.title)
41 Apache in Launchpad
42
43 We'll repeat the process for Tomcat, an IProduct that is part of the
44@@ -134,8 +134,8 @@ announcement so there is a "Latest news" portlet. Let's render the
45 portlet, taking care not to render today's date which would timebomb our
46 script.
47
48- >>> print latest_news(priv_browser.contents).encode(
49- ... 'ascii', 'backslashreplace')
50+ >>> print(latest_news(priv_browser.contents).encode(
51+ ... 'ascii', 'backslashreplace'))
52 Announcements
53 Apache announcement headline...
54 Read all announcements
55@@ -154,13 +154,13 @@ work too:
56 ... name='field.publication_date.announcement_date').value = (
57 ... '2007-11-24 09:00:00')
58 >>> priv_browser.getControl('Make announcement').click()
59- >>> print priv_browser.title
60+ >>> print(priv_browser.title)
61 Tomcat in Launchpad
62
63 And check out the results:
64
65- >>> print latest_news(priv_browser.contents).encode(
66- ... 'ascii', 'backslashreplace')
67+ >>> print(latest_news(priv_browser.contents).encode(
68+ ... 'ascii', 'backslashreplace'))
69 Announcements
70 Apache announcement headline ...
71 Tomcat announcement headline on 2007-11-24 ...
72@@ -169,7 +169,7 @@ And check out the results:
73
74 Let's make sure that the announcement is presented as a link.
75
76- >>> print priv_browser.getLink('Tomcat announcement headline').url
77+ >>> print(priv_browser.getLink('Tomcat announcement headline').url)
78 http://launchpad.test/tomcat/+announcement/...
79
80 We'll repeat the process for Derby, an IProduct that is part of the
81@@ -185,7 +185,7 @@ announcement immediately:
82 >>> priv_browser.getControl('Summary').value = (
83 ... 'Derby announcement summary')
84 >>> priv_browser.getControl('Make announcement').click()
85- >>> print priv_browser.title
86+ >>> print(priv_browser.title)
87 Derby in Launchpad
88 >>> 'Derby announcement' in latest_news(priv_browser.contents)
89 True
90@@ -205,7 +205,7 @@ date in the future when the announcement will be made:
91 ... name='field.publication_date.announcement_date').value = (
92 ... '2021-12-24 09:00:00')
93 >>> priv_browser.getControl('Make announcement').click()
94- >>> print priv_browser.title
95+ >>> print(priv_browser.title)
96 Jokosher in Launchpad
97 >>> 'Jokosher announcement' in latest_news(priv_browser.contents)
98 True
99@@ -221,7 +221,7 @@ a date for the announcement at all:
100 ... 'Kubuntu announcement summary')
101 >>> priv_browser.getControl('some time in the future').click()
102 >>> priv_browser.getControl('Make announcement').click()
103- >>> print priv_browser.title
104+ >>> print(priv_browser.title)
105 Kubuntu in Launchpad
106 >>> "Kubuntu announcement" in latest_news(priv_browser.contents)
107 True
108@@ -235,7 +235,7 @@ And finally for RedHat, an IDistribution, with immediate announcement:
109 >>> priv_browser.getControl('Summary').value = (
110 ... 'RedHat announcement summary')
111 >>> priv_browser.getControl('Make announcement').click()
112- >>> print priv_browser.title
113+ >>> print(priv_browser.title)
114 Red Hat in Launchpad
115 >>> "RedHat announcement" in latest_news(priv_browser.contents)
116 True
117@@ -264,21 +264,21 @@ published:
118
119 >>> anon_browser.open('http://launchpad.test/apache/+announcements')
120 >>> anon_browser.getLink('Derby announcement headline').click()
121- >>> print anon_browser.title
122+ >>> print(anon_browser.title)
123 Derby announcement headline : Derby
124
125 The page shows the announcement and it has a link back to the announcements
126 page that any user can navigate.
127
128 >>> content = find_main_content(anon_browser.contents)
129- >>> print extract_text(content.h1)
130+ >>> print(extract_text(content.h1))
131 Derby announcement headline
132
133- >>> print extract_text(content.findAll('p')[1])
134+ >>> print(extract_text(content.findAll('p')[1]))
135 Derby announcement summary
136
137 >>> anon_browser.getLink("Read all announcements").click()
138- >>> print anon_browser.title
139+ >>> print(anon_browser.title)
140 News and announcements...
141
142
143@@ -366,9 +366,9 @@ We can publish this announcement immediately.
144
145 >>> priv_browser.getLink('Kubuntu announcement headline').click()
146 >>> priv_browser.getLink('Publish announcement').click()
147- >>> print priv_browser.title
148+ >>> print(priv_browser.title)
149 Publish announcement : Kubuntu announcement headline : Kubuntu
150- >>> print priv_browser.url
151+ >>> print(priv_browser.url)
152 http://launchpad.test/kubuntu/+announceme.../+publish
153 >>> radio = priv_browser.getControl(name="field.publication_date.action")
154 >>> radio.value = ['immediately']
155@@ -376,7 +376,7 @@ We can publish this announcement immediately.
156
157 Doing so takes us back to the list of announcements.
158
159- >>> print priv_browser.title
160+ >>> print(priv_browser.title)
161 News and announcements...
162
163 And since the announcement has been made, the everybody can now see
164@@ -464,7 +464,7 @@ hosted in Launchpad:
165 The announcements are batched so only the latest four are shown,
166 leaving Tomcat out:
167
168- >>> print extract_text(anon_browser.contents)
169+ >>> print(extract_text(anon_browser.contents))
170 Announcements from all projects hosted in Launchpad
171 ...
172 1...4 of 25 results
173@@ -486,34 +486,34 @@ The announcement listing page does not have editing links. They are
174 available on the individual announcement pages.
175
176 >>> priv_browser.open('http://launchpad.test/tomcat/+announcements')
177- >>> print priv_browser.getLink('Read more').url
178+ >>> print(priv_browser.getLink('Read more').url)
179 http://apache.org/announcement/rocking/
180 >>> priv_browser.getLink('Apache announcement headline').click()
181 >>> priv_browser.getLink('Modify announcement').click()
182- >>> print priv_browser.title
183+ >>> print(priv_browser.title)
184 Modify announcement : Apache announcement headline : Apache
185 >>> headline = priv_browser.getControl('Headline')
186- >>> print headline.value
187+ >>> print(headline.value)
188 Apache announcement headline
189 >>> headline.value = 'Modified headline'
190 >>> summary = priv_browser.getControl('Summary')
191- >>> print summary.value
192+ >>> print(summary.value)
193 Apache announcement summary
194 >>> summary.value = 'Modified summary'
195 >>> url = priv_browser.getControl('URL')
196- >>> print url.value
197+ >>> print(url.value)
198 http://apache.org/announcement/rocking/
199 >>> url.value = (
200 ... 'http://apache.org/modified/url/')
201 >>> priv_browser.getControl('Modify').click()
202- >>> print priv_browser.title
203+ >>> print(priv_browser.title)
204 News and announcements...
205 >>> priv_browser.open('http://launchpad.test/tomcat/+announcements')
206 >>> 'Modified headline' in announcements(priv_browser.contents)
207 True
208 >>> 'Modified summary' in announcements(priv_browser.contents)
209 True
210- >>> print priv_browser.getLink('Read more').url
211+ >>> print(priv_browser.getLink('Read more').url)
212 http://apache.org/modified/url/
213
214
215@@ -530,14 +530,14 @@ You can retract an announcement which was previously announced.
216 >>> priv_browser.getLink('Kubuntu announcement headline').click()
217 >>> priv_browser.getLink('Delete announcement').click()
218 >>> priv_browser.getLink('retracting the announcement').click()
219- >>> print priv_browser.title
220+ >>> print(priv_browser.title)
221 Retract announcement : Kubuntu announcement headline : Kubuntu
222
223 Actually clicking "Retract" takes us back to the listing page. The item
224 is shown as having been retracted if you are a privileged user.
225
226 >>> priv_browser.getControl('Retract').click()
227- >>> print priv_browser.title
228+ >>> print(priv_browser.title)
229 News and announcements...
230 >>> 'Kubuntu announcement ' in announcements(priv_browser.contents)
231 True
232@@ -562,14 +562,14 @@ Once something has been retracted, it can be published again.
233
234 >>> priv_browser.getLink('Kubuntu announcement headline').click()
235 >>> priv_browser.getLink('Publish announcement').click()
236- >>> print priv_browser.title
237+ >>> print(priv_browser.title)
238 Publish announcement : Kubuntu announcement headline : Kubuntu
239 >>> radio = priv_browser.getControl(name="field.publication_date.action")
240 >>> radio.value = ['immediately']
241 >>> priv_browser.getControl(
242 ... name="field.publication_date.announcement_date").value = ''
243 >>> priv_browser.getControl('Publish').click()
244- >>> print priv_browser.title
245+ >>> print(priv_browser.title)
246 News and announcements...
247
248 And once again it is visible to unprivileged users:
249@@ -591,11 +591,11 @@ it.
250 >>> priv_browser.open('http://launchpad.test/kubuntu/+announcements')
251 >>> priv_browser.getLink('Kubuntu announcement headline').click()
252 >>> priv_browser.getLink('Move announcement').click()
253- >>> print priv_browser.title
254+ >>> print(priv_browser.title)
255 Move announcement : Kubuntu announcement headline : Kubuntu
256 >>> priv_browser.getControl('For').value = 'guadalinex'
257 >>> priv_browser.getControl('Retarget').click()
258- >>> print priv_browser.title
259+ >>> print(priv_browser.title)
260 News and announcements...
261 >>> 'Kubuntu announcement' in announcements(priv_browser.contents)
262 True
263@@ -608,14 +608,14 @@ not be able to move it.
264 >>> kamion_browser.open('http://launchpad.test/guadalinex/+announcements')
265 >>> kamion_browser.getLink('Kubuntu announcement headline').click()
266 >>> kamion_browser.getLink('Move announcement').click()
267- >>> print kamion_browser.title
268+ >>> print(kamion_browser.title)
269 Move announcement : Kubuntu announcement headline : GuadaLinex
270 >>> kamion_browser.getControl('For').value = 'kubuntu'
271 >>> kamion_browser.getControl('Retarget').click()
272 >>> "don't have permission" in extract_text(
273 ... find_main_content(kamion_browser.contents))
274 True
275- >>> print kamion_browser.title
276+ >>> print(kamion_browser.title)
277 Move announcement : Kubuntu announcement headline : GuadaLinex
278
279
280@@ -642,11 +642,11 @@ domain.
281 >>> strainer = SoupStrainer('link', rel='self')
282 >>> links = parse_links(nopriv_browser.contents, rel='self')
283 >>> for link in links:
284- ... print link
285+ ... print(link)
286 <link href="http://feeds.launchpad.test/netapplet/announcements.atom" rel="self"/>
287
288 >>> for id_ in parse_ids(nopriv_browser.contents):
289- ... print extract_text(id_)
290+ ... print(extract_text(id_))
291 tag:launchpad.net,2005-03-10:/netapplet/+announcements
292
293 The feeds include only published announcements. The Jokosher
294@@ -672,7 +672,7 @@ Retracted items do not show up either.
295 >>> 'Kubuntu announcement headline' in nopriv_browser.contents
296 True
297 >>> for id_ in parse_ids(nopriv_browser.contents):
298- ... print extract_text(id_)
299+ ... print(extract_text(id_))
300 tag:launchpad.net,2006-10-16:/guadalinex/+announcements
301 tag:launchpad.net,...:/+announcement/...
302
303@@ -683,7 +683,7 @@ Retracted items do not show up either.
304 >>> priv_browser.getLink('Kubuntu announcement headline').click()
305 >>> priv_browser.getLink('Delete announcement').click()
306 >>> priv_browser.getLink('retracting the announcement').click()
307- >>> print priv_browser.title
308+ >>> print(priv_browser.title)
309 Retract announcement : Kubuntu announcement headline : GuadaLinex
310 >>> priv_browser.getControl('Retract').click()
311 >>> nopriv_browser.reload()
312@@ -706,7 +706,7 @@ products.
313 >>> 'Derby announcement headline' in nopriv_browser.contents
314 True
315 >>> for id_ in parse_ids(nopriv_browser.contents):
316- ... print extract_text(id_)
317+ ... print(extract_text(id_))
318 tag:launchpad.net,2004-09-24:/apache/+announcements
319 tag:launchpad.net,...:/+announcement/...
320 tag:launchpad.net,...:/+announcement/...
321@@ -715,7 +715,7 @@ products.
322 >>> strainer = SoupStrainer('link', rel='self')
323 >>> links = parse_links(nopriv_browser.contents, rel='self')
324 >>> for link in links:
325- ... print link
326+ ... print(link)
327 <link href="http://feeds.launchpad.test/apache/announcements.atom" rel="self"/>
328
329 Finally, there is a feed for all announcements across all projects
330@@ -781,10 +781,10 @@ An owner can permanently delete an announcement.
331 False
332 >>> kamion_browser.getLink('Kubuntu announcement headline').click()
333 >>> kamion_browser.getLink('Delete announcement').click()
334- >>> print kamion_browser.title
335+ >>> print(kamion_browser.title)
336 Delete announcement : Kubuntu announcement headline : GuadaLinex
337 >>> kamion_browser.getControl('Delete').click()
338- >>> print priv_browser.title
339+ >>> print(priv_browser.title)
340 News and announcements...
341 >>> no_announcements(kamion_browser.contents)
342 True
343diff --git a/lib/lp/registry/stories/distribution/xx-distribution-launchpad-usage.txt b/lib/lp/registry/stories/distribution/xx-distribution-launchpad-usage.txt
344index 07a4613..f8dc2c9 100644
345--- a/lib/lp/registry/stories/distribution/xx-distribution-launchpad-usage.txt
346+++ b/lib/lp/registry/stories/distribution/xx-distribution-launchpad-usage.txt
347@@ -33,23 +33,23 @@ The distribution's registrant can access the page and change the usage.
348 >>> registrant = setupBrowser(
349 ... auth='Basic celso.providelo@canonical.com:test')
350 >>> registrant.open('http://launchpad.test/ubuntu/+edit')
351- >>> print registrant.url
352+ >>> print(registrant.url)
353 http://launchpad.test/ubuntu/+edit
354
355- >>> print registrant.getControl(name='field.translations_usage').value[0]
356+ >>> print(registrant.getControl(name='field.translations_usage').value[0])
357 LAUNCHPAD
358- >>> print registrant.getControl(name='field.official_malone').value
359+ >>> print(registrant.getControl(name='field.official_malone').value)
360 True
361- >>> print registrant.getControl(name='field.enable_bug_expiration').value
362+ >>> print(registrant.getControl(name='field.enable_bug_expiration').value)
363 True
364- >>> print registrant.getControl(name='field.blueprints_usage').value[0]
365+ >>> print(registrant.getControl(name='field.blueprints_usage').value[0])
366 LAUNCHPAD
367- >>> print registrant.getControl(name='field.answers_usage').value[0]
368+ >>> print(registrant.getControl(name='field.answers_usage').value[0])
369 LAUNCHPAD
370- >>> print bool(
371- ... registrant.getControl(name='field.require_virtualized').value)
372+ >>> print(bool(
373+ ... registrant.getControl(name='field.require_virtualized').value))
374 False
375- >>> print registrant.getControl(name='field.processors').value
376+ >>> print(registrant.getControl(name='field.processors').value)
377 ['386', 'amd64', 'hppa']
378
379 >>> registrant.getControl(name='field.translations_usage').value = [
380@@ -60,19 +60,19 @@ Just like Launchpad administrators can.
381
382 >>> admin_browser.open('http://launchpad.test/ubuntu')
383 >>> admin_browser.getLink('Change details').click()
384- >>> print admin_browser.title
385+ >>> print(admin_browser.title)
386 Change Ubuntu details...
387- >>> print admin_browser.getControl(
388- ... name='field.translations_usage').value[0]
389+ >>> print(admin_browser.getControl(
390+ ... name='field.translations_usage').value[0])
391 UNKNOWN
392- >>> print admin_browser.getControl(name='field.official_malone').value
393+ >>> print(admin_browser.getControl(name='field.official_malone').value)
394 True
395- >>> print admin_browser.getControl(
396- ... name='field.enable_bug_expiration').value
397+ >>> print(admin_browser.getControl(
398+ ... name='field.enable_bug_expiration').value)
399 True
400- >>> print admin_browser.getControl(name='field.blueprints_usage').value[0]
401+ >>> print(admin_browser.getControl(name='field.blueprints_usage').value[0])
402 LAUNCHPAD
403- >>> print admin_browser.getControl(name='field.answers_usage').value[0]
404+ >>> print(admin_browser.getControl(name='field.answers_usage').value[0])
405 LAUNCHPAD
406
407 >>> admin_browser.getControl(
408@@ -84,13 +84,13 @@ Just like Launchpad administrators can.
409 ... name='field.answers_usage').value = ['UNKNOWN']
410 >>> admin_browser.getControl('Change', index=3).click()
411
412- >>> print admin_browser.url
413+ >>> print(admin_browser.url)
414 http://launchpad.test/ubuntu
415
416 Only administators can configure the publisher for the distribution:
417
418 >>> admin_browser.getLink('Configure publisher').click()
419- >>> print admin_browser.title
420+ >>> print(admin_browser.title)
421 Publisher configuration for...
422
423 >>> admin_browser.getControl(
424@@ -101,7 +101,7 @@ Only administators can configure the publisher for the distribution:
425 ... name='field.copy_base_url').value = "http://copy.base.url/"
426 >>> admin_browser.getControl('Save').click()
427
428- >>> print admin_browser.url
429+ >>> print(admin_browser.url)
430 http://launchpad.test/ubuntu
431
432
433@@ -130,11 +130,11 @@ do not change the expiration check box, and they do the whole
434 operation before the page complete loading.
435
436 >>> admin_browser.getLink('Change details').click()
437- >>> print admin_browser.getControl(name='field.official_malone').value
438+ >>> print(admin_browser.getControl(name='field.official_malone').value)
439 True
440
441- >>> print admin_browser.getControl(
442- ... name='field.enable_bug_expiration').value
443+ >>> print(admin_browser.getControl(
444+ ... name='field.enable_bug_expiration').value)
445 True
446
447 >>> admin_browser.getControl(name='field.official_malone').value = False
448diff --git a/lib/lp/registry/stories/distribution/xx-distribution-overview.txt b/lib/lp/registry/stories/distribution/xx-distribution-overview.txt
449index cc5ddcf..cb14899 100644
450--- a/lib/lp/registry/stories/distribution/xx-distribution-overview.txt
451+++ b/lib/lp/registry/stories/distribution/xx-distribution-overview.txt
452@@ -14,7 +14,7 @@ Distribution listings
453 There is a listing of all distributions at /distros/:
454
455 >>> anon_browser.open('http://launchpad.test/distros/')
456- >>> print anon_browser.title
457+ >>> print(anon_browser.title)
458 Distributions registered in Launchpad
459
460
461@@ -28,7 +28,7 @@ series.
462 Some distributions have listings of major versions, for example Debian:
463
464 >>> anon_browser.open('http://launchpad.test/debian')
465- >>> print extract_text(find_tag_by_id(anon_browser.contents, 'sandm'))
466+ >>> print(extract_text(find_tag_by_id(anon_browser.contents, 'sandm')))
467 Active series and milestones
468 3.1 ā€œSargeā€ series - frozen
469 3.0 ā€œWoodyā€ series - current
470@@ -44,7 +44,7 @@ rules.
471 >>> admin_browser.getControl("Register Milestone").click()
472
473 >>> anon_browser.open('http://launchpad.test/debian')
474- >>> print extract_text(find_tag_by_id(anon_browser.contents, 'sandm'))
475+ >>> print(extract_text(find_tag_by_id(anon_browser.contents, 'sandm')))
476 Active series and milestones
477 ...
478 Milestones: testmilestone, 3.1, and 3.1-rc1
479@@ -77,15 +77,15 @@ to the distribution series and milestones pages respectively.
480 Others do not have any series so the portlet is not shown.
481
482 >>> anon_browser.open('http://launchpad.test/gentoo')
483- >>> print find_tag_by_id(anon_browser.contents, 'sandm')
484+ >>> print(find_tag_by_id(anon_browser.contents, 'sandm'))
485 None
486
487 The 5 latest derivatives are displayed on the home page
488 along with a link to list all of them.
489
490 >>> anon_browser.open('http://launchpad.test/ubuntu')
491- >>> print extract_text(
492- ... find_tag_by_id(anon_browser.contents, 'derivatives'))
493+ >>> print(extract_text(
494+ ... find_tag_by_id(anon_browser.contents, 'derivatives')))
495 Latest derivatives
496 9.9.9
497 ā€œHoary Mockā€ series
498@@ -111,8 +111,8 @@ If there are no derivatives, the link to the derivatives page is
499 not there.
500
501 >>> anon_browser.open('http://launchpad.test/ubuntutest')
502- >>> print extract_text(
503- ... find_tag_by_id(anon_browser.contents, 'derivatives'))
504+ >>> print(extract_text(
505+ ... find_tag_by_id(anon_browser.contents, 'derivatives')))
506 Latest derivatives
507 No derivatives.
508
509@@ -132,10 +132,10 @@ If there is a development series alias, it becomes a redirect.
510 ... ubuntu = getUtility(IDistributionSet).getByName(u"ubuntu")
511 ... ubuntu.development_series_alias = "devel"
512 >>> anon_browser.open("http://launchpad.test/ubuntu/devel")
513- >>> print anon_browser.url
514+ >>> print(anon_browser.url)
515 http://launchpad.test/ubuntu/hoary
516 >>> anon_browser.open("http://launchpad.test/ubuntu/devel/+builds")
517- >>> print anon_browser.url
518+ >>> print(anon_browser.url)
519 http://launchpad.test/ubuntu/hoary/+builds
520
521
522@@ -146,13 +146,13 @@ The distroseries pages presents the registration information.
523
524 >>> anon_browser.open('http://launchpad.test/ubuntu')
525
526- >>> print extract_text(
527- ... find_tag_by_id(anon_browser.contents, 'registration'))
528+ >>> print(extract_text(
529+ ... find_tag_by_id(anon_browser.contents, 'registration')))
530 Registered by
531 Registry Administrators
532 on 2006-10-16
533
534- >>> print anon_browser.getLink('Ubuntu Team').url
535+ >>> print(anon_browser.getLink('Ubuntu Team').url)
536 http://launchpad.test/~ubuntu-team
537
538
539@@ -164,11 +164,11 @@ Displaying the page for that URL is nonsensical (it looks like the PPA
540 index page), so the view redirect it to the distribution index page.
541
542 >>> anon_browser.open("http://launchpad.test/ubuntu/+archive/primary")
543- >>> print anon_browser.url
544+ >>> print(anon_browser.url)
545 http://launchpad.test/ubuntu
546
547 >>> anon_browser.open("http://launchpad.test/ubuntu/+archive/partner")
548- >>> print anon_browser.url
549+ >>> print(anon_browser.url)
550 http://launchpad.test/ubuntu
551
552 Any attempt to access an incomplete URL (missing the archive name
553diff --git a/lib/lp/registry/stories/distributionmirror/xx-distribution-countrymirrors.txt b/lib/lp/registry/stories/distributionmirror/xx-distribution-countrymirrors.txt
554index eea6781..b81fa99 100644
555--- a/lib/lp/registry/stories/distributionmirror/xx-distribution-countrymirrors.txt
556+++ b/lib/lp/registry/stories/distributionmirror/xx-distribution-countrymirrors.txt
557@@ -11,15 +11,15 @@ archive mirrors, plus the canonical one.
558
559 >>> browser.addHeader('X_FORWARDED_FOR', '83.196.46.77')
560 >>> browser.open('http://launchpad.test/ubuntu/+countrymirrors-archive')
561- >>> print browser.headers['content-type']
562+ >>> print(browser.headers['content-type'])
563 text/plain;charset=utf-8
564- >>> print browser.headers['X-Generated-For-Country']
565+ >>> print(browser.headers['X-Generated-For-Country'])
566 France
567- >>> print browser.headers['X-Generated-For-IP']
568+ >>> print(browser.headers['X-Generated-For-IP'])
569 83.196.46.77
570- >>> print browser.headers['X-REQUEST-HTTP_X_FORWARDED_FOR']
571+ >>> print(browser.headers['X-REQUEST-HTTP_X_FORWARDED_FOR'])
572 83.196.46.77
573- >>> print browser.headers['X-REQUEST-REMOTE_ADDR']
574+ >>> print(browser.headers['X-REQUEST-REMOTE_ADDR'])
575 127.0.0.1
576 >>> for url in sorted(browser.contents.split('\n')):
577 ... print(url)
578@@ -32,7 +32,7 @@ canonical mirror.
579
580 >>> anon_browser.open(
581 ... 'http://launchpad.test/ubuntu/+countrymirrors-archive')
582- >>> print anon_browser.headers['X-Generated-For-Country']
583+ >>> print(anon_browser.headers['X-Generated-For-Country'])
584 Unknown
585 >>> for url in sorted(anon_browser.contents.split('\n')):
586 ... print(url)
587diff --git a/lib/lp/registry/stories/distributionmirror/xx-distribution-mirrors.txt b/lib/lp/registry/stories/distributionmirror/xx-distribution-mirrors.txt
588index 19885a6..c694d2b 100644
589--- a/lib/lp/registry/stories/distributionmirror/xx-distribution-mirrors.txt
590+++ b/lib/lp/registry/stories/distributionmirror/xx-distribution-mirrors.txt
591@@ -13,7 +13,7 @@ on their status and content.
592 ... mirrors = []
593 ... for tr in header.findNextSiblings('tr'):
594 ... if 'head' in str(tr.attrs):
595- ... print "%s: %s" % (country, mirrors)
596+ ... print("%s: %s" % (country, mirrors))
597 ... country = extract_text(tr.find('th'))
598 ... if country == 'Total':
599 ... break
600@@ -39,7 +39,7 @@ The archive mirrors display the "freshness", how far behind they are.
601
602 >>> browser.open('http://launchpad.test/ubuntu')
603 >>> browser.getLink('Archive mirrors').click()
604- >>> print browser.title
605+ >>> print(browser.title)
606 Mirrors :...
607 >>> print_mirrors_by_countries(browser.contents)
608 Antarctica:
609@@ -89,7 +89,7 @@ seen by distro owners, mirror admins of the distro or launchpad admins.
610 >>> browser.url
611 'http://launchpad.test/ubuntu/+disabledmirrors'
612
613- >>> print find_tag_by_id(browser.contents, 'maincontent').renderContents()
614+ >>> print(find_tag_by_id(browser.contents, 'maincontent').renderContents())
615 <BLANKLINE>
616 ...We don't know of any Disabled Mirrors for this distribution...
617
618diff --git a/lib/lp/registry/stories/distroseries/distroseries-admin.txt b/lib/lp/registry/stories/distroseries/distroseries-admin.txt
619index 1edd1b1..33303f5 100644
620--- a/lib/lp/registry/stories/distroseries/distroseries-admin.txt
621+++ b/lib/lp/registry/stories/distroseries/distroseries-admin.txt
622@@ -8,29 +8,29 @@ Launchpad administrators can edit distroseries via two different
623 pages: 'Change details' and 'Administer'.
624
625 >>> admin_browser.open('http://launchpad.test/ubuntu/hoary')
626- >>> print admin_browser.title
627+ >>> print(admin_browser.title)
628 Hoary (5.04)...
629 >>> admin_browser.getLink('Change details').click()
630- >>> print admin_browser.url
631+ >>> print(admin_browser.url)
632 http://launchpad.test/ubuntu/hoary/+edit
633
634- >>> print admin_browser.title
635+ >>> print(admin_browser.title)
636 Edit The Hoary Hedgehog Release...
637
638 >>> admin_browser.getControl(
639 ... 'Display name', index=0).value = 'Happy'
640 >>> admin_browser.getControl('Change').click()
641- >>> print admin_browser.title
642+ >>> print(admin_browser.title)
643 Happy (5.04)...
644
645 A separate administration page is available via the 'Administer' link.
646
647 >>> admin_browser.open('http://launchpad.test/ubuntu/hoary')
648 >>> admin_browser.getLink('Administer').click()
649- >>> print admin_browser.url
650+ >>> print(admin_browser.url)
651 http://launchpad.test/ubuntu/hoary/+admin
652
653- >>> print admin_browser.title
654+ >>> print(admin_browser.title)
655 Administer The Hoary Hedgehog Release...
656
657 >>> admin_browser.getControl(
658@@ -38,9 +38,9 @@ A separate administration page is available via the 'Administer' link.
659 >>> admin_browser.getControl(
660 ... 'Version', index=0).value = '5.05'
661 >>> admin_browser.getControl('Change').click()
662- >>> print admin_browser.url
663+ >>> print(admin_browser.url)
664 http://launchpad.test/ubuntu/happy
665- >>> print admin_browser.title
666+ >>> print(admin_browser.title)
667 Happy (5.05)...
668
669
670@@ -71,10 +71,10 @@ Registry experts do have access to the administration page.
671
672 >>> registry_browser.open('http://launchpad.test/ubuntu/happy')
673 >>> registry_browser.getLink('Administer').click()
674- >>> print registry_browser.url
675+ >>> print(registry_browser.url)
676 http://launchpad.test/ubuntu/happy/+admin
677
678- >>> print registry_browser.title
679+ >>> print(registry_browser.title)
680 Administer The Hoary Hedgehog Release...
681
682 >>> registry_browser.getControl(
683@@ -82,7 +82,7 @@ Registry experts do have access to the administration page.
684 >>> registry_browser.getControl(
685 ... 'Version', index=0).value = '5.04'
686 >>> registry_browser.getControl('Change').click()
687- >>> print registry_browser.url
688+ >>> print(registry_browser.url)
689 http://launchpad.test/ubuntu/hoary
690- >>> print registry_browser.title
691+ >>> print(registry_browser.title)
692 Happy (5.04)...
693diff --git a/lib/lp/registry/stories/distroseries/xx-distroseries-index.txt b/lib/lp/registry/stories/distroseries/xx-distroseries-index.txt
694index 9be9c1e..f5eaa6f 100644
695--- a/lib/lp/registry/stories/distroseries/xx-distroseries-index.txt
696+++ b/lib/lp/registry/stories/distroseries/xx-distroseries-index.txt
697@@ -6,7 +6,7 @@ this distribution series.
698
699 >>> user_browser.open('http://launchpad.test/ubuntu/hoary')
700 >>> user_browser.getLink('Help translate').click()
701- >>> print user_browser.title
702+ >>> print(user_browser.title)
703 Hoary (5.04) : Translations : Ubuntu
704
705
706@@ -18,17 +18,17 @@ its main 'heading'.
707
708 >>> anon_browser.open('http://launchpad.test/ubuntu/warty')
709
710- >>> print extract_text(
711- ... find_tag_by_id(anon_browser.contents, 'registration'))
712+ >>> print(extract_text(
713+ ... find_tag_by_id(anon_browser.contents, 'registration')))
714 Registered by
715 Ubuntu Team on
716 2006-10-16
717
718- >>> print extract_text(find_main_content(anon_browser.contents))
719+ >>> print(extract_text(find_main_content(anon_browser.contents)))
720 Warty
721 ...
722
723- >>> print anon_browser.getLink('Ubuntu Team').url
724+ >>> print(anon_browser.getLink('Ubuntu Team').url)
725 http://launchpad.test/~ubuntu-team
726
727
728@@ -38,8 +38,8 @@ Details portlet
729 The distroseries page contains a details portlet giving more information
730 on the series' details.
731
732- >>> print extract_text(
733- ... find_portlet(anon_browser.contents, 'Series information'))
734+ >>> print(extract_text(
735+ ... find_portlet(anon_browser.contents, 'Series information')))
736 Series information
737 Distribution: Ubuntu
738 Series: Warty (4.10)
739@@ -55,8 +55,8 @@ On series that have no source or binary packages, the portlet will
740 change its text slightly to annouce this:
741
742 >>> anon_browser.open('http://launchpad.test/debian/sarge')
743- >>> print extract_text(
744- ... find_portlet(anon_browser.contents, 'Series information'))
745+ >>> print(extract_text(
746+ ... find_portlet(anon_browser.contents, 'Series information')))
747 Series information
748 Distribution: Debian
749 Series: Sarge (3.1)
750@@ -94,8 +94,8 @@ the series derived from this series:
751 ... for child in children]
752
753 >>> anon_browser.open('http://launchpad.test/debian/sarge')
754- >>> print extract_text(
755- ... find_portlet(anon_browser.contents, 'Series information'))
756+ >>> print(extract_text(
757+ ... find_portlet(anon_browser.contents, 'Series information')))
758 Series information
759 Distribution: Debian
760 Series: Sarge (3.1)
761@@ -116,10 +116,10 @@ series, we can create structural bug subscriptions.
762
763 >>> admin_browser.open('http://launchpad.test/ubuntu/warty')
764 >>> admin_browser.getLink('Subscribe to bug mail').click()
765- >>> print admin_browser.url
766+ >>> print(admin_browser.url)
767 http://launchpad.test/ubuntu/warty/+subscribe
768
769- >>> print admin_browser.title
770+ >>> print(admin_browser.title)
771 Subscribe : Warty (4.10) : Bugs : Ubuntu
772
773
774@@ -132,8 +132,8 @@ upstream packaging.
775 >>> # Note that warty's sourcecount is stale in sample data
776 >>> # which causes -2 need linking.
777 >>> anon_browser.open('http://launchpad.test/ubuntu/warty')
778- >>> print extract_text(
779- ... find_tag_by_id(anon_browser.contents, 'series-packaging'))
780+ >>> print(extract_text(
781+ ... find_tag_by_id(anon_browser.contents, 'series-packaging')))
782 Upstream packaging
783 5 source packages are linked to registered upstream projects.
784 3 need linking.
785diff --git a/lib/lp/registry/stories/distroseries/xx-show-distroseries-packaging.txt b/lib/lp/registry/stories/distroseries/xx-show-distroseries-packaging.txt
786index f557d62..2ac0e42 100644
787--- a/lib/lp/registry/stories/distroseries/xx-show-distroseries-packaging.txt
788+++ b/lib/lp/registry/stories/distroseries/xx-show-distroseries-packaging.txt
789@@ -6,14 +6,14 @@ series +index page.
790
791 >>> anon_browser.open('http://launchpad.test/ubuntu/hoary')
792 >>> anon_browser.getLink('All upstream links').click()
793- >>> print anon_browser.title
794+ >>> print(anon_browser.title)
795 All upstream links : ...
796
797 The page lists the upstream packaging links.
798
799 >>> content = find_main_content(anon_browser.contents)
800- >>> print extract_text(
801- ... find_tag_by_id(anon_browser.contents, 'packagings'))
802+ >>> print(extract_text(
803+ ... find_tag_by_id(anon_browser.contents, 'packagings')))
804 Source Package Upstream Project Upstream Contributor Connections
805 netapplet
806 NetApplet The Novell Network Applet
807@@ -30,7 +30,7 @@ The page lists the upstream packaging links.
808 Any use can see that this page is related to the needs packaging report. It
809 is linked, but the link to this page is not enabled.
810
811- >>> print extract_text(find_tag_by_id(content, 'related-pages'))
812+ >>> print(extract_text(find_tag_by_id(content, 'related-pages')))
813 Needs upstream links All upstream links
814
815 >>> anon_browser.getLink('Needs upstream links')
816@@ -47,14 +47,14 @@ links packages. Users can also hack the URL to set their own batch size.
817
818 >>> anon_browser.open(
819 ... 'http://launchpad.test/ubuntu/hoary/+packaging?start=0&batch=1')
820- >>> print extract_text(find_tag_by_id(
821- ... anon_browser.contents, 'packagings'))
822+ >>> print(extract_text(find_tag_by_id(
823+ ... anon_browser.contents, 'packagings')))
824 Source Package Upstream Project Upstream Contributor Connections
825 netapplet ...
826
827 >>> anon_browser.getLink('Next', index=0).click()
828- >>> print extract_text(
829- ... find_tag_by_id(anon_browser.contents, 'packagings'))
830+ >>> print(extract_text(
831+ ... find_tag_by_id(anon_browser.contents, 'packagings')))
832 Source Package Upstream Project Upstream Contributor Connections
833 evolution ...
834
835@@ -77,11 +77,11 @@ packages with the greatest need are listed first.
836
837 >>> anon_browser.open('http://launchpad.test/ubuntu/hoary')
838 >>> anon_browser.getLink('Needs upstream links').click()
839- >>> print anon_browser.title
840+ >>> print(anon_browser.title)
841 Needs upstream links : ...
842
843 >>> content = find_main_content(anon_browser.contents)
844- >>> print extract_text(find_tag_by_id(content, 'packages'))
845+ >>> print(extract_text(find_tag_by_id(content, 'packages')))
846 Source Package Bugs Translations
847 pmount No bugs 64 strings
848 linux-source-2.6.15 1 bug No strings
849@@ -103,13 +103,13 @@ pages.
850
851 The listing is batched so that the user can visit the next page listings.
852
853- >>> print extract_text(find_tag_by_id(content, 'listing-navigation'))
854+ >>> print(extract_text(find_tag_by_id(content, 'listing-navigation')))
855 1 ... 5 of 5 packages First ... Previous ... Next ... Last
856
857 Any use can see that this page is related to the packaging report. It is
858 linked, but the link to this page is not enabled.
859
860- >>> print extract_text(find_tag_by_id(content, 'related-pages'))
861+ >>> print(extract_text(find_tag_by_id(content, 'related-pages')))
862 Needs upstream links All upstream links
863
864 >>> anon_browser.getLink('All upstream links')
865diff --git a/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt b/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt
866index b7ab998..5b2819a 100644
867--- a/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt
868+++ b/lib/lp/registry/stories/gpg-coc/xx-gpg-coc.txt
869@@ -28,7 +28,7 @@ Start out with a clean page containing no imported keys:
870 >>> browser = setupBrowserFreshLogin(name12)
871 >>> browser.open("http://launchpad.test/~name12")
872 >>> browser.getLink(url='+editpgpkeys').click()
873- >>> print browser.title
874+ >>> print(browser.title)
875 Change your OpenPGP keys...
876
877 >>> browser.getControl(name='DEACTIVATE_GPGKEY')
878@@ -62,7 +62,7 @@ followed by ASCII armored encrypted confirmation instructions. Ensure that
879 the clear text instructions contain the expected URLs pointing to more help.
880
881 >>> cipher_body = msg.get_payload(decode=True)
882- >>> print cipher_body
883+ >>> print(cipher_body)
884 Hello,
885 <BLANKLINE>
886 This message contains the instructions for confirming registration of an
887@@ -123,7 +123,7 @@ Go to the link sent by email, to validate the email address.
888
889 Get redirected to +validategpg, and confirm token:
890
891- >>> print browser.url
892+ >>> print(browser.url)
893 http://launchpad.test/token/.../+validategpg
894 >>> browser.getControl('Continue').click()
895
896@@ -146,9 +146,9 @@ Verify that the key was imported with the "can encrypt" flag set:
897 >>> from lp.registry.model.gpgkey import GPGKey
898 >>> key = GPGKey.selectOneBy(
899 ... fingerprint='A419AE861E88BC9E04B9C26FBA2B9389DFD20543')
900- >>> print key.owner.name
901+ >>> print(key.owner.name)
902 name12
903- >>> print key.can_encrypt
904+ >>> print(key.can_encrypt)
905 True
906
907
908@@ -188,7 +188,7 @@ ability to decrypt text with this key.
909 The email does contain some information about the key, and a token URL
910 Sample Person should visit to verify their ownership of the key.
911
912- >>> print body
913+ >>> print(body)
914 <BLANKLINE>
915 Hello,
916 ...
917@@ -231,7 +231,7 @@ Let's look at the text.
918
919 >>> verification_content = find_main_content(
920 ... browser.contents).pre.string
921- >>> print verification_content
922+ >>> print(verification_content)
923 Please register 447DBF38C4F9C4ED752246B77D88913717B05A8F to the
924 Launchpad user name12. 2005-04-01 12:00:00 UTC
925
926@@ -354,7 +354,7 @@ Sample person has never signed a code of conduct.
927
928 >>> browser = setupBrowser(auth='Basic test@canonical.com:test')
929 >>> browser.open('http://launchpad.test/~name12/+codesofconduct')
930- >>> print extract_text(find_main_content(browser.contents))
931+ >>> print(extract_text(find_main_content(browser.contents)))
932 Codes of Conduct for Sample Person
933 Launchpad records codes of conduct you sign as commitments to the
934 principles of collaboration, tolerance and open communication that
935@@ -401,11 +401,11 @@ that there is a new version available.
936
937 >>> browser.open('http://launchpad.test/codeofconduct/1.0/+sign')
938 >>> browser.getLink('the current version').click()
939- >>> print browser.url
940+ >>> print(browser.url)
941 http://launchpad.test/codeofconduct/2.0
942
943 >>> browser.getLink('Sign it').click()
944- >>> print browser.url
945+ >>> print(browser.url)
946 http://launchpad.test/codeofconduct/2.0/+sign
947
948
949@@ -419,13 +419,13 @@ appear in the same order.
950 >>> reformatted_coc = read_file('reformatted_20_coc.asc')
951 >>> browser.getControl('Signed Code').value = reformatted_coc
952 >>> browser.getControl('Continue').click()
953- >>> print browser.url
954+ >>> print(browser.url)
955 http://launchpad.test/~name12/+codesofconduct
956
957 And now Sample Person's Codes of Conduct page shows that they've signed it.
958
959 >>> browser.open('http://launchpad.test/~name12/+codesofconduct')
960- >>> print extract_text(find_main_content(browser.contents))
961+ >>> print(extract_text(find_main_content(browser.contents)))
962 Codes of Conduct for Sample Person
963 Launchpad records codes of conduct you sign as commitments to the
964 principles of collaboration, tolerance and open communication that
965@@ -444,7 +444,7 @@ Now Sample Person will deactivate their key...
966 >>> browser.url
967 'http://launchpad.test/~name12/+editpgpkeys'
968
969- >>> print browser.contents
970+ >>> print(browser.contents)
971 <...
972 ...Your active keys...
973 ...1024D/A419AE861E88BC9E04B9C26FBA2B9389DFD20543...
974@@ -454,7 +454,7 @@ Now Sample Person will deactivate their key...
975
976 >>> browser.getControl('Deactivate Key').click()
977 >>> for tag in find_main_content(browser.contents)('p', 'error message'):
978- ... print tag.renderContents()
979+ ... print(tag.renderContents())
980 No key(s) selected for deactivation.
981
982
983@@ -465,7 +465,7 @@ Now they select the checkbox and deactivate it.
984 >>> browser.getControl('Deactivate Key').click()
985 >>> soup = find_main_content(browser.contents)
986 >>> for tag in soup('p', 'informational message'):
987- ... print tag.renderContents()
988+ ... print(tag.renderContents())
989 Deactivated key(s): 1024D/A419AE861E88BC9E04B9C26FBA2B9389DFD20543
990
991
992@@ -475,7 +475,7 @@ Sample Person already has a deactivated key.
993 >>> browser.url
994 'http://launchpad.test/~name12/+editpgpkeys'
995
996- >>> print browser.contents
997+ >>> print(browser.contents)
998 <...
999 ...Deactivated keys...
1000 ...1024D/A419AE861E88BC9E04B9C26FBA2B9389DFD20543...
1001@@ -486,7 +486,7 @@ Now they'll request their key to be reactivated.
1002 >>> browser.getControl('Reactivate Key').click()
1003 >>> soup = find_main_content(browser.contents)
1004 >>> for tag in soup('p', 'error message'):
1005- ... print tag.renderContents()
1006+ ... print(tag.renderContents())
1007 No key(s) selected for reactivation.
1008
1009 >>> browser.getControl(
1010@@ -494,7 +494,7 @@ Now they'll request their key to be reactivated.
1011 >>> browser.getControl('Reactivate Key').click()
1012 >>> soup = find_main_content(browser.contents)
1013 >>> for tag in soup('p', 'informational message'):
1014- ... print tag.renderContents()
1015+ ... print(tag.renderContents())
1016 A message has been sent to test@canonical.com with instructions to reactivate...
1017
1018
1019@@ -518,7 +518,7 @@ token type (+validategpg).
1020 >>> browser.url == '%s/+validategpg' % token_url
1021 True
1022
1023- >>> print browser.contents
1024+ >>> print(browser.contents)
1025 <...
1026 ...Confirm the OpenPGP key...A419AE861E88BC9E04B9C26FBA2B9389DFD20543...
1027 ...Sample Person...
1028@@ -530,7 +530,7 @@ Now Sample Person confirms the reactivation.
1029 >>> browser.url
1030 'http://launchpad.test/~name12'
1031
1032- >>> print browser.contents
1033+ >>> print(browser.contents)
1034 <...
1035 ...Key 1024D/A419AE861E88BC9E04B9C26FBA2B9389DFD20543 successfully
1036 reactivated...
1037@@ -539,7 +539,7 @@ Now Sample Person confirms the reactivation.
1038 And now we can see the key listed as one of Sample Person's active keys.
1039
1040 >>> browser.open('http://launchpad.test/~name12/+editpgpkeys')
1041- >>> print browser.contents
1042+ >>> print(browser.contents)
1043 <...
1044 ...Your active keys...
1045 ...1024D/A419AE861E88BC9E04B9C26FBA2B9389DFD20543...
1046@@ -567,7 +567,7 @@ Try to import a key which is already imported:
1047 False
1048 >>> stub.test_emails
1049 []
1050- >>> print browser.contents
1051+ >>> print(browser.contents)
1052 <BLANKLINE>
1053 ...
1054 ...has already been imported...
1055@@ -578,11 +578,11 @@ Try to import a key which is already imported:
1056
1057 Ensure we are raising 404 error instead of System Error
1058
1059- >>> print http(r"""
1060+ >>> print(http(r"""
1061 ... POST /codeofconduct/donkey HTTP/1.1
1062 ... Authorization: Basic Zm9vLmJhckBjYW5vbmljYWwuY29tOnRlc3Q=
1063 ... Referer: https://launchpad.test/
1064- ... """)
1065+ ... """))
1066 HTTP/1.1 404 Not Found
1067 ...
1068
1069@@ -613,7 +613,7 @@ Ensure the CoC was acknowledge by searching in the CoC Admin Console:
1070 >>> admin_browser.getControl(name='searchfor').value = ["all"]
1071 >>> admin_browser.getControl(name='name').value = "mark"
1072 >>> admin_browser.getControl(name='search').click()
1073- >>> print extract_text(find_tag_by_id(admin_browser.contents, 'matches'))
1074+ >>> print(extract_text(find_tag_by_id(admin_browser.contents, 'matches')))
1075 Mark ... paper submission accepted by Foo Bar [ACTIVE]
1076
1077 Test if the advertisement email was sent:
1078@@ -622,7 +622,7 @@ Test if the advertisement email was sent:
1079 >>> from lp.services.mail import stub
1080 >>> from_addr, to_addrs, raw_msg = stub.test_emails.pop()
1081 >>> msg = email.message_from_string(raw_msg)
1082- >>> print msg.get_payload(decode=True)
1083+ >>> print(msg.get_payload(decode=True))
1084 <BLANKLINE>
1085 ...
1086 User: 'Mark Shuttleworth'
1087diff --git a/lib/lp/registry/stories/gpg-coc/xx-ubuntu-codeofconduct-signer.txt b/lib/lp/registry/stories/gpg-coc/xx-ubuntu-codeofconduct-signer.txt
1088index 7bcc4c2..58dc5c4 100644
1089--- a/lib/lp/registry/stories/gpg-coc/xx-ubuntu-codeofconduct-signer.txt
1090+++ b/lib/lp/registry/stories/gpg-coc/xx-ubuntu-codeofconduct-signer.txt
1091@@ -7,21 +7,21 @@ Administrators can see the signed Ubuntu Code of Conducts of any given person.
1092 >>> admin_browser.open('http://launchpad.test/~name16')
1093 >>> admin_browser.url
1094 'http://launchpad.test/~name16'
1095- >>> print extract_text(
1096- ... find_tag_by_id(admin_browser.contents, 'ubuntu-coc'))
1097+ >>> print(extract_text(
1098+ ... find_tag_by_id(admin_browser.contents, 'ubuntu-coc')))
1099 Signed Ubuntu Code of Conduct: Yes
1100
1101 >>> admin_browser.getLink(url='+codesofconduct').click()
1102 >>> signatures = find_tags_by_class(admin_browser.contents, 'signature')
1103 >>> for signature in signatures:
1104- ... print extract_text(signature)
1105+ ... print(extract_text(signature))
1106 2005-09-27: digitally signed by Foo Bar
1107 (1024D/ABCDEF0123456789ABCDDCBA0000111112345678)
1108
1109 A regular user can't see the link to Foo Bar's signed codes of conduct.
1110
1111 >>> browser.open('http://launchpad.test/~name16')
1112- >>> print extract_text(find_tag_by_id(browser.contents, 'ubuntu-coc'))
1113+ >>> print(extract_text(find_tag_by_id(browser.contents, 'ubuntu-coc')))
1114 Signed Ubuntu Code of Conduct: Yes
1115
1116 >>> browser.getLink(url='+codesofconduct')
1117@@ -34,7 +34,7 @@ link to the Ubuntu Code of Conduct forms.
1118
1119 >>> browser.addHeader('Authorization', 'Basic no-priv@canonical.com:test')
1120 >>> browser.open('http://launchpad.test/~no-priv')
1121- >>> print extract_text(find_tag_by_id(browser.contents, 'ubuntu-coc'))
1122+ >>> print(extract_text(find_tag_by_id(browser.contents, 'ubuntu-coc')))
1123 Signed Ubuntu Code of Conduct: No
1124
1125 >>> browser.getLink(url='codeofconduct')
1126diff --git a/lib/lp/registry/stories/location/personlocation-edit.txt b/lib/lp/registry/stories/location/personlocation-edit.txt
1127index 53a5d66..a70877e 100644
1128--- a/lib/lp/registry/stories/location/personlocation-edit.txt
1129+++ b/lib/lp/registry/stories/location/personlocation-edit.txt
1130@@ -36,5 +36,5 @@ selected value.
1131
1132 >>> self_browser.open('http://launchpad.test/~zzz')
1133 >>> self_browser.getLink('Set location and time zone').click()
1134- >>> print self_browser.getControl(name='field.time_zone').value
1135+ >>> print(self_browser.getControl(name='field.time_zone').value)
1136 ['Europe/Madrid']
1137diff --git a/lib/lp/registry/stories/mailinglists/hosted-email-address.txt b/lib/lp/registry/stories/mailinglists/hosted-email-address.txt
1138index ec44e44..f9cebb1 100644
1139--- a/lib/lp/registry/stories/mailinglists/hosted-email-address.txt
1140+++ b/lib/lp/registry/stories/mailinglists/hosted-email-address.txt
1141@@ -38,7 +38,7 @@ Launchpad sends that address a confirmation message.
1142 >>> user_browser.getControl(
1143 ... name='field.contact_address').value = 'bar@example.com'
1144 >>> user_browser.getControl('Change').click()
1145- >>> print user_browser.title
1146+ >>> print(user_browser.title)
1147 Aardvarks in Launchpad
1148 >>> print_feedback_messages(user_browser.contents)
1149 A confirmation message has been sent to...
1150@@ -47,9 +47,9 @@ Launchpad sends that address a confirmation message.
1151 []
1152 >>> import email
1153 >>> msg = email.message_from_string(raw_msg)
1154- >>> print msg['From']
1155+ >>> print(msg['From'])
1156 Launchpad Email Validator <noreply@launchpad.net>
1157- >>> print msg['Subject']
1158+ >>> print(msg['Subject'])
1159 Launchpad: Validate your team's contact email address
1160
1161 When the confirmation token url is followed, the external email address is
1162@@ -59,10 +59,10 @@ confirmed.
1163 ... get_token_url_from_email)
1164 >>> token_url = get_token_url_from_email(raw_msg)
1165 >>> user_browser.open(token_url)
1166- >>> print user_browser.title
1167+ >>> print(user_browser.title)
1168 Confirm email address
1169 >>> user_browser.getControl('Continue').click()
1170- >>> print user_browser.title
1171+ >>> print(user_browser.title)
1172 Aardvarks in Launchpad
1173 >>> print_feedback_messages(user_browser.contents)
1174 Email address successfully confirmed.
1175diff --git a/lib/lp/registry/stories/mailinglists/lifecycle.txt b/lib/lp/registry/stories/mailinglists/lifecycle.txt
1176index ca20341..fccd031 100644
1177--- a/lib/lp/registry/stories/mailinglists/lifecycle.txt
1178+++ b/lib/lp/registry/stories/mailinglists/lifecycle.txt
1179@@ -15,19 +15,19 @@ The owner of Landscape Developers applies for a mailing list.
1180 >>> browser.open('http://launchpad.test/~landscape-developers')
1181 >>> browser.getLink(url='+mailinglist').click()
1182 >>> from lp.services.helpers import backslashreplace
1183- >>> print backslashreplace(browser.title)
1184+ >>> print(backslashreplace(browser.title))
1185 Mailing list configuration...
1186
1187 They think for a second whether their mailing list is for Ubuntu or not.
1188
1189- >>> print extract_text(find_tag_by_id(browser.contents, 'ubuntu-notice'))
1190+ >>> print(extract_text(find_tag_by_id(browser.contents, 'ubuntu-notice')))
1191 Ubuntu does not use Launchpad to host its mailing lists. Create them
1192 at lists.ubuntu.com instead.
1193- >>> print browser.getLink('lists.ubuntu.com')
1194+ >>> print(browser.getLink('lists.ubuntu.com'))
1195 <Link text='lists.ubuntu.com' url='https://lists.ubuntu.com'>
1196
1197 >>> browser.getControl('Create new Mailing List').click()
1198- >>> print browser.title
1199+ >>> print(browser.title)
1200 Landscape Developers in Launchpad
1201 >>> print_feedback_messages(browser.contents)
1202 The mailing list is being created and will be available for use in a few minutes.
1203@@ -52,7 +52,7 @@ Just because a mailing list has been applied for does not mean it has an
1204 archive link yet.
1205
1206 >>> browser.open('http://launchpad.test/~landscape-developers')
1207- >>> print find_tag_by_id(browser.contents, 'mailing-list-archive')
1208+ >>> print(find_tag_by_id(browser.contents, 'mailing-list-archive'))
1209 None
1210
1211 Even after the list has been created, it still cannot be used as the contact
1212@@ -60,7 +60,7 @@ address until Mailman has acknowledged successful creation.
1213
1214 >>> browser.reload()
1215 >>> browser.getLink(url='+mailinglist').click()
1216- >>> print mailing_list_status_message(browser.contents)
1217+ >>> print(mailing_list_status_message(browser.contents))
1218 This team's mailing list will be available within a few minutes.
1219
1220 Mailman eventually wakes up and creates the mailing list.
1221@@ -78,14 +78,14 @@ is true even if no messages have yet been posted to the mailing list (since
1222 the archiver will display an informative message to that effect).
1223
1224 >>> browser.open('http://launchpad.test/~landscape-developers')
1225- >>> print extract_link_from_tag(
1226- ... find_tag_by_id(browser.contents, 'mailing-list-archive'))
1227+ >>> print(extract_link_from_tag(
1228+ ... find_tag_by_id(browser.contents, 'mailing-list-archive')))
1229 http://lists.launchpad.test/landscape-developers
1230
1231 The team's overview page also displays the posting address.
1232
1233- >>> print extract_text(
1234- ... find_tag_by_id(browser.contents, 'mailing-list-posting-address'))
1235+ >>> print(extract_text(
1236+ ... find_tag_by_id(browser.contents, 'mailing-list-posting-address')))
1237 landscape-developers@lists.launchpad.test
1238
1239 Now that the mailing list is active, it can be used as the team's contact
1240@@ -94,8 +94,8 @@ address.
1241 >>> from lp.testing.pages import strip_label
1242
1243 >>> browser.getLink(url='+mailinglist').click()
1244- >>> print extract_text(find_tag_by_id(browser.contents,
1245- ... 'mailing_list_not_contact_address'))
1246+ >>> print(extract_text(find_tag_by_id(browser.contents,
1247+ ... 'mailing_list_not_contact_address')))
1248 The mailing list is not set as the team contact address. You can
1249 set it.
1250
1251@@ -110,7 +110,7 @@ address.
1252
1253 The mailing list's configuration screen is also now available.
1254
1255- >>> print browser.getLink(url='+mailinglist').url
1256+ >>> print(browser.getLink(url='+mailinglist').url)
1257 http://launchpad.test/~landscape-developers/+mailinglist
1258
1259 When the mailing list is not the team's contact address, the mailing
1260@@ -120,8 +120,8 @@ list configuration screen displays a message to this effect.
1261 >>> browser.getControl('Change').click()
1262
1263 >>> browser.getLink(url='+mailinglist').click()
1264- >>> print extract_text(find_tag_by_id(browser.contents,
1265- ... 'mailing_list_not_contact_address'))
1266+ >>> print(extract_text(find_tag_by_id(browser.contents,
1267+ ... 'mailing_list_not_contact_address')))
1268 The mailing list is not set as the team contact address. You can
1269 set it.
1270
1271@@ -130,7 +130,7 @@ The message contains a link to the contact address screen.
1272 >>> browser.getLink('set it').click()
1273 >>> browser.getControl('The Launchpad mailing list').selected = True
1274 >>> browser.getControl('Change').click()
1275- >>> print browser.title
1276+ >>> print(browser.title)
1277 Landscape Developers in Launchpad
1278
1279 When the mailing list is the team's contact address, the message does
1280@@ -169,15 +169,15 @@ to 'each user individually'.
1281 >>> act()
1282 >>> browser.open(
1283 ... 'http://launchpad.test/~landscape-developers/+mailinglist')
1284- >>> print mailing_list_status_message(browser.contents)
1285+ >>> print(mailing_list_status_message(browser.contents))
1286 This team's mailing list has been deactivated.
1287
1288 A deactivated mailing list still has a link to its archive, because archives
1289 are never deleted.
1290
1291 >>> browser.open('http://launchpad.test/~landscape-developers')
1292- >>> print extract_link_from_tag(
1293- ... find_tag_by_id(browser.contents, 'mailing-list-archive'))
1294+ >>> print(extract_link_from_tag(
1295+ ... find_tag_by_id(browser.contents, 'mailing-list-archive')))
1296 http://lists.launchpad.test/landscape-developers
1297
1298 An inactive mailing list can be reactivated.
1299@@ -205,8 +205,8 @@ This does not restore the mailing list as the team's contact method:
1300 Of course, the reactivated list still has a link to its archive.
1301
1302 >>> browser.open('http://launchpad.test/~landscape-developers')
1303- >>> print extract_link_from_tag(
1304- ... find_tag_by_id(browser.contents, 'mailing-list-archive'))
1305+ >>> print(extract_link_from_tag(
1306+ ... find_tag_by_id(browser.contents, 'mailing-list-archive')))
1307 http://lists.launchpad.test/landscape-developers
1308
1309 The archive link is only available for public mailing lists as shown above,
1310@@ -222,8 +222,8 @@ and for private mailing lists for team members.
1311 The owner of the list can see archive link.
1312
1313 >>> user_browser.open('http://launchpad.test/~bassists')
1314- >>> print extract_link_from_tag(
1315- ... find_tag_by_id(user_browser.contents, 'mailing-list-archive'))
1316+ >>> print(extract_link_from_tag(
1317+ ... find_tag_by_id(user_browser.contents, 'mailing-list-archive')))
1318 http://lists.launchpad.test/bassists
1319
1320 Anonymous users cannot see the link, because they cannot even see the
1321@@ -255,15 +255,15 @@ Members who are not owners can see the link.
1322 >>> admin_browser.getControl('Add Member').click()
1323
1324 >>> cprov_browser.open('http://launchpad.test/~bassists')
1325- >>> print extract_link_from_tag(
1326- ... find_tag_by_id(cprov_browser.contents, 'mailing-list-archive'))
1327+ >>> print(extract_link_from_tag(
1328+ ... find_tag_by_id(cprov_browser.contents, 'mailing-list-archive')))
1329 http://lists.launchpad.test/bassists
1330
1331 Admins who are not members of the team can see the link too.
1332
1333 >>> admin_browser.open('http://launchpad.test/~bassists')
1334- >>> print extract_link_from_tag(
1335- ... find_tag_by_id(admin_browser.contents, 'mailing-list-archive'))
1336+ >>> print(extract_link_from_tag(
1337+ ... find_tag_by_id(admin_browser.contents, 'mailing-list-archive')))
1338 http://lists.launchpad.test/bassists
1339
1340
1341@@ -287,14 +287,14 @@ to delete the archives of an INACTIVE list, this must be done manually.
1342 >>> def print_list_state(team_name=u'aardvarks'):
1343 ... login('foo.bar@canonical.com')
1344 ... mailing_list = getUtility(IMailingListSet).get(team_name)
1345- ... print mailing_list.status.name
1346+ ... print(mailing_list.status.name)
1347 ... logout()
1348
1349 The team owner can see that they can purge or reactivate mailing list.
1350
1351 >>> user_browser.open('http://launchpad.test/~aardvarks/+mailinglist')
1352 >>> user_browser.getControl('Create new Mailing List').click()
1353- >>> print user_browser.title
1354+ >>> print(user_browser.title)
1355 Aardvarks in Launchpad
1356 >>> act()
1357 >>> user_browser.open('http://launchpad.test/~aardvarks/+mailinglist')
1358@@ -310,7 +310,7 @@ The team owner can see that they can purge or reactivate mailing list.
1359 ... return tag.p.contents[0].strip()
1360
1361 >>> user_browser.getLink(url='+mailinglist').click()
1362- >>> print purge_text(user_browser)
1363+ >>> print(purge_text(user_browser))
1364 You can purge this mailing list...
1365
1366 >>> user_browser.getControl('Reactivate this Mailing List')
1367@@ -338,7 +338,7 @@ administrator, can purge a list.
1368
1369 >>> expert_browser = setupBrowser('Basic test@canonical.com:test')
1370 >>> expert_browser.open('http://launchpad.test/~aardvarks/+mailinglist')
1371- >>> print purge_text(expert_browser)
1372+ >>> print(purge_text(expert_browser))
1373 You can purge this mailing list...
1374
1375 A constructing, modified, updating, or deactivating or mod-failed list cannot
1376@@ -361,9 +361,9 @@ be purged.
1377 ... set_list_state(u'aardvarks', status)
1378 ... print_list_state()
1379 ... admin_browser.open(url)
1380- ... print purge_text(admin_browser)
1381+ ... print(purge_text(admin_browser))
1382 ... expert_browser.open(url)
1383- ... print purge_text(expert_browser)
1384+ ... print(purge_text(expert_browser))
1385
1386 A purged list acts as if it doesn't even exist.
1387
1388diff --git a/lib/lp/registry/stories/mailinglists/subscriptions.txt b/lib/lp/registry/stories/mailinglists/subscriptions.txt
1389index d993e0a..9cbc162 100644
1390--- a/lib/lp/registry/stories/mailinglists/subscriptions.txt
1391+++ b/lib/lp/registry/stories/mailinglists/subscriptions.txt
1392@@ -92,7 +92,7 @@ it's currently the team contact method.
1393 >>> carlos_browser.getLink(url="+editmailinglists").click()
1394
1395 >>> from lp.services.helpers import backslashreplace
1396- >>> print backslashreplace(carlos_browser.title)
1397+ >>> print(backslashreplace(carlos_browser.title))
1398 Change your mailing list subscriptions...
1399
1400 >>> admins = carlos_browser.getControl(name='field.subscription.admins')
1401@@ -103,9 +103,9 @@ it's currently the team contact method.
1402 ['Preferred address', "Don't subscribe",
1403 'carlos@canonical.com', 'carlos@test.com']
1404
1405- >>> print admins.value
1406+ >>> print(admins.value)
1407 ["Don't subscribe"]
1408- >>> print rosetta_admins.value
1409+ >>> print(rosetta_admins.value)
1410 ["Don't subscribe"]
1411
1412 However, testing-spanish-team's list doesn't show up because its creation has
1413@@ -133,9 +133,9 @@ explicitly with whatever is his preferred email address.
1414 >>> admins = carlos_browser.getControl(name='field.subscription.admins')
1415 >>> rosetta_admins = carlos_browser.getControl(
1416 ... name='field.subscription.rosetta-admins')
1417- >>> print admins.value
1418+ >>> print(admins.value)
1419 ['Preferred address']
1420- >>> print rosetta_admins.value
1421+ >>> print(rosetta_admins.value)
1422 ["Don't subscribe"]
1423
1424 Carlos can subscribe to a list using any of his validated addresses
1425@@ -148,9 +148,9 @@ explicitly.
1426 >>> admins = carlos_browser.getControl(name='field.subscription.admins')
1427 >>> rosetta_admins = carlos_browser.getControl(
1428 ... name='field.subscription.rosetta-admins')
1429- >>> print admins.value
1430+ >>> print(admins.value)
1431 ['carlos@canonical.com']
1432- >>> print rosetta_admins.value
1433+ >>> print(rosetta_admins.value)
1434 ['carlos@test.com']
1435
1436 He can switch from one address to another, or from a specific address
1437@@ -163,9 +163,9 @@ to the preferred address.
1438 >>> admins = carlos_browser.getControl(name='field.subscription.admins')
1439 >>> rosetta_admins = carlos_browser.getControl(
1440 ... name='field.subscription.rosetta-admins')
1441- >>> print admins.value
1442+ >>> print(admins.value)
1443 ['Preferred address']
1444- >>> print rosetta_admins.value
1445+ >>> print(rosetta_admins.value)
1446 ['carlos@canonical.com']
1447
1448 Finally, he can unsubscribe from any mailing list by setting the subscription
1449@@ -181,9 +181,9 @@ menu item to "Don't subscribe".
1450 >>> admins = carlos_browser.getControl(name='field.subscription.admins')
1451 >>> rosetta_admins = carlos_browser.getControl(
1452 ... name='field.subscription.rosetta-admins')
1453- >>> print admins.value
1454+ >>> print(admins.value)
1455 ["Don't subscribe"]
1456- >>> print rosetta_admins.value
1457+ >>> print(rosetta_admins.value)
1458 ["Don't subscribe"]
1459
1460
1461@@ -200,7 +200,7 @@ Admins team, and he should know if the list is available.
1462
1463 >>> carlos_browser.open('http://launchpad.test/~carlos')
1464 >>> carlos_browser.getLink(url="+editmailinglists").click()
1465- >>> print backslashreplace(carlos_browser.title)
1466+ >>> print(backslashreplace(carlos_browser.title))
1467 Change your mailing list subscriptions...
1468
1469 >>> rosetta_admins = carlos_browser.getControl(
1470@@ -223,7 +223,7 @@ Now Jdub can apply for team membership and mailing list access.
1471 'http://launchpad.test/~rosetta-admins'
1472
1473 >>> for tag in find_tags_by_class(browser.contents, 'informational'):
1474- ... print tag.renderContents()
1475+ ... print(tag.renderContents())
1476 Your request to join Rosetta Administrators is awaiting approval.
1477 Your mailing list subscription is awaiting approval.
1478
1479@@ -237,7 +237,7 @@ screen.
1480 >>> jdub_browser = setupBrowserFreshLogin(jdub)
1481 >>> jdub_browser.open('http://launchpad.test/~jdub')
1482 >>> jdub_browser.getLink(url="+editmailinglists").click()
1483- >>> print jdub_browser.title
1484+ >>> print(jdub_browser.title)
1485 Change your mailing list subscriptions...
1486
1487 >>> jdub_browser.getControl(
1488@@ -254,7 +254,7 @@ been approved for the team.
1489 >>> admin_browser.getLink('All members').click()
1490 >>> admin_browser.getLink(
1491 ... url='/~rosetta-admins/+member/jdub').click()
1492- >>> print admin_browser.url
1493+ >>> print(admin_browser.url)
1494 http://launchpad.test/~rosetta-admins/+member/jdub
1495 >>> admin_browser.getControl(name='approve').click()
1496
1497@@ -262,7 +262,7 @@ His mailing list subscription is now available to be managed.
1498
1499 >>> jdub_browser.open('http://launchpad.test/~jdub')
1500 >>> jdub_browser.getLink(url="+editmailinglists").click()
1501- >>> print jdub_browser.title
1502+ >>> print(jdub_browser.title)
1503 Change your mailing list subscriptions...
1504
1505 >>> rosetta_team = jdub_browser.getControl(
1506@@ -280,7 +280,7 @@ list is not presented.
1507
1508 >>> browser.open('http://launchpad.test/~rosetta-admins')
1509 >>> browser.getLink('Join the team').click()
1510- >>> print browser.url
1511+ >>> print(browser.url)
1512 http://launchpad.test/~rosetta-admins/+join
1513
1514 >>> browser.getControl(name='mailinglist_subscribe')
1515@@ -294,7 +294,7 @@ for teams that don't have mailing lists.
1516
1517 >>> browser.open('http://launchpad.test/~testing-spanish-team')
1518 >>> browser.getLink('Join the team').click()
1519- >>> print browser.url
1520+ >>> print(browser.url)
1521 http://launchpad.test/~testing-spanish-team/+join
1522
1523 >>> browser.getControl(name='mailinglist_subscribe')
1524@@ -309,7 +309,7 @@ if we visit the URL directly, as the link is not present on the Team
1525 Overview.)
1526
1527 >>> browser.open('http://launchpad.test/~launchpad/+join')
1528- >>> print browser.url
1529+ >>> print(browser.url)
1530 http://launchpad.test/~launchpad/+join
1531
1532 >>> browser.getControl(name='mailinglist_subscribe')
1533@@ -330,7 +330,7 @@ page, because he is not subscribed to the team mailing list.
1534
1535 >>> carlos_browser.open('http://launchpad.test/~admins')
1536 >>> carlos_browser.getLink('Subscribe to mailing list').click()
1537- >>> print carlos_browser.url
1538+ >>> print(carlos_browser.url)
1539 http://launchpad.test/~carlos/+editmailinglists
1540
1541 The unsubscribe link is visible for the rosetta admins team, which
1542@@ -343,11 +343,11 @@ has an active mailing list.
1543 ... name='field.subscription.rosetta-admins')
1544 >>> rosetta_admins.value = ['Preferred address']
1545 >>> carlos_browser.getControl('Update Subscriptions').click()
1546- >>> print rosetta_admins.value
1547+ >>> print(rosetta_admins.value)
1548 ['Preferred address']
1549 >>> for tag in find_tags_by_class(
1550 ... carlos_browser.contents, 'informational'):
1551- ... print tag.renderContents()
1552+ ... print(tag.renderContents())
1553 Subscriptions updated.
1554
1555 >>> carlos_browser.open('http://launchpad.test/~rosetta-admins')
1556@@ -361,8 +361,8 @@ Clicking the link will unsubscribe you from the list immediately.
1557 You have been unsubscribed from the team mailing list.
1558
1559 >>> carlos_browser.open('http://launchpad.test/~rosetta-admins')
1560- >>> print extract_text(
1561- ... find_tag_by_id(carlos_browser.contents, 'mailing-lists'))
1562+ >>> print(extract_text(
1563+ ... find_tag_by_id(carlos_browser.contents, 'mailing-lists')))
1564 Mailing list...
1565 Subscribe to mailing list...
1566
1567@@ -370,8 +370,8 @@ The Ubuntu translators team, which does not have any lists configured,
1568 does not show either link.
1569
1570 >>> carlos_browser.open('http://launchpad.test/~ubuntu-translators')
1571- >>> print extract_text(
1572- ... find_portlet(carlos_browser.contents, 'Mailing list'))
1573+ >>> print(extract_text(
1574+ ... find_portlet(carlos_browser.contents, 'Mailing list')))
1575 Mailing list
1576 This team does not use Launchpad to host a mailing list.
1577 Create a mailing list
1578@@ -395,8 +395,8 @@ mailing list subscribers, if there is an active mailing list. The
1579 rosetta admins team has such a list and carlos is the owner.
1580
1581 >>> carlos_browser.open('http://launchpad.test/~rosetta-admins')
1582- >>> print extract_text(
1583- ... find_portlet(carlos_browser.contents, 'Mailing list'))
1584+ >>> print(extract_text(
1585+ ... find_portlet(carlos_browser.contents, 'Mailing list')))
1586 Mailing list
1587 rosetta-admins@lists.launchpad.test
1588 Policy: You must be a team member to subscribe to the team mailing list.
1589@@ -409,11 +409,11 @@ The mailing list for Rosetta Admins has no subscribers.
1590 because his membership on Rosetta Admins hasn't been approved)
1591
1592 >>> carlos_browser.getLink('View subscribers').click()
1593- >>> print carlos_browser.title
1594+ >>> print(carlos_browser.title)
1595 Mailing list subscribers for the Rosetta Administrators team...
1596
1597- >>> print extract_text(
1598- ... find_tag_by_id(carlos_browser.contents, 'subscribers'))
1599+ >>> print(extract_text(
1600+ ... find_tag_by_id(carlos_browser.contents, 'subscribers')))
1601 Nobody has subscribed to this team's mailing list yet.
1602
1603 If it had subscribers, though, they'd be shown on that page, in a batched
1604@@ -439,15 +439,15 @@ list.
1605 >>> rosetta_admins.mailing_list.subscribe(jordi)
1606 >>> logout()
1607 >>> carlos_browser.reload()
1608- >>> print extract_text(
1609- ... find_tag_by_id(carlos_browser.contents, 'subscribers'))
1610+ >>> print(extract_text(
1611+ ... find_tag_by_id(carlos_browser.contents, 'subscribers')))
1612 The following people are subscribed...
1613 Guilherme Salgado
1614 1 of 2 results...
1615
1616 >>> carlos_browser.getLink('Next').click()
1617- >>> print extract_text(
1618- ... find_tag_by_id(carlos_browser.contents, 'subscribers'))
1619+ >>> print(extract_text(
1620+ ... find_tag_by_id(carlos_browser.contents, 'subscribers')))
1621 The following people are subscribed...
1622 Jordi Mallach
1623 2 of 2 results...
1624@@ -474,7 +474,7 @@ list based on a setting in the person's Email preferences page.
1625
1626 >>> carlos_browser.open('http://launchpad.test/~carlos')
1627 >>> carlos_browser.getLink(url="+editmailinglists").click()
1628- >>> print backslashreplace(carlos_browser.title)
1629+ >>> print(backslashreplace(carlos_browser.title))
1630 Change your mailing list subscriptions...
1631
1632 Carlos's default setting, 'Ask me when I join a team', is still in place.
1633@@ -534,8 +534,8 @@ team they are a member of creates a new mailing list. This notification
1634 offers them to join the new mailing list. This page informs them of this
1635 behaviour.
1636
1637- >>> print extract_text(
1638- ... find_tag_by_id(carlos_browser.contents, 'notification-info'))
1639+ >>> print(extract_text(
1640+ ... find_tag_by_id(carlos_browser.contents, 'notification-info')))
1641 When a team you are a member of creates a new mailing list, you will
1642 receive an email notification offering you the opportunity to join the new
1643 mailing list. Launchpad can also automatically subscribe you to a team's
1644@@ -562,10 +562,10 @@ subscription settings will see the box checked by default.
1645
1646 >>> browser.open('http://launchpad.test/~rosetta-admins')
1647 >>> browser.getLink('Join the team').click()
1648- >>> print browser.url
1649+ >>> print(browser.url)
1650 http://launchpad.test/~rosetta-admins/+join
1651
1652- >>> print browser.getControl(name='field.mailinglist_subscribe').value
1653+ >>> print(browser.getControl(name='field.mailinglist_subscribe').value)
1654 True
1655
1656 # Change James' setting
1657@@ -578,7 +578,7 @@ subscription settings will see the box checked by default.
1658
1659 >>> browser.open('http://launchpad.test/~rosetta-admins')
1660 >>> browser.getLink('Join the team').click()
1661- >>> print browser.getControl(name='field.mailinglist_subscribe').value
1662+ >>> print(browser.getControl(name='field.mailinglist_subscribe').value)
1663 True
1664
1665 Users who have chosen to never be auto-subscribed to mailing
1666@@ -594,8 +594,8 @@ lists will not have the box checked.
1667
1668 >>> browser.open('http://launchpad.test/~rosetta-admins')
1669 >>> browser.getLink('Join the team').click()
1670- >>> print bool(
1671- ... browser.getControl(name='field.mailinglist_subscribe').value)
1672+ >>> print(bool(
1673+ ... browser.getControl(name='field.mailinglist_subscribe').value))
1674 False
1675
1676 # Restore James' setting.
1677diff --git a/lib/lp/registry/stories/mailinglists/welcome-message.txt b/lib/lp/registry/stories/mailinglists/welcome-message.txt
1678index 2565616..d7dd43d 100644
1679--- a/lib/lp/registry/stories/mailinglists/welcome-message.txt
1680+++ b/lib/lp/registry/stories/mailinglists/welcome-message.txt
1681@@ -22,7 +22,7 @@ Changes to the welcome message take effect as soon as Mailman can act on it.
1682
1683 >>> user_browser.getLink('Configure mailing list').click()
1684 >>> welcome_message = user_browser.getControl('Welcome message')
1685- >>> print welcome_message.value
1686+ >>> print(welcome_message.value)
1687 Welcome to the Aardvarks.
1688
1689 >>> from lp.registry.tests import mailinglists_helper
1690@@ -55,6 +55,6 @@ What if Mailman failed to apply the change?
1691 >>> logout()
1692
1693 >>> user_browser.open('http://launchpad.test/~aardvarks/+mailinglist')
1694- >>> print extract_text(find_tag_by_id(
1695- ... user_browser.contents, 'mailing_list_status_message').strong)
1696+ >>> print(extract_text(find_tag_by_id(
1697+ ... user_browser.contents, 'mailing_list_status_message').strong))
1698 This team's mailing list is in an inconsistent state...
1699diff --git a/lib/lp/registry/stories/milestone/object-milestones.txt b/lib/lp/registry/stories/milestone/object-milestones.txt
1700index eb0efe0..5eaf227 100644
1701--- a/lib/lp/registry/stories/milestone/object-milestones.txt
1702+++ b/lib/lp/registry/stories/milestone/object-milestones.txt
1703@@ -46,7 +46,7 @@ Distributions
1704 >>> anon_browser.url
1705 'http://launchpad.test/debian/+milestones'
1706
1707- >>> print all_milestones(anon_browser)
1708+ >>> print(all_milestones(anon_browser))
1709 Debian 3.1 Woody ...
1710 Debian 3.1-rc1 Woody ...
1711
1712@@ -55,12 +55,12 @@ Distribution Series
1713 ...................
1714
1715 >>> anon_browser.open('http://launchpad.test/debian/woody/+milestones')
1716- >>> print all_milestones(anon_browser)
1717+ >>> print(all_milestones(anon_browser))
1718 Debian 3.1 ...
1719 Debian 3.1-rc1 ...
1720
1721 >>> anon_browser.open('http://launchpad.test/debian/sarge/+milestones')
1722- >>> print all_milestones(anon_browser)
1723+ >>> print(all_milestones(anon_browser))
1724 None
1725
1726
1727@@ -75,7 +75,7 @@ counts (because they are costly to retrieve).
1728 >>> anon_browser.url
1729 'http://launchpad.test/firefox/+milestones'
1730
1731- >>> print all_milestones(anon_browser)
1732+ >>> print(all_milestones(anon_browser))
1733 Mozilla Firefox 1.0.0 "First Stable Release" 1.0 None ...
1734 Mozilla Firefox 0.9.2 "One (secure) Tree Hill" trunk None ...
1735 Mozilla Firefox 0.9.1 "One Tree Hill (v2)" trunk None ...
1736@@ -88,7 +88,7 @@ link to the project groups's milestone's page.
1737
1738 >>> anon_browser.getLink(
1739 ... 'View milestones for The Mozilla Project').click()
1740- >>> print anon_browser.title
1741+ >>> print(anon_browser.title)
1742 Milestones : The Mozilla Project
1743
1744
1745@@ -96,14 +96,14 @@ Product Series
1746 ..............
1747
1748 >>> anon_browser.open('http://launchpad.test/firefox/trunk/+milestones')
1749- >>> print all_milestones(anon_browser)
1750+ >>> print(all_milestones(anon_browser))
1751 Mozilla Firefox 0.9.2 ...
1752 Mozilla Firefox 0.9.1 ...
1753 Mozilla Firefox 0.9 ...
1754 Mozilla Firefox 1.0 ...
1755
1756 >>> anon_browser.open('http://launchpad.test/firefox/1.0/+milestones')
1757- >>> print all_milestones(anon_browser)
1758+ >>> print(all_milestones(anon_browser))
1759 Mozilla Firefox 1.0.0 ...
1760
1761
1762@@ -123,7 +123,7 @@ the bug and blueprint counts (because they are costly to retrieve).
1763 >>> logout()
1764 >>> anon_browser.open('http://launchpad.test/gnome')
1765 >>> anon_browser.getLink('See all milestones').click()
1766- >>> print all_milestones(anon_browser)
1767+ >>> print(all_milestones(anon_browser))
1768 GNOME 2.1.6 None This is an inactive milestone
1769 GNOME 1.0 None This is an inactive milestone
1770 GNOME 1.3 A date This is an inactive milestone
1771@@ -139,17 +139,17 @@ Pages for the individual milestones show all specifications and bugtasks
1772 associated with that milestone for products of this project:
1773
1774 >>> anon_browser.getLink('1.1', index=1).click()
1775- >>> print anon_browser.title
1776+ >>> print(anon_browser.title)
1777 1.1 : GNOME
1778
1779 >>> specs = find_tag_by_id(anon_browser.contents, 'milestone_specs')
1780- >>> print extract_text(specs)
1781+ >>> print(extract_text(specs))
1782 Blueprint Project Priority Assignee Delivery
1783 Title evolution specification Evolution High Unknown
1784 Title gnomebaker specification gnomebaker High Unknown
1785
1786 >>> bugtasks = find_tag_by_id(anon_browser.contents, 'milestone_bugtasks')
1787- >>> print extract_text(bugtasks)
1788+ >>> print(extract_text(bugtasks))
1789 Bug report Project Importance Assignee Status ...
1790 Milestone test bug for evolution Evolution Undecided Confirmed ...
1791 Milestone test bug for gnomebaker gnomebaker Undecided Confirmed ...
1792@@ -158,7 +158,7 @@ associated with that milestone for products of this project:
1793 A project milestone page has the same navigation as the project:
1794
1795 >>> anon_browser.open('http://launchpad.test/firefox/+milestone/1.0')
1796- >>> print anon_browser.title
1797+ >>> print(anon_browser.title)
1798 1.0 : Mozilla Firefox
1799
1800 >>> print_location(anon_browser.contents)
1801@@ -176,7 +176,7 @@ Similarly, a distribution milestone page has the same navigation as the
1802 distribution:
1803
1804 >>> anon_browser.open('http://launchpad.test/debian/+milestone/3.1')
1805- >>> print anon_browser.title
1806+ >>> print(anon_browser.title)
1807 3.1 : Debian
1808
1809 >>> print_location(anon_browser.contents)
1810@@ -251,42 +251,42 @@ Mozilla Firefox product, to complement the existing series "1.0":
1811
1812 >>> browser.open('http://launchpad.test/firefox')
1813 >>> browser.getLink('Register a series').click()
1814- >>> print browser.title
1815+ >>> print(browser.title)
1816 Register a new Mozilla Firefox release series...
1817
1818 >>> browser.getControl('Name').value = '2.0'
1819 >>> browser.getControl('Summary').value = 'The Firefox 2.0 Series'
1820 >>> browser.getControl('Register Series').click()
1821- >>> print browser.title
1822+ >>> print(browser.title)
1823 Series 2.0 : Mozilla Firefox
1824
1825 We'll also create a new test milestone within the "trunk" series:
1826
1827 >>> browser.open('http://launchpad.test/firefox/trunk')
1828- >>> print browser.title
1829+ >>> print(browser.title)
1830 Series trunk : Mozilla Firefox
1831
1832 >>> browser.getLink('Create milestone').click()
1833- >>> print browser.title
1834+ >>> print(browser.title)
1835 Register a new milestone...
1836
1837 >>> milestone = 'test-milestone'
1838 >>> browser.getControl('Name').value = milestone
1839 >>> browser.getControl('Date Targeted').value = '2100-08-08'
1840 >>> browser.getControl('Register Milestone').click()
1841- >>> print browser.title
1842+ >>> print(browser.title)
1843 Series trunk : Mozilla Firefox
1844
1845 >>> browser.open('http://launchpad.test/firefox/trunk')
1846
1847- >>> print extract_text(find_tag_by_id(browser.contents, 'series-trunk'))
1848+ >>> print(extract_text(find_tag_by_id(browser.contents, 'series-trunk')))
1849 Version Expected Released Summary
1850 Mozilla Firefox 0.9.2... Set date Change details 2004-10-16 ...
1851 Mozilla Firefox... Set date Change details 2004-10-16 ...
1852 Mozilla Firefox test-milestone 2100-08-08 Release now ...
1853
1854 >>> browser.getLink('test-milestone').click()
1855- >>> print browser.title
1856+ >>> print(browser.title)
1857 test-milestone : Mozilla Firefox
1858
1859 >>> milestone_url = browser.url
1860@@ -295,11 +295,11 @@ Let's target an existing bug to both series "1.0" and series "2.0":
1861
1862 >>> from lp.services.helpers import backslashreplace
1863 >>> browser.open(bug_1_url)
1864- >>> print backslashreplace(browser.title)
1865+ >>> print(backslashreplace(browser.title))
1866 Bug #...Test Bug 1... : Bugs : Mozilla Firefox
1867
1868 >>> browser.getLink('Target to series').click()
1869- >>> print browser.title
1870+ >>> print(browser.title)
1871 Target bug #... to series...
1872
1873 >>> browser.getControl('1.0').selected = True
1874@@ -308,7 +308,7 @@ Let's target an existing bug to both series "1.0" and series "2.0":
1875
1876 The bug page now lists a bug task for each series:
1877
1878- >>> print extract_text(first_tag_by_class(browser.contents, 'listing'))
1879+ >>> print(extract_text(first_tag_by_class(browser.contents, 'listing')))
1880 Affects Status Importance ...
1881 1.0 ... New Undecided ...
1882 2.0 ... New Undecided ...
1883@@ -332,7 +332,7 @@ milestone:
1884 >>> browser.getControl('Importance').value = ['Critical']
1885 >>> browser.getControl('Save Changes').click()
1886
1887- >>> print extract_text(first_tag_by_class(browser.contents, 'listing'))
1888+ >>> print(extract_text(first_tag_by_class(browser.contents, 'listing')))
1889 Affects Status Importance ...
1890 1.0 ... New Critical ...
1891
1892@@ -345,7 +345,7 @@ method. However this time we'll use a different importance:
1893 >>> browser.getControl('Importance').value = ['High']
1894 >>> browser.getControl('Save Changes').click()
1895
1896- >>> print extract_text(first_tag_by_class(browser.contents, 'listing'))
1897+ >>> print(extract_text(first_tag_by_class(browser.contents, 'listing')))
1898 Affects Status Importance ...
1899 2.0 ... New High ...
1900
1901@@ -354,14 +354,14 @@ listing:
1902
1903 >>> browser.open(milestone_url)
1904 >>> bug_table = find_tag_by_id(browser.contents, 'milestone_bugtasks')
1905- >>> print extract_text(bug_table )
1906+ >>> print(extract_text(bug_table ))
1907 Bug report Importance Assignee Status
1908 #... Test Bug 1 Critical New
1909 #... Test Bug 1 High New
1910
1911 Each bugtask has one or more badges.
1912
1913- >>> print bug_table.findAll('tr')[1]
1914+ >>> print(bug_table.findAll('tr')[1])
1915 <tr>...Test Bug 1...<a...alt="milestone test-milestone"...
1916 class="sprite milestone"...>...
1917
1918@@ -382,8 +382,8 @@ that milestone's bug listing:
1919 >>> browser.getControl('Save Changes').click()
1920
1921 >>> browser.open(milestone_url)
1922- >>> print extract_text(find_tag_by_id(browser.contents,
1923- ... 'milestone_bugtasks'))
1924+ >>> print(extract_text(find_tag_by_id(browser.contents,
1925+ ... 'milestone_bugtasks')))
1926 Bug report...
1927 Test Bug 2...
1928
1929@@ -392,25 +392,25 @@ bug still appears in the milestone's bug listing:
1930
1931 >>> browser.open(bug_2_url)
1932 >>> browser.getLink('Target to series').click()
1933- >>> print browser.url
1934+ >>> print(browser.url)
1935 http://bugs.launchpad.test/firefox/+bug/.../+nominate
1936
1937 >>> browser.getControl('Trunk').selected = True
1938 >>> browser.getControl('Target').click()
1939- >>> print extract_text(first_tag_by_class(browser.contents, 'listing'))
1940+ >>> print(extract_text(first_tag_by_class(browser.contents, 'listing')))
1941 Affects Status ...
1942 Mozilla Firefox ... Status tracked in Trunk ...
1943
1944 >>> browser.open(milestone_url)
1945 >>> bugtasks = extract_text(find_tag_by_id(browser.contents,
1946 ... 'milestone_bugtasks'))
1947- >>> print bugtasks
1948+ >>> print(bugtasks)
1949 Bug report...
1950 Test Bug 2...
1951
1952 Moreover, the bug appears only once in the listing:
1953
1954- >>> print bugtasks.count('Test Bug 2')
1955+ >>> print(bugtasks.count('Test Bug 2'))
1956 1
1957
1958
1959diff --git a/lib/lp/registry/stories/milestone/xx-create-milestone-on-distribution.txt b/lib/lp/registry/stories/milestone/xx-create-milestone-on-distribution.txt
1960index 70b52f8..d1a8eb1 100644
1961--- a/lib/lp/registry/stories/milestone/xx-create-milestone-on-distribution.txt
1962+++ b/lib/lp/registry/stories/milestone/xx-create-milestone-on-distribution.txt
1963@@ -26,8 +26,8 @@ redirect to the Ubuntu Hoary page showing the milestone we added.
1964 >>> name12_browser.getControl('Register Milestone').click()
1965 >>> name12_browser.url
1966 'http://launchpad.test/ubuntu/hoary'
1967- >>> print extract_text(
1968- ... find_tag_by_id(name12_browser.contents, 'series-hoary'))
1969+ >>> print(extract_text(
1970+ ... find_tag_by_id(name12_browser.contents, 'series-hoary')))
1971 Version ...
1972 sounder01 ...
1973
1974diff --git a/lib/lp/registry/stories/milestone/xx-milestone-add-and-edit.txt b/lib/lp/registry/stories/milestone/xx-milestone-add-and-edit.txt
1975index a6159c8..2a229aa 100644
1976--- a/lib/lp/registry/stories/milestone/xx-milestone-add-and-edit.txt
1977+++ b/lib/lp/registry/stories/milestone/xx-milestone-add-and-edit.txt
1978@@ -70,9 +70,9 @@ can create structural bug subscriptions.
1979
1980 >>> user_browser.open('http://launchpad.test/firefox/+milestone/1.0')
1981 >>> user_browser.getLink('Subscribe to bug mail').click()
1982- >>> print user_browser.url
1983+ >>> print(user_browser.url)
1984 http://launchpad.test/firefox/+milestone/1.0/+subscribe
1985- >>> print user_browser.title
1986+ >>> print(user_browser.title)
1987 Subscribe : 1.0 : Bugs : Mozilla Firefox
1988
1989 But we can't subscribe to project milestones, since they are not real objects.
1990@@ -91,10 +91,10 @@ the series.
1991
1992 >>> driver_browser = setupBrowser(auth='Basic test@canonical.com:test')
1993 >>> driver_browser.open('http://launchpad.test/firefox/trunk')
1994- >>> print driver_browser.title
1995+ >>> print(driver_browser.title)
1996 Series trunk : Mozilla Firefox
1997- >>> print extract_text(find_tag_by_id(
1998- ... driver_browser.contents, 'series-trunk'))
1999+ >>> print(extract_text(find_tag_by_id(
2000+ ... driver_browser.contents, 'series-trunk')))
2001 Version Expected Released Summary
2002 Mozilla Firefox 0.9.2... Set date Change details 2004-10-16
2003 ...
2004@@ -109,17 +109,17 @@ A user with launchpad.Edit rights for a release can see the delete link and
2005 access the delete page. Sample Person is the driver so they have those rights.
2006
2007 >>> driver_browser.getLink('0.9.2').click()
2008- >>> print driver_browser.title
2009+ >>> print(driver_browser.title)
2010 0.9.2 "One (secure) Tree Hill" : Mozilla Firefox
2011
2012 >>> driver_browser.getLink('Delete milestone').click()
2013- >>> print driver_browser.title
2014+ >>> print(driver_browser.title)
2015 Delete Mozilla Firefox 0.9.2...
2016
2017 The 0.9.2 release has a release and files associated with it. Sample
2018 Person reads that they will be deleted too.
2019
2020- >>> print extract_text(find_main_content(driver_browser.contents))
2021+ >>> print(extract_text(find_main_content(driver_browser.contents)))
2022 Delete Mozilla Firefox 0.9.2 "One (secure) Tree Hill"
2023 ...
2024 The associated 0.9.2 release "One (secure) Tree Hill" and its files
2025@@ -130,13 +130,13 @@ Sample Person chooses the delete button, then reads that the action is
2026 successful.
2027
2028 >>> driver_browser.getControl('Delete Milestone').click()
2029- >>> print driver_browser.title
2030+ >>> print(driver_browser.title)
2031 Series trunk : Mozilla Firefox
2032
2033 >>> print_feedback_messages(driver_browser.contents)
2034 Milestone 0.9.2 deleted.
2035- >>> print extract_text(find_tag_by_id(
2036- ... driver_browser.contents, 'series-trunk'))
2037+ >>> print(extract_text(find_tag_by_id(
2038+ ... driver_browser.contents, 'series-trunk')))
2039 Version Expected Released Summary
2040 Mozilla Firefox 0.9.1 ...
2041 Mozilla Firefox 0.9 ...
2042diff --git a/lib/lp/registry/stories/milestone/xx-milestone-description.txt b/lib/lp/registry/stories/milestone/xx-milestone-description.txt
2043index 27db913..d131f2b 100644
2044--- a/lib/lp/registry/stories/milestone/xx-milestone-description.txt
2045+++ b/lib/lp/registry/stories/milestone/xx-milestone-description.txt
2046@@ -28,7 +28,7 @@ The summary appears on the milestone index page.
2047
2048 >>> test_browser.open('http://launchpad.test/ubuntu/+milestone/milestone1')
2049 >>> tag = find_tag_by_id(test_browser.contents, 'description')
2050- >>> print extract_text(tag)
2051+ >>> print(extract_text(tag))
2052 Summary of first Ubuntu milestone.
2053
2054 We can edit the summary after creating the milestone.
2055@@ -43,7 +43,7 @@ And see that it is indeed modified on the milestone page.
2056
2057 >>> test_browser.open('http://launchpad.test/ubuntu/+milestone/milestone1')
2058 >>> tag = find_tag_by_id(test_browser.contents, 'description')
2059- >>> print extract_text(tag)
2060+ >>> print(extract_text(tag))
2061 Modified summary of first Ubuntu milestone.
2062
2063
2064@@ -63,7 +63,7 @@ The summary appears on the milestone index page.
2065 >>> test_browser.open(
2066 ... 'http://launchpad.test/alsa-utils/+milestone/milestone1')
2067 >>> tag = find_tag_by_id(test_browser.contents, 'description')
2068- >>> print extract_text(tag)
2069+ >>> print(extract_text(tag))
2070 Summary of first alsa-utils milestone.
2071
2072 We can edit the summary after creating the milestone.
2073@@ -79,5 +79,5 @@ And see that it is indeed modified on the milestone page.
2074 >>> test_browser.open(
2075 ... 'http://launchpad.test/alsa-utils/+milestone/milestone1')
2076 >>> tag = find_tag_by_id(test_browser.contents, 'description')
2077- >>> print extract_text(tag)
2078+ >>> print(extract_text(tag))
2079 Modified summary of first alsa-utils milestone.
2080diff --git a/lib/lp/registry/stories/object/xx-karmacontext-topcontributors.txt b/lib/lp/registry/stories/object/xx-karmacontext-topcontributors.txt
2081index cacfde8..1e99a5e 100644
2082--- a/lib/lp/registry/stories/object/xx-karmacontext-topcontributors.txt
2083+++ b/lib/lp/registry/stories/object/xx-karmacontext-topcontributors.txt
2084@@ -19,7 +19,7 @@ The top contributors page can be reached from the top contributors portlet.
2085 True
2086
2087 >>> anon_browser.getLink('More contributors').click()
2088- >>> print anon_browser.title
2089+ >>> print(anon_browser.title)
2090 Top Ubuntu Contributors...
2091
2092
2093@@ -34,7 +34,7 @@ The top contributors page can be reached from the top contributors portlet.
2094 True
2095
2096 >>> anon_browser.getLink('More contributors').click()
2097- >>> print anon_browser.title
2098+ >>> print(anon_browser.title)
2099 Top Mozilla Firefox Contributors...
2100
2101
2102@@ -49,5 +49,5 @@ The top contributors page can be reached from the top contributors portlet.
2103 True
2104
2105 >>> anon_browser.getLink('More contributors').click()
2106- >>> print anon_browser.title
2107+ >>> print(anon_browser.title)
2108 Top The Mozilla Project Contributors...
2109diff --git a/lib/lp/registry/stories/packaging/xx-distributionsourcepackage-packaging-concurrent-deletion.txt b/lib/lp/registry/stories/packaging/xx-distributionsourcepackage-packaging-concurrent-deletion.txt
2110index 746dcc6..dcccb46 100644
2111--- a/lib/lp/registry/stories/packaging/xx-distributionsourcepackage-packaging-concurrent-deletion.txt
2112+++ b/lib/lp/registry/stories/packaging/xx-distributionsourcepackage-packaging-concurrent-deletion.txt
2113@@ -22,9 +22,9 @@ deletion succeeds and the usual informational message is displayed.
2114 >>> first_browser.getControl('Unlink').click()
2115 >>> content = first_browser.contents
2116 >>> for tag in find_tags_by_class(content, 'error'):
2117- ... print extract_text(tag)
2118+ ... print(extract_text(tag))
2119 >>> for tag in find_tags_by_class(content, 'informational'):
2120- ... print extract_text(tag)
2121+ ... print(extract_text(tag))
2122 Removed upstream association between alsa-utils trunk series and Warty.
2123
2124 A few minutes later, the user sees the same packaging association in the
2125@@ -37,7 +37,7 @@ succeed.
2126 ... url='/ubuntu/warty/+source/alsa-utils/+remove-packaging').click()
2127 >>> content = second_browser.contents
2128 >>> for tag in find_tags_by_class(content, 'informational'):
2129- ... print extract_text(tag)
2130+ ... print(extract_text(tag))
2131 >>> for tag in find_tags_by_class(content, 'error'):
2132- ... print extract_text(tag)
2133+ ... print(extract_text(tag))
2134 This upstream association was deleted already.
2135diff --git a/lib/lp/registry/stories/packaging/xx-distributionsourcepackage-packaging.txt b/lib/lp/registry/stories/packaging/xx-distributionsourcepackage-packaging.txt
2136index ca22f47..a1f0e86 100644
2137--- a/lib/lp/registry/stories/packaging/xx-distributionsourcepackage-packaging.txt
2138+++ b/lib/lp/registry/stories/packaging/xx-distributionsourcepackage-packaging.txt
2139@@ -8,7 +8,7 @@ Any user can see the summary of the binaries built from the current version
2140 of the package.
2141
2142 >>> anon_browser.open('http://launchpad.test/ubuntu/+source/pmount')
2143- >>> print extract_text(find_tag_by_id(anon_browser.contents, 'summary'))
2144+ >>> print(extract_text(find_tag_by_id(anon_browser.contents, 'summary')))
2145 pmount: pmount shortdesc
2146
2147 This page includes a table that lists all the releases of this source
2148@@ -17,7 +17,7 @@ source package in each series of this distribution.
2149
2150 >>> anon_browser.open('http://launchpad.test/ubuntu/+source/alsa-utils')
2151 >>> content = anon_browser.contents
2152- >>> print extract_text(find_tag_by_id(content, 'packages_list'))
2153+ >>> print(extract_text(find_tag_by_id(content, 'packages_list')))
2154 The Hoary Hedgehog Release (active development) Set upstream link
2155 1.0.9a-4ubuntu1 release (main) 2005-09-15
2156 The Warty Warthog Release (current stable release) alsa-utils trunk series
2157@@ -35,7 +35,7 @@ packaging links.
2158 >>> user_browser.open('http://launchpad.test/ubuntu/+source/alsa-utils')
2159 >>> link = user_browser.getLink(
2160 ... url='/ubuntu/warty/+source/alsa-utils/+remove-packaging')
2161- >>> print link
2162+ >>> print(link)
2163 <Link text='Remove upstream link'...
2164
2165 This button is not displayed to anonymous users.
2166@@ -54,11 +54,11 @@ Clicking this button deletes the corresponding packaging association.
2167 >>> user_browser.getControl('Unlink').click()
2168 >>> content = user_browser.contents
2169 >>> for tag in find_tags_by_class(content, 'error'):
2170- ... print extract_text(tag)
2171+ ... print(extract_text(tag))
2172 >>> for tag in find_tags_by_class(content, 'informational'):
2173- ... print extract_text(tag)
2174+ ... print(extract_text(tag))
2175 Removed upstream association between alsa-utils trunk series and Warty.
2176- >>> print extract_text(find_tag_by_id(content, 'packages_list'))
2177+ >>> print(extract_text(find_tag_by_id(content, 'packages_list')))
2178 The Hoary Hedgehog Release (active development) Set upstream link
2179 1.0.9a-4ubuntu1 release (main) 2005-09-15
2180 The Warty Warthog Release (current stable release) Set upstream link
2181diff --git a/lib/lp/registry/stories/packaging/xx-sourcepackage-packaging.txt b/lib/lp/registry/stories/packaging/xx-sourcepackage-packaging.txt
2182index 7f33abc..0457b89 100644
2183--- a/lib/lp/registry/stories/packaging/xx-sourcepackage-packaging.txt
2184+++ b/lib/lp/registry/stories/packaging/xx-sourcepackage-packaging.txt
2185@@ -15,7 +15,7 @@ and sees that pmount is not linked.
2186
2187 >>> user_browser.open(
2188 ... 'http://launchpad.test/ubuntu/hoary/+needs-packaging')
2189- >>> print extract_text(find_tag_by_id(user_browser.contents, 'packages'))
2190+ >>> print(extract_text(find_tag_by_id(user_browser.contents, 'packages')))
2191 Source Package Bugs Translations
2192 pmount No bugs 64 strings ...
2193
2194@@ -23,8 +23,8 @@ They look at the pmount source package page in Hoary and read that the
2195 upstream project is not set.
2196
2197 >>> user_browser.getLink('pmount').click()
2198- >>> print extract_text(find_tag_by_id(
2199- ... user_browser.contents, 'no-upstreams'))
2200+ >>> print(extract_text(find_tag_by_id(
2201+ ... user_browser.contents, 'no-upstreams')))
2202 Launchpad...
2203 There are no projects registered in Launchpad that are a potential
2204 match for this source package. Can you help us find one?
2205@@ -42,16 +42,16 @@ project. They set the upstream packaging link and see that it is set.
2206 >>> user_browser.getControl('Continue').click()
2207 >>> user_browser.getControl(name='field.productseries').value = ['trunk']
2208 >>> user_browser.getControl("Change").click()
2209- >>> print extract_text(find_tag_by_id(
2210- ... user_browser.contents, 'upstreams'))
2211+ >>> print(extract_text(find_tag_by_id(
2212+ ... user_browser.contents, 'upstreams')))
2213 The Mozilla Project...Mozilla Thunderbird...trunk...
2214
2215 They see the "Show upstream links" link and take a look at the project's
2216 packaging in distributions.
2217
2218 >>> user_browser.getLink('Show upstream links').click()
2219- >>> print extract_text(
2220- ... find_tag_by_id(user_browser.contents, 'distribution-series'))
2221+ >>> print(extract_text(
2222+ ... find_tag_by_id(user_browser.contents, 'distribution-series')))
2223 Distribution series Source package Version Project series
2224 Hoary (5.04) pmount 0.1-2 Mozilla Thunderbird trunk...
2225
2226@@ -61,8 +61,8 @@ link to all versions and follows it to the distro source package page.
2227 >>> user_browser.getLink('pmount').click()
2228 >>> user_browser.getLink(
2229 ... 'All versions of pmount source in Ubuntu').click()
2230- >>> print extract_text(find_tag_by_id(
2231- ... user_browser.contents, 'packages_list'))
2232+ >>> print(extract_text(find_tag_by_id(
2233+ ... user_browser.contents, 'packages_list')))
2234 The Hoary Hedgehog Release (active development) ...
2235 0.1-2 release (main) 2005-08-24
2236
2237@@ -79,15 +79,15 @@ step of the multistep form.
2238 >>> user_browser.getControl(
2239 ... 'Register the upstream project').selected = True
2240 >>> user_browser.getControl("Link to Upstream Project").click()
2241- >>> print user_browser.getControl(name='field.name').value
2242+ >>> print(user_browser.getControl(name='field.name').value)
2243 bonkers
2244- >>> print user_browser.getControl(name='field.display_name').value
2245+ >>> print(user_browser.getControl(name='field.display_name').value)
2246 Bonkers
2247- >>> print user_browser.getControl(name='field.summary').value
2248+ >>> print(user_browser.getControl(name='field.summary').value)
2249 summary for flubber-bin
2250 summary for flubber-lib
2251- >>> print extract_text(
2252- ... find_tag_by_id(user_browser.contents, 'step-title'))
2253+ >>> print(extract_text(
2254+ ... find_tag_by_id(user_browser.contents, 'step-title')))
2255 Step 2 (of 2): Check for duplicate projects
2256
2257 When No Privileges Person selects "Choose another upstream project" and
2258@@ -99,19 +99,19 @@ then finds out that the project doesn't exist, they use the
2259 >>> user_browser.getControl(
2260 ... 'Choose another upstream project').selected = True
2261 >>> user_browser.getControl("Link to Upstream Project").click()
2262- >>> print user_browser.url
2263+ >>> print(user_browser.url)
2264 http://launchpad.test/youbuntu/busy/+source/bonkers/+edit-packaging
2265
2266 >>> user_browser.getLink("Register the upstream project").click()
2267- >>> print user_browser.getControl(name='field.name').value
2268+ >>> print(user_browser.getControl(name='field.name').value)
2269 bonkers
2270- >>> print user_browser.getControl(name='field.display_name').value
2271+ >>> print(user_browser.getControl(name='field.display_name').value)
2272 Bonkers
2273- >>> print user_browser.getControl(name='field.summary').value
2274+ >>> print(user_browser.getControl(name='field.summary').value)
2275 summary for flubber-bin
2276 summary for flubber-lib
2277- >>> print extract_text(
2278- ... find_tag_by_id(user_browser.contents, 'step-title'))
2279+ >>> print(extract_text(
2280+ ... find_tag_by_id(user_browser.contents, 'step-title')))
2281 Step 2 (of 2): Check for duplicate projects
2282
2283 After No Privileges Person selects the licences, the user is redirected back
2284@@ -120,14 +120,14 @@ to the source package page and an informational message will be displayed.
2285 >>> user_browser.getControl(name='field.licenses').value = ['BSD']
2286 >>> user_browser.getControl(
2287 ... "Complete registration and link to bonkers package").click()
2288- >>> print user_browser.url
2289+ >>> print(user_browser.url)
2290 http://launchpad.test/youbuntu/busy/+source/bonkers
2291 >>> for tag in find_tags_by_class(
2292 ... user_browser.contents, 'informational message'):
2293- ... print extract_text(tag)
2294+ ... print(extract_text(tag))
2295 Linked Bonkers project to bonkers source package.
2296- >>> print extract_text(
2297- ... find_tag_by_id(user_browser.contents, 'upstreams'))
2298+ >>> print(extract_text(
2299+ ... find_tag_by_id(user_browser.contents, 'upstreams')))
2300 Bonkers ā‡’ trunk
2301 Change upstream link
2302 Remove upstream link...
2303diff --git a/lib/lp/registry/stories/person/xx-add-sshkey.txt b/lib/lp/registry/stories/person/xx-add-sshkey.txt
2304index f3d42bc..47e4140 100644
2305--- a/lib/lp/registry/stories/person/xx-add-sshkey.txt
2306+++ b/lib/lp/registry/stories/person/xx-add-sshkey.txt
2307@@ -11,19 +11,19 @@ Profile page
2308 User keys are shown on profile pages, and any user can see that.
2309
2310 >>> anon_browser.open('http://launchpad.test/~name12')
2311- >>> print anon_browser.title
2312+ >>> print(anon_browser.title)
2313 Sample Person in Launchpad
2314- >>> print extract_text(
2315- ... find_tag_by_id(anon_browser.contents, 'sshkeys'))
2316+ >>> print(extract_text(
2317+ ... find_tag_by_id(anon_browser.contents, 'sshkeys')))
2318 SSH keys: andrew@trogdor
2319
2320 Salgado does not have a key, so we omit the 'SSH keys' section for anonymous
2321 users.
2322
2323 >>> anon_browser.open('http://launchpad.test/~salgado')
2324- >>> print anon_browser.title
2325+ >>> print(anon_browser.title)
2326 Guilherme Salgado in Launchpad
2327- >>> print find_tag_by_id(anon_browser.contents, 'sshkeys')
2328+ >>> print(find_tag_by_id(anon_browser.contents, 'sshkeys'))
2329 None
2330
2331 Salgado sees a message explaining that he can register his ssh key.
2332@@ -37,10 +37,10 @@ Salgado sees a message explaining that he can register his ssh key.
2333 >>> logout()
2334 >>> browser = setupBrowserFreshLogin(salgado)
2335 >>> browser.open('http://launchpad.test/~salgado')
2336- >>> print browser.title
2337+ >>> print(browser.title)
2338 Guilherme Salgado in Launchpad
2339- >>> print extract_text(
2340- ... find_tag_by_id(browser.contents, 'sshkeys'))
2341+ >>> print(extract_text(
2342+ ... find_tag_by_id(browser.contents, 'sshkeys')))
2343 SSH keys: Add an SSH key
2344 No SSH keys registered.
2345
2346@@ -53,7 +53,7 @@ an already uploaded one. Salgado sees a link on his profile page to update
2347 his SSH keys. The page allows him to add a key.
2348
2349 >>> browser.getLink('Add an SSH key').click()
2350- >>> print browser.title
2351+ >>> print(browser.title)
2352 Change your SSH keys...
2353
2354 Any key must be of the form "keytype keytext comment", where keytype must be
2355@@ -65,21 +65,21 @@ message will be shown.
2356 >>> browser.getControl(name='sshkey').value = sshkey
2357 >>> browser.getControl('Import Public Key').click()
2358 >>> for tag in find_main_content(browser.contents)('p', 'error message'):
2359- ... print tag.renderContents()
2360+ ... print(tag.renderContents())
2361 Invalid public key
2362
2363 >>> sshkey = "ssh-rsa foo"
2364 >>> browser.getControl(name='sshkey').value = sshkey
2365 >>> browser.getControl('Import Public Key').click()
2366 >>> for tag in find_main_content(browser.contents)('p', 'error message'):
2367- ... print tag.renderContents()
2368+ ... print(tag.renderContents())
2369 Invalid public key
2370
2371 >>> sshkey = "ssh-xsa foo comment"
2372 >>> browser.getControl(name='sshkey').value = sshkey
2373 >>> browser.getControl('Import Public Key').click()
2374 >>> for tag in find_main_content(browser.contents)('p', 'error message'):
2375- ... print tag.renderContents()
2376+ ... print(tag.renderContents())
2377 Invalid public key
2378
2379
2380@@ -91,7 +91,7 @@ format.
2381 >>> browser.getControl('Import Public Key').click()
2382 >>> soup = find_main_content(browser.contents)
2383 >>> for tag in soup('p', 'informational message'):
2384- ... print tag.renderContents()
2385+ ... print(tag.renderContents())
2386 SSH public key added.
2387
2388 >>> sshkey = "ssh-dss AAAAB3NzaC1kc3MAAAEBAObOoy3fScSSQPHE/V6tPGoFzo5y1JRjDLcs8CNcvIHh9L27Qdj6h18AXn6MUCvvSCKm49aHpp1Xe14a6fmEIesjz6VopPWGENaOwRmhH6zfqM6imKUXQ0sq9p0znYb0TMjyRC0/AmqYneUF6FA2mVXygkGAkp/vDRPFQhPwnHpVD9TVPxHBQdHgM3bTo2TT+GoL7kw/s32ZiAH4OPvN5fN7bCkQWoUs/ySfoNbISMdvdtq07Rra2Biwzgjjs0ZcKbMicbDyYCe4gXlqK4wqcDfcwgrdqdG6NM0LUdekarWjnv0pMb6ttUl4U7e7Nf+eGkiTVItlppC8DyrnqC9SKCUAAAAVAOlEYNobJottyObVWQcrU8eAP4T5AAABAQDmJmL4DcQ1GVvw1Pjy57V0WUyGrOVBRVz7BwYBIvMA7xJCCvzd47mYWrWJkjV6O3tw2vG5oZx+BXE+ve8O6jL89CrwqncoUS8WHCojRmuUHTmtCCiRBCH+/68HMCusO3Blk//kQSsaqfIn+8Xa56Vr2SweSUlLgjvb51+89JJ13oDlUvdftW2GZu+grbmojqcoJ1LVAI5n0qsDItsFid46f8XfNzPeksasY9JbY5fKq/xf1KcgXL2F9XwmrDjFCuI4/xkJWNfGwaLKC/cbrJ1xmvPLl1/Hm5kNqgrwpNwHVOwyYSCUqXroU5PnpE9uydHUhjhtU2K2Hj0i7fOyxoxyAAABAQCpXKgd6lpTAEKm7ECY3TbJaTXPkNvAwg/2ud+PrtefHrVFFWrXrblSQhnmnc6ut8G3BsDzCljAIV2v+XcdOo+m8EViLf+Bi+gfbAIz4vdVepwQ2XHWUOTKk90i7Xqg4mUUDRIVw9ioNF0GAHbNlJTK3FWC3gstbCJU2hyV3UzgB95b6zqpUHeyn1RK4VAFYGY9fCIdZNy926HEart6uO/N6cO1ETw5B63kI8fTBjU7HLGgGXRjOv1APAqvKgry3tQD2WYkVJGRyYLjDK9d8nStUpwN5swI1xx2IWAbD+UCsRXAixn8s3mvpBD/jbnWjrzEensBc96jtiAsx2P5oXEd salgado@canario"
2389@@ -99,7 +99,7 @@ format.
2390 >>> browser.getControl('Import Public Key').click()
2391 >>> soup = find_main_content(browser.contents)
2392 >>> for tag in soup('p', 'informational message'):
2393- ... print tag.renderContents()
2394+ ... print(tag.renderContents())
2395 SSH public key added.
2396
2397 >>> sshkey = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJseCUmxVG7D6qh4JmhLp0Du4kScScJ9PtZ0LGHYHaURnRw9tbX1wwURAio8og6dbnT75CQ3TbUE/xJhxI0aFXE= salgado@canario"
2398@@ -107,7 +107,7 @@ format.
2399 >>> browser.getControl('Import Public Key').click()
2400 >>> soup = find_main_content(browser.contents)
2401 >>> for tag in soup('p', 'informational message'):
2402- ... print tag.renderContents()
2403+ ... print(tag.renderContents())
2404 SSH public key added.
2405
2406 >>> sshkey = "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBDUR0E0zCHRHJER6uzjfE/o0HAHFLcq/n8lp0duThpeIPsmo+wr3vHHuAAyOddOgkuQC8Lj8FzHlrOEYgXL6qa7FvpviE9YWUgmqVDa/yJbL/m6Mg8fvSIXlDJKmvOSv6g== salgado@canario"
2407@@ -115,7 +115,7 @@ format.
2408 >>> browser.getControl('Import Public Key').click()
2409 >>> soup = find_main_content(browser.contents)
2410 >>> for tag in soup('p', 'informational message'):
2411- ... print tag.renderContents()
2412+ ... print(tag.renderContents())
2413 SSH public key added.
2414
2415 >>> sshkey = "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB3rpD+Ozb/kwUOqCZUXSiruAkIx6sNZLJyjJ0zxVTZSannaysCLxMQ/IiVxCd59+U2NaLduMzd93JcYDRlX3M5+AApY+3JjfSPo01Sb17HTLNSYU3RZWx0A3XJxm/YN+x/iuYZ3IziuAKeYMsNsdfHlO4/IWjw4Ruy0enW+QhWaY2qAQ== salgado@canario"
2416@@ -123,7 +123,7 @@ format.
2417 >>> browser.getControl('Import Public Key').click()
2418 >>> soup = find_main_content(browser.contents)
2419 >>> for tag in soup('p', 'informational message'):
2420- ... print tag.renderContents()
2421+ ... print(tag.renderContents())
2422 SSH public key added.
2423
2424 Launchpad administrators are not allowed to poke at other user's ssh keys.
2425@@ -141,9 +141,9 @@ Salgado chooses to remove one of his ssh keys from Launchpad. The link
2426 to edit his keys is on the page.
2427
2428 >>> browser.open('http://launchpad.test/~salgado')
2429- >>> print browser.title
2430+ >>> print(browser.title)
2431 Guilherme Salgado in Launchpad
2432- >>> print extract_text(find_tag_by_id(browser.contents, 'sshkeys'))
2433+ >>> print(extract_text(find_tag_by_id(browser.contents, 'sshkeys')))
2434 SSH keys: Update SSH keys
2435 salgado@canario
2436 salgado@canario
2437@@ -151,13 +151,13 @@ to edit his keys is on the page.
2438 salgado@canario
2439 salgado@canario
2440 >>> browser.getLink('Update SSH keys').click()
2441- >>> print browser.title
2442+ >>> print(browser.title)
2443 Change your SSH keys...
2444
2445 >>> browser.getControl('Remove', index=0).click()
2446 >>> soup = find_main_content(browser.contents)
2447 >>> for tag in soup('p', 'informational message'):
2448- ... print tag.renderContents()
2449+ ... print(tag.renderContents())
2450 Key ... removed
2451
2452 If Salgado tries to remove a key that doesn't exist or one that doesn't
2453@@ -167,7 +167,7 @@ belong to him, it will fail with an error message.
2454 >>> browser.getControl('Remove', index=0).click()
2455 >>> soup = find_main_content(browser.contents)
2456 >>> for tag in soup('p', 'error message'):
2457- ... print tag.renderContents()
2458+ ... print(tag.renderContents())
2459 Cannot remove a key that doesn't exist
2460
2461 >>> browser.getControl(name='key', index=0).value = '1'
2462diff --git a/lib/lp/registry/stories/person/xx-admin-person-review.txt b/lib/lp/registry/stories/person/xx-admin-person-review.txt
2463index 1173f52..58c7a88 100644
2464--- a/lib/lp/registry/stories/person/xx-admin-person-review.txt
2465+++ b/lib/lp/registry/stories/person/xx-admin-person-review.txt
2466@@ -10,10 +10,10 @@ Registry admins can review users and update some of their information.
2467
2468 >>> expert_browser.open('http://launchpad.test/~salgado')
2469 >>> expert_browser.getLink('Administer').click()
2470- >>> print expert_browser.url
2471+ >>> print(expert_browser.url)
2472 http://launchpad.test/~salgado/+review
2473
2474- >>> print expert_browser.title
2475+ >>> print(expert_browser.title)
2476 Review person...
2477
2478 >>> expert_browser.getControl('Name', index=0).value = 'no-way'
2479@@ -21,7 +21,7 @@ Registry admins can review users and update some of their information.
2480 >>> expert_browser.getControl(
2481 ... name='field.personal_standing_reason').value = 'good guy'
2482 >>> expert_browser.getControl('Change').click()
2483- >>> print expert_browser.url
2484+ >>> print(expert_browser.url)
2485 http://launchpad.test/~no-way
2486
2487 Registry experts can't change the displayname.
2488@@ -40,9 +40,9 @@ But Launchpad admins can.
2489 >>> admin_browser.getControl(
2490 ... 'Display Name', index=0).value = 'The one and only Salgado'
2491 >>> admin_browser.getControl('Change').click()
2492- >>> print admin_browser.title
2493+ >>> print(admin_browser.title)
2494 The one and only Salgado in Launchpad
2495- >>> print admin_browser.url
2496+ >>> print(admin_browser.url)
2497 http://launchpad.test/~salgado
2498
2499
2500@@ -53,7 +53,7 @@ The review page has a link to the review account page.
2501
2502 >>> expert_browser.open('http://launchpad.test/~salgado')
2503 >>> expert_browser.getLink('Administer Account').click()
2504- >>> print expert_browser.title
2505+ >>> print(expert_browser.title)
2506 Review person's account...
2507
2508 The +reviewaccount page displays account information that is normally
2509@@ -61,7 +61,7 @@ hidden from the UI.
2510
2511 >>> content = find_main_content(expert_browser.contents)
2512 >>> for tr in content.find(id='summary').findAll('tr'):
2513- ... print extract_text(tr)
2514+ ... print(extract_text(tr))
2515 Created: 2005-06-06
2516 Creation reason: Created by the owner themselves, coming from Launchpad.
2517 OpenID identifiers: salgado_oid
2518@@ -72,5 +72,5 @@ hidden from the UI.
2519 The page also contains a link back to the +review page.
2520
2521 >>> link = expert_browser.getLink(url='+review')
2522- >>> print link.text
2523+ >>> print(link.text)
2524 edit[IMG] Review the user's Launchpad information
2525diff --git a/lib/lp/registry/stories/person/xx-approve-members.txt b/lib/lp/registry/stories/person/xx-approve-members.txt
2526index 5e1eebc..ee879bb 100644
2527--- a/lib/lp/registry/stories/person/xx-approve-members.txt
2528+++ b/lib/lp/registry/stories/person/xx-approve-members.txt
2529@@ -11,7 +11,7 @@ proposed members at once.
2530
2531 Let's have a look at the proposed members that we have.
2532
2533- >>> print extract_text(find_tag_by_id(browser.contents, 'member-list'))
2534+ >>> print(extract_text(find_tag_by_id(browser.contents, 'member-list')))
2535 Andrew Bennetts (Applied on ...) Approve Decline Hold
2536 Sample Person (Applied on ...) Approve Decline Hold
2537
2538@@ -29,7 +29,7 @@ Person's. A comment is also sent to the applying users and the team admins.
2539 >>> len(stub.test_emails)
2540 12
2541 >>> for from_addr, to_addrs, raw_msg in sorted(stub.test_emails):
2542- ... print to_addrs
2543+ ... print(to_addrs)
2544 ['andrew.bennetts@ubuntulinux.com']
2545 ['colin.watson@ubuntulinux.com']
2546 ['colin.watson@ubuntulinux.com']
2547@@ -42,7 +42,7 @@ Person's. A comment is also sent to the applying users and the team admins.
2548 ['mark@example.com']
2549 ['mark@example.com']
2550 ['test@canonical.com']
2551- >>> print raw_msg
2552+ >>> print(raw_msg)
2553 Content-Type: text/plain; charset="utf-8"
2554 ...
2555 Mark Shuttleworth said:
2556@@ -54,7 +54,7 @@ as an inactive one.
2557
2558 >>> browser.url
2559 'http://launchpad.test/~ubuntu-team/+members'
2560- >>> print extract_text(find_tag_by_id(browser.contents, 'activemembers'))
2561+ >>> print(extract_text(find_tag_by_id(browser.contents, 'activemembers')))
2562 Name Member since Expires Status
2563 ...
2564 Andrew Bennetts
2565diff --git a/lib/lp/registry/stories/person/xx-deactivate-account.txt b/lib/lp/registry/stories/person/xx-deactivate-account.txt
2566index 4267cc7..9b41ec4 100644
2567--- a/lib/lp/registry/stories/person/xx-deactivate-account.txt
2568+++ b/lib/lp/registry/stories/person/xx-deactivate-account.txt
2569@@ -56,8 +56,8 @@ And now the Launchpad page for Sample Person person will clearly say they
2570 do not use Launchpad.
2571
2572 >>> browser.open('http://launchpad.test/~name12-deactivatedaccount')
2573- >>> print extract_text(
2574- ... find_tag_by_id(browser.contents, 'not-lp-user-or-team'))
2575+ >>> print(extract_text(
2576+ ... find_tag_by_id(browser.contents, 'not-lp-user-or-team')))
2577 Sample Person does not use Launchpad.
2578
2579 The bugs that were assigned to Sample Person will no longer have an
2580@@ -65,7 +65,7 @@ assignee.
2581
2582 >>> browser.open('http://launchpad.test/debian/+source/'
2583 ... 'mozilla-firefox/+bug/3')
2584- >>> print extract_text(find_main_content(browser.contents))
2585+ >>> print(extract_text(find_main_content(browser.contents)))
2586 Bug Title Test
2587 ...
2588 Assigned to
2589@@ -76,7 +76,7 @@ Although teams have NOACCOUNT as their account_status, they are teams and so
2590 it makes no sense to say they don't use Launchpad.
2591
2592 >>> browser.open('http://launchpad.test/~ubuntu-team')
2593- >>> print find_tag_by_id(browser.contents, 'not-lp-user-or-team')
2594+ >>> print(find_tag_by_id(browser.contents, 'not-lp-user-or-team'))
2595 None
2596
2597 The action of deactivating an account is something that can only be done by
2598diff --git a/lib/lp/registry/stories/person/xx-people-index.txt b/lib/lp/registry/stories/person/xx-people-index.txt
2599index e09d112..ea6f71d 100644
2600--- a/lib/lp/registry/stories/person/xx-people-index.txt
2601+++ b/lib/lp/registry/stories/person/xx-people-index.txt
2602@@ -1,9 +1,9 @@
2603
2604 Test /people.
2605
2606- >>> print http(r"""
2607+ >>> print(http(r"""
2608 ... GET /people HTTP/1.1
2609- ... """)
2610+ ... """))
2611 HTTP/1.1 200 Ok
2612 Content-Length: ...
2613 Content-Type: text/html;charset=utf-8
2614diff --git a/lib/lp/registry/stories/person/xx-people-search.txt b/lib/lp/registry/stories/person/xx-people-search.txt
2615index 702092b..c9b4b9a 100644
2616--- a/lib/lp/registry/stories/person/xx-people-search.txt
2617+++ b/lib/lp/registry/stories/person/xx-people-search.txt
2618@@ -5,7 +5,7 @@ Searching for people
2619 --------------------
2620
2621 >>> browser.open('http://launchpad.test/people')
2622- >>> print browser.title
2623+ >>> print(browser.title)
2624 People and teams in Launchpad
2625
2626 Search for all people and teams with the string "foo bar". There
2627@@ -14,13 +14,13 @@ should just be the one person named "Foo Bar" found.
2628 >>> browser.getControl(name='name').value = 'foo bar'
2629 >>> browser.getControl('Search').click()
2630 >>> listing = find_tag_by_id(browser.contents, 'people-results')
2631- >>> print extract_text(listing)
2632+ >>> print(extract_text(listing))
2633 Name Launchpad ID Karma
2634 Foo Bar name16 241
2635
2636 The listing is sortable.
2637
2638- >>> print ' '.join(listing['class'])
2639+ >>> print(' '.join(listing['class']))
2640 listing sortable
2641
2642 Search for all people and teams like "launchpad" the users sees three
2643@@ -29,7 +29,7 @@ columns of people and teams..
2644 >>> browser.getControl(name='name').value = 'launchpad'
2645 >>> browser.getControl('Search').click()
2646 >>> listing = find_tag_by_id(browser.contents, 'people-results')
2647- >>> print extract_text(listing, formatter='html')
2648+ >>> print(extract_text(listing, formatter='html'))
2649 Name Launchpad ID Karma
2650 Julian Edwards launchpad-julian-edwards 0
2651 Launchpad Administrators admins &mdash;
2652@@ -45,7 +45,7 @@ shown. There are only two columns because teams cannot have karma.
2653 >>> browser.getControl(name='searchfor').value = ['teamsonly']
2654 >>> browser.getControl('Search').click()
2655 >>> listing = find_tag_by_id(browser.contents, 'people-results')
2656- >>> print extract_text(listing)
2657+ >>> print(extract_text(listing))
2658 Name Launchpad ID
2659 Launchpad Administrators admins
2660 Launchpad Beta Testers launchpad-beta-testers
2661@@ -59,7 +59,7 @@ Restrict the search to people and only individuals are listed.
2662 >>> browser.getControl(name='searchfor').value = ['peopleonly']
2663 >>> browser.getControl('Search').click()
2664 >>> listing = find_tag_by_id(browser.contents, 'people-results')
2665- >>> print extract_text(listing)
2666+ >>> print(extract_text(listing))
2667 Name Launchpad ID Karma
2668 Julian Edwards launchpad-julian-edwards 0
2669 Launchpad Beta Testers Owner launchpad-beta-owner 0
2670diff --git a/lib/lp/registry/stories/person/xx-person-claim-merge.txt b/lib/lp/registry/stories/person/xx-person-claim-merge.txt
2671index 1b723b6..caad3d3 100644
2672--- a/lib/lp/registry/stories/person/xx-person-claim-merge.txt
2673+++ b/lib/lp/registry/stories/person/xx-person-claim-merge.txt
2674@@ -7,7 +7,7 @@ exception that will redirect the user to the login page.
2675
2676 >>> anon_browser.open('http://launchpad.test/~matsubara')
2677 >>> link = anon_browser.getLink("Are you Diogo Matsubara?")
2678- >>> print link.url
2679+ >>> print(link.url)
2680 http://launchpad.test/people/+requestmerge?field.dupe_person=matsubara
2681 >>> link.click()
2682 Traceback (most recent call last):
2683diff --git a/lib/lp/registry/stories/person/xx-person-edit-jabber-ids.txt b/lib/lp/registry/stories/person/xx-person-edit-jabber-ids.txt
2684index ae19df1..f2a6112 100644
2685--- a/lib/lp/registry/stories/person/xx-person-edit-jabber-ids.txt
2686+++ b/lib/lp/registry/stories/person/xx-person-edit-jabber-ids.txt
2687@@ -13,7 +13,7 @@ profile page and uses the 'Update Jabber IDs' link.
2688
2689 >>> user_browser.open('http://launchpad.test/~no-priv')
2690 >>> user_browser.getLink('Update Jabber IDs').click()
2691- >>> print user_browser.title
2692+ >>> print(user_browser.title)
2693 No Privileges Person's Jabber IDs...
2694
2695 The user enters the Jabber ID in the text field and clicks on the
2696@@ -29,7 +29,7 @@ an error is displayed and the user can enter another one:
2697
2698 >>> def show_errors(browser):
2699 ... for error in find_tags_by_class(browser.contents, 'error'):
2700- ... print extract_text(error)
2701+ ... print(extract_text(error))
2702 >>> show_errors(user_browser)
2703 There is 1 error.
2704 New Jabber user ID:
2705@@ -46,7 +46,7 @@ it will be associated with their account.
2706 >>> def show_jabberids(browser):
2707 ... tags = find_tag_by_id(browser.contents, 'jabber-ids')
2708 ... for dd in tags.findAll('dd'):
2709- ... print extract_text(dd)
2710+ ... print(extract_text(dd))
2711
2712 >>> show_jabberids(user_browser)
2713 no-priv@jabber.org
2714diff --git a/lib/lp/registry/stories/person/xx-person-edit.txt b/lib/lp/registry/stories/person/xx-person-edit.txt
2715index 54b12b6..4769324 100644
2716--- a/lib/lp/registry/stories/person/xx-person-edit.txt
2717+++ b/lib/lp/registry/stories/person/xx-person-edit.txt
2718@@ -23,8 +23,8 @@ Launchpad.
2719 They can see a link to an FAQ that explains launchpad accounts and passwords.
2720 Note that this is a link to an FAQ in production databases.
2721
2722- >>> print browser.getLink(
2723- ... 'Learn about your Launchpad account and password').url
2724+ >>> print(browser.getLink(
2725+ ... 'Learn about your Launchpad account and password').url)
2726 http://launchpad.test/launchpad/+faq/51
2727
2728 They noticed that their information is out of date and will update it.
2729diff --git a/lib/lp/registry/stories/person/xx-person-editgpgkeys-invalid-key.txt b/lib/lp/registry/stories/person/xx-person-editgpgkeys-invalid-key.txt
2730index 352d3e9..d3f8e52 100644
2731--- a/lib/lp/registry/stories/person/xx-person-editgpgkeys-invalid-key.txt
2732+++ b/lib/lp/registry/stories/person/xx-person-editgpgkeys-invalid-key.txt
2733@@ -38,7 +38,7 @@ Attempts to claim a revoked OpenPGP key fail:
2734 ... '84D205F03E1E67096CB54E262BE83793AACCD97C')
2735 >>> browser.getControl('Import Key').click()
2736 >>> for tag in find_tags_by_class(browser.contents, 'error message'):
2737- ... print tag.renderContents()
2738+ ... print(tag.renderContents())
2739 <BLANKLINE>
2740 The key 84D205F03E1E67096CB54E262BE83793AACCD97C cannot be validated
2741 because it has been publicly revoked.
2742@@ -54,7 +54,7 @@ Attempts to claim an expired OpenPGP key also fail:
2743 ... '0DD64D28E5F41138533495200E3DB4D402F53CC6')
2744 >>> browser.getControl('Import Key').click()
2745 >>> for tag in find_tags_by_class(browser.contents, 'error message'):
2746- ... print tag.renderContents()
2747+ ... print(tag.renderContents())
2748 <BLANKLINE>
2749 The key 0DD64D28E5F41138533495200E3DB4D402F53CC6 cannot be validated
2750 because it has expired. Change the expiry date (in a terminal, enter
2751@@ -89,7 +89,7 @@ Try to validate the revoked OpenPGP key:
2752 ... 'http://launchpad.test/token/%s/+validategpg' % revoked_key_token)
2753 >>> browser.getControl('Continue').click()
2754 >>> for tag in find_tags_by_class(browser.contents, 'error message'):
2755- ... print tag.renderContents()
2756+ ... print(tag.renderContents())
2757 There is 1 error.
2758 The key 84D205F03E1E67096CB54E262BE83793AACCD97C cannot be validated
2759 because it has been publicly revoked.
2760@@ -105,7 +105,7 @@ Try to validate the revoked OpenPGP key:
2761 ... 'http://launchpad.test/token/%s/+validategpg' % expired_key_token)
2762 >>> browser.getControl('Continue').click()
2763 >>> for tag in find_tags_by_class(browser.contents, 'error message'):
2764- ... print tag.renderContents()
2765+ ... print(tag.renderContents())
2766 There is 1 error.
2767 The key 0DD64D28E5F41138533495200E3DB4D402F53CC6 cannot be validated
2768 because it has expired. Change the expiry date (in a terminal, enter
2769diff --git a/lib/lp/registry/stories/person/xx-person-home.txt b/lib/lp/registry/stories/person/xx-person-home.txt
2770index ecc4958..e1de161 100644
2771--- a/lib/lp/registry/stories/person/xx-person-home.txt
2772+++ b/lib/lp/registry/stories/person/xx-person-home.txt
2773@@ -11,7 +11,7 @@ profile for them.
2774 'Diogo Matsubara does not use Launchpad'
2775
2776 >>> content = find_main_content(browser.contents).find('p')
2777- >>> print extract_text(content)
2778+ >>> print(extract_text(content))
2779 Diogo Matsubara does not use Launchpad. This page was created on
2780 2006-12-13 when importing the Portuguese...
2781
2782@@ -23,31 +23,31 @@ Mark has a registered email address, and he has chosen to disclose it to
2783 the world. Anonymous users cannot see Mark's address
2784
2785 >>> anon_browser.open('http://launchpad.test/~mark')
2786- >>> print extract_text(
2787- ... find_tag_by_id(anon_browser.contents, 'email-addresses'))
2788+ >>> print(extract_text(
2789+ ... find_tag_by_id(anon_browser.contents, 'email-addresses')))
2790 Email: Log in for email information.
2791
2792 A logged in user such as Sample Person, can see Mark's addresses.
2793
2794 >>> sample_browser = setupBrowser(auth='Basic test@canonical.com:test')
2795 >>> sample_browser.open('http://launchpad.test/~mark')
2796- >>> print extract_text(
2797- ... find_tag_by_id(sample_browser.contents, 'email-addresses'))
2798+ >>> print(extract_text(
2799+ ... find_tag_by_id(sample_browser.contents, 'email-addresses')))
2800 Email: mark@example.com
2801
2802 As for Sample Person, they have chosen not to disclose their email addresses.
2803 Unprivileged users like No Privileges Person cannot see their addresses:
2804
2805 >>> user_browser.open('http://launchpad.test/~name12')
2806- >>> print extract_text(
2807- ... find_tag_by_id(user_browser.contents, 'email-addresses'))
2808+ >>> print(extract_text(
2809+ ... find_tag_by_id(user_browser.contents, 'email-addresses')))
2810 Email: No public address provided.
2811
2812 But Foo Bar can:
2813
2814 >>> admin_browser.open('http://launchpad.test/~name12')
2815- >>> print extract_text(
2816- ... find_tag_by_id(admin_browser.contents, 'email-addresses'))
2817+ >>> print(extract_text(
2818+ ... find_tag_by_id(admin_browser.contents, 'email-addresses')))
2819 Email:
2820 test@canonical.com
2821 testing@canonical.com
2822@@ -61,25 +61,25 @@ Open ID link
2823 When a person visits their own page, they'll see their OpenID login URL.
2824
2825 >>> user_browser.open('http://launchpad.test/~no-priv')
2826- >>> print extract_text(
2827- ... find_tag_by_id(user_browser.contents, 'openid-info'))
2828+ >>> print(extract_text(
2829+ ... find_tag_by_id(user_browser.contents, 'openid-info')))
2830 OpenID login:
2831 http://launchpad.test/~no-priv...
2832
2833 The URL is followed by a helpful link.
2834
2835- >>> print user_browser.getLink('OpenID help').url
2836+ >>> print(user_browser.getLink('OpenID help').url)
2837 http://launchpad.test/+help-registry/openid.html
2838
2839 However, when the user visits someone else's page, they see no such URL.
2840
2841 >>> user_browser.open('http://launchpad.test/~salgado')
2842- >>> print find_tag_by_id(user_browser.contents, 'openid-info')
2843+ >>> print(find_tag_by_id(user_browser.contents, 'openid-info'))
2844 None
2845
2846 And there is no helpful link.
2847
2848- >>> print user_browser.getLink('openid help').url
2849+ >>> print(user_browser.getLink('openid help').url)
2850 Traceback (most recent call last):
2851 ...
2852 LinkNotFoundError
2853@@ -91,13 +91,13 @@ Jabber IDs
2854 A person's jabber IDs are only show to authenticated users.
2855
2856 >>> user_browser.open('http://launchpad.test/~mark')
2857- >>> print extract_text(
2858- ... find_tag_by_id(user_browser.contents, 'jabber-ids'))
2859+ >>> print(extract_text(
2860+ ... find_tag_by_id(user_browser.contents, 'jabber-ids')))
2861 Jabber: markshuttleworth@jabber.org
2862
2863 >>> anon_browser.open('http://launchpad.test/~mark')
2864- >>> print extract_text(
2865- ... find_tag_by_id(anon_browser.contents, 'jabber-ids'))
2866+ >>> print(extract_text(
2867+ ... find_tag_by_id(anon_browser.contents, 'jabber-ids')))
2868 Jabber: &lt;email address hidden&gt;
2869
2870
2871@@ -109,12 +109,12 @@ just by following the link to that person's OpenPGP keys, only
2872 authenticated users can see the key fingerprint with a link to the keyserver.
2873
2874 >>> user_browser.open('http://launchpad.test/~name16')
2875- >>> print find_tag_by_id(user_browser.contents, 'pgp-keys')
2876+ >>> print(find_tag_by_id(user_browser.contents, 'pgp-keys'))
2877 <dl...
2878 <a href="https://keyserver...
2879
2880 >>> anon_browser.open('http://launchpad.test/~name16')
2881- >>> print find_tag_by_id(anon_browser.contents, 'pgp-keys')
2882+ >>> print(find_tag_by_id(anon_browser.contents, 'pgp-keys'))
2883 <dl...
2884 <dd> ABCDEF0123456789ABCDDCBA0000111112345678...
2885
2886@@ -126,7 +126,7 @@ The contact details portlet shows the languages that the user speaks. No
2887 Privileges Person can see the languages that mark speaks.
2888
2889 >>> user_browser.open('http://launchpad.test/~carlos')
2890- >>> print extract_text(find_tag_by_id(user_browser.contents, 'languages'))
2891+ >>> print(extract_text(find_tag_by_id(user_browser.contents, 'languages')))
2892 Languages:
2893 Catalan, English, Spanish
2894
2895@@ -134,7 +134,7 @@ When viewing their own page, No Privileges Person sees their languages and
2896 can edit them.
2897
2898 >>> user_browser.open('http://launchpad.test/~no-priv')
2899- >>> print extract_text(find_tag_by_id(user_browser.contents, 'languages'))
2900+ >>> print(extract_text(find_tag_by_id(user_browser.contents, 'languages')))
2901 Languages: Set preferred languages
2902 English
2903
2904@@ -145,36 +145,36 @@ Summary Pagelets
2905 A person's homepage also lists Karma and Time zone information:
2906
2907 >>> browser.open('http://launchpad.test/~mark')
2908- >>> print extract_text(find_tag_by_id(browser.contents, 'karma'))
2909+ >>> print(extract_text(find_tag_by_id(browser.contents, 'karma')))
2910 Karma: 130 Karma help
2911
2912 >>> browser.open('http://launchpad.test/~ddaa')
2913- >>> print extract_text(find_tag_by_id(browser.contents, 'timezone'))
2914+ >>> print(extract_text(find_tag_by_id(browser.contents, 'timezone')))
2915 Time zone: UTC (UTC+0000)
2916
2917 Negative Ubuntu Code of Conduct signatory status is only displayed for
2918 yourself; others won't see it:
2919
2920- >>> print find_tag_by_id(browser.contents, 'ubuntu-coc')
2921+ >>> print(find_tag_by_id(browser.contents, 'ubuntu-coc'))
2922 None
2923
2924 >>> browser = setupBrowser(auth='Basic mark@example.com:test')
2925 >>> browser.open('http://launchpad.test/~mark')
2926- >>> print extract_text(find_tag_by_id(browser.contents, 'ubuntu-coc'))
2927+ >>> print(extract_text(find_tag_by_id(browser.contents, 'ubuntu-coc')))
2928 Signed Ubuntu Code of Conduct: No
2929
2930 You can grab certain bits of information programatically:
2931
2932- >>> print extract_text(find_tag_by_id(browser.contents, 'karma-total'))
2933+ >>> print(extract_text(find_tag_by_id(browser.contents, 'karma-total')))
2934 130
2935
2936- >>> print extract_text(find_tag_by_id(browser.contents, 'member-since'))
2937+ >>> print(extract_text(find_tag_by_id(browser.contents, 'member-since')))
2938 2005-06-06
2939
2940 Teams don't have member-since; they have created-date:
2941
2942 >>> browser.open('http://launchpad.test/~guadamen')
2943- >>> print extract_text(find_tag_by_id(browser.contents, 'created-date'))
2944+ >>> print(extract_text(find_tag_by_id(browser.contents, 'created-date')))
2945 2005-06-06
2946
2947
2948@@ -188,11 +188,11 @@ most active and also the areas in which they worked on each project.
2949 >>> anon_browser.open('http://launchpad.test/~name16')
2950 >>> table = find_tag_by_id(anon_browser.contents, 'contributions')
2951 >>> for tr in table.findAll('tr'):
2952- ... print tr.find('th').find('a').renderContents()
2953+ ... print(tr.find('th').find('a').renderContents())
2954 ... for td in tr.findAll('td'):
2955 ... img = td.find('img')
2956 ... if img is not None:
2957- ... print "\t", img['title']
2958+ ... print("\t", img['title'])
2959 Evolution
2960 Bug Management
2961 Translations in Rosetta
2962@@ -214,13 +214,13 @@ If the person hasn't made any contributions, the table is not present in
2963 its page.
2964
2965 >>> anon_browser.open('http://launchpad.test/~jdub')
2966- >>> print find_tag_by_id(anon_browser.contents, 'contributions')
2967+ >>> print(find_tag_by_id(anon_browser.contents, 'contributions'))
2968 None
2969
2970 The same for teams.
2971
2972 >>> anon_browser.open('http://launchpad.test/~ubuntu-team')
2973- >>> print find_tag_by_id(anon_browser.contents, 'contributions')
2974+ >>> print(find_tag_by_id(anon_browser.contents, 'contributions'))
2975 None
2976
2977
2978@@ -232,10 +232,10 @@ were imported into Launchpad. Any user can see an unclaimed profile and
2979 a link to request a claim the profile.
2980
2981 >>> anon_browser.open('https://launchpad.test/~jvprat')
2982- >>> print anon_browser.title
2983+ >>> print(anon_browser.title)
2984 Jordi Vilalta does not use Launchpad
2985
2986- >>> print extract_text(find_main_content(anon_browser.contents))
2987+ >>> print(extract_text(find_main_content(anon_browser.contents)))
2988 Jordi Vilalta does not use Launchpad. This page was created on ...
2989 when importing the Catalan (ca) translation of pmount in Ubuntu Hoary...
2990
2991@@ -257,16 +257,16 @@ users cannot see this, but admins like Foo Bar can.
2992 >>> logout()
2993
2994 >>> anon_browser.open('https://launchpad.test/~jvprat')
2995- >>> print find_tag_by_id(anon_browser.contents, 'email-addresses')
2996+ >>> print(find_tag_by_id(anon_browser.contents, 'email-addresses'))
2997 None
2998
2999 >>> user_browser.open('https://launchpad.test/~jvprat')
3000- >>> print find_tag_by_id(user_browser.contents, 'email-addresses')
3001+ >>> print(find_tag_by_id(user_browser.contents, 'email-addresses'))
3002 None
3003
3004 >>> admin_browser.open('https://launchpad.test/~jvprat')
3005- >>> print extract_text(
3006- ... find_tag_by_id(admin_browser.contents, 'email-addresses'))
3007+ >>> print(extract_text(
3008+ ... find_tag_by_id(admin_browser.contents, 'email-addresses')))
3009 jvprat@wanadoo.es
3010 Change email settings
3011
3012diff --git a/lib/lp/registry/stories/person/xx-person-karma.txt b/lib/lp/registry/stories/person/xx-person-karma.txt
3013index db6931a..fe6181c 100644
3014--- a/lib/lp/registry/stories/person/xx-person-karma.txt
3015+++ b/lib/lp/registry/stories/person/xx-person-karma.txt
3016@@ -7,32 +7,32 @@ the community. A person's current total karma is available on their
3017 profile page.
3018
3019 >>> anon_browser.open('http://launchpad.test/~name12')
3020- >>> print anon_browser.title
3021+ >>> print(anon_browser.title)
3022 Sample Person in Launchpad
3023
3024 >>> content = find_main_content(anon_browser.contents)
3025 >>> karma = find_tag_by_id(content, 'karma-total')
3026- >>> print karma.renderContents()
3027+ >>> print(karma.renderContents())
3028 138
3029
3030 The total karma points is also a link to the person's karma summary page.
3031
3032 >>> anon_browser.getLink('138').click()
3033- >>> print anon_browser.title
3034+ >>> print(anon_browser.title)
3035 Karma : Sample Person
3036
3037 Any user can see the categories that a user has earned karma in.
3038
3039 >>> content = find_main_content(anon_browser.contents)
3040 >>> for row in find_tag_by_id(content, 'karmapoints').findAll('tr'):
3041- ... print extract_text(row)
3042+ ... print(extract_text(row))
3043 Bug Management 94
3044 Specification Tracking 44
3045
3046 Any user can see that a user has latest actions.
3047
3048 >>> for row in find_tag_by_id(content, 'karmaactions').findAll('tr'):
3049- ... print extract_text(row)
3050+ ... print(extract_text(row))
3051 Date Action
3052 2001-11-02 Registered Specification
3053 2001-11-02 Registered Specification
3054@@ -43,7 +43,7 @@ The karma page can also show any user that a user has never earned karma.
3055
3056 >>> anon_browser.open('http://launchpad.test/~salgado/+karma')
3057 >>> content = find_main_content(anon_browser.contents)
3058- >>> print extract_text(find_tag_by_id(content, 'no-karma'))
3059+ >>> print(extract_text(find_tag_by_id(content, 'no-karma')))
3060 No karma has yet been assigned to Guilherme Salgado. Karma is updated
3061 daily.
3062
3063@@ -52,10 +52,10 @@ a that user's last karma actions
3064
3065 >>> anon_browser.open('http://launchpad.test/~karl/+karma')
3066 >>> content = find_main_content(anon_browser.contents)
3067- >>> print extract_text(find_tag_by_id(content, 'no-karma'))
3068+ >>> print(extract_text(find_tag_by_id(content, 'no-karma')))
3069 Karl Tilbury's karma has expired.
3070
3071 >>> for row in find_tag_by_id(content, 'karmaactions').findAll('tr'):
3072- ... print extract_text(row)
3073+ ... print(extract_text(row))
3074 Date Action
3075 2001-08-09 New Bug Filed
3076diff --git a/lib/lp/registry/stories/person/xx-person-projects.txt b/lib/lp/registry/stories/person/xx-person-projects.txt
3077index ea1e800..89a323c 100644
3078--- a/lib/lp/registry/stories/person/xx-person-projects.txt
3079+++ b/lib/lp/registry/stories/person/xx-person-projects.txt
3080@@ -8,7 +8,7 @@ team.
3081 >>> related_projects = find_tag_by_id(
3082 ... anon_browser.contents, 'portlet-related-projects')
3083 >>> for tr in related_projects.findAll('tr'):
3084- ... print extract_text(tr)
3085+ ... print(extract_text(tr))
3086 Ubuntu
3087 ubuntutest
3088 Tomcat
3089@@ -16,12 +16,12 @@ team.
3090 The +related-projects page displays a table with project names.
3091
3092 >>> anon_browser.getLink('Show related projects').click()
3093- >>> print anon_browser.title
3094+ >>> print(anon_browser.title)
3095 Related projects : ...Ubuntu Team... team
3096
3097 >>> related_projects = find_tag_by_id(
3098 ... anon_browser.contents, 'related-projects')
3099- >>> print extract_text(related_projects)
3100+ >>> print(extract_text(related_projects))
3101 Name Owner Driver Bug Supervisor
3102 Ubuntu yes no no
3103 ubuntutest yes no no
3104@@ -32,16 +32,16 @@ A person's projects are accessible via a link on the 'Related packages' page.
3105
3106 >>> anon_browser.open('http://launchpad.test/~mark')
3107 >>> anon_browser.getLink('Related packages').click()
3108- >>> print anon_browser.url
3109+ >>> print(anon_browser.url)
3110 http://launchpad.test/~mark/+related-packages
3111- >>> print anon_browser.title
3112+ >>> print(anon_browser.title)
3113 Related packages : Mark Shuttleworth
3114
3115 >>> anon_browser.open('http://launchpad.test/~mark')
3116 >>> anon_browser.getLink('Related projects').click()
3117 >>> related_projects = find_tag_by_id(
3118 ... anon_browser.contents, 'related-projects')
3119- >>> print extract_text(related_projects)
3120+ >>> print(extract_text(related_projects))
3121 Name Owner Driver Bug Supervisor
3122 Debian yes no no
3123 Gentoo yes no no
3124diff --git a/lib/lp/registry/stories/person/xx-person-rdf.txt b/lib/lp/registry/stories/person/xx-person-rdf.txt
3125index 849853f..fa390ab 100644
3126--- a/lib/lp/registry/stories/person/xx-person-rdf.txt
3127+++ b/lib/lp/registry/stories/person/xx-person-rdf.txt
3128@@ -10,7 +10,7 @@ We export FOAF RDF metadata from the /~Person.name/+index document.
3129 >>> anon_browser.open("http://launchpad.test/~name16")
3130 >>> strainer = SoupStrainer(['link'], {'type': ['application/rdf+xml']})
3131 >>> soup = BeautifulSoup(anon_browser.contents, parse_only=strainer)
3132- >>> print soup.renderContents()
3133+ >>> print(soup.renderContents())
3134 <link href="+rdf" rel="meta" title="FOAF" type="application/rdf+xml"/>
3135
3136
3137@@ -21,7 +21,7 @@ And this is what the FOAF document for an individual actually looks
3138 like. It includes GPG information, if the user has any.
3139
3140 >>> anon_browser.open("http://launchpad.test/~name16/+rdf")
3141- >>> print anon_browser.contents
3142+ >>> print(anon_browser.contents)
3143 <?xml version="1.0"...?>
3144 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
3145 xmlns:foaf="http://xmlns.com/foaf/0.1/"
3146@@ -45,7 +45,7 @@ like. It includes GPG information, if the user has any.
3147 It also includes SSH keys:
3148
3149 >>> anon_browser.open("http://launchpad.test/~name12/+rdf")
3150- >>> print anon_browser.contents
3151+ >>> print(anon_browser.contents)
3152 <?xml version="1.0"...?>
3153 ...
3154 <foaf:name>Sample Person</foaf:name>
3155@@ -57,7 +57,7 @@ And it's valid XML and RDF:
3156
3157 >>> from xml.dom.minidom import parseString
3158 >>> document = parseString(str(anon_browser.contents))
3159- >>> print document.documentElement.nodeName
3160+ >>> print(document.documentElement.nodeName)
3161 rdf:RDF
3162
3163
3164@@ -78,7 +78,7 @@ Now, generate the RDF itself:
3165
3166 >>> from lp.services.helpers import backslashreplace
3167 >>> anon_browser.open("http://launchpad.test/~testing-spanish-team/+rdf")
3168- >>> print backslashreplace(anon_browser.contents)
3169+ >>> print(backslashreplace(anon_browser.contents))
3170 <?xml version="1.0"...?>
3171 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
3172 xmlns:foaf="http://xmlns.com/foaf/0.1/"
3173@@ -118,7 +118,7 @@ present:
3174
3175 And nothing about them is rendered at all:
3176
3177- >>> print anon_browser.contents
3178+ >>> print(anon_browser.contents)
3179 <?xml version="1.0"...?>
3180 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
3181 xmlns:foaf="http://xmlns.com/foaf/0.1/"
3182diff --git a/lib/lp/registry/stories/person/xx-person-subscriptions.txt b/lib/lp/registry/stories/person/xx-person-subscriptions.txt
3183index 669d940..8546cb1 100644
3184--- a/lib/lp/registry/stories/person/xx-person-subscriptions.txt
3185+++ b/lib/lp/registry/stories/person/xx-person-subscriptions.txt
3186@@ -8,7 +8,7 @@ Any user can view the direct subscriptions that a person or team has to
3187 blueprints, branches, bugs, merge proposals and questions.
3188
3189 >>> anon_browser.open('http://launchpad.test/~ubuntu-team/+subscriptions')
3190- >>> print anon_browser.title
3191+ >>> print(anon_browser.title)
3192 Subscriptions : Bugs : ā€œUbuntu Teamā€ team
3193
3194 The user can see that the Ubuntu Team does not have any direct bug
3195@@ -39,8 +39,8 @@ Any user can see Webster's bug subscriptions. The bug subscriptions table
3196 includes the bug number, title and location.
3197
3198 >>> anon_browser.open('http://launchpad.test/~webster/+subscriptions')
3199- >>> print extract_text(find_tag_by_id(
3200- ... anon_browser.contents, 'bug_subscriptions'))
3201+ >>> print(extract_text(find_tag_by_id(
3202+ ... anon_browser.contents, 'bug_subscriptions')))
3203 Summary
3204 In
3205 ...
3206@@ -77,7 +77,7 @@ subscribed to the bug. They click cancel which takes them back to their
3207
3208 >>> cancel_link = subscriber_browser.getLink('Cancel')
3209 >>> cancel_link.click()
3210- >>> print subscriber_browser.title
3211+ >>> print(subscriber_browser.title)
3212 Subscriptions : Bugs : Webster
3213
3214 They choose to unsubscribe from the bug about Affluenza.
3215@@ -87,7 +87,7 @@ They choose to unsubscribe from the bug about Affluenza.
3216 >>> subscriber_browser.getControl(
3217 ... "unsubscribe me from this bug").selected = True
3218 >>> subscriber_browser.getControl("Continue").click()
3219- >>> print subscriber_browser.title
3220+ >>> print(subscriber_browser.title)
3221 Subscriptions : Bugs : Webster
3222
3223 Webster can see that the bug about Affluenza is no longer listed in their
3224@@ -95,8 +95,8 @@ direct bug subscriptions.
3225
3226 >>> subscriber_browser.open(
3227 ... 'http://bugs.launchpad.test/~webster/+subscriptions')
3228- >>> print extract_text(find_tag_by_id(
3229- ... subscriber_browser.contents, 'bug_subscriptions'))
3230+ >>> print(extract_text(find_tag_by_id(
3231+ ... subscriber_browser.contents, 'bug_subscriptions')))
3232 Summary
3233 In
3234 ...
3235@@ -118,11 +118,11 @@ Webster chooses to review the subscriptions for their team America.
3236
3237 >>> subscriber_browser.open(
3238 ... 'http://bugs.launchpad.test/~america/+subscriptions')
3239- >>> print subscriber_browser.title
3240+ >>> print(subscriber_browser.title)
3241 Subscriptions : Bugs ...
3242
3243- >>> print extract_text(find_tag_by_id(
3244- ... subscriber_browser.contents, 'bug_subscriptions'))
3245+ >>> print(extract_text(find_tag_by_id(
3246+ ... subscriber_browser.contents, 'bug_subscriptions')))
3247 Summary
3248 In
3249 ...
3250@@ -133,8 +133,8 @@ Webster now chooses to unsubscribe team America from the bug about Scofflaw.
3251
3252 >>> subscriber_browser.getLink(id='unsubscribe-subscriber-%s' %
3253 ... team.id).click()
3254- >>> print extract_text(find_tags_by_class(
3255- ... subscriber_browser.contents, 'value')[0])
3256+ >>> print(extract_text(find_tags_by_class(
3257+ ... subscriber_browser.contents, 'value')[0]))
3258 subscribe me to this bug, or
3259 unsubscribe America from this bug.
3260
3261@@ -171,9 +171,9 @@ followed by a link to edit the subscription.
3262 ... admin_browser.contents, 'structural-subscriptions')
3263 >>> for subscription in subscriptions.findAll("li"):
3264 ... structure_link, modify_link = subscription.findAll("a")[:2]
3265- ... print "%s <%s>" % (
3266- ... extract_text(structure_link), structure_link.get("href"))
3267- ... print "--> %s" % modify_link.get("href")
3268+ ... print("%s <%s>" % (
3269+ ... extract_text(structure_link), structure_link.get("href")))
3270+ ... print("--> %s" % modify_link.get("href"))
3271 mozilla-firefox in Ubuntu </ubuntu/+source/mozilla-firefox>
3272 --> /ubuntu/+source/mozilla-firefox/+subscribe
3273 pmount in Ubuntu </ubuntu/+source/pmount>
3274@@ -188,8 +188,8 @@ permission to modify those subscriptions.
3275 ... subscriber_browser.contents, 'structural-subscriptions')
3276 >>> for subscription in subscriptions.findAll("li"):
3277 ... structure_link = subscription.find("a")
3278- ... print "%s <%s>" % (
3279- ... extract_text(structure_link), structure_link.get("href"))
3280+ ... print("%s <%s>" % (
3281+ ... extract_text(structure_link), structure_link.get("href")))
3282 mozilla-firefox in Ubuntu </ubuntu/+source/mozilla-firefox>
3283 pmount in Ubuntu </ubuntu/+source/pmount>
3284
3285@@ -204,8 +204,8 @@ structural subscriptions.
3286
3287 >>> subscriber_browser.open(
3288 ... "http://launchpad.test/people/+me/+structural-subscriptions")
3289- >>> print extract_text(find_tag_by_id(
3290- ... subscriber_browser.contents, "structural-subscriptions"))
3291+ >>> print(extract_text(find_tag_by_id(
3292+ ... subscriber_browser.contents, "structural-subscriptions")))
3293 Webster does not have any structural subscriptions.
3294
3295
3296@@ -222,14 +222,14 @@ subscription filter.
3297 ... browser.contents, 'structural-subscriptions')
3298 ... for subscription in subscriptions.findAll("li"):
3299 ... structure_link = subscription.find("a")
3300- ... print extract_text(structure_link)
3301+ ... print(extract_text(structure_link))
3302 ... create_text = subscription.find(text=re.compile("Create"))
3303 ... if create_text is None:
3304- ... print "* No create link."
3305+ ... print("* No create link.")
3306 ... else:
3307- ... print "* %s --> %s" % (
3308+ ... print("* %s --> %s" % (
3309 ... create_text.strip(),
3310- ... create_text.parent.get("href"))
3311+ ... create_text.parent.get("href")))
3312
3313 >>> admin_browser.open(
3314 ... "http://launchpad.test/people/+me/+structural-subscriptions")
3315@@ -273,9 +273,9 @@ filters are shown with a message stating that there is no filtering.
3316 ... subscriptions = find_tag_by_id(
3317 ... nigel_browser.contents, 'structural-subscriptions')
3318 ... for subscription in subscriptions.findAll("li"):
3319- ... print extract_text(subscription.p)
3320+ ... print(extract_text(subscription.p))
3321 ... if subscription.dl is not None:
3322- ... print extract_text(subscription.dl)
3323+ ... print(extract_text(subscription.dl))
3324
3325 >>> show_nigels_subscriptions()
3326 Bug mail for Nigel about Scofflaw is filtered;
3327diff --git a/lib/lp/registry/stories/person/xx-person-working-on.txt b/lib/lp/registry/stories/person/xx-person-working-on.txt
3328index 651e90b..fe7041f 100644
3329--- a/lib/lp/registry/stories/person/xx-person-working-on.txt
3330+++ b/lib/lp/registry/stories/person/xx-person-working-on.txt
3331@@ -31,8 +31,8 @@ displayed there.
3332 >>> logout()
3333
3334 >>> anon_browser.open(new_person_url)
3335- >>> print extract_text(
3336- ... find_tag_by_id(anon_browser.contents, 'working-on'))
3337+ >>> print(extract_text(
3338+ ... find_tag_by_id(anon_browser.contents, 'working-on')))
3339 All bugs in progress
3340 Assigned bugs
3341 ...
3342diff --git a/lib/lp/registry/stories/person/xx-user-to-user.txt b/lib/lp/registry/stories/person/xx-user-to-user.txt
3343index db92486..c035e1d 100644
3344--- a/lib/lp/registry/stories/person/xx-user-to-user.txt
3345+++ b/lib/lp/registry/stories/person/xx-user-to-user.txt
3346@@ -11,13 +11,13 @@ wants to contact Salgado.
3347
3348 >>> user_browser.open('http://launchpad.test/~salgado')
3349 >>> user_browser.getLink('Contact this user').click()
3350- >>> print user_browser.title
3351+ >>> print(user_browser.title)
3352 Contact this user : Guilherme Salgado
3353
3354 >>> user_browser.getControl('Subject').value = 'Hi Salgado'
3355 >>> user_browser.getControl('Message').value = 'Just saying hello'
3356 >>> user_browser.getControl('Send').click()
3357- >>> print user_browser.title
3358+ >>> print(user_browser.title)
3359 Guilherme Salgado in Launchpad
3360
3361 Salgado receives the email message from No Priv.
3362@@ -25,13 +25,13 @@ Salgado receives the email message from No Priv.
3363 >>> len(stub.test_emails)
3364 1
3365 >>> from_addr, to_addrs, raw_msg = stub.test_emails.pop()
3366- >>> print from_addr
3367+ >>> print(from_addr)
3368 bounces@canonical.com
3369 >>> len(to_addrs)
3370 1
3371- >>> print to_addrs[0]
3372+ >>> print(to_addrs[0])
3373 Guilherme Salgado <guilherme.salgado@canonical.com>
3374- >>> print raw_msg
3375+ >>> print(raw_msg)
3376 Content-Type: text/plain; charset="us-ascii"
3377 MIME-Version: 1.0
3378 Content-Transfer-Encoding: 7bit
3379@@ -47,7 +47,7 @@ mind.
3380 >>> user_browser.getControl('Subject').value = 'Hi Salgado'
3381 >>> user_browser.getControl('Message').value = 'Hello again'
3382 >>> user_browser.getLink('Cancel').click()
3383- >>> print user_browser.title
3384+ >>> print(user_browser.title)
3385 Guilherme Salgado in Launchpad
3386
3387
3388@@ -63,7 +63,7 @@ Sample Person has multiple registered and validated email addresses.
3389
3390 By default, Sample can use their preferred email address.
3391
3392- >>> print browser.getControl('From').value
3393+ >>> print(browser.getControl('From').value)
3394 ['test@canonical.com']
3395
3396 But they don't have to use their preferred address; they can use one of
3397@@ -74,7 +74,7 @@ their alternative addresses.
3398 >>> browser.getControl('Send').click()
3399
3400 >>> from_addr, to_addrs, raw_msg = stub.test_emails.pop()
3401- >>> print raw_msg
3402+ >>> print(raw_msg)
3403 Content-Type: text/plain; charset="us-ascii"
3404 MIME-Version: 1.0
3405 Content-Transfer-Encoding: 7bit
3406diff --git a/lib/lp/registry/stories/pillar/xx-pillar-deactivation.txt b/lib/lp/registry/stories/pillar/xx-pillar-deactivation.txt
3407index d2f0fb2..259de37 100644
3408--- a/lib/lp/registry/stories/pillar/xx-pillar-deactivation.txt
3409+++ b/lib/lp/registry/stories/pillar/xx-pillar-deactivation.txt
3410@@ -65,12 +65,14 @@ But an administrator can still see them if they traverse directly, and
3411 they'll see an informative message. They can then reactivate them..
3412
3413 >>> admin_browser.open('http://launchpad.test/firefox')
3414- >>> print find_tag_by_id(admin_browser.contents, 'project-inactive').renderContents()
3415+ >>> print(find_tag_by_id(
3416+ ... admin_browser.contents, 'project-inactive').renderContents())
3417 This project is currently inactive...
3418 >>> toggleProject('firefox')
3419
3420 >>> admin_browser.open('http://launchpad.test/mozilla')
3421- >>> print find_tag_by_id(admin_browser.contents, 'project-inactive').renderContents()
3422+ >>> print(find_tag_by_id(
3423+ ... admin_browser.contents, 'project-inactive').renderContents())
3424 This project is currently inactive...
3425 >>> toggleProject('mozilla')
3426
3427@@ -80,12 +82,12 @@ And they are back to normal:
3428 >>> anon_browser.getLink(url='/firefox').click()
3429 >>> anon_browser.title
3430 'Mozilla Firefox in Launchpad'
3431- >>> print find_tag_by_id(anon_browser.contents, 'project-inactive')
3432+ >>> print(find_tag_by_id(anon_browser.contents, 'project-inactive'))
3433 None
3434
3435 >>> anon_browser.open('http://launchpad.test/projects/+index?text=mozilla')
3436 >>> anon_browser.getLink(url='/mozilla').click()
3437 >>> anon_browser.title
3438 'The Mozilla Project in Launchpad'
3439- >>> print find_tag_by_id(anon_browser.contents, 'project-inactive')
3440+ >>> print(find_tag_by_id(anon_browser.contents, 'project-inactive'))
3441 None
3442diff --git a/lib/lp/registry/stories/pillar/xx-pillar-sprints.txt b/lib/lp/registry/stories/pillar/xx-pillar-sprints.txt
3443index c5784e9..940c933 100644
3444--- a/lib/lp/registry/stories/pillar/xx-pillar-sprints.txt
3445+++ b/lib/lp/registry/stories/pillar/xx-pillar-sprints.txt
3446@@ -8,7 +8,7 @@ all events relevant to that pillar.
3447 ... maincontent = find_tag_by_id(contents, 'maincontent')
3448 ... for link in maincontent.findAll('a'):
3449 ... if re.search('/sprints/[a-z0-9]', link['href']) is not None:
3450- ... print link.renderContents()
3451+ ... print(link.renderContents())
3452
3453 >>> anon_browser.open('http://launchpad.test/firefox/+sprints')
3454 >>> print_sprints(anon_browser.contents)
3455diff --git a/lib/lp/registry/stories/product/xx-launchpad-project-search.txt b/lib/lp/registry/stories/product/xx-launchpad-project-search.txt
3456index 9e1b3b0..d1595e8 100644
3457--- a/lib/lp/registry/stories/product/xx-launchpad-project-search.txt
3458+++ b/lib/lp/registry/stories/product/xx-launchpad-project-search.txt
3459@@ -12,8 +12,8 @@ distributions.
3460
3461 The user is informed when no matches are found.
3462
3463- >>> print extract_text(
3464- ... find_tag_by_id(anon_browser.contents, 'no-matches'))
3465+ >>> print(extract_text(
3466+ ... find_tag_by_id(anon_browser.contents, 'no-matches')))
3467 No projects matching ...whizzbar... were found...
3468
3469 Launchpad shows up to config.launchpad.default_batch_size results; if there
3470@@ -32,16 +32,16 @@ the user to refine their search.
3471 'http://launchpad.test/projects/+index?text=ubuntu'
3472
3473 >>> content = find_main_content(anon_browser.contents)
3474- >>> print extract_text(find_tag_by_id(content, 'search-summary'))
3475+ >>> print(extract_text(find_tag_by_id(content, 'search-summary')))
3476 6 projects found matching ...ubuntu..., showing the most relevant 5
3477
3478- >>> print extract_text(find_tag_by_id(content, 'too-many-matches'))
3479+ >>> print(extract_text(find_tag_by_id(content, 'too-many-matches')))
3480 More than 5 projects were found.
3481 You can do another search with more relevant search terms.
3482
3483 A lower search form is shown when there are matches.
3484
3485- >>> print find_tag_by_id(content, 'project-search-lower').name
3486+ >>> print(find_tag_by_id(content, 'project-search-lower').name)
3487 form
3488
3489 The search results contain projects, project-groups, and distributions.
3490@@ -50,7 +50,7 @@ The search results contain projects, project-groups, and distributions.
3491 ... search_results = find_tag_by_id(
3492 ... abrowser.contents, 'search-results')
3493 ... for tr in search_results.tbody('tr'):
3494- ... print ' '.join(tr.td.a['class']), extract_text(tr.td.a)
3495+ ... print(' '.join(tr.td.a['class']), extract_text(tr.td.a))
3496 >>> print_search_results(anon_browser)
3497 sprite distribution Ubuntu
3498 sprite distribution ubuntutest
3499@@ -74,7 +74,7 @@ some terms and do another search.
3500 ''
3501 >>> project_search.getControl('Search').click()
3502 >>> empty_search = find_tag_by_id(anon_browser.contents, 'empty-search-string')
3503- >>> print empty_search.renderContents()
3504+ >>> print(empty_search.renderContents())
3505 <BLANKLINE>
3506 ...Enter one or more words related to the project you want to find.
3507 <BLANKLINE>
3508@@ -93,10 +93,10 @@ A similar page is available for only searching project groups.
3509 >>> tags = find_tags_by_class(
3510 ... anon_browser.contents, "informational message")
3511 >>> for tag in tags:
3512- ... print tag.renderContents()
3513+ ... print(tag.renderContents())
3514
3515 The search results contains only project-groups.
3516
3517- >>> print extract_text(
3518- ... find_main_content(anon_browser.contents).findAll('p')[1])
3519+ >>> print(extract_text(
3520+ ... find_main_content(anon_browser.contents).findAll('p')[1]))
3521 1 project group found matching ...gnome...
3522diff --git a/lib/lp/registry/stories/product/xx-product-add.txt b/lib/lp/registry/stories/product/xx-product-add.txt
3523index b418979..2a861ca 100644
3524--- a/lib/lp/registry/stories/product/xx-product-add.txt
3525+++ b/lib/lp/registry/stories/product/xx-product-add.txt
3526@@ -6,30 +6,30 @@ either from the Launchpad home page or the projects home page.
3527
3528 >>> user_browser.open('http://launchpad.test')
3529 >>> user_browser.getLink('Register a project').click()
3530- >>> print user_browser.title
3531+ >>> print(user_browser.title)
3532 Register a project in Launchpad...
3533
3534 >>> user_browser.open('http://launchpad.test/projects')
3535 >>> user_browser.getLink('Register a project').click()
3536- >>> print user_browser.title
3537+ >>> print(user_browser.title)
3538 Register a project in Launchpad...
3539
3540 The user can see links about things that are often assumed to be related to
3541 project registration.
3542
3543- >>> print user_browser.getLink('Register a team').url
3544+ >>> print(user_browser.getLink('Register a team').url)
3545 https://help.launchpad.net/Teams
3546
3547- >>> print user_browser.getLink('Activate a PPA').url
3548+ >>> print(user_browser.getLink('Activate a PPA').url)
3549 https://help.launchpad.net/Packaging/PPA
3550
3551- >>> print user_browser.getLink('Access your personal branches').url
3552+ >>> print(user_browser.getLink('Access your personal branches').url)
3553 https://help.launchpad.net/Code/PersonalBranches
3554
3555- >>> print user_browser.getLink('Translate a project').url
3556+ >>> print(user_browser.getLink('Translate a project').url)
3557 https://help.launchpad.net/Translations/YourProject
3558
3559- >>> print user_browser.getLink('Request a project group').url
3560+ >>> print(user_browser.getLink('Request a project group').url)
3561 https://help.launchpad.net/ProjectGroups
3562
3563
3564@@ -73,7 +73,7 @@ information correctly this time.
3565 The project is not yet created; instead, the project basics are successfully
3566 validated and the second step of the process is entered.
3567
3568- >>> print user_browser.title
3569+ >>> print(user_browser.title)
3570 Register a project in Launchpad...
3571
3572
3573@@ -85,7 +85,7 @@ modify the project's URL.
3574
3575 >>> user_browser.getControl(name='field.name')
3576 <Control name='field.name' type='hidden'>
3577- >>> print user_browser.getControl(name='field.name').value
3578+ >>> print(user_browser.getControl(name='field.name').value)
3579 aardvark
3580
3581 Sample Person is given the opportunity though to change the summary.
3582@@ -97,30 +97,30 @@ They can also add a longer description.
3583 ... 'The desktop aardvark is an ornery thing.')
3584 >>> user_browser.getControl('Python Licence').click()
3585 >>> user_browser.getControl('Complete Registration').click()
3586- >>> print user_browser.title
3587+ >>> print(user_browser.title)
3588 Aardvark Center in Launchpad
3589
3590 Let's ensure the summary and description are presented.
3591
3592 >>> summary = find_tags_by_class(user_browser.contents,
3593 ... 'summary', only_first=True)
3594- >>> print extract_text(summary)
3595+ >>> print(extract_text(summary))
3596 Control pesky aardvarkian fnords
3597 >>> desc = find_tags_by_class(user_browser.contents,
3598 ... 'description', only_first=True)
3599- >>> print extract_text(desc)
3600+ >>> print(extract_text(desc))
3601 The desktop aardvark is an ornery thing.
3602
3603 Let's ensure the registrant and maintainer are listed correctly.
3604
3605 >>> registrant = find_tag_by_id(user_browser.contents,
3606 ... 'registration')
3607- >>> print extract_text(registrant)
3608+ >>> print(extract_text(registrant))
3609 Registered...by...No Privileges Person...
3610
3611 >>> maintainer = find_tag_by_id(user_browser.contents,
3612 ... 'owner')
3613- >>> print extract_text(maintainer)
3614+ >>> print(extract_text(maintainer))
3615 Maintainer: No Privileges Person...
3616
3617
3618@@ -150,12 +150,12 @@ Registry Admins.
3619
3620 >>> registrant = find_tag_by_id(user_browser.contents,
3621 ... 'registration')
3622- >>> print extract_text(registrant)
3623+ >>> print(extract_text(registrant))
3624 Registered...by...No Privileges Person...
3625
3626 >>> maintainer = find_tag_by_id(user_browser.contents,
3627 ... 'owner')
3628- >>> print extract_text(maintainer)
3629+ >>> print(extract_text(maintainer))
3630 Maintainer: Registry Administrators...
3631
3632
3633@@ -167,7 +167,7 @@ Firefox.
3634
3635 >>> user_browser.open('http://launchpad.test')
3636 >>> user_browser.getLink('Register a project').click()
3637- >>> print user_browser.title
3638+ >>> print(user_browser.title)
3639 Register a project in Launchpad...
3640
3641 >>> user_browser.getControl('Name').value = 'Snowdog'
3642@@ -183,7 +183,7 @@ Instead of registering their new project, Sample Person decides to participate
3643 in the Mozilla Project.
3644
3645 >>> user_browser.getLink('The Mozilla Project').click()
3646- >>> print user_browser.title
3647+ >>> print(user_browser.title)
3648 The Mozilla Project in Launchpad
3649
3650
3651@@ -195,8 +195,8 @@ The project registration workflow used to get started at
3652 location at /projects/+new.
3653
3654 >>> user_browser.open('http://launchpad.test/projects/+new-guided')
3655- >>> print user_browser.title
3656+ >>> print(user_browser.title)
3657 Register a project in Launchpad...
3658
3659- >>> print user_browser.url
3660+ >>> print(user_browser.url)
3661 http://launchpad.test/projects/+new
3662diff --git a/lib/lp/registry/stories/product/xx-product-code-trunk.txt b/lib/lp/registry/stories/product/xx-product-code-trunk.txt
3663index 157bae2..04ba410 100644
3664--- a/lib/lp/registry/stories/product/xx-product-code-trunk.txt
3665+++ b/lib/lp/registry/stories/product/xx-product-code-trunk.txt
3666@@ -24,33 +24,33 @@ Make revisions for the branch so it has a codebrowse link.
3667 >>> def print_development_focus(browser):
3668 ... """Print out the development focus part of the project info."""
3669 ... dev_focus = find_tag_by_id(browser.contents, 'development-focus')
3670- ... print extract_text(dev_focus)
3671- ... print "Links:"
3672+ ... print(extract_text(dev_focus))
3673+ ... print("Links:")
3674 ... for a in dev_focus.findAll('a'):
3675 ... for content in a.contents:
3676- ... print content
3677+ ... print(content)
3678 ... title = a.get('title', '')
3679- ... print "%s (%s)" % (title, a['href'])
3680+ ... print("%s (%s)" % (title, a['href']))
3681 >>> def print_code_trunk(browser):
3682 ... """Print out code trunk part of the project info."""
3683 ... project_info = find_tag_by_id(browser.contents, 'code-info')
3684 ... code_trunk = project_info.find(attrs={'id':'code-trunk'})
3685 ... try:
3686- ... print extract_text(code_trunk)
3687+ ... print(extract_text(code_trunk))
3688 ... except TypeError:
3689 ... return
3690- ... print "Links:"
3691+ ... print("Links:")
3692 ... for a in code_trunk.findAll('a'):
3693 ... for content in a.contents:
3694- ... print content
3695+ ... print(content)
3696 ... title = a.get('title', '')
3697- ... print "%s (%s)" % (title, a['href'])
3698+ ... print("%s (%s)" % (title, a['href']))
3699 >>> def print_involvement_portlet(browser):
3700 ... involvement = find_tag_by_id(browser.contents, 'involvement')
3701 ... for a in involvement.findAll('a'):
3702 ... for content in a.contents:
3703- ... print content
3704- ... print a['href']
3705+ ... print(content)
3706+ ... print(a['href'])
3707
3708
3709 Projects without development focus branches
3710diff --git a/lib/lp/registry/stories/product/xx-product-edit-sourceforge-project.txt b/lib/lp/registry/stories/product/xx-product-edit-sourceforge-project.txt
3711index 734d465..66bccea 100644
3712--- a/lib/lp/registry/stories/product/xx-product-edit-sourceforge-project.txt
3713+++ b/lib/lp/registry/stories/product/xx-product-edit-sourceforge-project.txt
3714@@ -6,7 +6,7 @@ The setting of the SourceForge project is constrained.
3715 ... admin_browser.open('http://launchpad.test/firefox/+edit')
3716 ... admin_browser.getControl('Sourceforge Project').value = name
3717 ... admin_browser.getControl('Change').click()
3718- ... print admin_browser.url
3719+ ... print(admin_browser.url)
3720 ... print_feedback_messages(admin_browser.contents)
3721
3722 >>> set_sourceforge_project('1234')
3723diff --git a/lib/lp/registry/stories/product/xx-product-edit.txt b/lib/lp/registry/stories/product/xx-product-edit.txt
3724index 8f82dd3..1b6a7c6 100644
3725--- a/lib/lp/registry/stories/product/xx-product-edit.txt
3726+++ b/lib/lp/registry/stories/product/xx-product-edit.txt
3727@@ -7,10 +7,10 @@ Page to edit a product - does the page load as the product owner?
3728 >>> browser = setupBrowser(auth='Basic test@canonical.com:test')
3729 >>> browser.open('http://launchpad.test/firefox')
3730 >>> browser.getLink('Change details').click()
3731- >>> print browser.url
3732+ >>> print(browser.url)
3733 http://launchpad.test/firefox/+edit
3734
3735- >>> print browser.title
3736+ >>> print(browser.title)
3737 Change Mozilla Firefox's details...
3738
3739 We try to change the project related to that product. First with a
3740@@ -19,7 +19,7 @@ invalid project.
3741 >>> browser.getControl('Part of', index=0).value = 'asdasfasd'
3742 >>> browser.getControl(name='field.actions.change').click()
3743 >>> for message in find_tags_by_class(browser.contents, 'error'):
3744- ... print message.renderContents()
3745+ ... print(message.renderContents())
3746 There is 1 error.
3747 <BLANKLINE>
3748 ...
3749@@ -30,12 +30,12 @@ Now we try to edit with a project that exists.
3750
3751 >>> browser.getControl('Part of', index=0).value = 'gnome'
3752 >>> browser.getControl(name='field.actions.change').click()
3753- >>> print browser.url
3754+ >>> print(browser.url)
3755 http://launchpad.test/firefox
3756
3757 Now we test if we edited it successfully.
3758
3759- >>> print extract_text(find_tag_by_id(browser.contents, 'partof'))
3760+ >>> print(extract_text(find_tag_by_id(browser.contents, 'partof')))
3761 Part of: GNOME
3762
3763
3764@@ -50,7 +50,7 @@ But administrators can access the page:
3765 >>> admin_browser.url
3766 'http://launchpad.test/firefox/+admin'
3767
3768- >>> print admin_browser.title
3769+ >>> print(admin_browser.title)
3770 Administer Mozilla Firefox...
3771
3772 And in that page they can set aliases to the product.
3773@@ -82,7 +82,7 @@ First a user adds a product named newproductname.
3774 >>> user_browser.getControl(name='field.licenses').value = ['GNU_GPL_V2']
3775 >>> user_browser.getControl(name='field.license_info').value = 'foo'
3776 >>> user_browser.getControl('Complete Registration').click()
3777- >>> print user_browser.url
3778+ >>> print(user_browser.url)
3779 http://launchpad.test/newproductname
3780
3781 Then a product named newproductname2.
3782@@ -98,7 +98,7 @@ Then a product named newproductname2.
3783 >>> user_browser.getControl(name='field.licenses').value = ['GNU_GPL_V2']
3784 >>> user_browser.getControl(name='field.license_info').value = 'foo'
3785 >>> user_browser.getControl('Complete Registration').click()
3786- >>> print user_browser.url
3787+ >>> print(user_browser.url)
3788 http://launchpad.test/newproductname2
3789
3790 Now we try to change newproductname2's name to newproductname.
3791@@ -108,7 +108,7 @@ Now we try to change newproductname2's name to newproductname.
3792 >>> admin_browser.getControl('Name').value = 'newproductname'
3793 >>> admin_browser.getControl(name='field.actions.change').click()
3794 >>> for message in find_tags_by_class(admin_browser.contents, 'error'):
3795- ... print message.renderContents()
3796+ ... print(message.renderContents())
3797 There is 1 error.
3798 <BLANKLINE>
3799 ...
3800@@ -121,7 +121,7 @@ will be accepted because there is no product called newproductname3
3801
3802 >>> admin_browser.getControl('Name').value = 'newproductname3'
3803 >>> admin_browser.getControl(name='field.actions.change').click()
3804- >>> print admin_browser.url
3805+ >>> print(admin_browser.url)
3806 http://launchpad.test/newproductname3
3807
3808
3809@@ -132,7 +132,7 @@ Administrators can change the owner of a project.
3810
3811 >>> admin_browser.open(
3812 ... 'http://launchpad.test/newproductname3')
3813- >>> print extract_text(find_tag_by_id(admin_browser.contents, 'owner'))
3814+ >>> print(extract_text(find_tag_by_id(admin_browser.contents, 'owner')))
3815 Maintainer: No Privileges Person
3816 ...
3817
3818@@ -140,7 +140,7 @@ Administrators can change the owner of a project.
3819 ... 'http://launchpad.test/newproductname3/+admin')
3820 >>> admin_browser.getControl('Maintainer').value = 'cprov'
3821 >>> admin_browser.getControl(name='field.actions.change').click()
3822- >>> print extract_text(find_tag_by_id(admin_browser.contents, 'owner'))
3823+ >>> print(extract_text(find_tag_by_id(admin_browser.contents, 'owner')))
3824 Maintainer: Celso Providelo
3825 ...
3826
3827@@ -150,16 +150,16 @@ is created but we allow admins to change it to correct data.
3828
3829 >>> admin_browser.open(
3830 ... 'http://launchpad.test/newproductname3')
3831- >>> print extract_text(
3832- ... find_tag_by_id(admin_browser.contents, 'registration'))
3833+ >>> print(extract_text(
3834+ ... find_tag_by_id(admin_browser.contents, 'registration')))
3835 Registered ... by No Privileges Person
3836
3837 >>> admin_browser.open(
3838 ... 'http://launchpad.test/newproductname3/+admin')
3839 >>> admin_browser.getControl('Registrant').value = 'cprov'
3840 >>> admin_browser.getControl(name='field.actions.change').click()
3841- >>> print extract_text(
3842- ... find_tag_by_id(admin_browser.contents, 'registration'))
3843+ >>> print(extract_text(
3844+ ... find_tag_by_id(admin_browser.contents, 'registration')))
3845 Registered ... by Celso Providelo
3846
3847 The registrant really should only be a person, not a team, but that
3848@@ -169,8 +169,8 @@ teams as registrants.
3849 >>> admin_browser.open('http://launchpad.test/newproductname3/+admin')
3850 >>> admin_browser.getControl('Registrant').value = 'registry'
3851 >>> admin_browser.getControl('Change').click()
3852- >>> print extract_text(
3853- ... find_tag_by_id(admin_browser.contents, 'registration'))
3854+ >>> print(extract_text(
3855+ ... find_tag_by_id(admin_browser.contents, 'registration')))
3856 Registered ... by Registry Administrators
3857
3858
3859@@ -213,9 +213,9 @@ But registry experts can change a product name and set an alias.
3860 >>> browser.getControl('Change').click()
3861
3862 >>> browser.getLink('Administer').click()
3863- >>> print browser.getControl('Name').value
3864+ >>> print(browser.getControl('Name').value)
3865 trebuchet
3866- >>> print browser.getControl('Aliases').value
3867+ >>> print(browser.getControl('Aliases').value)
3868 trebucket
3869
3870
3871@@ -241,7 +241,7 @@ The Admins and Registry Experts can deactivate a project.
3872 >>> registry_browser.open('http://launchpad.test/bzr/+review-license')
3873 >>> registry_browser.getControl(name='field.active').value = False
3874 >>> registry_browser.getControl(name='field.actions.change').click()
3875- >>> print registry_browser.url
3876+ >>> print(registry_browser.url)
3877 http://launchpad.test/bzr
3878
3879 The product overview page should show a notice that a product is
3880@@ -250,27 +250,27 @@ Admins can still see the product, but regular users can't.
3881
3882 >>> registry_browser.open('http://launchpad.test/bzr')
3883 >>> contents = find_main_content(registry_browser.contents)
3884- >>> print extract_text(contents.find(id='project-inactive'))
3885+ >>> print(extract_text(contents.find(id='project-inactive')))
3886 This project is currently inactive ...
3887
3888 >>> admin_browser.open('http://launchpad.test/bzr')
3889 >>> contents = find_main_content(admin_browser.contents)
3890- >>> print extract_text(contents.find(id='project-inactive'))
3891+ >>> print(extract_text(contents.find(id='project-inactive')))
3892 This project is currently inactive ...
3893
3894 The product can then be reactivated.
3895
3896 >>> registry_browser.getLink('Review project').click()
3897- >>> print registry_browser.url
3898+ >>> print(registry_browser.url)
3899 http://launchpad.test/bzr/+review-license
3900
3901 >>> registry_browser.getControl(name='field.active').value = True
3902 >>> registry_browser.getControl(name='field.actions.change').click()
3903- >>> print registry_browser.url
3904+ >>> print(registry_browser.url)
3905 http://launchpad.test/bzr
3906
3907 >>> contents = find_main_content(registry_browser.contents)
3908- >>> print contents.find(id='project-inactive')
3909+ >>> print(contents.find(id='project-inactive'))
3910 None
3911
3912 Revert team memberships.
3913diff --git a/lib/lp/registry/stories/product/xx-product-files.txt b/lib/lp/registry/stories/product/xx-product-files.txt
3914index fff1d46..673a34c 100644
3915--- a/lib/lp/registry/stories/product/xx-product-files.txt
3916+++ b/lib/lp/registry/stories/product/xx-product-files.txt
3917@@ -9,7 +9,7 @@ Any user can see that a project with no releases has no downloads.
3918
3919 >>> anon_browser.open('http://launchpad.test/aptoncd')
3920 >>> content = find_tag_by_id(anon_browser.contents, 'downloads')
3921- >>> print extract_text(content)
3922+ >>> print(extract_text(content))
3923 Downloads
3924 APTonCD does not have any download files registered with Launchpad.
3925
3926@@ -19,7 +19,7 @@ downloadable files.
3927
3928 >>> anon_browser.open('http://launchpad.test/thunderbird')
3929 >>> content = find_tag_by_id(anon_browser.contents, 'downloads')
3930- >>> print extract_text(content)
3931+ >>> print(extract_text(content))
3932 Downloads
3933 Mozilla Thunderbird does not have any download files
3934 registered with Launchpad.
3935@@ -30,14 +30,14 @@ release to add download files.
3936
3937 >>> anon_browser.open('http://launchpad.test/firefox')
3938 >>> content = find_tag_by_id(anon_browser.contents, 'downloads')
3939- >>> print extract_text(content)
3940+ >>> print(extract_text(content))
3941 Downloads
3942 Latest version is 0.9.2
3943 firefox_0.9.2.orig.tar.gz...
3944
3945 >>> anon_browser.getLink('All downloads').click()
3946- >>> print extract_text(
3947- ... find_tag_by_id(anon_browser.contents, 'project-downloads'))
3948+ >>> print(extract_text(
3949+ ... find_tag_by_id(anon_browser.contents, 'project-downloads')))
3950 0.9.2 (One (secure) Tree Hill) release from the trunk series
3951 released 2004-10-15
3952 Release information
3953@@ -56,7 +56,7 @@ otherwise.
3954 ... name='prop-prod', information_type=InformationType.PROPRIETARY)
3955 >>> logout()
3956 >>> admin_browser.open('http://launchpad.test/prop-prod')
3957- >>> print find_tag_by_id(admin_browser.contents, 'downloads')
3958+ >>> print(find_tag_by_id(admin_browser.contents, 'downloads'))
3959 None
3960
3961
3962@@ -71,7 +71,7 @@ the delete options.
3963 'http://launchpad.test/firefox/+download'
3964 >>> content = find_main_content(anon_browser.contents)
3965 >>> row = content.find('table').find('tr')
3966- >>> print extract_text(row)
3967+ >>> print(extract_text(row))
3968 File
3969 Description
3970 Downloads
3971@@ -85,7 +85,7 @@ Again, for an authenticated user who is not the firefox product owner.
3972 'http://launchpad.test/firefox/+download'
3973 >>> content = find_main_content(non_owner.contents)
3974 >>> row = content.find('table').find('tr')
3975- >>> print extract_text(row)
3976+ >>> print(extract_text(row))
3977 File
3978 Description
3979 Downloads
3980@@ -99,7 +99,7 @@ Now, login as a firefox admin and see the delete fields.
3981 'http://launchpad.test/firefox/+download'
3982 >>> content = find_main_content(firefox_owner.contents)
3983 >>> row = content.find('table').find('tr')
3984- >>> print extract_text(row)
3985+ >>> print(extract_text(row))
3986 File
3987 Description
3988 Downloads
3989@@ -110,11 +110,11 @@ A project owner should not see the delete button when there are no files.
3990 >>> tbird_owner = setupBrowser(
3991 ... auth='Basic foo.bar@canonical.com:test')
3992 >>> tbird_owner.open('http://launchpad.test/thunderbird/+download')
3993- >>> print tbird_owner.title
3994+ >>> print(tbird_owner.title)
3995 Mozilla Thunderbird project files...
3996
3997 >>> main_content = find_main_content(tbird_owner.contents)
3998- >>> print extract_text(main_content)
3999+ >>> print(extract_text(main_content))
4000 Download project files
4001 No download files exist for this project...
4002 Add download file to the trunk series for release: 0.8
4003@@ -134,7 +134,7 @@ add download files for each release in that series is presented.
4004
4005 >>> firefox_owner.open('http://launchpad.test/firefox/+download')
4006 >>> for tag in find_tags_by_class(firefox_owner.contents, 'add-files'):
4007- ... print extract_text(tag)
4008+ ... print(extract_text(tag))
4009 Add download file to the trunk series for release: 0.9.2, 0.9.1, 0.9
4010 Add download file to the 1.0 series for release: 1.0.0
4011
4012@@ -149,7 +149,7 @@ series should not show up in the list.
4013 >>> firefox_owner.getControl('Register Series').click()
4014 >>> firefox_owner.open('http://launchpad.test/firefox/+download')
4015 >>> for tag in find_tags_by_class(firefox_owner.contents, 'add-files'):
4016- ... print extract_text(tag)
4017+ ... print(extract_text(tag))
4018 Add download file to the trunk series for release: 0.9.2, 0.9.1, 0.9
4019 Add download file to the 1.0 series for release: 1.0.0
4020
4021@@ -166,11 +166,11 @@ the list.
4022 >>> firefox_owner.getLink('Create release').click()
4023 >>> firefox_owner.getControl('Date released').value = '2000-01-01'
4024 >>> firefox_owner.getControl('Create release').click()
4025- >>> print firefox_owner.url
4026+ >>> print(firefox_owner.url)
4027 http://launchpad.test/firefox/+milestone/3.14159
4028 >>> firefox_owner.open('http://launchpad.test/firefox/+download')
4029 >>> for tag in find_tags_by_class(firefox_owner.contents, 'add-files'):
4030- ... print extract_text(tag)
4031+ ... print(extract_text(tag))
4032 Add download file to the trunk series for release: 0.9.2, 0.9.1, 0.9
4033 Add download file to the 3.0 series for release: 3.14159
4034 Add download file to the 1.0 series for release: 1.0.0
4035@@ -199,7 +199,7 @@ To add a download file the release version link is used.
4036
4037 >>> firefox_owner.open('http://launchpad.test/firefox/+download')
4038 >>> firefox_owner.getLink('1.0.0').click()
4039- >>> print firefox_owner.title
4040+ >>> print(firefox_owner.title)
4041 Add a download file to Mozilla Firefox...
4042
4043 Ensure a non-owner doesn't see the 'Add download file' link after
4044@@ -219,7 +219,7 @@ To add a download file the +adddownloadfile page is accessed.
4045 The maximum size of the upload file is shown on the page.
4046
4047 >>> content = find_main_content(firefox_owner.contents)
4048- >>> print content
4049+ >>> print(content)
4050 <...
4051 ...You may upload files up to 1.0 GiB...
4052
4053@@ -260,7 +260,7 @@ user to see.
4054 >>> anon_browser.open('http://launchpad.test/firefox/+download')
4055 >>> content = find_main_content(anon_browser.contents)
4056 >>> for tr in content.findAll('table')[1].findAll('tr'):
4057- ... print extract_text(tr)
4058+ ... print(extract_text(tr))
4059 File Description Downloads
4060 bar.txt (md5) Bar installer -
4061 foo.txt (md5, sig) Foo installer -
4062@@ -274,7 +274,7 @@ an admin can also delete a release file.
4063 >>> checkbox.value = checkbox.options
4064 >>> table = find_tag_by_id(admin_browser.contents, 'downloads')
4065 >>> for tr in table.findAll('tr'):
4066- ... print extract_text(tr)
4067+ ... print(extract_text(tr))
4068 File Description Downloads Delete
4069 bar.txt (md5) Bar installer -
4070 foo.txt (md5, sig) Foo installer -
4071@@ -285,7 +285,7 @@ an admin can also delete a release file.
4072 1 file has been deleted.
4073 >>> table = find_tag_by_id(admin_browser.contents, 'downloads')
4074 >>> for tr in table.findAll('tr'):
4075- ... print extract_text(tr)
4076+ ... print(extract_text(tr))
4077 File Description Downloads Delete
4078 foo.txt (md5, sig) Foo installer -
4079
4080@@ -297,7 +297,7 @@ the md5 digest of the file, and the signature that we uploaded.
4081 >>> non_owner.url
4082 'http://launchpad.test/firefox/+download'
4083 >>> content = find_main_content(non_owner.contents)
4084- >>> print content
4085+ >>> print(content)
4086 <...
4087 ...foo.txt...md5...sig...Foo installer...
4088
4089@@ -388,7 +388,7 @@ are listed within series in reverse chronological order, except
4090 >>> for row in rows[1:]:
4091 ... a_list = row.findAll('a')
4092 ... if len(a_list) > 0:
4093- ... print a_list[0].string
4094+ ... print(a_list[0].string)
4095 firefox_0.9.2.orig.tar.gz
4096 foo09.txt
4097 foo3.txt
4098@@ -423,7 +423,7 @@ XXX Mon May 7 10:02:49 2007 -- bac
4099 ... if key.lower() == "location":
4100 ... redirect_url = value
4101 ... break
4102- >>> print urlopen(redirect_url).read()
4103+ >>> print(urlopen(redirect_url).read())
4104 Foo2 installer package...
4105
4106 Delete the file foo2.txt.
4107@@ -449,7 +449,7 @@ Ensure the file is no longer listed.
4108 >>> for row in rows[1:]:
4109 ... a_list = row.findAll('a')
4110 ... if len(a_list) > 0:
4111- ... print a_list[0].string
4112+ ... print(a_list[0].string)
4113 firefox_0.9.2.orig.tar.gz
4114 foo09.txt
4115 foo3.txt
4116@@ -465,7 +465,7 @@ Non-administrators do not have the delete option.
4117 >>> non_owner.open('http://launchpad.test/firefox/trunk/0.9')
4118 >>> table = find_tag_by_id(non_owner.contents, 'downloads')
4119 >>> for tr in table.findAll('tr'):
4120- ... print extract_text(tr)
4121+ ... print(extract_text(tr))
4122 File Description Downloads
4123 foo09.txt (md5) Foo09 installer -
4124
4125@@ -484,7 +484,7 @@ so it is not shown.
4126 >>> firefox_owner.open('http://launchpad.test/firefox/trunk/0.9')
4127 >>> table = find_tag_by_id(firefox_owner.contents, 'downloads')
4128 >>> for tr in table.findAll('tr'):
4129- ... print extract_text(tr)
4130+ ... print(extract_text(tr))
4131 File Description Downloads Delete
4132 foo09.txt (md5) Foo09 installer -
4133
4134diff --git a/lib/lp/registry/stories/product/xx-product-index.txt b/lib/lp/registry/stories/product/xx-product-index.txt
4135index 72e1d36..28e7079 100644
4136--- a/lib/lp/registry/stories/product/xx-product-index.txt
4137+++ b/lib/lp/registry/stories/product/xx-product-index.txt
4138@@ -11,7 +11,7 @@ The product page has a link to help translate it.
4139 >>> link = user_browser.getLink(
4140 ... url='http://translations.launchpad.test/evolution')
4141 >>> link.click()
4142- >>> print user_browser.title
4143+ >>> print(user_browser.title)
4144 Translations : Evolution
4145
4146
4147@@ -20,7 +20,7 @@ Links and Programming languages
4148
4149 Evolution has no external links.
4150
4151- >>> print find_tag_by_id(user_browser.contents, 'external-links-heading')
4152+ >>> print(find_tag_by_id(user_browser.contents, 'external-links-heading'))
4153 None
4154
4155 Now update Tomcat to actually have this data:
4156@@ -51,14 +51,14 @@ Let's check it out:
4157 >>> content = find_main_content(browser.contents)
4158 >>> external_links = find_tag_by_id(content, 'external-links')
4159 >>> for link in external_links.findAll('a'):
4160- ... print extract_text(link), link['href']
4161+ ... print(extract_text(link), link['href'])
4162 Home page http://home.page/
4163 Sourceforge project http://sourceforge.net/projects/sf-tomcat
4164 Wiki http://wiki.url/
4165 Screenshots http://screenshots.url/
4166 External downloads http://download.url/
4167
4168- >>> print extract_text(find_tag_by_id(content, 'product-languages'))
4169+ >>> print(extract_text(find_tag_by_id(content, 'product-languages')))
4170 Programming languages: C++,Xenon and Purple
4171
4172 When the sourceforge URL is identical to the homepage, we omit the homepage:
4173@@ -76,7 +76,7 @@ When the sourceforge URL is identical to the homepage, we omit the homepage:
4174 >>> content = find_main_content(browser.contents)
4175 >>> external_links = find_tag_by_id(content, 'external-links')
4176 >>> for link in external_links.findAll('a'):
4177- ... print extract_text(link), link['href']
4178+ ... print(extract_text(link), link['href'])
4179 Sourceforge project http://sourceforge.net/projects/sf-tomcat
4180 Wiki http://wiki.url/
4181 Screenshots http://screenshots.url/
4182@@ -101,8 +101,8 @@ been reviewed by a Launchpad administrator will be displayed as
4183 Any user can see that the project's licence has not been reviewed.
4184
4185 >>> user_browser.open('http://launchpad.test/thunderbird')
4186- >>> print extract_text(
4187- ... find_tag_by_id(user_browser.contents, 'license-status'))
4188+ >>> print(extract_text(
4189+ ... find_tag_by_id(user_browser.contents, 'license-status')))
4190 This projectā€™s licence has not been reviewed.
4191
4192 Changing the state to reviewed but not approved results in the project
4193@@ -129,11 +129,11 @@ direct the owner to purchase a subscription.
4194 >>> transaction.commit()
4195 >>> logout()
4196 >>> owner_browser.open('http://launchpad.test/firefox')
4197- >>> print find_tag_by_id(owner_browser.contents, 'license-status')
4198+ >>> print(find_tag_by_id(owner_browser.contents, 'license-status'))
4199 <...This projectā€™s licence is proprietary...
4200
4201- >>> print find_tag_by_id(owner_browser.contents,
4202- ... 'portlet-requires-subscription')
4203+ >>> print(find_tag_by_id(owner_browser.contents,
4204+ ... 'portlet-requires-subscription'))
4205 <div...Purchasing a commercial subscription is required...</div>
4206
4207 Any user can see that the project's licence is proprietary.
4208@@ -141,8 +141,8 @@ Any user can see that the project's licence is proprietary.
4209 >>> user_browser.open('http://launchpad.test/firefox')
4210 >>> user_browser.contents
4211 '<...This project&rsquo;s licence is proprietary...
4212- >>> print extract_text(
4213- ... find_tag_by_id(user_browser.contents, 'licences'))
4214+ >>> print(extract_text(
4215+ ... find_tag_by_id(user_browser.contents, 'licences')))
4216 Licence:
4217 Other/Proprietary (Internal project.)
4218 Commercial subscription expires ...
4219@@ -150,8 +150,8 @@ Any user can see that the project's licence is proprietary.
4220
4221 A non-owner does not see that a commercial subscription is due.
4222
4223- >>> print find_tag_by_id(user_browser.contents,
4224- ... 'portlet-requires-subscription')
4225+ >>> print(find_tag_by_id(user_browser.contents,
4226+ ... 'portlet-requires-subscription'))
4227 None
4228
4229 If the project qualifies for free hosting, tghe portlet is not displayed.
4230@@ -160,8 +160,8 @@ If the project qualifies for free hosting, tghe portlet is not displayed.
4231 >>> flush_database_updates()
4232 >>> transaction.commit()
4233 >>> owner_browser.open('http://launchpad.test/firefox')
4234- >>> print find_tag_by_id(owner_browser.contents,
4235- ... 'portlet-requires-subscription')
4236+ >>> print(find_tag_by_id(owner_browser.contents,
4237+ ... 'portlet-requires-subscription'))
4238 None
4239
4240 If the project's licence is open source, the licence status is not
4241@@ -169,10 +169,10 @@ displayed on the index page, since most projects fall into this
4242 category.
4243
4244 >>> user_browser.open('http://launchpad.test/firefox')
4245- >>> print find_tag_by_id(owner_browser.contents, 'license-status')
4246+ >>> print(find_tag_by_id(owner_browser.contents, 'license-status'))
4247 None
4248- >>> print extract_text(
4249- ... find_tag_by_id(user_browser.contents, 'licences'))
4250+ >>> print(extract_text(
4251+ ... find_tag_by_id(user_browser.contents, 'licences')))
4252 Licence:
4253 GNU GPL v2
4254 Commercial subscription expires ...
4255@@ -200,8 +200,8 @@ Enable the subscription.
4256
4257 >>> owner_browser = setupBrowser(auth='Basic bac@canonical.com:test')
4258 >>> owner_browser.open('http://launchpad.test/mega-money-maker')
4259- >>> print extract_text(find_tag_by_id(owner_browser.contents,
4260- ... 'commercial_subscription'))
4261+ >>> print(extract_text(find_tag_by_id(owner_browser.contents,
4262+ ... 'commercial_subscription')))
4263 Commercial subscription expires ...
4264
4265 Commercial team members will see the expiration information.
4266@@ -209,15 +209,15 @@ Commercial team members will see the expiration information.
4267 >>> comm_browser = setupBrowser(
4268 ... auth='Basic commercial-member@canonical.com:test')
4269 >>> comm_browser.open('http://launchpad.test/mega-money-maker')
4270- >>> print extract_text(find_tag_by_id(comm_browser.contents,
4271- ... 'commercial_subscription'))
4272+ >>> print(extract_text(find_tag_by_id(comm_browser.contents,
4273+ ... 'commercial_subscription')))
4274 Commercial subscription expires ...
4275
4276 Launchpad administrators will see the expiration information.
4277
4278 >>> admin_browser.open('http://launchpad.test/mega-money-maker')
4279- >>> print extract_text(find_tag_by_id(admin_browser.contents,
4280- ... 'commercial_subscription'))
4281+ >>> print(extract_text(find_tag_by_id(admin_browser.contents,
4282+ ... 'commercial_subscription')))
4283 Commercial subscription expires ...
4284
4285
4286@@ -227,8 +227,8 @@ Development
4287 The project page shows the series that is the focus of development.
4288
4289 >>> anon_browser.open('http://launchpad.test/firefox')
4290- >>> print extract_text(
4291- ... find_tag_by_id(anon_browser.contents, 'development-focus'))
4292+ >>> print(extract_text(
4293+ ... find_tag_by_id(anon_browser.contents, 'development-focus')))
4294 trunk series is the current focus of development.
4295
4296 The page has a link to view the project's milestones.
4297@@ -252,7 +252,7 @@ home page.
4298
4299 >>> Product.byName("firefox").setAliases(['iceweasel', 'snowchicken'])
4300 >>> anon_browser.open('http://launchpad.test/firefox')
4301- >>> print extract_text(find_tag_by_id(anon_browser.contents, 'aliases'))
4302+ >>> print(extract_text(find_tag_by_id(anon_browser.contents, 'aliases')))
4303 Also known as: iceweasel, snowchicken
4304
4305
4306@@ -262,8 +262,8 @@ Ubuntu packaging
4307 If a product is packaged in Ubuntu the links are shown.
4308
4309 >>> user_browser.open('http://launchpad.test/firefox')
4310- >>> print extract_text(
4311- ... find_tag_by_id(user_browser.contents, 'portlet-packages'))
4312+ >>> print(extract_text(
4313+ ... find_tag_by_id(user_browser.contents, 'portlet-packages')))
4314 All packages
4315 Packages in Distributions
4316 mozilla-firefox source package in Warty Version 0.9 uploaded on...
4317diff --git a/lib/lp/registry/stories/product/xx-product-package-pages.txt b/lib/lp/registry/stories/product/xx-product-package-pages.txt
4318index 93e9bbf..54261e5 100644
4319--- a/lib/lp/registry/stories/product/xx-product-package-pages.txt
4320+++ b/lib/lp/registry/stories/product/xx-product-package-pages.txt
4321@@ -6,16 +6,16 @@ each.
4322
4323 >>> anon_browser.open(
4324 ... 'http://launchpad.test/evolution/+packages')
4325- >>> print anon_browser.title
4326+ >>> print(anon_browser.title)
4327 Linked packages ...
4328- >>> print extract_text(
4329- ... find_tag_by_id(anon_browser.contents, 'distribution-series'))
4330+ >>> print(extract_text(
4331+ ... find_tag_by_id(anon_browser.contents, 'distribution-series')))
4332 Distribution series Source package Version Project series
4333 Warty (4.10) evolution Evolution trunk series ...
4334
4335 >>> anon_browser.getLink(url='/ubuntu/warty/+source/evolution').click()
4336- >>> print extract_text(
4337- ... find_tag_by_id(anon_browser.contents, 'maincontent').h1)
4338+ >>> print(extract_text(
4339+ ... find_tag_by_id(anon_browser.contents, 'maincontent').h1))
4340 evolution source package in Warty
4341
4342 It can also show the packages by product series. And if you have permission
4343@@ -25,10 +25,10 @@ Evolution.
4344
4345 >>> evo_owner = setupBrowser(auth='Basic mark@example.com:test')
4346 >>> evo_owner.open('http://launchpad.test/evolution/+packages')
4347- >>> print evo_owner.title
4348+ >>> print(evo_owner.title)
4349 Linked packages ...
4350- >>> print extract_text(find_tag_by_id(
4351- ... evo_owner.contents, 'packages-trunk'))
4352+ >>> print(extract_text(find_tag_by_id(
4353+ ... evo_owner.contents, 'packages-trunk')))
4354 Distribution Distribution series Source package Version
4355 Ubuntu Warty (4.10) evolution Remove...
4356 Ubuntu Hoary (5.04) evolution 1.0 Remove...
4357@@ -39,7 +39,7 @@ Evolution.
4358 Any logged in users can still see the links to create a packaging link.
4359
4360 >>> user_browser.open('http://launchpad.test/evolution/+packages')
4361- >>> print user_browser.getLink(url='/evolution/trunk/+ubuntupkg').url
4362+ >>> print(user_browser.getLink(url='/evolution/trunk/+ubuntupkg').url)
4363 http://launchpad.test/evolution/trunk/+ubuntupkg
4364
4365 >>> anon_browser.open('http://launchpad.test/evolution/+packages')
4366@@ -56,16 +56,16 @@ Packaging links can be deleted if they were created in error.
4367
4368 >>> evo_owner.getLink(
4369 ... url='/ubuntu/warty/+source/evolution/+remove-packaging').click()
4370- >>> print evo_owner.title
4371+ >>> print(evo_owner.title)
4372 Unlink an upstream project...
4373 >>> evo_owner.getControl('Unlink').click()
4374- >>> print evo_owner.title
4375+ >>> print(evo_owner.title)
4376 Linked packages...
4377
4378 >>> print_feedback_messages(evo_owner.contents)
4379 Removed upstream association between Evolution trunk series and Warty.
4380
4381- >>> print extract_text(find_tag_by_id(
4382- ... evo_owner.contents, 'packages-trunk'))
4383+ >>> print(extract_text(find_tag_by_id(
4384+ ... evo_owner.contents, 'packages-trunk')))
4385 Distribution Distribution series Source package Version
4386 Ubuntu Hoary (5.04) evolution 1.0 Remove...
4387diff --git a/lib/lp/registry/stories/product/xx-product-rdf.txt b/lib/lp/registry/stories/product/xx-product-rdf.txt
4388index 711ceeb..32219d1 100644
4389--- a/lib/lp/registry/stories/product/xx-product-rdf.txt
4390+++ b/lib/lp/registry/stories/product/xx-product-rdf.txt
4391@@ -3,7 +3,7 @@ We export DOAP RDF metadata for products from a link in the
4392
4393 >>> anon_browser.open("http://launchpad.test/firefox")
4394 >>> anon_browser.getLink("RDF metadata").click()
4395- >>> print anon_browser.contents
4396+ >>> print(anon_browser.contents)
4397 <?xml version="1.0" encoding="utf-8"...?>
4398 <rdf:RDF ...xmlns:lp="https://launchpad.net/rdf/launchpad#"...>
4399 <lp:Product>
4400@@ -26,5 +26,5 @@ And it's valid XML and RDF:
4401
4402 >>> from xml.dom.minidom import parseString
4403 >>> document = parseString(str(anon_browser.contents))
4404- >>> print document.documentElement.nodeName
4405+ >>> print(document.documentElement.nodeName)
4406 rdf:RDF
4407diff --git a/lib/lp/registry/stories/product/xx-product-reassignment-and-milestones.txt b/lib/lp/registry/stories/product/xx-product-reassignment-and-milestones.txt
4408index c04c1dd..abb9ff1 100644
4409--- a/lib/lp/registry/stories/product/xx-product-reassignment-and-milestones.txt
4410+++ b/lib/lp/registry/stories/product/xx-product-reassignment-and-milestones.txt
4411@@ -9,7 +9,7 @@ even if the user was trying to set the milestone value.
4412 >>> browser.getControl("Save Changes").click()
4413
4414 >>> for message in find_tags_by_class(browser.contents, 'message'):
4415- ... print message.renderContents()
4416+ ... print(message.renderContents())
4417 The milestone setting was ignored because you reassigned the bug
4418 to...Evolution...
4419
4420@@ -37,6 +37,6 @@ milestone value, if one was set.
4421 >>> browser.getControl("Save Changes").click()
4422
4423 >>> for message in find_tags_by_class(browser.contents, 'message'):
4424- ... print message.renderContents()
4425+ ... print(message.renderContents())
4426 The Mozilla Firefox 1.0 milestone setting has been removed
4427 because you reassigned the bug to Evolution.
4428diff --git a/lib/lp/registry/stories/product/xx-productset.txt b/lib/lp/registry/stories/product/xx-productset.txt
4429index 8d24a47..c13ab3a 100644
4430--- a/lib/lp/registry/stories/product/xx-productset.txt
4431+++ b/lib/lp/registry/stories/product/xx-productset.txt
4432@@ -33,7 +33,7 @@ A member of the Launchpad registry experts team may successfully access the
4433 >>> registry_browser.getLink("Review projects").click()
4434 >>> registry_browser.url
4435 'http://launchpad.test/projects/+review-licenses'
4436- >>> print registry_browser.title
4437+ >>> print(registry_browser.title)
4438 Review projects...
4439
4440
4441@@ -43,13 +43,13 @@ View all projects
4442 The unprivileged user can see "+all".
4443
4444 >>> user_browser.open('http://launchpad.test/projects/+all')
4445- >>> print user_browser.title
4446+ >>> print(user_browser.title)
4447 Projects registered in Launchpad...
4448
4449 The commercial user can also view "+all".
4450
4451 >>> registry_browser.open('http://launchpad.test/projects/+all')
4452- >>> print registry_browser.title
4453+ >>> print(registry_browser.title)
4454 Projects registered in Launchpad...
4455
4456
4457@@ -59,17 +59,17 @@ Create a project
4458 The unprivileged user can see "+new".
4459
4460 >>> user_browser.open('http://launchpad.test/projects/+new')
4461- >>> print user_browser.title
4462+ >>> print(user_browser.title)
4463 Register a project in Launchpad...
4464
4465 The commercial user can also view "+new".
4466
4467 >>> registry_browser.open('http://launchpad.test/projects/+new')
4468- >>> print registry_browser.title
4469+ >>> print(registry_browser.title)
4470 Register a project in Launchpad...
4471
4472 The commercial user can also view "+new".
4473
4474 >>> registry_browser.open('http://launchpad.test/projects/+new')
4475- >>> print registry_browser.title
4476+ >>> print(registry_browser.title)
4477 Register a project in Launchpad...
4478diff --git a/lib/lp/registry/stories/productrelease/xx-productrelease-basics.txt b/lib/lp/registry/stories/productrelease/xx-productrelease-basics.txt
4479index 082bdb6..e33c07c 100644
4480--- a/lib/lp/registry/stories/productrelease/xx-productrelease-basics.txt
4481+++ b/lib/lp/registry/stories/productrelease/xx-productrelease-basics.txt
4482@@ -22,22 +22,22 @@ release in the series.
4483 >>> browser = setupBrowser(auth='Basic test@canonical.com:test')
4484 >>> browser.open('http://launchpad.test/firefox/+milestone/1.0')
4485 >>> browser.getLink('Create release').click()
4486- >>> print browser.url
4487+ >>> print(browser.url)
4488 http://launchpad.test/firefox/+milestone/1.0/+addrelease
4489
4490- >>> print browser.title
4491+ >>> print(browser.title)
4492 Create a new release for Mozilla Firefox...
4493
4494 Links to previous releases from the series are listed.
4495
4496 >>> other_releases = find_tag_by_id(browser.contents, 'other-releases')
4497- >>> print extract_text(other_releases)
4498+ >>> print(extract_text(other_releases))
4499 The following releases have been made for the trunk series:
4500 2004-10-16 Mozilla Firefox 0.9.2 (One (secure) Tree Hill)
4501 2004-10-16 Mozilla Firefox 0.9.1 (One Tree Hill (v2))
4502 2004-10-16 Mozilla Firefox 0.9 (One Tree Hill)
4503
4504- >>> print browser.getLink('0.9.1').url
4505+ >>> print(browser.getLink('0.9.1').url)
4506 http://launchpad.test/firefox/trunk/0.9.1
4507
4508 Sample Person completes the release.
4509@@ -54,9 +54,9 @@ After creating the release, Sample Person sees the release page.
4510
4511 The release's information is displayed in the page.
4512
4513- >>> print extract_text(find_tag_by_id(browser.contents, 'release-notes'))
4514+ >>> print(extract_text(find_tag_by_id(browser.contents, 'release-notes')))
4515 Released 1.0
4516- >>> print extract_text(find_tag_by_id(browser.contents, 'changelog'))
4517+ >>> print(extract_text(find_tag_by_id(browser.contents, 'changelog')))
4518 Fix Foo
4519
4520 Only one release can be created for each milestone.
4521@@ -106,12 +106,12 @@ The release owner can edit the release via its +edit form:
4522
4523 >>> browser.open('http://launchpad.test/firefox/trunk/1.0')
4524 >>> browser.getLink('Change release details', index=1).click()
4525- >>> print browser.title
4526+ >>> print(browser.title)
4527 Edit Mozilla Firefox 1.0 release details...
4528
4529 >>> browser.getControl('Changelog').value = 'This is not a joke.'
4530 >>> browser.getControl('Change').click()
4531- >>> print browser.title
4532+ >>> print(browser.title)
4533 1.0 : Series trunk : Mozilla Firefox
4534
4535
4536@@ -123,7 +123,7 @@ release too.
4537 >>> from lp.registry.model.person import Person
4538 >>> from lp.registry.model.product import Product
4539 >>> tomcat = Product.selectOneBy(name='tomcat')
4540- >>> print tomcat.owner.name
4541+ >>> print(tomcat.owner.name)
4542 ubuntu-team
4543
4544 Let's add a release as Jeff:
4545@@ -137,7 +137,7 @@ Let's add a release as Jeff:
4546 >>> browser.getControl('Date released').value = '2008-12-01'
4547 >>> browser.getControl('Changelog').value = 'Fix Foo'
4548 >>> browser.getControl('Create release').click()
4549- >>> print browser.url
4550+ >>> print(browser.url)
4551 http://launchpad.test/tomcat/+milestone/0.6.6.6
4552
4553 Celso is a member of ubuntu-team, so he can edit this release too:
4554@@ -145,12 +145,12 @@ Celso is a member of ubuntu-team, so he can edit this release too:
4555 >>> browser = setupBrowser(auth='Basic celso.providelo@canonical.com:test')
4556 >>> browser.open('http://launchpad.test/tomcat/trunk/0.6.6.6')
4557 >>> browser.getLink('Change release details', index=0).click()
4558- >>> print browser.title
4559+ >>> print(browser.title)
4560 Edit Tomcat 0.6.6.6 release details...
4561
4562 >>> browser.getControl('Changelog').value = 'Fixes 3 bugs.'
4563 >>> browser.getControl('Change').click()
4564- >>> print browser.title
4565+ >>> print(browser.title)
4566 0.6.6.6 : Series trunk : Tomcat
4567
4568 And if no-priv drives the series...
4569@@ -164,10 +164,10 @@ others:
4570 >>> browser = setupBrowser(auth='Basic no-priv@canonical.com:test')
4571 >>> browser.open('http://launchpad.test/tomcat/trunk/0.6.6.6')
4572 >>> browser.getLink('Change release details', index=0).click()
4573- >>> print browser.title
4574+ >>> print(browser.title)
4575 Edit Tomcat 0.6.6.6 release details...
4576
4577 >>> browser.getControl('Changelog').value = 'Fixes 4 bugs.'
4578 >>> browser.getControl('Change').click()
4579- >>> print browser.title
4580+ >>> print(browser.title)
4581 0.6.6.6 : Series trunk : Tomcat
4582diff --git a/lib/lp/registry/stories/productrelease/xx-productrelease-delete.txt b/lib/lp/registry/stories/productrelease/xx-productrelease-delete.txt
4583index 08aa581..31563f9 100644
4584--- a/lib/lp/registry/stories/productrelease/xx-productrelease-delete.txt
4585+++ b/lib/lp/registry/stories/productrelease/xx-productrelease-delete.txt
4586@@ -4,11 +4,11 @@ The main page of a product series includes a list of releases of that series.
4587 The 0.9.2 milestone has a release.
4588
4589 >>> user_browser.open('http://launchpad.test/firefox/trunk')
4590- >>> print user_browser.title
4591+ >>> print(user_browser.title)
4592 Series trunk : Mozilla Firefox
4593
4594- >>> print extract_text(find_tag_by_id(
4595- ... user_browser.contents, 'series-trunk'))
4596+ >>> print(extract_text(find_tag_by_id(
4597+ ... user_browser.contents, 'series-trunk')))
4598 Version Expected Released Summary
4599 Mozilla Firefox 0.9.2 ... None 2004-10-15 ...
4600
4601@@ -17,7 +17,7 @@ access the delete page. A user without the necessary rights won't see the
4602 link and cannot access the +delete page.
4603
4604 >>> user_browser.getLink('0.9.2').click()
4605- >>> print user_browser.title
4606+ >>> print(user_browser.title)
4607 0.9.2 "One (secure) Tree Hill" : Mozilla Firefox
4608
4609 >>> user_browser.getLink(url='/firefox/trunk/0.9.2/+delete')
4610@@ -34,14 +34,14 @@ Salgado has the necessary rights, so he sees the link and the +delete page.
4611 >>> salgados_browser = setupBrowser(auth='Basic salgado@ubuntu.com:test')
4612 >>> salgados_browser.open('http://launchpad.test/firefox/trunk/0.9.2')
4613 >>> salgados_browser.getLink('Delete release').click()
4614- >>> print salgados_browser.title
4615+ >>> print(salgados_browser.title)
4616 Delete Mozilla Firefox 0.9.2...
4617
4618 The 0.9.2 release has some files associated with it. Salgado reads that
4619 they will be deleted too.
4620
4621 >>> text = extract_text(find_main_content(salgados_browser.contents))
4622- >>> print text.encode('ASCII', 'backslashreplace')
4623+ >>> print(text.encode('ASCII', 'backslashreplace'))
4624 Delete Mozilla Firefox 0.9.2 \u201cOne (secure) Tree Hill\u201d
4625 ...
4626 Are you sure you want to delete the 0.9.2 release of
4627@@ -52,7 +52,7 @@ they will be deleted too.
4628 Salgado chooses the delete button, then reads that the action is successful.
4629
4630 >>> salgados_browser.getControl('Delete Release').click()
4631- >>> print salgados_browser.title
4632+ >>> print(salgados_browser.title)
4633 Series trunk : Mozilla Firefox
4634
4635 >>> print_feedback_messages(salgados_browser.contents)
4636@@ -61,7 +61,7 @@ Salgado chooses the delete button, then reads that the action is successful.
4637 Milestone 0.9.2 no longer has a release. The release column explains that
4638 the milestone is inactive.
4639
4640- >>> print extract_text(
4641- ... find_tag_by_id(salgados_browser.contents, 'series-trunk'))
4642+ >>> print(extract_text(
4643+ ... find_tag_by_id(salgados_browser.contents, 'series-trunk')))
4644 Version Expected Released Summary
4645 Mozilla Firefox 0.9.2... Set date Change details This is an inactive ...
4646diff --git a/lib/lp/registry/stories/productrelease/xx-productrelease-rdf.txt b/lib/lp/registry/stories/productrelease/xx-productrelease-rdf.txt
4647index 5eb96c5..a620ac3 100644
4648--- a/lib/lp/registry/stories/productrelease/xx-productrelease-rdf.txt
4649+++ b/lib/lp/registry/stories/productrelease/xx-productrelease-rdf.txt
4650@@ -1,8 +1,8 @@
4651 Check that the productrelease RDF export works.
4652
4653- >>> print http(r"""
4654+ >>> print(http(r"""
4655 ... GET /firefox/trunk/0.9/+rdf HTTP/1.1
4656- ... """)
4657+ ... """))
4658 HTTP/1.1 200 Ok
4659 Content-Disposition: attachment; filename="firefox-trunk-0.9.rdf"
4660 Content-Length: ...
4661diff --git a/lib/lp/registry/stories/productrelease/xx-productrelease-view.txt b/lib/lp/registry/stories/productrelease/xx-productrelease-view.txt
4662index 8c41ffd..05f00e4 100644
4663--- a/lib/lp/registry/stories/productrelease/xx-productrelease-view.txt
4664+++ b/lib/lp/registry/stories/productrelease/xx-productrelease-view.txt
4665@@ -1,11 +1,11 @@
4666 Any user can see a release for a series.
4667
4668 >>> anon_browser.open('http://launchpad.test/firefox/trunk/0.9.2')
4669- >>> print anon_browser.title
4670+ >>> print(anon_browser.title)
4671 0.9.2 "One (secure) Tree Hill" : Series trunk : Mozilla Firefox
4672
4673 >>> content = find_main_content(anon_browser.contents)
4674- >>> print extract_text(find_tag_by_id(content, 'Release-details'))
4675+ >>> print(extract_text(find_tag_by_id(content, 'Release-details')))
4676 Milestone information
4677 Project: Mozilla Firefox
4678 Series: trunk
4679@@ -21,11 +21,11 @@ Any user can see a table describing the files that are associated with the
4680 release. Each file is linked.
4681
4682 >>> table = find_tag_by_id(content, 'downloads')
4683- >>> print extract_text(table)
4684+ >>> print(extract_text(table))
4685 File Description Downloads
4686 firefox_0.9.2.orig.tar.gz (md5) -
4687
4688- >>> print table.a
4689+ >>> print(table.a)
4690 <a href=".../firefox/trunk/0.9.2/+download/firefox_0.9.2.orig.tar.gz"
4691 title="firefox_0.9.2.orig.tar.gz (9.5 MiB)">...
4692
4693@@ -46,7 +46,7 @@ downloaded and the date of the last download on that table as well.
4694 >>> lfa.updateDownloadCount(date(2006, 5, 4), None, 1)
4695
4696 >>> anon_browser.reload()
4697- >>> print extract_text(find_tag_by_id(anon_browser.contents, 'downloads'))
4698+ >>> print(extract_text(find_tag_by_id(anon_browser.contents, 'downloads')))
4699 File Description Downloads
4700 firefox_0.9.2.orig.tar.gz (md5) 1 last downloaded ...
4701 Total downloads: 1
4702@@ -58,7 +58,7 @@ downloaded, so we can't say it was downloaded a few minutes/hours ago.
4703 >>> import pytz
4704 >>> lfa.updateDownloadCount(datetime.now(pytz.utc).date(), None, 4356)
4705 >>> anon_browser.reload()
4706- >>> print extract_text(find_tag_by_id(anon_browser.contents, 'downloads'))
4707+ >>> print(extract_text(find_tag_by_id(anon_browser.contents, 'downloads')))
4708 File Description Downloads
4709 firefox_0.9.2.orig.tar.gz (md5) 4,357 last downloaded today
4710 Total downloads: 4,357
4711diff --git a/lib/lp/registry/stories/productseries/xx-productseries-add-and-edit.txt b/lib/lp/registry/stories/productseries/xx-productseries-add-and-edit.txt
4712index c5c938f..64c43bc 100644
4713--- a/lib/lp/registry/stories/productseries/xx-productseries-add-and-edit.txt
4714+++ b/lib/lp/registry/stories/productseries/xx-productseries-add-and-edit.txt
4715@@ -23,10 +23,10 @@ But Sample Person will and be able to add a series.
4716 >>> browser.addHeader('Authorization', 'Basic test@canonical.com:test')
4717 >>> browser.open('http://launchpad.test/firefox')
4718 >>> browser.getLink('Register a series').click()
4719- >>> print browser.url
4720+ >>> print(browser.url)
4721 http://launchpad.test/firefox/+addseries
4722
4723- >>> print find_main_content(browser.contents).find('h1').renderContents()
4724+ >>> print(find_main_content(browser.contents).find('h1').renderContents())
4725 Register a new Mozilla Firefox release series
4726
4727 After checking that the page +addseries is there, we try to add a new series.
4728@@ -43,7 +43,7 @@ Now we are redirected to the Overview page of the product series we just added
4729 >>> browser.url
4730 'http://launchpad.test/firefox/stable'
4731
4732- >>> print extract_text(find_tag_by_id(browser.contents, 'description'))
4733+ >>> print(extract_text(find_tag_by_id(browser.contents, 'description')))
4734 Product series add testing
4735
4736 >>> browser.getLink('lp://dev/~mark/firefox/release-0.9.2')
4737@@ -76,7 +76,7 @@ name already in use and an invalud release URL pattern:
4738 We'll get a nice error message for the three problems:
4739
4740 >>> for tag in find_tags_by_class(browser.contents, 'message'):
4741- ... print extract_text(tag)
4742+ ... print(extract_text(tag))
4743 There are 2 errors.
4744 1.0 is already in use by another series.
4745 Invalid release URL pattern.
4746@@ -97,7 +97,7 @@ of firefox:
4747 The new values are then shown in the series' page.
4748
4749 >>> content = find_tag_by_id(browser.contents, 'series-details')
4750- >>> print extract_text(find_tag_by_id(content, 'series-name'))
4751+ >>> print(extract_text(find_tag_by_id(content, 'series-name')))
4752 Series: unstable
4753
4754 And if we try to add another series with the same name to same product, we
4755@@ -110,7 +110,7 @@ should get a nice error message.
4756 >>> browser.getControl('Register Series').click()
4757
4758 >>> for message in find_tags_by_class(browser.contents, 'message'):
4759- ... print message.renderContents()
4760+ ... print(message.renderContents())
4761 There is 1 error.
4762 unstable is already in use by another series.
4763
4764@@ -123,7 +123,7 @@ we can create structural bug subscriptions.
4765
4766 >>> browser.open('http://launchpad.test/firefox/unstable')
4767 >>> browser.getLink('Subscribe to bug mail').click()
4768- >>> print browser.url
4769+ >>> print(browser.url)
4770 http://launchpad.test/firefox/unstable/+subscribe
4771- >>> print browser.title
4772+ >>> print(browser.title)
4773 Subscribe : Series unstable : Bugs : Mozilla Firefox
4774diff --git a/lib/lp/registry/stories/productseries/xx-productseries-delete.txt b/lib/lp/registry/stories/productseries/xx-productseries-delete.txt
4775index b551c96..b1c867d 100644
4776--- a/lib/lp/registry/stories/productseries/xx-productseries-delete.txt
4777+++ b/lib/lp/registry/stories/productseries/xx-productseries-delete.txt
4778@@ -8,19 +8,19 @@ is really happening in the 1.0 series.
4779
4780 >>> owner_browser = setupBrowser(auth='Basic test@canonical.com:test')
4781 >>> owner_browser.open('http://launchpad.test/firefox/trunk')
4782- >>> print owner_browser.title
4783+ >>> print(owner_browser.title)
4784 Series trunk : Mozilla Firefox
4785
4786 >>> owner_browser.getLink('Delete series').click()
4787- >>> print owner_browser.title
4788+ >>> print(owner_browser.title)
4789 Delete Mozilla Firefox trunk series...
4790
4791 The trunk series is the focus of development. It cannot be deleted.
4792 The owner learns that they must make another series the focus of development
4793 first. There is no delete button on the page.
4794
4795- >>> print extract_text(
4796- ... find_tag_by_id(owner_browser.contents, 'cannot-delete'))
4797+ >>> print(extract_text(
4798+ ... find_tag_by_id(owner_browser.contents, 'cannot-delete')))
4799 You cannot delete a series that is the focus of development. Make
4800 another series the focus of development before deleting this one.
4801 You cannot delete a series that is linked to packages in distributions.
4802@@ -37,12 +37,12 @@ bogus.
4803
4804 >>> owner_browser.getLink('Cancel').click()
4805 >>> owner_browser.open('http://launchpad.test/firefox/+edit')
4806- >>> print owner_browser.title
4807+ >>> print(owner_browser.title)
4808 Change Mozilla Firefox's details...
4809
4810 >>> owner_browser.getControl('Development focus').value = ['2']
4811 >>> owner_browser.getControl('Change').click()
4812- >>> print owner_browser.title
4813+ >>> print(owner_browser.title)
4814 Mozilla Firefox in Launchpad
4815
4816 >>> owner_browser.getLink('All packages').click()
4817@@ -57,35 +57,35 @@ deleted. The milestones and releases are linked.
4818
4819 >>> owner_browser.getLink('trunk series').click()
4820 >>> owner_browser.getLink('Delete series').click()
4821- >>> print owner_browser.title
4822+ >>> print(owner_browser.title)
4823 Delete Mozilla Firefox trunk series...
4824
4825 >>> contents = find_main_content(owner_browser.contents)
4826- >>> print extract_text(find_tag_by_id(contents, 'milestones-and-files'))
4827+ >>> print(extract_text(find_tag_by_id(contents, 'milestones-and-files')))
4828 The associated milestones and releases
4829 and their files will be also be deleted:
4830
4831- >>> print extract_text(find_tag_by_id(contents, 'milestones'))
4832+ >>> print(extract_text(find_tag_by_id(contents, 'milestones')))
4833 0.9.2 "One (secure) Tree Hill"
4834 0.9.1 "One Tree Hill (v2)"
4835 0.9 "One Tree Hill"
4836 1.0
4837
4838- >>> print owner_browser.getLink('0.9.2 "One (secure) Tree Hill"')
4839+ >>> print(owner_browser.getLink('0.9.2 "One (secure) Tree Hill"'))
4840 <Link text='0.9.2 "One (secure) Tree Hill"' ...>
4841
4842- >>> print extract_text(find_tag_by_id(contents, 'files'))
4843+ >>> print(extract_text(find_tag_by_id(contents, 'files')))
4844 firefox_0.9.2.orig.tar.gz
4845
4846- >>> print extract_text(
4847- ... find_tag_by_id(contents, 'bugtasks-and-blueprints'))
4848+ >>> print(extract_text(
4849+ ... find_tag_by_id(contents, 'bugtasks-and-blueprints')))
4850 Support E4X in EcmaScript
4851
4852 The owner deletes the series and the project page is displayed. They read
4853 that the series was deleted, and can not see a link to it anymore.
4854
4855 >>> owner_browser.getControl('Delete this Series').click()
4856- >>> print owner_browser.title
4857+ >>> print(owner_browser.title)
4858 Mozilla Firefox in Launchpad
4859
4860 >>> print_feedback_messages(owner_browser.contents)
4861@@ -101,10 +101,10 @@ release manager sees the explanation when they try to delete the series.
4862
4863 >>> owner_browser.open('http://launchpad.test/evolution/trunk')
4864 >>> owner_browser.getLink('Delete series').click()
4865- >>> print owner_browser.title
4866+ >>> print(owner_browser.title)
4867 Delete Evolution trunk series ...
4868
4869- >>> print extract_text(
4870- ... find_tag_by_id(owner_browser.contents, 'cannot-delete'))
4871+ >>> print(extract_text(
4872+ ... find_tag_by_id(owner_browser.contents, 'cannot-delete')))
4873 You ...
4874 This series cannot be deleted because it has translations.
4875diff --git a/lib/lp/registry/stories/productseries/xx-productseries-driver.txt b/lib/lp/registry/stories/productseries/xx-productseries-driver.txt
4876index bb36017..6910665 100644
4877--- a/lib/lp/registry/stories/productseries/xx-productseries-driver.txt
4878+++ b/lib/lp/registry/stories/productseries/xx-productseries-driver.txt
4879@@ -8,16 +8,16 @@ by appointing someone else as the driver.
4880 >>> browser.addHeader('Authorization', 'Basic test@canonical.com:test')
4881 >>> browser.open('http://launchpad.test/firefox/1.0')
4882 >>> content = find_tag_by_id(browser.contents, 'series-details')
4883- >>> print extract_text(find_tag_by_id(content, 'series-drivers'))
4884+ >>> print(extract_text(find_tag_by_id(content, 'series-drivers')))
4885 Project drivers: Sample Person
4886- >>> print extract_text(find_tag_by_id(content, 'series-release-manager'))
4887+ >>> print(extract_text(find_tag_by_id(content, 'series-release-manager')))
4888 Release manager: None Appoint release manager
4889
4890 >>> browser.getLink('Appoint release manager').click()
4891
4892 >>> browser.url
4893 'http://launchpad.test/firefox/1.0/+driver'
4894- >>> print browser.title
4895+ >>> print(browser.title)
4896 Appoint the release manager for...
4897 >>> browser.getControl('Release manager').value
4898 ''
4899@@ -38,8 +38,8 @@ message explains that the driver changed.
4900 Sample Person and Guilherme Salgado are listed as the drivers of Firefox 1.0.
4901
4902 >>> content = find_tag_by_id(browser.contents, 'series-details')
4903- >>> print extract_text(find_tag_by_id(content, 'series-drivers'))
4904+ >>> print(extract_text(find_tag_by_id(content, 'series-drivers')))
4905 Project drivers: Guilherme Salgado, Sample Person
4906- >>> print extract_text(find_tag_by_id(content, 'series-release-manager'))
4907+ >>> print(extract_text(find_tag_by_id(content, 'series-release-manager')))
4908 Release manager: Guilherme Salgado Appoint release manager
4909
4910diff --git a/lib/lp/registry/stories/productseries/xx-productseries-index.txt b/lib/lp/registry/stories/productseries/xx-productseries-index.txt
4911index bbd88b8..7a4470c 100644
4912--- a/lib/lp/registry/stories/productseries/xx-productseries-index.txt
4913+++ b/lib/lp/registry/stories/productseries/xx-productseries-index.txt
4914@@ -4,14 +4,14 @@ Product Series Overview
4915 The product series overview page summarises the series.
4916
4917 >>> anon_browser.open('http://launchpad.test/firefox/trunk')
4918- >>> print extract_text(anon_browser.title)
4919+ >>> print(extract_text(anon_browser.title))
4920 Series trunk : Mozilla Firefox
4921
4922 >>> content = find_main_content(anon_browser.contents)
4923- >>> print extract_text(content.h1)
4924+ >>> print(extract_text(content.h1))
4925 Mozilla Firefox trunk series
4926
4927- >>> print extract_text(find_tag_by_id(content, 'series-details'))
4928+ >>> print(extract_text(find_tag_by_id(content, 'series-details')))
4929 Series information
4930 Project: Mozilla Firefox
4931 Series: trunk
4932@@ -22,7 +22,7 @@ The product series overview page summarises the series.
4933 Release URL pattern: None
4934 Download RDF metadata
4935
4936- >>> print extract_text(find_tag_by_id(content, 'description'))
4937+ >>> print(extract_text(find_tag_by_id(content, 'description')))
4938 The "trunk" series represents the primary line of
4939 development rather than a stable release branch. This is sometimes
4940 also called MAIN or HEAD.
4941@@ -52,7 +52,7 @@ The series page lists the milestones and releases for the series.
4942
4943 >>> rows = find_tag_by_id(content, 'series-trunk').findAll('tr')
4944 >>> for row in rows[0:2]:
4945- ... print extract_text(row)
4946+ ... print(extract_text(row))
4947 Version Expected Released Summary
4948 Mozilla Firefox 0.9.2 "One ... None 2004-10-15 This was a ...
4949
4950@@ -62,7 +62,7 @@ The driver can see a link to set the expected date.
4951 >>> driver_rows = find_tag_by_id(
4952 ... driver_content, 'series-trunk').findAll('tr')
4953 >>> for row in driver_rows[0:2]:
4954- ... print extract_text(row)
4955+ ... print(extract_text(row))
4956 Version Expected Released Summary
4957 Mozilla Firefox 0.9.2 "One ... Set date Chang... 2004-10-16 ...
4958
4959@@ -72,13 +72,13 @@ The driver can see a link to set the expected date.
4960 The milestone summary column in the table may also contain a summary of
4961 the status of the bugs and blueprints.
4962
4963- >>> print extract_text(rows[-1])
4964+ >>> print(extract_text(rows[-1]))
4965 Mozilla Firefox 1.0 2056-10-16 not yet released
4966 Blueprints targeted: 1 Unknown
4967
4968 The driver can see a link to create a release for the milestone.
4969
4970- >>> print extract_text(driver_rows[-1])
4971+ >>> print(extract_text(driver_rows[-1]))
4972 Mozilla Firefox 1.0 2056-10-16 Release now Blueprints targeted: ...
4973
4974 >>> driver_browser.getLink('Release now')
4975@@ -96,13 +96,13 @@ The user can learn where the code of the series is located if a branch
4976 is set. Otherwise, there is a message explaining that the information has
4977 not been set.
4978
4979- >>> print extract_text(find_tag_by_id(content, 'branch-details'))
4980+ >>> print(extract_text(find_tag_by_id(content, 'branch-details')))
4981 No revision control details recorded for Mozilla Firefox trunk series.
4982
4983 The driver sees that they can link a branch to this series, and there is
4984 an explanation where they can push the branch.
4985
4986- >>> print extract_text(find_tag_by_id(driver_content, 'branch-details'))
4987+ >>> print(extract_text(find_tag_by_id(driver_content, 'branch-details')))
4988 You haven't yet told Launchpad where your source code is ...
4989 bzr push lp:~name12/firefox/trunk ...
4990
4991@@ -112,11 +112,11 @@ an explanation where they can push the branch.
4992 Distribution packaging is listed too. There is a link to the source package
4993 in each Ubuntu series.
4994
4995- >>> print extract_text(find_tag_by_id(
4996- ... content, 'distribution-packaging-explanation'))
4997+ >>> print(extract_text(find_tag_by_id(
4998+ ... content, 'distribution-packaging-explanation')))
4999 This series is packaged in the following distribution series:
5000
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to status/vote changes: