Merge lp:~cjwatson/ubuntu-archive-publishing/python3 into lp:ubuntu-archive-publishing

Proposed by Colin Watson
Status: Merged
Merged at revision: 125
Proposed branch: lp:~cjwatson/ubuntu-archive-publishing/python3
Merge into: lp:ubuntu-archive-publishing
Diff against target: 531 lines (+56/-84)
13 files modified
lib/scripts/base.py (+1/-2)
lib/scripts/generate_extra_overrides.py (+5/-8)
lib/scripts/get_supported_series.py (+1/-3)
scripts/generate-extra-overrides.py (+1/-1)
scripts/get-supported-series.py (+1/-1)
scripts/maintenance-check.py (+18/-15)
tests/germinate-test-data/mock-scripts/generate-extra-overrides.py (+1/-1)
tests/germinate-test-data/mock-scripts/get-supported-series.py (+1/-3)
tests/run (+1/-1)
tests/test_cron_germinate.py (+3/-5)
tests/test_generate_extra_overrides.py (+12/-18)
tests/test_get_supported_series.py (+5/-10)
tests/testing.py (+6/-16)
To merge this branch: bzr merge lp:~cjwatson/ubuntu-archive-publishing/python3
Reviewer Review Type Date Requested Status
Steve Langasek Approve
Dimitri John Ledkov (community) lgtm Approve
Review via email: mp+454205@code.launchpad.net

Commit message

Port to Python 3.

Description of the change

