Merge lp:~jelmer/lptools/breezy-python3 into lp:lptools

Proposed by Jelmer Vernooij
Status: Merged
Merged at revision: 48
Proposed branch: lp:~jelmer/lptools/breezy-python3
Merge into: lp:lptools
Prerequisite: lp:~jelmer/lptools/breezy
Diff against target: 888 lines (+134/-132)
20 files modified
bin/lp-attach (+9/-9)
bin/lp-bug-dupe-properties (+6/-6)
bin/lp-capture-bug-counts (+5/-5)
bin/lp-check-membership (+4/-4)
bin/lp-force-branch-mirror (+4/-4)
bin/lp-get-branches (+7/-7)
bin/lp-grab-attachments (+2/-2)
bin/lp-list-bugs (+8/-9)
bin/lp-milestone2ical (+4/-4)
bin/lp-milestones (+2/-2)
bin/lp-project (+1/-1)
bin/lp-project-upload (+25/-23)
bin/lp-recipe-status (+7/-7)
bin/lp-remove-team-members (+5/-5)
bin/lp-review-list (+8/-8)
bin/lp-review-notifier (+8/-8)
bin/lp-set-dup (+16/-16)
bin/lp-shell (+8/-8)
lptools/config.py (+1/-1)
setup.py (+4/-3)
To merge this branch: bzr merge lp:~jelmer/lptools/breezy-python3
Reviewer Review Type Date Requested Status
Colin Watson (community) Needs Fixing
dobey Approve
Jelmer Vernooij Approve
Ubuntu One Control Tower Pending
Review via email: mp+372112@code.launchpad.net

Commit message

Convert lptools to Python 3.

Description of the change

Convert lptools to Python 3.

There's probably some things I missed because test coverage is poor, but it should at least be better than the current state of things.

To post a comment you must log in.
lp:~jelmer/lptools/breezy-python3 updated
48. By Jelmer Vernooij

use open rather than file.

49. By Jelmer Vernooij

Fix binaryness.

50. By Jelmer Vernooij

Improve python3 compatibility of lp-project-upload.

Revision history for this message
Jelmer Vernooij (jelmer) :
review: Approve
Revision history for this message
dobey (dobey) wrote :

Looks OK. Thanks.

review: Approve
Revision history for this message
Colin Watson (cjwatson) wrote :

Mostly just a few minor tweaks because I'm a pedant, but I did notice one definite mistake.

