Merge lp:~cjwatson/ubuntu-archive-publishing/python3 into lp:ubuntu-archive-publishing
- python3
- Merge into trunk
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 |
Related bugs: |
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
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 |
however i am not an archive admin