There's one test failure, but it's pre-existing (I think it's due to the test suite not setting up its test input for apt correctly).

To post a comment you must log in.
Revision history for this message
Dimitri John Ledkov (xnox) wrote :

however i am not an archive admin

review: Approve (lgtm)
Revision history for this message
Steve Langasek (vorlon) wrote :

LGTM; nothing I'm going to catch here that a testsuite wouldn't.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/scripts/base.py'
2--- lib/scripts/base.py 2014-06-27 13:47:52 +0000
3+++ lib/scripts/base.py 2023-10-21 21:40:06 +0000
4@@ -3,7 +3,6 @@
5
6 """Basic script utilities."""
7
8-__metaclass__ = type
9 __all__ = [
10 'ScriptBase',
11 'ScriptFailure',
12@@ -132,7 +131,7 @@
13 try:
14 fcntl.flock(self.fdlock, fcntl.LOCK_EX | fcntl.LOCK_NB)
15 except IOError as message:
16- match = re.search("^\[Errno ([0-9]+)\]", str(message))
17+ match = re.search(r"^\[Errno ([0-9]+)\]", str(message))
18 if match:
19 if int(match.group(1)) == errno.EWOULDBLOCK:
20 self.logger.info('Lockfile %s in use' % self.lockfilepath)
21
22=== modified file 'lib/scripts/generate_extra_overrides.py'
23--- lib/scripts/generate_extra_overrides.py 2021-05-13 11:35:02 +0000
24+++ lib/scripts/generate_extra_overrides.py 2023-10-21 21:40:06 +0000
25@@ -1,13 +1,10 @@
26-#! /usr/bin/python
27+#! /usr/bin/python3
28 #
29 # Copyright 2011-2014 Canonical Ltd. This software is licensed under the
30 # GNU Affero General Public License version 3 (see the file LICENSE).
31
32 """Generate extra overrides using Germinate."""
33
34-from __future__ import print_function
35-
36-__metaclass__ = type
37 __all__ = [
38 'GenerateExtraOverrides',
39 ]
40@@ -15,12 +12,12 @@
41 import copy
42 from functools import partial
43 import glob
44+from io import StringIO
45 import logging
46 from optparse import OptionValueError
47 import os
48 import pickle
49 import re
50-from StringIO import StringIO
51 import traceback
52
53 from germinate.archive import TagFile
54@@ -62,7 +59,7 @@
55 """A log handler which stores records for emission by another logger."""
56
57 def __init__(self):
58- super(BufferHandler, self).__init__()
59+ super().__init__()
60 self.records = []
61
62 def emit(self, record):
63@@ -92,7 +89,7 @@
64 _log_unhandled_exceptions_level = 0
65
66 def __init__(self, *args, **kwargs):
67- super(GenerateExtraOverrides, self).__init__(*args, **kwargs)
68+ super().__init__(*args, **kwargs)
69 self.germinate_logger = None
70
71 def add_my_options(self):
72@@ -389,7 +386,7 @@
73 with os.fdopen(wfd, "wb") as writer:
74 pickle.dump(self.germinateArch(*args), writer, -1)
75 return 0
76- except:
77+ except Exception:
78 traceback.print_exc()
79 return 1
80
81
82=== modified file 'lib/scripts/get_supported_series.py'
83--- lib/scripts/get_supported_series.py 2014-06-27 13:22:50 +0000
84+++ lib/scripts/get_supported_series.py 2023-10-21 21:40:06 +0000
85@@ -1,12 +1,10 @@
86-#! /usr/bin/python
87+#! /usr/bin/python3
88 #
89 # Copyright 2014 Canonical Ltd. This software is licensed under the
90 # GNU Affero General Public License version 3 (see the file LICENSE).
91
92 """Get supported suites from Launchpad."""
93
94-from __future__ import print_function
95-
96 from optparse import OptionValueError
97
98 from scripts.base import (
99
100=== modified file 'scripts/generate-extra-overrides.py'
101--- scripts/generate-extra-overrides.py 2014-06-09 08:58:59 +0000
102+++ scripts/generate-extra-overrides.py 2023-10-21 21:40:06 +0000
103@@ -1,4 +1,4 @@
104-#!/usr/bin/python
105+#!/usr/bin/python3
106 #
107 # Copyright 2011-2014 Canonical Ltd. This software is licensed under the
108 # GNU Affero General Public License version 3 (see the file LICENSE).
109
110=== modified file 'scripts/get-supported-series.py'
111--- scripts/get-supported-series.py 2014-06-27 13:07:05 +0000
112+++ scripts/get-supported-series.py 2023-10-21 21:40:06 +0000
113@@ -1,4 +1,4 @@
114-#!/usr/bin/python
115+#!/usr/bin/python3
116 #
117 # Copyright 2014 Canonical Ltd. This software is licensed under the
118 # GNU Affero General Public License version 3 (see the file LICENSE).
119
120=== modified file 'scripts/maintenance-check.py'
121--- scripts/maintenance-check.py 2022-07-05 09:33:22 +0000
122+++ scripts/maintenance-check.py 2023-10-21 21:40:06 +0000
123@@ -1,15 +1,14 @@
124-#!/usr/bin/python
125+#!/usr/bin/python3
126 #
127 # python port of the nice maintenance-check script by Nick Barcet
128
129-from __future__ import print_function
130-
131 import logging
132 from optparse import OptionParser
133 import os
134 import sys
135-import urllib2
136-import urlparse
137+from urllib.error import HTTPError
138+from urllib.parse import urlsplit
139+from urllib.request import urlopen
140
141 import apt
142 import apt_pkg
143@@ -376,10 +375,10 @@
144 :param version: Code name of the distribution version (e.g. lucid).
145 :return: List of strings with the structure file content
146 """
147- f = urllib2.urlopen(
148+ f = urlopen(
149 "%s/%s.%s/structure" % (BASE_URL, distroname, version),
150 timeout=SEED_TIMEOUT)
151- structure = f.readlines()
152+ structure = [line.decode() for line in f.readlines()]
153 f.close()
154 return structure
155
156@@ -413,8 +412,9 @@
157 seedurl = "%s/%s.%s/%s" % (BASE_URL, name, distro, seed)
158 logging.debug("looking for '%s'", seedurl)
159 try:
160- f = urllib2.urlopen(seedurl, timeout=SEED_TIMEOUT)
161+ f = urlopen(seedurl, timeout=SEED_TIMEOUT)
162 for line in f:
163+ line = line.decode()
164 # Ignore lines that are not package names (headers etc).
165 if line[0] < 'a' or line[0] > 'z':
166 continue
167@@ -460,6 +460,10 @@
168 return int(x[0:-1])
169 else:
170 raise ValueError("support time '%s' has to end with y or m" % x)
171+
172+ def cmp(x, y):
173+ return (x > y) - (x < y)
174+
175 return cmp(support_to_int(x), support_to_int(y))
176
177
178@@ -529,8 +533,7 @@
179
180 if options.hints_file:
181 hints_file = options.hints_file
182- (schema, netloc, path, query, fragment) = urlparse.urlsplit(
183- hints_file)
184+ (schema, netloc, path, query, fragment) = urlsplit(hints_file)
185 if not schema:
186 hints_file = "file:%s" % path
187 else:
188@@ -546,7 +549,7 @@
189 # get basic structure file
190 try:
191 structure = get_structure(name, distro)
192- except urllib2.HTTPError:
193+ except HTTPError:
194 logging.error("Can not get structure for '%s'." % name)
195 continue
196
197@@ -579,8 +582,8 @@
198 # now check the hints file that is used to overwrite
199 # the default seeds
200 try:
201- for line in urllib2.urlopen(hints_file, timeout=SEED_TIMEOUT):
202- line = line.strip()
203+ for line in urlopen(hints_file, timeout=SEED_TIMEOUT):
204+ line = line.decode().strip()
205 if not line or line.startswith("#"):
206 continue
207 try:
208@@ -600,9 +603,9 @@
209 pkgname, pkg_support_time.get(pkgname),
210 support_time))
211 pkg_support_time[pkgname] = support_time
212- except:
213+ except Exception:
214 logging.exception("can not parse line '%s'" % line)
215- except urllib2.HTTPError as e:
216+ except HTTPError as e:
217 if e.code != 404:
218 raise
219 sys.stderr.write("hints-file: %s gave 404 error\n" % hints_file)
220
221=== modified file 'tests/germinate-test-data/mock-scripts/generate-extra-overrides.py'
222--- tests/germinate-test-data/mock-scripts/generate-extra-overrides.py 2014-06-09 08:58:59 +0000
223+++ tests/germinate-test-data/mock-scripts/generate-extra-overrides.py 2023-10-21 21:40:06 +0000
224@@ -1,4 +1,4 @@
225-#! /usr/bin/python
226+#! /usr/bin/python3
227 #
228 # We don't need to run generate-extra-overrides.py when testing
229 # maintenance-check.py. We could, but it would slow down the tests and its
230
231=== modified file 'tests/germinate-test-data/mock-scripts/get-supported-series.py'
232--- tests/germinate-test-data/mock-scripts/get-supported-series.py 2014-06-30 01:11:46 +0000
233+++ tests/germinate-test-data/mock-scripts/get-supported-series.py 2023-10-21 21:40:06 +0000
234@@ -1,11 +1,9 @@
235-#!/usr/bin/python
236+#!/usr/bin/python3
237 #
238 # This is a mock version of the get-supported-series.py script that
239 # returns static data so that the cron.germinate shell script
240 # can be tested.
241
242-from __future__ import print_function
243-
244 from optparse import OptionParser
245 import sys
246
247
248=== modified file 'tests/run'
249--- tests/run 2014-06-09 08:58:59 +0000
250+++ tests/run 2023-10-21 21:40:06 +0000
251@@ -5,4 +5,4 @@
252 set -- discover
253 fi
254
255-PYTHONPATH="$(readlink -f "$(dirname "$0")/../lib")" python -m unittest "$@"
256+PYTHONPATH="$(readlink -f "$(dirname "$0")/../lib")" python3 -m unittest "$@"
257
258=== modified file 'tests/test_cron_germinate.py'
259--- tests/test_cron_germinate.py 2014-07-22 11:02:31 +0000
260+++ tests/test_cron_germinate.py 2023-10-21 21:40:06 +0000
261@@ -3,8 +3,6 @@
262
263 """This is a test for the cron.germinate script."""
264
265-__metaclass__ = type
266-
267 import copy
268 import gzip
269 import os
270@@ -24,7 +22,7 @@
271 source_root = os.path.normpath(os.path.join(BASEPATH, ".."))
272
273 def setUp(self):
274- super(TestCronGerminate, self).setUp()
275+ super().setUp()
276
277 # Setup a temp archive directory and populate it with the right
278 # sub-directories.
279@@ -62,8 +60,8 @@
280
281 If no content is given a empty file is created.
282 """
283- with gzip.GzipFile(filepath, "w") as gz:
284- gz.write(content)
285+ with gzip.GzipFile(filepath, "wb") as gz:
286+ gz.write(content.encode())
287
288 def create_file(self, filepath, content=""):
289 """Create a file in the given path with the given content.
290
291=== modified file 'tests/test_generate_extra_overrides.py'
292--- tests/test_generate_extra_overrides.py 2021-05-13 11:35:02 +0000
293+++ tests/test_generate_extra_overrides.py 2023-10-21 21:40:06 +0000
294@@ -3,20 +3,13 @@
295
296 """Test for the `generate-extra-overrides` script."""
297
298-from __future__ import print_function
299-
300-__metaclass__ = type
301-
302 from collections import defaultdict
303 from functools import partial
304 import gzip
305 import logging
306 from optparse import OptionValueError
307 import os
308-try:
309- from unittest import mock
310-except ImportError:
311- import mock
312+from unittest import mock
313
314 from germinate import (
315 archive,
316@@ -120,12 +113,12 @@
317 """
318
319 def __init__(self, sourcepackagename=None):
320- super(MockSourcePackagePublishingHistory, self).__init__()
321+ super().__init__()
322 if sourcepackagename is None:
323 sourcepackagename = factory.getUniqueString()
324 self.sourcepackagename = sourcepackagename
325 self.binaries = []
326- self.version = unicode(factory.getUniqueInteger()) + "version"
327+ self.version = str(factory.getUniqueInteger()) + "version"
328 self.section = factory.getUniqueString(prefix="section")
329 self.dsc_maintainer_rfc822 = "%s <%s>" % (
330 factory.getUniqueString(), factory.getUniqueEmailAddress())
331@@ -156,7 +149,7 @@
332 """
333
334 def __init__(self, spph, das, binarypackagename=None, depends=None):
335- super(MockBinaryPackagePublishingHistory, self).__init__()
336+ super().__init__()
337 if binarypackagename is None:
338 binarypackagename = factory.getUniqueString()
339 self.spph = spph
340@@ -180,7 +173,7 @@
341
342 class MockDistroArchSeries(mock.MagicMock):
343 def __init__(self, distroseries, architecture_tag=None):
344- super(MockDistroArchSeries, self).__init__()
345+ super().__init__()
346 if architecture_tag is None:
347 architecture_tag = factory.getUniqueString(prefix="arch")
348 self.distroseries = distroseries
349@@ -190,7 +183,7 @@
350
351 class MockDistroSeries(mock.MagicMock):
352 def __init__(self, distribution, status="Active Development"):
353- super(MockDistroSeries, self).__init__()
354+ super().__init__()
355 self.name = factory.getUniqueString(prefix="distroseries")
356 self.distribution = distribution
357 self.component_names = []
358@@ -207,7 +200,7 @@
359
360 class MockDistribution(mock.MagicMock):
361 def __init__(self, name):
362- super(MockDistribution, self).__init__()
363+ super().__init__()
364 self.name = name
365 self.series = []
366
367@@ -219,7 +212,7 @@
368
369 class MockLaunchpad(mock.MagicMock):
370 def __init__(self):
371- super(MockLaunchpad, self).__init__(name="Launchpad")
372+ super().__init__(name="Launchpad")
373 self.distributions = {}
374
375 def makeDistribution(self, name=None):
376@@ -234,7 +227,7 @@
377 """Tests for the actual `GenerateExtraOverrides` script."""
378
379 def setUp(self):
380- super(TestGenerateExtraOverrides, self).setUp()
381+ super().setUp()
382 self.seeddir = self.makeTemporaryDirectory()
383 self.launchpad = MockLaunchpad()
384 # XXX cjwatson 2011-12-06 bug=694140: Make sure germinate doesn't
385@@ -272,6 +265,7 @@
386 script.login = lambda: self.launchpad
387 if distribution is not None and run_setup:
388 script.setUp()
389+ self.addCleanup(script.log_handler.close)
390 else:
391 script.distribution = distribution
392 return script
393@@ -314,7 +308,7 @@
394 ensure_directory_exists(os.path.dirname(sources_path))
395 sources_index = gzip.GzipFile(sources_path, "wb")
396 for spp in distroseries.test_sources[component]:
397- stanza = spp.getIndexStanza().encode("utf-8") + "\n\n"
398+ stanza = spp.getIndexStanza().encode("utf-8") + b"\n\n"
399 sources_index.write(stanza)
400 sources_index.close()
401
402@@ -325,7 +319,7 @@
403 ensure_directory_exists(os.path.dirname(packages_path))
404 packages_index = gzip.GzipFile(packages_path, "wb")
405 for bpp in arch.test_binaries[component]:
406- stanza = bpp.getIndexStanza().encode("utf-8") + "\n\n"
407+ stanza = bpp.getIndexStanza().encode("utf-8") + b"\n\n"
408 packages_index.write(stanza)
409 packages_index.close()
410
411
412=== modified file 'tests/test_get_supported_series.py'
413--- tests/test_get_supported_series.py 2014-06-27 13:23:03 +0000
414+++ tests/test_get_supported_series.py 2023-10-21 21:40:06 +0000
415@@ -3,14 +3,9 @@
416
417 """Test for the `get-supported-series` script."""
418
419-__metaclass__ = type
420-
421 import logging
422 from optparse import OptionValueError
423-try:
424- from unittest import mock
425-except ImportError:
426- import mock
427+from unittest import mock
428
429 from scripts.base import ScriptFailure
430 from scripts.get_supported_series import GetSupportedSeries
431@@ -23,7 +18,7 @@
432
433 class MockDistroSeries(mock.MagicMock):
434 def __init__(self, distribution, name=None, status="Active Development"):
435- super(MockDistroSeries, self).__init__()
436+ super().__init__()
437 if name is None:
438 name = factory.getUniqueString(prefix="distroseries")
439 self.name = name
440@@ -33,7 +28,7 @@
441
442 class MockDistribution(mock.MagicMock):
443 def __init__(self, name):
444- super(MockDistribution, self).__init__()
445+ super().__init__()
446 self.name = name
447 self.series = []
448
449@@ -45,7 +40,7 @@
450
451 class MockLaunchpad(mock.MagicMock):
452 def __init__(self):
453- super(MockLaunchpad, self).__init__(name="Launchpad")
454+ super().__init__(name="Launchpad")
455 self.distributions = {}
456
457 def makeDistribution(self, name=None):
458@@ -60,7 +55,7 @@
459 """Tests for the `GetSupportedSeries` script."""
460
461 def setUp(self):
462- super(TestGetSupportedSeries, self).setUp()
463+ super().setUp()
464 self.launchpad = MockLaunchpad()
465
466 def makeScript(self, distribution, extra_args=None):
467
468=== modified file 'tests/testing.py'
469--- tests/testing.py 2014-06-30 01:18:10 +0000
470+++ tests/testing.py 2023-10-21 21:40:06 +0000
471@@ -6,8 +6,6 @@
472 Many of these are taken more or less directly from Launchpad.
473 """
474
475-__metaclass__ = type
476-
477 __all__ = [
478 "ensure_directory_exists",
479 "factory",
480@@ -18,7 +16,6 @@
481 "write_file",
482 ]
483
484-import errno
485 from itertools import count
486 import logging
487 import os
488@@ -36,10 +33,8 @@
489 """
490 try:
491 os.makedirs(directory, mode=mode)
492- except OSError as e:
493- if e.errno == errno.EEXIST:
494- return False
495- raise
496+ except FileExistsError:
497+ return False
498 return True
499
500
501@@ -56,10 +51,9 @@
502 """
503 try:
504 return open(filename, mode)
505- except IOError as e:
506- if e.errno == errno.ENOENT:
507- os.makedirs(os.path.dirname(filename), mode=dirmode)
508- return open(filename, mode)
509+ except FileNotFoundError:
510+ os.makedirs(os.path.dirname(filename), mode=dirmode)
511+ return open(filename, mode)
512
513
514 def write_file(path, content):
515@@ -115,7 +109,7 @@
516 class TestCase(unittest.TestCase):
517
518 def setUp(self):
519- super(TestCase, self).setUp()
520+ super().setUp()
521 self.save_env = dict(os.environ)
522
523 def makeTemporaryDirectory(self):
524@@ -169,7 +163,3 @@
525 def tearDown(self):
526 self.resetEnvironment()
527 self.resetLogging()
528-
529- # Monkey-patch for Python 2/3 compatibility.
530- if not hasattr(unittest.TestCase, 'assertCountEqual'):
531- assertCountEqual = unittest.TestCase.assertItemsEqual

Subscribers

People subscribed via source and target branches