Merge ~cjwatson/launchpadlib:py3-doctests into launchpadlib:main
- Git
- lp:~cjwatson/launchpadlib
- py3-doctests
- Merge into main
Proposed by
Colin Watson
Status: | Merged |
---|---|
Merged at revision: | a9134e386c3957b5ffc27eb1d499e8c5e9a74c72 |
Proposed branch: | ~cjwatson/launchpadlib:py3-doctests |
Merge into: | launchpadlib:main |
Diff against target: |
650 lines (+113/-111) 6 files modified
NEWS.rst (+1/-0) src/launchpadlib/docs/command-line.rst (+2/-2) src/launchpadlib/docs/hosted-files.rst (+10/-10) src/launchpadlib/docs/introduction.rst (+36/-35) src/launchpadlib/docs/people.rst (+45/-45) src/launchpadlib/docs/toplevel.rst (+19/-19) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andrey Fedoseev (community) | Approve | ||
Jürgen Gmach | Approve | ||
Review via email: mp+425086@code.launchpad.net |
Commit message
Fix doctests for Python 3
Description of the change
The doctests are currently only run via Launchpad's test suite, and we'd accidentally not been running them since renaming from `.txt` to `.rst` in 1.10.8.
To post a comment you must log in.
Revision history for this message
Andrey Fedoseev (andrey-fedoseev) wrote : | # |
LGTM
> we'd accidentally not been running them since renaming from `.txt` to `.rst` in 1.10.8.
Shall we be running them from now on?
review:
Approve
Revision history for this message
Colin Watson (cjwatson) wrote : | # |
Indeed, at the moment we can only run these tests by using Launchpad itself as a test fixture.
We'll be running them again once we upgrade Launchpad to this version of launchpadlib. I'll get on that!
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/NEWS.rst b/NEWS.rst |
2 | index ac72636..d1ab45a 100644 |
3 | --- a/NEWS.rst |
4 | +++ b/NEWS.rst |
5 | @@ -6,6 +6,7 @@ NEWS for launchpadlib |
6 | ==================== |
7 | - Generate coverage report. |
8 | - Use ``pytest`` as test runner. |
9 | +- Fix doctests for Python 3. |
10 | |
11 | 1.10.16 (2022-01-21) |
12 | ==================== |
13 | diff --git a/src/launchpadlib/docs/command-line.rst b/src/launchpadlib/docs/command-line.rst |
14 | index 8fd0ef8..4f8d6e9 100644 |
15 | --- a/src/launchpadlib/docs/command-line.rst |
16 | +++ b/src/launchpadlib/docs/command-line.rst |
17 | @@ -33,8 +33,8 @@ token and the available access levels. |
18 | oauth_token_consumer |
19 | oauth_token_secret |
20 | |
21 | - >>> print token_json['lp.context'] |
22 | + >>> print(token_json['lp.context']) |
23 | context |
24 | |
25 | - >>> print token_json['oauth_token_consumer'] |
26 | + >>> print(token_json['oauth_token_consumer']) |
27 | consumer |
28 | diff --git a/src/launchpadlib/docs/hosted-files.rst b/src/launchpadlib/docs/hosted-files.rst |
29 | index 98d8125..1ba1beb 100644 |
30 | --- a/src/launchpadlib/docs/hosted-files.rst |
31 | +++ b/src/launchpadlib/docs/hosted-files.rst |
32 | @@ -16,11 +16,11 @@ you try to upload a non-image for a field that expects an image. |
33 | 'image/png' |
34 | >>> file_handle.filename |
35 | 'nonimage.txt' |
36 | - >>> file_handle.write("Not an image.") |
37 | + >>> file_handle.write(b"Not an image.") |
38 | >>> try: |
39 | ... file_handle.close() |
40 | - ... except HTTPError, e: |
41 | - ... print e.content |
42 | + ... except HTTPError as e: |
43 | + ... print(e.content.decode()) |
44 | <BLANKLINE> |
45 | The file uploaded was not recognized as an image; please |
46 | check it and retry. |
47 | @@ -31,7 +31,8 @@ Of course, uploading an image works fine. |
48 | >>> def load_image(filename): |
49 | ... image_file = os.path.join( |
50 | ... os.path.dirname(__file__), 'files', filename) |
51 | - ... return open(image_file).read() |
52 | + ... with open(image_file, "rb") as f: |
53 | + ... return f.read() |
54 | >>> image = load_image("mugshot.png") |
55 | >>> len(image) |
56 | 2260 |
57 | @@ -51,11 +52,11 @@ written to a particular file. |
58 | 'image/png' |
59 | >>> file_handle.filename |
60 | 'nonimage.txt' |
61 | - >>> file_handle.write("Not an image.") |
62 | + >>> file_handle.write(b"Not an image.") |
63 | >>> file_handle.close() |
64 | Traceback (most recent call last): |
65 | ... |
66 | - BadRequest: HTTP Error 400: Bad Request |
67 | + lazr.restfulclient.errors.BadRequest: HTTP Error 400: Bad Request |
68 | ... |
69 | |
70 | == Caching == |
71 | @@ -70,7 +71,7 @@ mechanism. |
72 | >>> import httplib2 |
73 | >>> httplib2.debuglevel = 1 |
74 | >>> launchpad = salgado_with_full_permissions.login() |
75 | - connect: ... |
76 | + send: ... |
77 | >>> mugshot = launchpad.me.mugshot |
78 | send: ... |
79 | |
80 | @@ -90,14 +91,13 @@ already have a fresh copy. |
81 | >>> len(mugshot.open().read()) |
82 | send: ... |
83 | reply: 'HTTP/1.1 303 See Other... |
84 | - header: Location: http://.../image.png |
85 | - ... |
86 | + header: Location... |
87 | 2260 |
88 | |
89 | Finally, some cleanup code that deletes the mugshot. |
90 | |
91 | >>> mugshot.delete() |
92 | - send: 'DELETE... |
93 | + send: b'DELETE... |
94 | reply: 'HTTP/1.1 200... |
95 | |
96 | >>> httplib2.debuglevel = 0 |
97 | diff --git a/src/launchpadlib/docs/introduction.rst b/src/launchpadlib/docs/introduction.rst |
98 | index 722ebac..0bb321e 100644 |
99 | --- a/src/launchpadlib/docs/introduction.rst |
100 | +++ b/src/launchpadlib/docs/introduction.rst |
101 | @@ -75,9 +75,9 @@ behalf. |
102 | >>> from launchpadlib.testing.helpers import ( |
103 | ... TestableLaunchpad as Launchpad) |
104 | >>> launchpad = Launchpad(credentials=credentials) |
105 | - >>> sorted(launchpad.people) |
106 | + >>> list(launchpad.people) |
107 | [...] |
108 | - >>> sorted(launchpad.bugs) |
109 | + >>> list(launchpad.bugs) |
110 | [...] |
111 | |
112 | If available, the Gnome keyring or KDE wallet will be used to store access |
113 | @@ -102,9 +102,9 @@ appropriate instance variables and use the save() method. |
114 | And the credentials are perfectly valid for accessing Launchpad. |
115 | |
116 | >>> launchpad = Launchpad(credentials=credentials) |
117 | - >>> sorted(launchpad.people) |
118 | + >>> list(launchpad.people) |
119 | [...] |
120 | - >>> sorted(launchpad.bugs) |
121 | + >>> list(launchpad.bugs) |
122 | [...] |
123 | |
124 | The credentials can also be retrieved from the file, so that the OAuth request |
125 | @@ -126,22 +126,22 @@ dance can be avoided. |
126 | These credentials too, are perfectly usable to access Launchpad. |
127 | |
128 | >>> launchpad = Launchpad(credentials=credentials) |
129 | - >>> sorted(launchpad.people) |
130 | + >>> list(launchpad.people) |
131 | [...] |
132 | - >>> sorted(launchpad.bugs) |
133 | + >>> list(launchpad.bugs) |
134 | [...] |
135 | |
136 | The security of the stored credentials is left up to the file-like object. |
137 | Here, the application decides to use a dubious encryption algorithm to hide |
138 | Salgado's credentials. |
139 | |
140 | - >>> from StringIO import StringIO |
141 | + >>> import io |
142 | >>> from codecs import EncodedFile |
143 | - >>> encrypted_file = StringIO() |
144 | + >>> encrypted_file = io.BytesIO() |
145 | >>> stream = EncodedFile(encrypted_file, 'rot_13', 'ascii') |
146 | >>> credentials.save(stream) |
147 | - >>> stream.seek(0, 0) |
148 | - >>> print ''.join(sorted(encrypted_file)) |
149 | + >>> _ = stream.seek(0, 0) |
150 | + >>> print(''.join(sorted([line.decode() for line in encrypted_file]))) |
151 | [1] |
152 | <BLANKLINE> |
153 | <BLANKLINE> |
154 | @@ -150,7 +150,7 @@ Salgado's credentials. |
155 | pbafhzre_frperg = |
156 | pbafhzre_xrl = ynhapucnq-yvoenel |
157 | |
158 | - >>> stream.seek(0) |
159 | + >>> _ = stream.seek(0) |
160 | >>> credentials = Credentials() |
161 | >>> credentials.load(stream) |
162 | >>> credentials.consumer.key |
163 | @@ -179,7 +179,7 @@ of the Launchpad dataset. |
164 | >>> launchpad = Launchpad(credentials=credentials) |
165 | |
166 | >>> salgado = launchpad.people['salgado'] |
167 | - >>> print salgado.display_name |
168 | + >>> print(salgado.display_name) |
169 | Guilherme Salgado |
170 | |
171 | An anonymous client can't modify the dataset, or read any data that's |
172 | @@ -188,14 +188,14 @@ permission-controlled or scoped to a particular user. |
173 | >>> launchpad.me |
174 | Traceback (most recent call last): |
175 | ... |
176 | - Unauthorized: HTTP Error 401: Unauthorized |
177 | + lazr.restfulclient.errors.Unauthorized: HTTP Error 401: Unauthorized |
178 | ... |
179 | |
180 | >>> salgado.display_name = "This won't work." |
181 | >>> salgado.lp_save() |
182 | Traceback (most recent call last): |
183 | ... |
184 | - Unauthorized: HTTP Error 401: Unauthorized |
185 | + lazr.restfulclient.errors.Unauthorized: HTTP Error 401: Unauthorized |
186 | ... |
187 | |
188 | Convenience |
189 | @@ -207,13 +207,13 @@ to provide is the consumer name. |
190 | |
191 | >>> launchpad = Launchpad.login_anonymously( |
192 | ... 'launchpad-library', service_root="test_dev") |
193 | - >>> sorted(launchpad.people) |
194 | + >>> list(launchpad.people) |
195 | [...] |
196 | |
197 | >>> launchpad.me |
198 | Traceback (most recent call last): |
199 | ... |
200 | - Unauthorized: HTTP Error 401: Unauthorized |
201 | + lazr.restfulclient.errors.Unauthorized: HTTP Error 401: Unauthorized |
202 | ... |
203 | |
204 | Otherwise, the application should obtain authorization from the user |
205 | @@ -244,7 +244,7 @@ attribute of the Credentials object. |
206 | True |
207 | >>> credentials._request_token.secret is not None |
208 | True |
209 | - >>> print credentials._request_token.context |
210 | + >>> print(credentials._request_token.context) |
211 | firefox |
212 | |
213 | Now the user must authorize that token, and this is the part we can't |
214 | @@ -282,7 +282,7 @@ fields set as if you had asked for the default URI token format. |
215 | True |
216 | >>> credentials._request_token.secret is not None |
217 | True |
218 | - >>> print credentials._request_token.context |
219 | + >>> print(credentials._request_token.context) |
220 | firefox |
221 | |
222 | |
223 | @@ -292,32 +292,33 @@ Credentials file errors |
224 | If the credentials file is empty, loading it raises an exception. |
225 | |
226 | >>> credentials = Credentials() |
227 | - >>> credentials.load(StringIO()) |
228 | + >>> credentials.load(io.StringIO()) |
229 | Traceback (most recent call last): |
230 | ... |
231 | - CredentialsFileError: No configuration for version 1 |
232 | + lazr.restfulclient.errors.CredentialsFileError: No configuration for |
233 | + version 1 |
234 | |
235 | It is an error to save a credentials file when no consumer or access token is |
236 | available. |
237 | |
238 | >>> credentials.consumer = None |
239 | - >>> credentials.save(StringIO()) |
240 | + >>> credentials.save(io.StringIO()) |
241 | Traceback (most recent call last): |
242 | ... |
243 | - CredentialsFileError: No consumer |
244 | + lazr.restfulclient.errors.CredentialsFileError: No consumer |
245 | |
246 | >>> credentials.consumer = consumer |
247 | >>> credentials.access_token = None |
248 | - >>> credentials.save(StringIO()) |
249 | + >>> credentials.save(io.StringIO()) |
250 | Traceback (most recent call last): |
251 | ... |
252 | - CredentialsFileError: No access token |
253 | + lazr.restfulclient.errors.CredentialsFileError: No access token |
254 | |
255 | The credentials file is not intended to be edited, but because it's human |
256 | readable, that's of course possible. If the credentials file gets corrupted, |
257 | an error is raised. |
258 | |
259 | - >>> credentials_file = StringIO("""\ |
260 | + >>> credentials_file = io.StringIO("""\ |
261 | ... [1] |
262 | ... #consumer_key: aardvark |
263 | ... consumer_secret: badger |
264 | @@ -327,9 +328,9 @@ an error is raised. |
265 | >>> credentials.load(credentials_file) |
266 | Traceback (most recent call last): |
267 | ... |
268 | - NoOptionError: No option 'consumer_key' in section: '1' |
269 | + configparser.NoOptionError: No option 'consumer_key' in section: '1' |
270 | |
271 | - >>> credentials_file = StringIO("""\ |
272 | + >>> credentials_file = io.StringIO("""\ |
273 | ... [1] |
274 | ... consumer_key: aardvark |
275 | ... #consumer_secret: badger |
276 | @@ -339,9 +340,9 @@ an error is raised. |
277 | >>> credentials.load(credentials_file) |
278 | Traceback (most recent call last): |
279 | ... |
280 | - NoOptionError: No option 'consumer_secret' in section: '1' |
281 | + configparser.NoOptionError: No option 'consumer_secret' in section: '1' |
282 | |
283 | - >>> credentials_file = StringIO("""\ |
284 | + >>> credentials_file = io.StringIO("""\ |
285 | ... [1] |
286 | ... consumer_key: aardvark |
287 | ... consumer_secret: badger |
288 | @@ -351,9 +352,9 @@ an error is raised. |
289 | >>> credentials.load(credentials_file) |
290 | Traceback (most recent call last): |
291 | ... |
292 | - NoOptionError: No option 'access_token' in section: '1' |
293 | + configparser.NoOptionError: No option 'access_token' in section: '1' |
294 | |
295 | - >>> credentials_file = StringIO("""\ |
296 | + >>> credentials_file = io.StringIO("""\ |
297 | ... [1] |
298 | ... consumer_key: aardvark |
299 | ... consumer_secret: badger |
300 | @@ -363,7 +364,7 @@ an error is raised. |
301 | >>> credentials.load(credentials_file) |
302 | Traceback (most recent call last): |
303 | ... |
304 | - NoOptionError: No option 'access_secret' in section: '1' |
305 | + configparser.NoOptionError: No option 'access_secret' in section: '1' |
306 | |
307 | |
308 | Bad credentials |
309 | @@ -378,7 +379,7 @@ The application is not allowed to access Launchpad with a bad access token. |
310 | >>> launchpad = Launchpad(credentials=credentials) |
311 | Traceback (most recent call last): |
312 | ... |
313 | - Unauthorized: HTTP Error 401: Unauthorized |
314 | + lazr.restfulclient.errors.Unauthorized: HTTP Error 401: Unauthorized |
315 | ... |
316 | |
317 | The application is not allowed to access Launchpad with a consumer |
318 | @@ -391,7 +392,7 @@ name that doesn't match the credentials. |
319 | >>> launchpad = Launchpad(credentials=credentials) |
320 | Traceback (most recent call last): |
321 | ... |
322 | - Unauthorized: HTTP Error 401: Unauthorized |
323 | + lazr.restfulclient.errors.Unauthorized: HTTP Error 401: Unauthorized |
324 | ... |
325 | |
326 | The application is not allowed to access Launchpad with a bad access secret. |
327 | @@ -403,7 +404,7 @@ The application is not allowed to access Launchpad with a bad access secret. |
328 | >>> launchpad = Launchpad(credentials=credentials) |
329 | Traceback (most recent call last): |
330 | ... |
331 | - Unauthorized: HTTP Error 401: Unauthorized |
332 | + lazr.restfulclient.errors.Unauthorized: HTTP Error 401: Unauthorized |
333 | ... |
334 | |
335 | Clean up |
336 | diff --git a/src/launchpadlib/docs/people.rst b/src/launchpadlib/docs/people.rst |
337 | index d1dc629..83a98c8 100644 |
338 | --- a/src/launchpadlib/docs/people.rst |
339 | +++ b/src/launchpadlib/docs/people.rst |
340 | @@ -21,29 +21,29 @@ The list of people is available from the service root. |
341 | |
342 | The list of people is not fetched until you actually use data. |
343 | |
344 | - >>> print people._wadl_resource.representation |
345 | + >>> print(people._wadl_resource.representation) |
346 | None |
347 | |
348 | >>> len(people) |
349 | 4 |
350 | |
351 | - >>> print people._wadl_resource.representation |
352 | + >>> print(people._wadl_resource.representation) |
353 | {...} |
354 | |
355 | The 'me' attribute is also available from the service root. It's a |
356 | quick way to get a reference to your own user account. |
357 | |
358 | >>> me = launchpad.me |
359 | - >>> me.name |
360 | - u'salgado' |
361 | + >>> print(me.name) |
362 | + salgado |
363 | |
364 | You can find a person by name. |
365 | |
366 | >>> salgado = launchpad.people['salgado'] |
367 | - >>> salgado.name |
368 | - u'salgado' |
369 | - >>> salgado.display_name |
370 | - u'Guilherme Salgado' |
371 | + >>> print(salgado.name) |
372 | + salgado |
373 | + >>> print(salgado.display_name) |
374 | + Guilherme Salgado |
375 | >>> salgado.is_team |
376 | False |
377 | |
378 | @@ -67,8 +67,8 @@ You can find a person by email. |
379 | |
380 | >>> email = salgado.preferred_email_address.email |
381 | >>> salgado = launchpad.people.getByEmail(email=email) |
382 | - >>> salgado.name |
383 | - u'salgado' |
384 | + >>> print(salgado.name) |
385 | + salgado |
386 | |
387 | Besides a name and a display name, a person has many other attributes that you |
388 | can read. |
389 | @@ -79,7 +79,7 @@ can read. |
390 | |
391 | >>> salgado.karma |
392 | 0 |
393 | - >>> print salgado.homepage_content |
394 | + >>> print(salgado.homepage_content) |
395 | None |
396 | >>> #salgado.mugshot |
397 | >>> #salgado.languages |
398 | @@ -87,7 +87,7 @@ can read. |
399 | False |
400 | >>> salgado.date_created |
401 | datetime.datetime(2005, 6, 6, 8, 59, 51, 596025, ...) |
402 | - >>> print salgado.time_zone |
403 | + >>> print(salgado.time_zone) |
404 | UTC |
405 | >>> salgado.is_valid |
406 | True |
407 | @@ -100,10 +100,10 @@ can read. |
408 | >>> #salgado.teams_indirectly_participated_in |
409 | >>> #salgado.confirmed_email_addresses |
410 | >>> #salgado.preferred_email_address |
411 | - >>> salgado.mailing_list_auto_subscribe_policy |
412 | - u'Ask me when I join a team' |
413 | - >>> salgado.visibility |
414 | - u'Public' |
415 | + >>> print(salgado.mailing_list_auto_subscribe_policy) |
416 | + Ask me when I join a team |
417 | + >>> print(salgado.visibility) |
418 | + Public |
419 | |
420 | |
421 | Teams |
422 | @@ -112,16 +112,16 @@ Teams |
423 | You also access teams using the same interface. |
424 | |
425 | >>> team = launchpad.people['ubuntu-team'] |
426 | - >>> team.name |
427 | - u'ubuntu-team' |
428 | - >>> team.display_name |
429 | - u'Ubuntu Team' |
430 | + >>> print(team.name) |
431 | + ubuntu-team |
432 | + >>> print(team.display_name) |
433 | + Ubuntu Team |
434 | >>> team.is_team |
435 | True |
436 | |
437 | Regular people have team attributes, but they're not used. |
438 | |
439 | - >>> print salgado.team_owner |
440 | + >>> print(salgado.team_owner) |
441 | None |
442 | |
443 | You can find out how a person has membership in a team. |
444 | @@ -143,27 +143,27 @@ this requires only the new team's name, owner and display name. |
445 | |
446 | >>> bassists = launchpad.people.newTeam( |
447 | ... name='bassists', display_name='Awesome Rock Bass Players') |
448 | - >>> bassists.name |
449 | - u'bassists' |
450 | - >>> bassists.display_name |
451 | - u'Awesome Rock Bass Players' |
452 | + >>> print(bassists.name) |
453 | + bassists |
454 | + >>> print(bassists.display_name) |
455 | + Awesome Rock Bass Players |
456 | >>> bassists.is_team |
457 | True |
458 | |
459 | And of course, that team is now accessible directly. |
460 | |
461 | >>> bassists = launchpad.people['bassists'] |
462 | - >>> bassists.name |
463 | - u'bassists' |
464 | - >>> bassists.display_name |
465 | - u'Awesome Rock Bass Players' |
466 | + >>> print(bassists.name) |
467 | + bassists |
468 | + >>> print(bassists.display_name) |
469 | + Awesome Rock Bass Players |
470 | |
471 | You cannot create the same team twice. |
472 | |
473 | >>> launchpad.people.newTeam(name='bassists', display_name='Bass Gods') |
474 | Traceback (most recent call last): |
475 | ... |
476 | - BadRequest: HTTP Error 400: Bad Request |
477 | + lazr.restfulclient.errors.BadRequest: HTTP Error 400: Bad Request |
478 | ... |
479 | |
480 | Actually, the exception contains other useful information. |
481 | @@ -172,25 +172,25 @@ Actually, the exception contains other useful information. |
482 | >>> try: |
483 | ... launchpad.people.newTeam( |
484 | ... name='bassists', display_name='Bass Gods') |
485 | - ... except HTTPError, error: |
486 | - ... pass |
487 | + ... except HTTPError as e: |
488 | + ... error = e |
489 | >>> error.response['status'] |
490 | '400' |
491 | - >>> error.content |
492 | - 'name: bassists is already in use by another person or team.' |
493 | + >>> print(error.content.decode()) |
494 | + name: bassists is already in use by another person or team. |
495 | |
496 | Besides a name and a display name, a team has many other attributes that you |
497 | can read. |
498 | |
499 | >>> bassists.karma |
500 | 0 |
501 | - >>> print bassists.homepage_content |
502 | + >>> print(bassists.homepage_content) |
503 | None |
504 | >>> bassists.hide_email_addresses |
505 | False |
506 | >>> bassists.date_created |
507 | datetime.datetime(...) |
508 | - >>> print bassists.time_zone |
509 | + >>> print(bassists.time_zone) |
510 | UTC |
511 | >>> bassists.is_valid |
512 | True |
513 | @@ -209,15 +209,15 @@ can read. |
514 | >>> #bassists.invited_members |
515 | >>> #bassists.member_memberships |
516 | >>> #bassists.proposed_members |
517 | - >>> bassists.visibility |
518 | - u'Public' |
519 | - >>> print bassists.team_description |
520 | + >>> print(bassists.visibility) |
521 | + Public |
522 | + >>> print(bassists.team_description) |
523 | None |
524 | - >>> bassists.subscription_policy |
525 | - u'Moderated Team' |
526 | - >>> bassists.renewal_policy |
527 | - u'invite them to apply for renewal' |
528 | - >>> print bassists.default_membership_period |
529 | + >>> print(bassists.subscription_policy) |
530 | + Moderated Team |
531 | + >>> print(bassists.renewal_policy) |
532 | + invite them to apply for renewal |
533 | + >>> print(bassists.default_membership_period) |
534 | None |
535 | - >>> print bassists.default_renewal_period |
536 | + >>> print(bassists.default_renewal_period) |
537 | None |
538 | diff --git a/src/launchpadlib/docs/toplevel.rst b/src/launchpadlib/docs/toplevel.rst |
539 | index 76d2a56..67c480a 100644 |
540 | --- a/src/launchpadlib/docs/toplevel.rst |
541 | +++ b/src/launchpadlib/docs/toplevel.rst |
542 | @@ -10,14 +10,14 @@ Launchpad-wide objects like projects and people. |
543 | |
544 | >>> from launchpadlib.testing.helpers import salgado_with_full_permissions |
545 | >>> launchpad = salgado_with_full_permissions.login() |
546 | - connect: ... |
547 | + send: ... |
548 | ... |
549 | |
550 | It's possible to do key-based lookups on the top-level |
551 | collections. The bug collection does lookups by bug ID. |
552 | |
553 | >>> bug = launchpad.bugs[1] |
554 | - send: 'GET /.../bugs/1 ...' |
555 | + send: b'GET /.../bugs/1 ...' |
556 | ... |
557 | |
558 | To avoid triggering an HTTP request when simply looking up an object, |
559 | @@ -28,8 +28,8 @@ you can use a different syntax: |
560 | The HTTP request will happen when you need information that can only |
561 | be obtained from the web service. |
562 | |
563 | - >>> print bug.id |
564 | - send: 'GET /.../bugs/1 ...' |
565 | + >>> print(bug.id) |
566 | + send: b'GET /.../bugs/1 ...' |
567 | ... |
568 | 1 |
569 | |
570 | @@ -37,24 +37,24 @@ Let's look at some more collections. The project collection does |
571 | lookups by project name. |
572 | |
573 | >>> project = launchpad.projects('firefox') |
574 | - >>> print project.name |
575 | - send: 'GET /.../firefox ...' |
576 | + >>> print(project.name) |
577 | + send: b'GET /.../firefox ...' |
578 | ... |
579 | firefox |
580 | |
581 | The project group collection does lookups by project group name. |
582 | |
583 | >>> group = launchpad.project_groups('gnome') |
584 | - >>> print group.name |
585 | - send: 'GET /.../gnome ...' |
586 | + >>> print(group.name) |
587 | + send: b'GET /.../gnome ...' |
588 | ... |
589 | gnome |
590 | |
591 | The distribution collection does lookups by distribution name. |
592 | |
593 | >>> distribution = launchpad.distributions('ubuntu') |
594 | - >>> print distribution.name |
595 | - send: 'GET /.../ubuntu ...' |
596 | + >>> print(distribution.name) |
597 | + send: b'GET /.../ubuntu ...' |
598 | ... |
599 | ubuntu |
600 | |
601 | @@ -62,26 +62,26 @@ The person collection does lookups by a person's Launchpad |
602 | name. |
603 | |
604 | >>> person = launchpad.people('salgado') |
605 | - >>> print person.name |
606 | - send: 'GET /.../~salgado ...' |
607 | + >>> print(person.name) |
608 | + send: b'GET /.../~salgado ...' |
609 | ... |
610 | salgado |
611 | |
612 | >>> team = launchpad.people('rosetta-admins') |
613 | - >>> print team.name |
614 | - send: 'GET /1.0/~rosetta-admins ...' |
615 | + >>> print(team.name) |
616 | + send: b'GET /1.0/~rosetta-admins ...' |
617 | ... |
618 | rosetta-admins |
619 | |
620 | How does launchpadlib know that 'salgado' is a person and |
621 | 'rosetta-admins' is a team? |
622 | |
623 | - >>> print person.resource_type_link |
624 | + >>> print(person.resource_type_link) |
625 | http://.../1.0/#person |
626 | >>> 'default_membership_period' in person.lp_attributes |
627 | False |
628 | |
629 | - >>> print team.resource_type_link |
630 | + >>> print(team.resource_type_link) |
631 | http://.../1.0/#team |
632 | >>> 'default_membership_period' in team.lp_attributes |
633 | True |
634 | @@ -99,8 +99,8 @@ But accessing any attribute of an object--even trying to see what kind |
635 | of object 'salgado' is--will trigger the HTTP request that will |
636 | determine that 'salgado' is actually a person. |
637 | |
638 | - >>> print person2.resource_type_link |
639 | - send: 'GET /.../~salgado ...' |
640 | + >>> print(person2.resource_type_link) |
641 | + send: b'GET /.../~salgado ...' |
642 | ... |
643 | http://.../1.0/#person |
644 | |
645 | @@ -118,4 +118,4 @@ to be a team. |
646 | |
647 | Cleanup. |
648 | |
649 | - >>> httplib2.debuglevel = None |
650 | + >>> httplib2.debuglevel = 0 |
I was wondering why this package is not tested in isolation... but then again I found this line:
>>> web_root = "http:// launchpad. test:8085/"