review: Needs Fixing

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/lp-attach'
2--- bin/lp-attach 2012-03-30 19:49:05 +0000
3+++ bin/lp-attach 2022-11-17 00:45:19 +0000
4@@ -1,4 +1,4 @@
5-#! /usr/bin/python
6+#! /usr/bin/python3
7 #
8 # Copyright (C) 2010 Canonical Ltd
9
10@@ -35,7 +35,7 @@
11 def guess_mime_type(attachment_bytes):
12 try:
13 import magic
14- except ImportError, e:
15+ except ImportError as e:
16 sys.stderr.write("can't guess mime-types without the python-magic library: %s" % e)
17 mimetype = None
18 else:
19@@ -43,13 +43,13 @@
20 mimetype = mime.buffer(attachment_bytes)
21 if mimetype is None:
22 mimetype = 'application/binary'
23- print 'attachment type %s' % mimetype
24+ print('attachment type %s' % mimetype)
25 return mimetype
26
27
28 def main(argv):
29 if len(argv) != 2 or argv[1] == '--help':
30- print __doc__
31+ print(__doc__)
32 return 3
33
34 try:
35@@ -59,23 +59,23 @@
36 return 1
37
38 lp = config.get_launchpad("attach")
39- print "getting bug %s" % bugnumber
40+ print("getting bug %s" % bugnumber)
41 bug = lp.bugs[bugnumber]
42- print 'Attaching to %s' % bug
43+ print('Attaching to %s' % bug)
44
45 attachment_bytes = sys.stdin.read()
46- print '%d bytes to attach' % len(attachment_bytes)
47+ print('%d bytes to attach' % len(attachment_bytes))
48
49 mime_type = guess_mime_type(attachment_bytes)
50
51 # mime type must be specified otherwise
52 # <https://bugs.edge.launchpad.net/malone/+bug/204560> assumes it's
53 # chemical/x-mopac-input
54- print bug.addAttachment(comment='',
55+ print(bug.addAttachment(comment='',
56 data=attachment_bytes,
57 description='',
58 filename='attachment',
59- content_type=mime_type)
60+ content_type=mime_type))
61
62
63 if __name__ == '__main__':
64
65=== modified file 'bin/lp-bug-dupe-properties'
66--- bin/lp-bug-dupe-properties 2012-06-05 15:17:54 +0000
67+++ bin/lp-bug-dupe-properties 2022-11-17 00:45:19 +0000
68@@ -1,4 +1,4 @@
69-#!/usr/bin/python
70+#!/usr/bin/python3
71 #
72 # Copyright (C) 2012, Canonical Ltd.
73 # Written by Brian Murray
74@@ -99,25 +99,25 @@
75 key = None
76
77 if bug.number_of_duplicates == 0:
78- print('LP: #%s has no duplicates!' % bug_number)
79+ print(('LP: #%s has no duplicates!' % bug_number))
80 sys.exit(1)
81
82 for dupe in bug.duplicates:
83 dupe_num = dupe.id
84 prop = check_duplicate(dupe, search, key)
85- if prop in dupe_props.keys():
86+ if prop in list(dupe_props.keys()):
87 dupe_props[prop].append(str(dupe_num))
88 else:
89 dupe_props[prop] = [str(dupe_num)]
90
91 dupe_count = bug.number_of_duplicates
92 if dupe_count > 1:
93- print('LP: #%s has %s duplicates' % (bug_number, dupe_count))
94+ print(('LP: #%s has %s duplicates' % (bug_number, dupe_count)))
95 elif dupe_count == 1:
96- print('LP: #%s has %s duplicate' % (bug_number, dupe_count))
97+ print(('LP: #%s has %s duplicate' % (bug_number, dupe_count)))
98
99 for prop, bugs in sorted(dupe_props.items()):
100- print(' %s: %s' % (prop, ' '.join(bugs)))
101+ print((' %s: %s' % (prop, ' '.join(bugs))))
102
103
104 if __name__ == '__main__':
105
106=== modified file 'bin/lp-capture-bug-counts'
107--- bin/lp-capture-bug-counts 2012-03-31 13:07:36 +0000
108+++ bin/lp-capture-bug-counts 2022-11-17 00:45:19 +0000
109@@ -1,4 +1,4 @@
110-#! /usr/bin/python
111+#! /usr/bin/python3
112
113 import sys
114
115@@ -70,10 +70,10 @@
116 def show_text(self):
117 # print self.get_name()
118 for category in self.query_categories():
119- print '%6d %s %s' % (category.count_bugs(),
120+ print('%6d %s %s' % (category.count_bugs(),
121 category.get_name(),
122- category.get_link_url() or '')
123- print
124+ category.get_link_url() or ''))
125+ print()
126
127
128 class PatchCannedQuery(CannedQuery):
129@@ -103,7 +103,7 @@
130 if bugtask.status not in by_status:
131 by_status[bugtask.status] = StatusBugCategory(bugtask.status)
132 by_status[bugtask.status].add(bugtask)
133- return by_status.values()
134+ return list(by_status.values())
135
136
137 def show_bug_report(project):
138
139=== modified file 'bin/lp-check-membership'
140--- bin/lp-check-membership 2012-02-18 23:46:23 +0000
141+++ bin/lp-check-membership 2022-11-17 00:45:19 +0000
142@@ -1,4 +1,4 @@
143-#! /usr/bin/python
144+#! /usr/bin/python3
145 #
146 # Copyright (C) 2009 Canonical Ltd
147
148@@ -38,7 +38,7 @@
149 parser = optparse.OptionParser('%prog [options] PERSON GROUP')
150 opts, args = parser.parse_args()
151 if len(args) != 2:
152- print __doc__
153+ print(__doc__)
154 return 2
155 user_name = args[0]
156 group_name = args[1]
157@@ -46,10 +46,10 @@
158 user = lp.people[user_name]
159 for user_team in user.super_teams:
160 if user_team.name == group_name:
161- print '%s is a member of %s' % (user_name, group_name)
162+ print('%s is a member of %s' % (user_name, group_name))
163 return 0
164 else:
165- print '%s is not a member of %s' % (user_name, group_name)
166+ print('%s is not a member of %s' % (user_name, group_name))
167 return 1
168
169
170
171=== modified file 'bin/lp-force-branch-mirror'
172--- bin/lp-force-branch-mirror 2011-08-28 11:22:34 +0000
173+++ bin/lp-force-branch-mirror 2022-11-17 00:45:19 +0000
174@@ -1,4 +1,4 @@
175-#! /usr/bin/python
176+#! /usr/bin/python3
177 # vi: expandtab:sts=4
178
179 # Copyright (C) 2011 Jelmer Vernooij
180@@ -22,12 +22,12 @@
181
182 lp = config.get_launchpad("force-branch-mirror")
183 branches = lp.branches.getByUrls(urls=args)
184- for url, branch_dict in branches.iteritems():
185+ for url, branch_dict in branches.items():
186 if branch_dict is None:
187- print "Branch %s not found" % url
188+ print("Branch %s not found" % url)
189 else:
190 branch = lp.load(branch_dict["self_link"])
191- print "%s: %s" % (branch.bzr_identity, branch.requestMirror())
192+ print("%s: %s" % (branch.bzr_identity, branch.requestMirror()))
193
194 if __name__ == '__main__':
195 sys.exit(main(sys.argv))
196
197=== modified file 'bin/lp-get-branches'
198--- bin/lp-get-branches 2011-08-23 13:13:13 +0000
199+++ bin/lp-get-branches 2022-11-17 00:45:19 +0000
200@@ -1,4 +1,4 @@
201-#!/usr/bin/python
202+#!/usr/bin/python3
203 # -*- coding: utf-8 -*-
204 #
205 # Copyright (C) 2007 Canonical Ltd.
206@@ -79,13 +79,13 @@
207 try:
208 team = launchpad.people[team]
209 except KeyError:
210- print >> sys.stderr, "E: The team '%s' doesn't exist." % team
211+ print("E: The team '%s' doesn't exist." % team, file=sys.stderr)
212
213 # Get a list of branches
214 branches = team.getBranches()
215
216- print "Downloading all branches for the '%s' team. This may take some " \
217- "time." % team.display_name
218+ print("Downloading all branches for the '%s' team. This may take some " \
219+ "time." % team.display_name)
220
221 try:
222 os.makedirs(team.name)
223@@ -101,11 +101,11 @@
224 os.chdir(project_name)
225
226 if not os.path.exists(branch.name):
227- print "Branching %s ..." % branch.display_name
228+ print("Branching %s ..." % branch.display_name)
229 cmd = ["bzr", operation_type, branch.bzr_identity, branch.name]
230 subprocess.call(cmd)
231 else:
232- print "Merging %s ..." % branch.display_name
233+ print("Merging %s ..." % branch.display_name)
234 os.chdir(branch.name)
235 subprocess.call(["bzr", "merge", "--pull", "--remember"])
236 os.chdir(os.path.join(directory, team.name))
237@@ -117,4 +117,4 @@
238 try:
239 main()
240 except KeyboardInterrupt:
241- print "Operation was interrupted by user."
242+ print("Operation was interrupted by user.")
243
244=== modified file 'bin/lp-grab-attachments'
245--- bin/lp-grab-attachments 2012-05-18 20:56:40 +0000
246+++ bin/lp-grab-attachments 2022-11-17 00:45:19 +0000
247@@ -1,4 +1,4 @@
248-#!/usr/bin/python
249+#!/usr/bin/python3
250 #
251 # Copyright (C) 2007, Canonical Ltd.
252 # Written by Daniel Holbach,
253@@ -36,7 +36,7 @@
254
255 try:
256 os.mkdir(bug_folder_name)
257- except OSError, error:
258+ except OSError as error:
259 if error.errno == errno.EEXIST:
260 return
261
262
263=== modified file 'bin/lp-list-bugs'
264--- bin/lp-list-bugs 2011-07-25 14:47:03 +0000
265+++ bin/lp-list-bugs 2022-11-17 00:45:19 +0000
266@@ -1,4 +1,4 @@
267-#! /usr/bin/python
268+#! /usr/bin/python3
269 # -*- coding: UTF-8 -*-
270 """Briefly list status of Launchpad bugs."""
271
272@@ -42,18 +42,17 @@
273 for bugnum in args:
274 try:
275 bug = launchpad.bugs[bugnum]
276- print "Bug %s: %s" % (bugnum, bug.title)
277+ print("Bug %s: %s" % (bugnum, bug.title))
278 for task in bug.bug_tasks:
279- print " %s: %s" % (task.bug_target_name, task.status)
280- except HTTPError, error:
281+ print(" %s: %s" % (task.bug_target_name, task.status))
282+ except HTTPError as error:
283 if error.response.status == 401:
284- print >> sys.stderr, \
285- ("E: Don't have enough permissions to access bug %s" %
286- bugnum)
287- print >> sys.stderr, error.content
288+ print(("E: Don't have enough permissions to access bug %s" %
289+ bugnum), file=sys.stderr)
290+ print(error.content, file=sys.stderr)
291 continue
292 elif error.response.status == 404:
293- print >> sys.stderr, "E: Bug %s not found" % bugnum
294+ print("E: Bug %s not found" % bugnum, file=sys.stderr)
295 else:
296 raise
297
298
299=== modified file 'bin/lp-milestone2ical'
300--- bin/lp-milestone2ical 2010-02-01 05:30:54 +0000
301+++ bin/lp-milestone2ical 2022-11-17 00:45:19 +0000
302@@ -1,4 +1,4 @@
303-#!/usr/bin/python
304+#!/usr/bin/python3
305 #
306 # Author: Rodney Dawes <rodney.dawes@canonical.com>
307 #
308@@ -16,7 +16,7 @@
309 # You should have received a copy of the GNU General Public License along
310 # with this program. If not, see <http://www.gnu.org/licenses/>.
311
312-from __future__ import with_statement
313+
314
315 import os
316 import sys
317@@ -84,7 +84,7 @@
318 finally:
319 self.__convert_to_ical(lp_project)
320 self.__end_calendar()
321- print self.calendar()
322+ print(self.calendar())
323
324 def run(self):
325 self.thread = Thread(target=self.__login_and_go).start()
326@@ -99,7 +99,7 @@
327 try:
328 project = sys.argv[1]
329 except IndexError:
330- print "Usage: %s <project>" % sys.argv[0]
331+ print("Usage: %s <project>" % sys.argv[0])
332 exit(1)
333
334 try:
335
336=== modified file 'bin/lp-milestones'
337--- bin/lp-milestones 2022-11-17 00:45:19 +0000
338+++ bin/lp-milestones 2022-11-17 00:45:19 +0000
339@@ -1,4 +1,4 @@
340-#!/usr/bin/python
341+#!/usr/bin/python3
342 #
343 # Author: Robert Collins <robert.collins@canonical.com>
344 #
345@@ -74,7 +74,7 @@
346 m = self.launchpad.load('%s/+milestone/%s' % tuple(components))
347 try:
348 m.delete()
349- except HTTPError, e:
350+ except HTTPError as e:
351 if e.response.status == 404:
352 pass
353 elif e.response.status == 500:
354
355=== modified file 'bin/lp-project'
356--- bin/lp-project 2022-11-17 00:45:19 +0000
357+++ bin/lp-project 2022-11-17 00:45:19 +0000
358@@ -1,4 +1,4 @@
359-#!/usr/bin/python
360+#!/usr/bin/python3
361 #
362 # Author: Robert Collins <robert.collins@canonical.com>
363 #
364
365=== modified file 'bin/lp-project-upload'
366--- bin/lp-project-upload 2012-01-20 15:02:37 +0000
367+++ bin/lp-project-upload 2022-11-17 00:45:19 +0000
368@@ -1,4 +1,4 @@
369-#!/usr/bin/python
370+#!/usr/bin/python333
371
372 # Copyright (c) 2009 Canonical Ltd.
373 #
374@@ -34,8 +34,8 @@
375 def create_release(project, version):
376 '''Create new release and milestone for LP project.'''
377
378- print 'Release %s could not be found for project. Create it? (Y/n)' % \
379- version
380+ print('Release %s could not be found for project. Create it? (Y/n)' % \
381+ version)
382 answer = sys.stdin.readline().strip()
383 if answer.startswith('n'):
384 sys.exit(0)
385@@ -46,21 +46,21 @@
386 elif n_series > 1:
387 msg = 'More than one series exist. Which one would you like to ' \
388 'upload to? Possible series are (listed as index, name):'
389- print msg
390+ print(msg)
391 for idx, serie in enumerate(project.series):
392- print '\t%i - %s' % (idx, serie.name)
393- print 'Enter series index: '
394+ print('\t%i - %s' % (idx, serie.name))
395+ print('Enter series index: ')
396 answer = sys.stdin.readline().strip()
397 try:
398 series = project.series[int(answer)]
399 except (ValueError, IndexError):
400- print >> sys.stderr, 'The series index is invalid (%s).' % answer
401+ print('The series index is invalid (%s).' % answer, file=sys.stderr)
402 sys.exit(3)
403 else:
404- print "Using series named '%s'" % series.name
405+ print("Using series named '%s'" % series.name)
406 else:
407- print >> sys.stderr, ('Does not support creating releases if no '
408- 'series exists.')
409+ print(('Does not support creating releases if no '
410+ 'series exists.'), file=sys.stderr)
411 sys.exit(3)
412
413 release_date = datetime.date.today().strftime('%Y-%m-%d')
414@@ -70,8 +70,8 @@
415
416 def edit_file(prefix, description):
417 (fd, f) = tempfile.mkstemp(prefix=prefix+'.')
418- os.write(fd, '\n\n#------\n# Please enter the %s here. '
419- 'Lines which start with "#" are ignored.\n' % description)
420+ os.write(fd, b'\n\n#------\n# Please enter the %s here. '
421+ b'Lines which start with "#" are ignored.\n' % description.encode())
422 os.close(fd)
423 subprocess.call(['sensible-editor', f])
424 return cat_file(f)
425@@ -86,9 +86,9 @@
426
427 def main():
428 if len(sys.argv) < 4 or len(sys.argv) > 7:
429- print >> sys.stderr, '''Upload a release tarball to a Launchpad project.
430+ print('''Upload a release tarball to a Launchpad project.
431
432- Usage: %s <project name> <version> <tarball> [new milestone] [changelog file] [releasenotes file]''' % sys.argv[0]
433+ Usage: %s <project name> <version> <tarball> [new milestone] [changelog file] [releasenotes file]''' % sys.argv[0], file=sys.stderr)
434 sys.exit(1)
435
436 new_milestone = None
437@@ -123,26 +123,28 @@
438 release = create_release(proj, version)
439
440 # Get the file contents.
441- file_content = open(tarball, 'r').read()
442+ with open(tarball, 'rb') as f:
443+ file_content = f.read()
444 # Get the signature, if available.
445 signature = tarball + '.asc'
446 if not os.path.exists(signature):
447- print 'Calling GPG to create tarball signature...'
448+ print('Calling GPG to create tarball signature...')
449 cmd = ['gpg', '--armor', '--sign', '--detach-sig', tarball]
450 if subprocess.call(cmd) != 0:
451- print >> sys.stderr, 'gpg failed, aborting'
452+ print('gpg failed, aborting', file=sys.stderr)
453
454 if os.path.exists(signature):
455- signature_content = open(signature, 'r').read()
456+ with open(signature, 'rb') as f:
457+ signature_content = f.read()
458 else:
459 signature_content = None
460
461 # Create a new product release file.
462 filename = os.path.basename(tarball)
463 release.add_file(filename=filename, description='release tarball',
464- file_content=file_content, content_type='application/x-gzip',
465- file_type='Code Release Tarball', signature_filename=signature,
466- signature_content=signature_content)
467+ file_content=file_content, content_type='application/x-gzip',
468+ file_type='Code Release Tarball', signature_filename=signature,
469+ signature_content=signature_content)
470
471 if changelog_file is not None:
472 changelog = cat_file(changelog_file)
473@@ -167,8 +169,8 @@
474 if mil.name in [milestone.name for milestone in series.all_milestones]:
475 series.newMilestone(name=new_milestone)
476
477- except HTTPError, error:
478- print 'An error happened in the upload:', error.content
479+ except HTTPError as error:
480+ print('An error happened in the upload:', error.content)
481 sys.exit(1)
482
483 if __name__ == '__main__':
484
485=== modified file 'bin/lp-recipe-status'
486--- bin/lp-recipe-status 2011-11-04 13:41:07 +0000
487+++ bin/lp-recipe-status 2022-11-17 00:45:19 +0000
488@@ -1,4 +1,4 @@
489-#!/usr/bin/python
490+#!/usr/bin/python3
491 # vi: expandtab:sts=4
492
493 # Copyright (C) 2011 Jelmer Vernooij <jelmer@samba.org>
494@@ -22,13 +22,13 @@
495 """Show the status of the recipes owned by a particular user.
496 """
497
498-from cStringIO import StringIO
499+from io import StringIO
500 import gzip
501 import optparse
502 import os
503 import re
504 import sys
505-import urllib
506+import urllib.request, urllib.parse, urllib.error
507
508 from lptools import config
509
510@@ -70,7 +70,7 @@
511 if cached_version:
512 return tuple(cached_version.split(" "))
513 # FIXME: Find a more efficient way to retrieve the package/version that was built
514- build_log_gz = urllib.urlopen(source_build.build_log_url)
515+ build_log_gz = urllib.request.urlopen(source_build.build_log_url)
516 build_log = gzip.GzipFile(fileobj=StringIO(build_log_gz.read()))
517 version = None
518 source_name = None
519@@ -172,10 +172,10 @@
520 last_per_distroseries = gather_per_distroseries_source_builds(recipe)
521 source_builds[recipe.name] = last_per_distroseries
522 relevant_distroseries.update(set(last_per_distroseries))
523- (sp_success, sp_failures) = filter_source_builds(last_per_distroseries.values())
524+ (sp_success, sp_failures) = filter_source_builds(list(last_per_distroseries.values()))
525 binary_builds[recipe.name] = find_binary_builds(recipe, sp_success)
526 all_binary_builds_ok[recipe.name] = {}
527- for distroseries, recipe_binary_builds in binary_builds[recipe.name].iteritems():
528+ for distroseries, recipe_binary_builds in binary_builds[recipe.name].items():
529 all_binary_builds_ok[recipe.name][distroseries] = all(
530 [bb.buildstate == "Successfully built" for bb in recipe_binary_builds])
531 relevant_distroseries = list(relevant_distroseries)
532@@ -201,7 +201,7 @@
533 for recipe in recipes:
534 last_per_distroseries = gather_per_distroseries_source_builds(recipe)
535 (sp_success, sp_failures) = filter_source_builds(
536- last_per_distroseries.values())
537+ list(last_per_distroseries.values()))
538 sp_success_distroseries = [build.distro_series.name for build in sp_success]
539 if sp_failures:
540 outf.write("%s source build failures (%s successful):\n" % (
541
542=== modified file 'bin/lp-remove-team-members'
543--- bin/lp-remove-team-members 2011-02-03 06:40:04 +0000
544+++ bin/lp-remove-team-members 2022-11-17 00:45:19 +0000
545@@ -1,4 +1,4 @@
546-#!/usr/bin/python
547+#!/usr/bin/python3
548 #
549 # Copyright 2011 Canonical Ltd.
550 #
551@@ -28,21 +28,21 @@
552
553 def main(args):
554 if len(args) < 3:
555- print __doc__
556+ print(__doc__)
557 return 1
558 lp = get_launchpad('lptools on %s' % (socket.gethostname(),))
559 team_name = args[1]
560 team = lp.people[team_name]
561 members_details = team.members_details
562 for exile_name in args[2:]:
563- print 'remove %s from %s...' % (exile_name, team_name),
564+ print('remove %s from %s...' % (exile_name, team_name), end=' ')
565 for m in members_details:
566 if m.member.name == exile_name:
567 m.setStatus(status='Deactivated')
568- print 'done'
569+ print('done')
570 break
571 else:
572- print 'not a member?'
573+ print('not a member?')
574
575
576 if __name__ == '__main__':
577
578=== modified file 'bin/lp-review-list'
579--- bin/lp-review-list 2011-09-01 20:45:14 +0000
580+++ bin/lp-review-list 2022-11-17 00:45:19 +0000
581@@ -1,4 +1,4 @@
582-#!/usr/bin/python
583+#!/usr/bin/python3
584 #
585 # Author: Rodney Dawes <rodney.dawes@canonical.com>
586 #
587@@ -16,7 +16,7 @@
588 # You should have received a copy of the GNU General Public License along
589 # with this program. If not, see <http://www.gnu.org/licenses/>.
590
591-from __future__ import with_statement
592+
593 import re
594 import subprocess
595 from threading import Thread
596@@ -87,7 +87,7 @@
597
598 self.me = self.launchpad.me
599
600- print "Allo, %s" % self.me.name
601+ print("Allo, %s" % self.me.name)
602 gtk.gdk.threads_enter()
603 self.__refresh(None)
604 gtk.gdk.threads_leave()
605@@ -114,18 +114,18 @@
606
607 def __load_merges(self):
608 merges = []
609- mine = self.me.getRequestedReviews(status=[u'Needs review'])
610+ mine = self.me.getRequestedReviews(status=['Needs review'])
611 for merge in mine:
612 merges.append(merge)
613
614 for team in self.me.super_teams:
615- for merge in team.getRequestedReviews(status=[u'Needs review']):
616+ for merge in team.getRequestedReviews(status=['Needs review']):
617 if merge not in merges:
618 merges.append(merge)
619
620 for merge in merges:
621 votes = {}
622- for key in VOTES.keys():
623+ for key in list(VOTES.keys()):
624 votes[key] = 0
625
626 for vote in merge.votes:
627@@ -134,14 +134,14 @@
628 else:
629 votes[vote.comment.vote] += 1
630
631- for key in votes.keys():
632+ for key in list(votes.keys()):
633 if votes[key] == 0:
634 votes.pop(key, None)
635
636 vstr = ", ".join(
637 ["<span color='%s'>%s</span>: %d" \
638 % (VOTES[key], key, votes[key]) \
639- for key in votes.keys()]
640+ for key in list(votes.keys())]
641 )
642 if vstr == "":
643 vstr = "No Reviews"
644
645=== modified file 'bin/lp-review-notifier'
646--- bin/lp-review-notifier 2011-09-01 20:45:14 +0000
647+++ bin/lp-review-notifier 2022-11-17 00:45:19 +0000
648@@ -1,4 +1,4 @@
649-#!/usr/bin/python
650+#!/usr/bin/python3
651 #
652 # Author: Rodney Dawes <rodney.dawes@canonical.com>
653 #
654@@ -16,7 +16,7 @@
655 # You should have received a copy of the GNU General Public License along
656 # with this program. If not, see <http://www.gnu.org/licenses/>.
657
658-from __future__ import with_statement
659+
660 import os
661 import sys
662
663@@ -25,7 +25,7 @@
664 import pygtk
665 import pynotify
666
667-from ConfigParser import ConfigParser
668+from configparser import ConfigParser
669 import subprocess
670
671 from xdg.BaseDirectory import (
672@@ -182,7 +182,7 @@
673 self.config = Preferences()
674
675 if len(self.config.projects) == 0:
676- print "No Projects specified"
677+ print("No Projects specified")
678 sys.exit(1)
679
680 for project in self.config.projects:
681@@ -209,14 +209,14 @@
682 lp_project = self.launchpad.projects[project]
683 focus = lp_project.development_focus.branch
684 except AttributeError:
685- print "Project %s has no development focus." % project
686+ print("Project %s has no development focus." % project)
687 return False
688 except KeyError:
689- print "Project %s not found." % project
690+ print("Project %s not found." % project)
691 return False
692
693 if not focus:
694- print "Project %s has no development focus." % project
695+ print("Project %s has no development focus." % project)
696 return False
697
698 trunk = focus
699@@ -280,7 +280,7 @@
700 ICON_NAME)
701 updated = True
702 else:
703- print "%s status is %s." % (source, c.queue_status)
704+ print("%s status is %s." % (source, c.queue_status))
705
706 if updated:
707 n.set_urgency(pynotify.URGENCY_LOW)
708
709=== modified file 'bin/lp-set-dup'
710--- bin/lp-set-dup 2011-09-01 20:45:14 +0000
711+++ bin/lp-set-dup 2022-11-17 00:45:19 +0000
712@@ -1,4 +1,4 @@
713-#!/usr/bin/python
714+#!/usr/bin/python3
715 # -*- coding: UTF-8 -*-
716 """Sets the "duplicate of" bug of a bug and its dups."""
717
718@@ -30,7 +30,7 @@
719 from lptools import config
720
721 def die(message):
722- print >> sys.stderr, "Fatal: " + message
723+ print("Fatal: " + message, file=sys.stderr)
724 sys.exit(1)
725
726 def main():
727@@ -57,10 +57,10 @@
728 # check that the new main bug isn't a duplicate
729 try:
730 new_main_bug = launchpad.bugs[args[0]]
731- except HTTPError, error:
732+ except HTTPError as error:
733 if error.response.status == 401:
734- print >> sys.stderr, ("E: Don't have enough permissions to access "
735- "bug %s") % (args[0])
736+ print(("E: Don't have enough permissions to access "
737+ "bug %s") % (args[0]), file=sys.stderr)
738 die(error.content)
739 else:
740 raise
741@@ -68,7 +68,7 @@
742 if new_main_dup_of is not None:
743 answer = None
744 try:
745- answer = raw_input("Bug %s is a duplicate of %s; would you like to "
746+ answer = input("Bug %s is a duplicate of %s; would you like to "
747 "use %s as the new main bug instead? [y/N]" % \
748 (new_main_bug.id, new_main_dup_of.id,
749 new_main_dup_of.id))
750@@ -81,38 +81,38 @@
751 # build list of bugs to process, first the dups then the bug
752 bugs_to_process = []
753 for bug_number in args[1:]:
754- print "Processing %s" % (bug_number)
755+ print("Processing %s" % (bug_number))
756 try:
757 bug = launchpad.bugs[bug_number]
758- except HTTPError, error:
759+ except HTTPError as error:
760 if error.response.status == 401:
761- print >> sys.stderr, ("W: Don't have enough permissions to "
762- "access bug %s") % (bug_number)
763- print >> sys.stderr, "W: %s" % (error.content)
764+ print(("W: Don't have enough permissions to "
765+ "access bug %s") % (bug_number), file=sys.stderr)
766+ print("W: %s" % (error.content), file=sys.stderr)
767 continue
768 else:
769 raise
770 dups = bug.duplicates
771 if dups is not None:
772 bugs_to_process.extend(dups)
773- print "Found %i dups for %s" % (len(dups), bug_number)
774+ print("Found %i dups for %s" % (len(dups), bug_number))
775 bugs_to_process.append(bug)
776
777 # process dups first, then their main bug
778- print "Would set the following bugs as duplicates of %s: %s" % \
779- (new_main_bug.id, " ".join([str(b.id) for b in bugs_to_process]))
780+ print("Would set the following bugs as duplicates of %s: %s" % \
781+ (new_main_bug.id, " ".join([str(b.id) for b in bugs_to_process])))
782
783 if not options.force:
784 answer = None
785 try:
786- answer = raw_input("Proceed? [y/N]")
787+ answer = input("Proceed? [y/N]")
788 except:
789 die("Aborted")
790 if answer.lower() not in ("y", "yes"):
791 die("User aborted")
792
793 for bug in bugs_to_process:
794- print "Marking bug %s as a duplicate of %s" % (bug.id, new_main_bug.id)
795+ print("Marking bug %s as a duplicate of %s" % (bug.id, new_main_bug.id))
796 bug.duplicate_of = new_main_bug
797 bug.lp_save()
798
799
800=== modified file 'bin/lp-shell'
801--- bin/lp-shell 2011-11-03 12:41:49 +0000
802+++ bin/lp-shell 2022-11-17 00:45:19 +0000
803@@ -1,4 +1,4 @@
804-#!/usr/bin/python
805+#!/usr/bin/python3
806
807 # Open an interactive launchpadlib Python shell.
808 # It supports all known LP service instances and API versions. The login
809@@ -52,16 +52,16 @@
810 if len(args) >= 1:
811 try:
812 instance = lookup_service_root(args[0])
813- except ValueError, err:
814- print 'E: %s' % (err)
815- print 'I: Falling back to "production".'
816+ except ValueError as err:
817+ print('E: %s' % (err))
818+ print('I: Falling back to "production".')
819
820 if len(args) >= 2:
821 if args[1] in valid_api_versions:
822 api_version = args[1]
823 else:
824- print 'E: "%s" is not a valid LP API version.' % (args[1])
825- print 'I: Falling back to "1.0".'
826+ print('E: "%s" is not a valid LP API version.' % (args[1]))
827+ print('I: Falling back to "1.0".')
828
829 if options.anonymous:
830 launchpad = Launchpad.login_anonymously('lp-shell', instance,
831@@ -94,7 +94,7 @@
832 sh.set_banner(sh.IP.BANNER + '\n' + banner)
833 sh.excepthook = sys.__excepthook__
834 except ImportError:
835- print "E: ipython not available. Using normal python shell."
836+ print("E: ipython not available. Using normal python shell.")
837
838 if sh:
839 sh()
840@@ -106,7 +106,7 @@
841 try:
842 import readline
843 except ImportError:
844- print 'I: readline module not available.'
845+ print('I: readline module not available.')
846 else:
847 import rlcompleter
848 readline.parse_and_bind("tab: complete")
849
850=== modified file 'lptools/config.py'
851--- lptools/config.py 2011-11-03 12:46:59 +0000
852+++ lptools/config.py 2022-11-17 00:45:19 +0000
853@@ -14,7 +14,7 @@
854 # You should have received a copy of the GNU General Public License along
855 # with this program. If not, see <http://www.gnu.org/licenses/>.
856
857-from __future__ import with_statement
858+
859
860 """Configuration glue for lptools."""
861
862
863=== modified file 'setup.py'
864--- setup.py 2012-09-26 13:33:07 +0000
865+++ setup.py 2022-11-17 00:45:19 +0000
866@@ -1,10 +1,11 @@
867-#!/usr/bin/python
868+#!/usr/bin/python3
869
870 from glob import glob
871 from distutils.core import setup
872 import os.path
873
874-description = file(os.path.join(os.path.dirname(__file__), 'README'), 'rb').read()
875+with open(os.path.join(os.path.dirname(__file__), 'README'), 'r') as f:
876+ description = f.read()
877
878 setup(
879 name='lptools',
880@@ -20,7 +21,7 @@
881 'templates/recipe-status.html'])],
882 packages=['lptools'],
883 scripts=glob('bin/*'),
884- classifiers = [
885+ classifiers=[
886 'Development Status :: 4 - Beta',
887 'Intended Audience :: Developers',
888 'License :: OSI Approved :: GNU General Public License v3 (GPL3)'

Subscribers

People subscribed via source and target branches