Merge lp:~cjwatson/launchpad/new-python-apt into lp:launchpad

Proposed by Colin Watson on 2011-12-14
Status: Merged
Merged at revision: 14618
Proposed branch: lp:~cjwatson/launchpad/new-python-apt
Merge into: lp:launchpad
Diff against target: 929 lines (+154/-170)
21 files modified
cronscripts/publishing/maintenance-check.py (+7/-7)
lib/lp/archivepublisher/domination.py (+2/-2)
lib/lp/archivepublisher/tests/test_dominator.py (+2/-2)
lib/lp/archiveuploader/dscfile.py (+1/-1)
lib/lp/archiveuploader/nascentupload.py (+1/-1)
lib/lp/archiveuploader/nascentuploadfile.py (+41/-58)
lib/lp/archiveuploader/tagfiles.py (+1/-1)
lib/lp/archiveuploader/tests/test_tagfiles.py (+6/-7)
lib/lp/registry/browser/distroseries.py (+1/-1)
lib/lp/registry/browser/sourcepackage.py (+5/-5)
lib/lp/registry/model/distroseries.py (+1/-1)
lib/lp/registry/model/distroseriesdifference.py (+6/-6)
lib/lp/soyuz/browser/binarypackagerelease.py (+2/-2)
lib/lp/soyuz/browser/packagerelationship.py (+6/-1)
lib/lp/soyuz/model/binarypackagebuild.py (+13/-7)
lib/lp/soyuz/model/sourcepackagerelease.py (+2/-2)
lib/lp/soyuz/scripts/gina/archive.py (+9/-9)
lib/lp/soyuz/scripts/packagecopier.py (+2/-2)
lib/lp/soyuz/tests/test_publish_archive_indexes.py (+27/-32)
lib/lp_sitecustomize.py (+0/-4)
scripts/ftpmaster-tools/sync-source.py (+19/-19)
To merge this branch: bzr merge lp:~cjwatson/launchpad/new-python-apt
Reviewer Review Type Date Requested Status
Benji York (community) code 2011-12-14 Approve on 2011-12-19
Review via email: mp+85649@code.launchpad.net

Commit Message

[r=benji][bug=551510] Port to new python-apt API.

Description of the Change

= Summary =

Port Launchpad to the new python-apt API, introduced in lucid. Launchpad currently has to ignore a DeprecationWarning for its use of the old API; this is obviously bad since it might be removed at some point.

== Proposed fix ==

The proposed fix is fairly obvious for the most part; I searched for '(import|from) apt' and ran python-apt's utils/migrate-0.8.py script over them, screened out false positives, and replaced everything that was left with modern forms.

== Implementation details ==

I didn't discuss this with anyone before implementation since it seemed likely to be fairly mechanical. Maybe that was a mistake, since a few things did come up:

 * The new apt_pkg.parse_depends and apt_pkg.parse_src_depends interfaces have a slight difference in how they return strictly-less and strictly-greater dependencies, indicating these by '<' and '>' rather than '<<' and '>>'. Personally I think this is a misdesign in python-apt; if you actually try to use '<' and '>' in control files you get less-or-equal and greater-or-equal semantics respectively due to a very old design error in dpkg, which is why we have '<<' and '>>' in the first place, and it's better not to confuse the situation further by exposing these as '<' and '>'. Thus, I think the right thing to do here is to map these operators back to the versions used in control files. There are only three relevant call sites so this isn't hard.

 * cronscripts/publishing/maintenance-check.py passes deprecated apt.progress.FetchProgress and apt.progress.OpProgress instances to apt.Cache methods. I could have replaced these with modern forms, but it's unnecessary since by lucid python-apt has reasonable defaults for these parameters.

 * The replacements for apt_inst.debExtract* are substantially more OOPy. This necessitated some changes to lib/lp/archiveuploader/nascentuploadfile.py that went a bit beyond search-and-replace. (The new version is more compact and I think more readable, though.)

 * apt_pkg.TagFile objects are iterable. Where appropriate, I made use of this rather than using the 'step' (previously 'Step') method, which is ugly because it mutates the object.

== Tests ==

bin/test -vvct 'archivepublisher|archiveuploader|registry|soyuz'

== Demo and Q/A ==

This is mainly internal rearrangement, and I don't think any particular Q/A is required, although I'm happy to be corrected. The only untested code being modified here is scripts/ftpmaster-tools/sync-source.py, but (a) the changes to that are fairly simple and (b) that's in the process of going away in favour of API syncs anyway.

== lint ==

I cleaned up some pre-existing lint. What's left is:

./cronscripts/publishing/maintenance-check.py
      86: Line exceeds 78 characters.
      86: E501 line too long (84 characters)
./lib/lp/archiveuploader/tests/test_tagfiles.py
     123: Line exceeds 78 characters.
     145: Line exceeds 78 characters.
     123: E501 line too long (83 characters)
     145: E501 line too long (89 characters)

These are long URLs and didn't really seem worth adjusting to satisfy lint. (I hope to rewrite maintenance-check.py soon, anyway ...)

./lib/lp/soyuz/model/sourcepackagerelease.py
     205: redefinition of function 'copyright' from line 196

lint is wrong; this is a setter property.

./scripts/ftpmaster-tools/sync-source.py
      27: '_pythonpath' imported but unused

Usual lint wrongness.

To post a comment you must log in.
Benji York (benji) wrote :

This branch looks good. I concur with the decision to remap ">" and
"<"".

The only issue I found was that I think "ar" in this comment (line 304
of the diff, from nascentuploadfile.py) should be "tar":

    except SystemError, error:
        # We get an error from the constructor if the .deb does not
        # contain all the expected ar members.
        yield UploadError(error)

review: Approve (code)
Colin Watson (cjwatson) wrote :

I think "ar" is correct here. A .deb is an ar archive of three members, two of which are compressed tar archives; but the contents of the inner tar archives aren't checked here. The constructor in question is debDebFile::debDebFile(FileFd &File) in this file:

  http://bazaar.launchpad.net/~ubuntu-core-dev/apt/ubuntu/view/head:/apt-inst/deb/debfile.cc

That might fail, for example, if the "debian-binary" member is missing, which isn't a tar archive.

However, I can see a confusion between "members of the ar archive" and "members which are ar archives" here, so I've rephrased the comment:

             # We get an error from the constructor if the .deb does not
- # contain all the expected ar members.
+ # contain all the expected top-level members (debian-binary,
+ # control.tar.gz, and data.tar.*).

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cronscripts/publishing/maintenance-check.py'
2--- cronscripts/publishing/maintenance-check.py 2011-12-21 07:06:05 +0000
3+++ cronscripts/publishing/maintenance-check.py 2011-12-26 18:09:24 +0000
4@@ -102,9 +102,9 @@
5 :return: A list of binary package names.
6 """
7 pkgnames = set()
8- recs = apt_pkg.GetPkgSrcRecords()
9- while recs.Lookup(srcname):
10- for binary in recs.Binaries:
11+ recs = apt_pkg.SourceRecords()
12+ while recs.lookup(srcname):
13+ for binary in recs.binaries:
14 pkgnames.add(binary)
15 return pkgnames
16
17@@ -163,7 +163,7 @@
18 # open cache with our just prepared rootdir
19 cache = apt.Cache(rootdir=rootdir)
20 try:
21- cache.update(apt.progress.FetchProgress())
22+ cache.update()
23 except SystemError:
24 logging.exception("cache.update() failed")
25
26@@ -348,13 +348,13 @@
27 # they are not in any seed and got added manually into "main"
28 for arch in PRIMARY_ARCHES:
29 rootdir = "./aptroot.%s" % distro
30- apt_pkg.Config.Set("APT::Architecture", arch)
31+ apt_pkg.config.set("APT::Architecture", arch)
32 cache = apt.Cache(rootdir=rootdir)
33 try:
34- cache.update(apt.progress.FetchProgress())
35+ cache.update()
36 except SystemError:
37 logging.exception("cache.update() failed")
38- cache.open(apt.progress.OpProgress())
39+ cache.open()
40 for pkg in cache:
41 if not pkg.name in pkg_support_time:
42 pkg_support_time[pkg.name] = support_timeframe[-1][0]
43
44=== modified file 'lib/lp/archivepublisher/domination.py'
45--- lib/lp/archivepublisher/domination.py 2011-12-22 04:05:21 +0000
46+++ lib/lp/archivepublisher/domination.py 2011-12-26 18:09:24 +0000
47@@ -95,7 +95,7 @@
48
49
50 # Ugly, but works
51-apt_pkg.InitSystem()
52+apt_pkg.init_system()
53
54
55 def join_spph_spn():
56@@ -190,7 +190,7 @@
57 If both publications are for the same version, their creation dates
58 break the tie.
59 """
60- version_comparison = apt_pkg.VersionCompare(
61+ version_comparison = apt_pkg.version_compare(
62 self.getPackageVersion(pub1), self.getPackageVersion(pub2))
63
64 if version_comparison == 0:
65
66=== modified file 'lib/lp/archivepublisher/tests/test_dominator.py'
67--- lib/lp/archivepublisher/tests/test_dominator.py 2011-11-06 13:09:03 +0000
68+++ lib/lp/archivepublisher/tests/test_dominator.py 2011-12-26 18:09:24 +0000
69@@ -493,7 +493,7 @@
70 ]
71 spphs = make_spphs_for_versions(self.factory, versions)
72
73- debian_sorted_versions = sorted(versions, cmp=apt_pkg.VersionCompare)
74+ debian_sorted_versions = sorted(versions, cmp=apt_pkg.version_compare)
75
76 # Assumption: in this case, Debian version ordering is not the
77 # same as alphabetical version ordering.
78@@ -502,7 +502,7 @@
79 # The compare method produces the Debian ordering.
80 sorted_spphs = sorted(spphs, cmp=GeneralizedPublication().compare)
81 self.assertEqual(
82- sorted(versions, cmp=apt_pkg.VersionCompare),
83+ sorted(versions, cmp=apt_pkg.version_compare),
84 list_source_versions(sorted_spphs))
85
86 def test_compare_breaks_tie_with_creation_date(self):
87
88=== modified file 'lib/lp/archiveuploader/dscfile.py'
89--- lib/lp/archiveuploader/dscfile.py 2011-12-21 07:54:40 +0000
90+++ lib/lp/archiveuploader/dscfile.py 2011-12-26 18:09:24 +0000
91@@ -382,7 +382,7 @@
92 "%s: invalid %s field produced by a broken version "
93 "of dpkg-dev (1.10.11)" % (self.filename, field_name))
94 try:
95- apt_pkg.ParseSrcDepends(field)
96+ apt_pkg.parse_src_depends(field)
97 except (SystemExit, KeyboardInterrupt):
98 raise
99 except Exception, error:
100
101=== modified file 'lib/lp/archiveuploader/nascentupload.py'
102--- lib/lp/archiveuploader/nascentupload.py 2011-12-22 05:37:22 +0000
103+++ lib/lp/archiveuploader/nascentupload.py 2011-12-26 18:09:24 +0000
104@@ -655,7 +655,7 @@
105
106 def _checkVersion(self, proposed_version, archive_version, filename):
107 """Check if the proposed version is higher than the one in archive."""
108- if apt_pkg.VersionCompare(proposed_version, archive_version) < 0:
109+ if apt_pkg.version_compare(proposed_version, archive_version) < 0:
110 self.reject("%s: Version older than that in the archive. %s <= %s"
111 % (filename, proposed_version, archive_version))
112
113
114=== modified file 'lib/lp/archiveuploader/nascentuploadfile.py'
115--- lib/lp/archiveuploader/nascentuploadfile.py 2011-12-22 05:37:22 +0000
116+++ lib/lp/archiveuploader/nascentuploadfile.py 2011-12-26 18:09:24 +0000
117@@ -58,7 +58,7 @@
118 from lp.soyuz.model.files import SourceFileMixin
119
120
121-apt_pkg.InitSystem()
122+apt_pkg.init_system()
123
124
125 class UploadError(Exception):
126@@ -86,13 +86,12 @@
127 self.future_files = {}
128 self.ancient_files = {}
129
130- def callback(self, kind, name, link, mode, uid, gid, size, mtime,
131- major, minor):
132- """Callback designed to cope with apt_inst.debExtract.
133+ def callback(self, member, data):
134+ """Callback designed to cope with apt_inst.TarFile.go.
135
136 It check and store timestamp details of the extracted DEB.
137 """
138- self.check_cutoff(name, mtime)
139+ self.check_cutoff(member.name, member.mtime)
140
141 def check_cutoff(self, name, mtime):
142 """Check the timestamp details of the supplied file.
143@@ -529,28 +528,27 @@
144 yield error
145
146 def extractAndParseControl(self):
147- """Extract and parse tcontrol information."""
148- deb_file = open(self.filepath, "r")
149+ """Extract and parse control information."""
150 try:
151- control_file = apt_inst.debExtractControl(deb_file)
152- control_lines = apt_pkg.ParseSection(control_file)
153+ deb_file = apt_inst.DebFile(self.filepath)
154+ control_file = deb_file.control.extractdata("control")
155+ control_lines = apt_pkg.TagSection(control_file)
156 except (SystemExit, KeyboardInterrupt):
157 raise
158 except:
159- deb_file.close()
160 yield UploadError(
161- "%s: debExtractControl() raised %s, giving up."
162+ "%s: extracting control file raised %s, giving up."
163 % (self.filename, sys.exc_type))
164 return
165
166 for mandatory_field in self.mandatory_fields:
167- if control_lines.Find(mandatory_field) is None:
168+ if control_lines.find(mandatory_field) is None:
169 yield UploadError(
170 "%s: control file lacks mandatory field %r"
171 % (self.filename, mandatory_field))
172 control = {}
173 for key in control_lines.keys():
174- control[key] = control_lines.Find(key)
175+ control[key] = control_lines.find(key)
176 self.parseControl(control)
177
178 def parseControl(self, control):
179@@ -718,7 +716,7 @@
180 if data_tar == "data.tar.xz":
181 parsed_deps = []
182 try:
183- parsed_deps = apt_pkg.ParseDepends(
184+ parsed_deps = apt_pkg.parse_depends(
185 self.control['Pre-Depends'])
186 except (ValueError, TypeError):
187 yield UploadError(
188@@ -739,7 +737,7 @@
189 # VersionCompare returns values similar to cmp;
190 # negative if first < second, zero if first ==
191 # second and positive if first > second.
192- if apt_pkg.VersionCompare(
193+ if apt_pkg.version_compare(
194 version, XZ_REQUIRED_DPKG_VER) >= 0:
195 # Pre-Depends dpkg is fine.
196 return
197@@ -765,49 +763,34 @@
198 tar_checker = TarFileDateChecker(future_cutoff, past_cutoff)
199 tar_checker.reset()
200 try:
201- deb_file = open(self.filepath, "rb")
202- apt_inst.debExtract(deb_file, tar_checker.callback,
203- "control.tar.gz")
204- # Only one of these files is present in the archive, so loop
205- # until we find one of them, otherwise fail.
206- data_files = ("data.tar.gz", "data.tar.bz2", "data.tar.lzma",
207- "data.tar.xz")
208- for file in data_files:
209- deb_file.seek(0)
210- try:
211- apt_inst.debExtract(deb_file, tar_checker.callback, file)
212- except SystemError:
213- continue
214- else:
215- deb_file.close()
216-
217- future_files = tar_checker.future_files.keys()
218- if future_files:
219- first_file = future_files[0]
220- timestamp = time.ctime(
221- tar_checker.future_files[first_file])
222- yield UploadError(
223- "%s: has %s file(s) with a time stamp too "
224- "far into the future (e.g. %s [%s])."
225- % (self.filename, len(future_files), first_file,
226- timestamp))
227-
228- ancient_files = tar_checker.ancient_files.keys()
229- if ancient_files:
230- first_file = ancient_files[0]
231- timestamp = time.ctime(
232- tar_checker.ancient_files[first_file])
233- yield UploadError(
234- "%s: has %s file(s) with a time stamp too "
235- "far in the past (e.g. %s [%s])."
236- % (self.filename, len(ancient_files), first_file,
237- timestamp))
238- return
239-
240- deb_file.close()
241- yield UploadError(
242- "Could not find data tarball in %s" % self.filename)
243-
244+ deb_file = apt_inst.DebFile(self.filepath)
245+ except SystemError, error:
246+ # We get an error from the constructor if the .deb does not
247+ # contain all the expected top-level members (debian-binary,
248+ # control.tar.gz, and data.tar.*).
249+ yield UploadError(error)
250+ try:
251+ deb_file.control.go(tar_checker.callback)
252+ deb_file.data.go(tar_checker.callback)
253+ future_files = tar_checker.future_files.keys()
254+ if future_files:
255+ first_file = future_files[0]
256+ timestamp = time.ctime(tar_checker.future_files[first_file])
257+ yield UploadError(
258+ "%s: has %s file(s) with a time stamp too "
259+ "far into the future (e.g. %s [%s])."
260+ % (self.filename, len(future_files), first_file,
261+ timestamp))
262+
263+ ancient_files = tar_checker.ancient_files.keys()
264+ if ancient_files:
265+ first_file = ancient_files[0]
266+ timestamp = time.ctime(tar_checker.ancient_files[first_file])
267+ yield UploadError(
268+ "%s: has %s file(s) with a time stamp too "
269+ "far in the past (e.g. %s [%s])."
270+ % (self.filename, len(ancient_files), first_file,
271+ timestamp))
272 except (SystemExit, KeyboardInterrupt):
273 raise
274 except Exception, error:
275
276=== modified file 'lib/lp/archiveuploader/tagfiles.py'
277--- lib/lp/archiveuploader/tagfiles.py 2011-05-20 07:47:17 +0000
278+++ lib/lp/archiveuploader/tagfiles.py 2011-12-26 18:09:24 +0000
279@@ -35,7 +35,7 @@
280 with tempfile.TemporaryFile() as f:
281 f.write(strip_pgp_signature(content))
282 f.seek(0)
283- stanzas = list(apt_pkg.ParseTagFile(f))
284+ stanzas = list(apt_pkg.TagFile(f))
285 if len(stanzas) != 1:
286 raise TagFileParseError(
287 "%s: multiple stanzas where only one is expected" % filename)
288
289=== modified file 'lib/lp/archiveuploader/tests/test_tagfiles.py'
290--- lib/lp/archiveuploader/tests/test_tagfiles.py 2011-05-22 23:47:25 +0000
291+++ lib/lp/archiveuploader/tests/test_tagfiles.py 2011-12-26 18:09:24 +0000
292@@ -82,8 +82,8 @@
293
294 tagfile_path = datadir("test436182_0.1_source.changes")
295 tagfile = open(tagfile_path)
296- self.apt_pkg_parsed_version = apt_pkg.ParseTagFile(tagfile)
297- self.apt_pkg_parsed_version.Step()
298+ self.apt_pkg_parsed_version = apt_pkg.TagFile(tagfile)
299+ self.apt_pkg_parsed_version.step()
300
301 self.parse_tagfile_version = parse_tagfile(tagfile_path)
302
303@@ -104,7 +104,7 @@
304
305 self.assertEqual(
306 expected_text,
307- self.apt_pkg_parsed_version.Section['Binary'])
308+ self.apt_pkg_parsed_version.section['Binary'])
309
310 self.assertEqual(
311 expected_text,
312@@ -114,8 +114,7 @@
313 """parse_tagfile should not leave leading or tailing '\n' when
314 parsing newline delimited fields.
315
316- Newline-delimited fields should be parsed to match
317- apt_pkg.ParseTageFile.
318+ Newline-delimited fields should be parsed to match apt_pkg.TagFile.
319
320 Note: in the past, our parse_tagfile function left the leading
321 '\n' in the parsed value, whereas it should not have.
322@@ -133,7 +132,7 @@
323
324 self.assertEqual(
325 expected_text,
326- self.apt_pkg_parsed_version.Section['Files'])
327+ self.apt_pkg_parsed_version.section['Files'])
328
329 self.assertEqual(
330 expected_text,
331@@ -158,7 +157,7 @@
332
333 self.assertEqual(
334 expected_text,
335- self.apt_pkg_parsed_version.Section['Description'])
336+ self.apt_pkg_parsed_version.section['Description'])
337
338 # In the past our parse_tagfile function replaced blank-line
339 # indicators in the description (' .\n') with new lines ('\n'),
340
341=== modified file 'lib/lp/registry/browser/distroseries.py'
342--- lib/lp/registry/browser/distroseries.py 2011-12-24 17:49:30 +0000
343+++ lib/lp/registry/browser/distroseries.py 2011-12-26 18:09:24 +0000
344@@ -1081,7 +1081,7 @@
345 # The child doesn't have this package. Treat that as the
346 # parent being newer.
347 return False
348- comparison = apt_pkg.VersionCompare(
349+ comparison = apt_pkg.version_compare(
350 dsd.parent_source_version, dsd.source_version)
351 return comparison < 0
352
353
354=== modified file 'lib/lp/registry/browser/sourcepackage.py'
355--- lib/lp/registry/browser/sourcepackage.py 2011-12-24 17:49:30 +0000
356+++ lib/lp/registry/browser/sourcepackage.py 2011-12-26 18:09:24 +0000
357@@ -22,9 +22,9 @@
358 import urllib
359
360 from apt_pkg import (
361- ParseSrcDepends,
362+ parse_src_depends,
363 upstream_version,
364- VersionCompare,
365+ version_compare,
366 )
367 from lazr.enum import (
368 EnumeratedType,
369@@ -510,11 +510,11 @@
370 def _relationship_parser(self, content):
371 """Wrap the relationship_builder for SourcePackages.
372
373- Define apt_pkg.ParseSrcDep as a relationship 'parser' and
374+ Define apt_pkg.parse_src_depends as a relationship 'parser' and
375 IDistroSeries.getBinaryPackage as 'getter'.
376 """
377 getter = self.context.distroseries.getBinaryPackage
378- parser = ParseSrcDepends
379+ parser = parse_src_depends
380 return relationship_builder(content, parser=parser, getter=getter)
381
382 @property
383@@ -678,7 +678,7 @@
384 # Compare the base version contained in the full debian version
385 # to upstream release's version.
386 base_version = upstream_version(current_release.version)
387- age = VersionCompare(upstream_release.version, base_version)
388+ age = version_compare(upstream_release.version, base_version)
389 if age > 0:
390 return PackageUpstreamTracking.NEWER
391 elif age < 0:
392
393=== modified file 'lib/lp/registry/model/distroseries.py'
394--- lib/lp/registry/model/distroseries.py 2011-12-24 17:49:30 +0000
395+++ lib/lp/registry/model/distroseries.py 2011-12-26 18:09:24 +0000
396@@ -1459,7 +1459,7 @@
397 packagenames)
398 for spph in spphs:
399 latest_release = latest_releases.get(spph.meta_sourcepackage)
400- if latest_release is not None and apt_pkg.VersionCompare(
401+ if latest_release is not None and apt_pkg.version_compare(
402 latest_release.version, spph.source_package_version) > 0:
403 version = latest_release
404 else:
405
406=== modified file 'lib/lp/registry/model/distroseriesdifference.py'
407--- lib/lp/registry/model/distroseriesdifference.py 2011-12-21 14:58:31 +0000
408+++ lib/lp/registry/model/distroseriesdifference.py 2011-12-26 18:09:24 +0000
409@@ -772,7 +772,7 @@
410 new_source_version = new_parent_source_version = None
411 if self.source_pub:
412 new_source_version = self.source_pub.source_package_version
413- if self.source_version is None or apt_pkg.VersionCompare(
414+ if self.source_version is None or apt_pkg.version_compare(
415 self.source_version, new_source_version) != 0:
416 self.source_version = new_source_version
417 updated = True
418@@ -784,7 +784,7 @@
419 if self.parent_source_pub:
420 new_parent_source_version = (
421 self.parent_source_pub.source_package_version)
422- if self.parent_source_version is None or apt_pkg.VersionCompare(
423+ if self.parent_source_version is None or apt_pkg.version_compare(
424 self.parent_source_version,
425 new_parent_source_version) != 0:
426 self.parent_source_version = new_parent_source_version
427@@ -798,13 +798,13 @@
428 # If this difference was resolved but now the versions don't match
429 # then we re-open the difference.
430 if self.status == DistroSeriesDifferenceStatus.RESOLVED:
431- if apt_pkg.VersionCompare(
432+ if apt_pkg.version_compare(
433 self.source_version, self.parent_source_version) < 0:
434 # Higher parent version.
435 updated = True
436 self.status = DistroSeriesDifferenceStatus.NEEDS_ATTENTION
437 elif (
438- apt_pkg.VersionCompare(
439+ apt_pkg.version_compare(
440 self.source_version, self.parent_source_version) > 0
441 and not manual):
442 # The child was updated with a higher version so it's
443@@ -818,12 +818,12 @@
444 elif self.status in (
445 DistroSeriesDifferenceStatus.NEEDS_ATTENTION,
446 DistroSeriesDifferenceStatus.BLACKLISTED_CURRENT):
447- if apt_pkg.VersionCompare(
448+ if apt_pkg.version_compare(
449 self.source_version, self.parent_source_version) == 0:
450 updated = True
451 self.status = DistroSeriesDifferenceStatus.RESOLVED
452 elif (
453- apt_pkg.VersionCompare(
454+ apt_pkg.version_compare(
455 self.source_version, self.parent_source_version) > 0
456 and not manual):
457 # If the derived version is lower than the parent's, we
458
459=== modified file 'lib/lp/soyuz/browser/binarypackagerelease.py'
460--- lib/lp/soyuz/browser/binarypackagerelease.py 2011-12-24 17:49:30 +0000
461+++ lib/lp/soyuz/browser/binarypackagerelease.py 2011-12-26 18:09:24 +0000
462@@ -8,7 +8,7 @@
463 'BinaryPackageView',
464 ]
465
466-from apt_pkg import ParseDepends
467+from apt_pkg import parse_depends
468
469 from lp.services.webapp import Navigation
470 from lp.soyuz.browser.packagerelationship import relationship_builder
471@@ -33,7 +33,7 @@
472 IDistroArchSeries.getBinaryPackage as 'getter'.
473 """
474 getter = self.context.build.distro_arch_series.getBinaryPackage
475- parser = ParseDepends
476+ parser = parse_depends
477 return relationship_builder(content, parser=parser, getter=getter)
478
479 def depends(self):
480
481=== modified file 'lib/lp/soyuz/browser/packagerelationship.py'
482--- lib/lp/soyuz/browser/packagerelationship.py 2011-12-24 17:49:30 +0000
483+++ lib/lp/soyuz/browser/packagerelationship.py 2011-12-26 18:09:24 +0000
484@@ -41,6 +41,12 @@
485 url = canonical_url(target_object)
486 else:
487 url = None
488+ # The apt_pkg 0.8 API returns '<' and '>' rather than the '<<' and
489+ # '>>' form used in control files.
490+ if operator == '<':
491+ operator = '<<'
492+ elif operator == '>':
493+ operator = '>>'
494 relationship_set.add(name, operator, version, url)
495
496 return relationship_set
497@@ -81,4 +87,3 @@
498 def __iter__(self):
499 return iter(sorted(
500 self.contents, key=std_operator.attrgetter('name')))
501-
502
503=== modified file 'lib/lp/soyuz/model/binarypackagebuild.py'
504--- lib/lp/soyuz/model/binarypackagebuild.py 2011-12-24 17:49:30 +0000
505+++ lib/lp/soyuz/model/binarypackagebuild.py 2011-12-26 18:09:24 +0000
506@@ -433,13 +433,18 @@
507 "It is expected to be a tuple containing only another "
508 "tuple with 3 elements (name, version, relation)."
509 % (token, self.title, self.id, self.dependencies))
510+ # Map relations to the canonical form used in control files.
511+ if relation == '<':
512+ relation = '<<'
513+ elif relation == '>':
514+ relation = '>>'
515 return (name, version, relation)
516
517 def _checkDependencyVersion(self, available, required, relation):
518 """Return True if the available version satisfies the context."""
519 # This dict maps the package version relationship syntax in lambda
520 # functions which returns boolean according the results of
521- # apt_pkg.VersionCompare function (see the order above).
522+ # apt_pkg.version_compare function (see the order above).
523 # For further information about pkg relationship syntax see:
524 #
525 # http://www.debian.org/doc/debian-policy/ch-relationships.html
526@@ -447,11 +452,11 @@
527 version_relation_map = {
528 # any version is acceptable if no relationship is given
529 '': lambda x: True,
530- # stricly later
531+ # strictly later
532 '>>': lambda x: x == 1,
533 # later or equal
534 '>=': lambda x: x >= 0,
535- # stricly equal
536+ # strictly equal
537 '=': lambda x: x == 0,
538 # earlier or equal
539 '<=': lambda x: x <= 0,
540@@ -463,7 +468,7 @@
541 # it behaves similar to cmp, i.e. returns negative
542 # if first < second, zero if first == second and
543 # positive if first > second.
544- dep_result = apt_pkg.VersionCompare(available, required)
545+ dep_result = apt_pkg.version_compare(available, required)
546
547 return version_relation_map[relation](dep_result)
548
549@@ -500,12 +505,13 @@
550 def updateDependencies(self):
551 """See `IBuild`."""
552
553- # apt_pkg requires InitSystem to get VersionCompare working properly.
554- apt_pkg.InitSystem()
555+ # apt_pkg requires init_system to get version_compare working
556+ # properly.
557+ apt_pkg.init_system()
558
559 # Check package build dependencies using apt_pkg
560 try:
561- parsed_deps = apt_pkg.ParseDepends(self.dependencies)
562+ parsed_deps = apt_pkg.parse_depends(self.dependencies)
563 except (ValueError, TypeError):
564 raise UnparsableDependencies(
565 "Build dependencies for %s (%s) could not be parsed: '%s'\n"
566
567=== modified file 'lib/lp/soyuz/model/sourcepackagerelease.py'
568--- lib/lp/soyuz/model/sourcepackagerelease.py 2011-12-23 23:44:59 +0000
569+++ lib/lp/soyuz/model/sourcepackagerelease.py 2011-12-26 18:09:24 +0000
570@@ -637,7 +637,7 @@
571 if self.changelog is None:
572 return None
573
574- apt_pkg.InitSystem()
575+ apt_pkg.init_system()
576 chunks = []
577 changelog = self.changelog
578 # The python-debian API for parsing changelogs is pretty awful. The
579@@ -647,7 +647,7 @@
580 for block in Changelog(changelog.read()):
581 version = block._raw_version
582 if (since_version and
583- apt_pkg.VersionCompare(version, since_version) <= 0):
584+ apt_pkg.version_compare(version, since_version) <= 0):
585 break
586 # Poking in private attributes is not nice but again the
587 # API is terrible. We want to ensure that the name/date
588
589=== modified file 'lib/lp/soyuz/scripts/gina/archive.py'
590--- lib/lp/soyuz/scripts/gina/archive.py 2011-12-21 20:23:01 +0000
591+++ lib/lp/soyuz/scripts/gina/archive.py 2011-12-26 18:09:24 +0000
592@@ -199,10 +199,10 @@
593 # because most of them are the same for all architectures,
594 # but we go over it to also cover source packages that only
595 # compile for one architecture.
596- sources = apt_pkg.ParseTagFile(info_set.srcfile)
597- while sources.Step():
598+ sources = apt_pkg.TagFile(info_set.srcfile)
599+ for section in sources:
600 try:
601- src_tmp = dict(sources.Section)
602+ src_tmp = dict(section)
603 src_tmp['Component'] = info_set.component
604 src_name = src_tmp['Package']
605 except KeyError:
606@@ -222,10 +222,10 @@
607
608 tmpbin_map = self.bin_map[info_set.arch]
609
610- binaries = apt_pkg.ParseTagFile(info_set.binfile)
611- while binaries.Step():
612+ binaries = apt_pkg.TagFile(info_set.binfile)
613+ for section in binaries:
614 try:
615- bin_tmp = dict(binaries.Section)
616+ bin_tmp = dict(section)
617 # The component isn't listed in the tagfile.
618 bin_tmp['Component'] = info_set.component
619 bin_name = bin_tmp['Package']
620@@ -237,10 +237,10 @@
621 tmpbin_map[bin_name] = bin_tmp
622
623 # Run over the D-I stanzas and store info in tmp_bin_map.
624- dibinaries = apt_pkg.ParseTagFile(info_set.difile)
625- while dibinaries.Step():
626+ dibinaries = apt_pkg.TagFile(info_set.difile)
627+ for section in dibinaries:
628 try:
629- dibin_tmp = dict(dibinaries.Section)
630+ dibin_tmp = dict(section)
631 dibin_tmp['Component'] = info_set.component
632 dibin_name = dibin_tmp['Package']
633 except KeyError:
634
635=== modified file 'lib/lp/soyuz/scripts/packagecopier.py'
636--- lib/lp/soyuz/scripts/packagecopier.py 2011-12-22 05:37:22 +0000
637+++ lib/lp/soyuz/scripts/packagecopier.py 2011-12-26 18:09:24 +0000
638@@ -504,8 +504,8 @@
639 if ancestry is not None:
640 ancestry_version = ancestry.sourcepackagerelease.version
641 copy_version = source.sourcepackagerelease.version
642- apt_pkg.InitSystem()
643- if apt_pkg.VersionCompare(copy_version, ancestry_version) < 0:
644+ apt_pkg.init_system()
645+ if apt_pkg.version_compare(copy_version, ancestry_version) < 0:
646 raise CannotCopy(
647 "version older than the %s published in %s" %
648 (ancestry.displayname, ancestry.distroseries.name))
649
650=== modified file 'lib/lp/soyuz/tests/test_publish_archive_indexes.py'
651--- lib/lp/soyuz/tests/test_publish_archive_indexes.py 2011-07-27 23:06:20 +0000
652+++ lib/lp/soyuz/tests/test_publish_archive_indexes.py 2011-12-26 18:09:24 +0000
653@@ -22,7 +22,7 @@
654 def setUp(self):
655 """Setup global attributes."""
656 TestNativePublishingBase.setUp(self)
657- apt_pkg.InitSystem()
658+ apt_pkg.init_system()
659
660 def testSourceStanza(self):
661 """Check just-created source publication Index stanza.
662@@ -59,7 +59,7 @@
663 pub_source.getIndexStanza().splitlines())
664
665 def testSourceStanzaCustomFields(self):
666- """Check just-created source publication Index stanza
667+ """Check just-created source publication Index stanza
668 with custom fields (Python-Version).
669 """
670 pub_source = self.getPubSource(
671@@ -274,13 +274,13 @@
672
673 class TestNativeArchiveIndexesReparsing(TestNativePublishingBase):
674 """Tests for ensuring the native archive indexes that we publish
675- can be parsed correctly by apt_get.ParseTagFiles.
676+ can be parsed correctly by apt_pkg.TagFile.
677 """
678
679 def setUp(self):
680 """Setup global attributes."""
681 TestNativePublishingBase.setUp(self)
682- apt_pkg.InitSystem()
683+ apt_pkg.init_system()
684
685 def write_stanza_and_reparse(self, stanza):
686 """Helper method to return the apt_pkg parser for the stanza."""
687@@ -289,35 +289,34 @@
688 index_file.write(stanza.encode('utf-8'))
689 index_file.close()
690
691- parser = apt_pkg.ParseTagFile(open(index_filename))
692+ parser = apt_pkg.TagFile(open(index_filename))
693
694 # We're only interested in one stanza, so we'll parse it and remove
695 # the tmp file again.
696- parser.Step()
697+ section = next(parser)
698 os.remove(index_filename)
699
700- return parser
701+ return section
702
703 def test_getIndexStanza_binary_stanza(self):
704 """Check a binary stanza with APT parser."""
705 pub_binary = self.getPubBinaries()[0]
706
707- parser = self.write_stanza_and_reparse(pub_binary.getIndexStanza())
708+ section = self.write_stanza_and_reparse(pub_binary.getIndexStanza())
709
710- self.assertEqual(parser.Section.get('Package'), 'foo-bin')
711+ self.assertEqual(section.get('Package'), 'foo-bin')
712 self.assertEqual(
713- parser.Section.get('Description').splitlines(),
714+ section.get('Description').splitlines(),
715 ['Foo app is great', ' Well ...', ' it does nothing, though'])
716
717 def test_getIndexStanza_source_stanza(self):
718 """Check a source stanza with APT parser."""
719 pub_source = self.getPubSource()
720
721- parser = self.write_stanza_and_reparse(pub_source.getIndexStanza())
722+ section = self.write_stanza_and_reparse(pub_source.getIndexStanza())
723
724- self.assertEqual(parser.Section.get('Package'), 'foo')
725- self.assertEqual(
726- parser.Section.get('Maintainer'), 'Foo Bar <foo@bar.com>')
727+ self.assertEqual(section.get('Package'), 'foo')
728+ self.assertEqual(section.get('Maintainer'), 'Foo Bar <foo@bar.com>')
729
730 def test_getIndexStanza_with_corrupt_dsc_binaries(self):
731 """Ensure corrupt binary fields are written correctly to indexes.
732@@ -331,11 +330,10 @@
733 leaves a trailing '\n' (which results in a blank line after the
734 Binary field).
735
736- The second issue causes apt_pkg.ParseTagFile() to error during
737+ The second issue causes apt_pkg.TagFile() to error during
738 germination when it attempts to parse the generated Sources index.
739- But the first issue will also cause apt_pkg.ParseTagFile to
740- skip each newline of a multiline field that is not preceded with
741- a space.
742+ But the first issue will also cause apt_pkg.TagFile to skip each
743+ newline of a multiline field that is not preceded with a space.
744
745 This test ensures that binary fields saved as such will continue
746 to be written correctly to index files.
747@@ -350,19 +348,18 @@
748 pub_source.sourcepackagerelease.dsc_binaries = (
749 'foo_bin,\nbar_bin,\nzed_bin')
750
751- parser = self.write_stanza_and_reparse(pub_source.getIndexStanza())
752+ section = self.write_stanza_and_reparse(pub_source.getIndexStanza())
753
754- self.assertEqual('foo', parser.Section['Package'])
755+ self.assertEqual('foo', section['Package'])
756
757 # Without the fix, this raises a key-error due to apt-pkg not
758 # being able to parse the file.
759 self.assertEqual(
760- '666', parser.Section['Version'],
761+ '666', section['Version'],
762 'The Version field should be parsed correctly.')
763
764 # Without the fix, the second binary would not be parsed at all.
765- self.assertEqual(
766- 'foo_bin,\n bar_bin,\n zed_bin', parser.Section['Binary'])
767+ self.assertEqual('foo_bin,\n bar_bin,\n zed_bin', section['Binary'])
768
769 def test_getIndexStanza_with_correct_dsc_binaries(self):
770 """Ensure correct binary fields are written correctly to indexes.
771@@ -374,9 +371,9 @@
772 leaves a trailing '\n' (which results in a blank line after the
773 Binary field).
774
775- This test ensures that when our parser is updated to store
776- the binary field in the same way that apt_pkg.ParseTagFiles would,
777- that it will continue to be written correctly to index files.
778+ This test ensures that when our parser is updated to store the
779+ binary field in the same way that apt_pkg.TagFile would, that it
780+ will continue to be written correctly to index files.
781 """
782 pub_source = self.getPubSource()
783
784@@ -385,19 +382,18 @@
785 pub_source.sourcepackagerelease.dsc_binaries = (
786 'foo_bin,\n bar_bin,\n zed_bin')
787
788- parser = self.write_stanza_and_reparse(pub_source.getIndexStanza())
789+ section = self.write_stanza_and_reparse(pub_source.getIndexStanza())
790
791- self.assertEqual('foo', parser.Section['Package'])
792+ self.assertEqual('foo', section['Package'])
793
794 # Without the fix, this raises a key-error due to apt-pkg not
795 # being able to parse the file.
796 self.assertEqual(
797- '666', parser.Section['Version'],
798+ '666', section['Version'],
799 'The Version field should be parsed correctly.')
800
801 # Without the fix, the second binary would not be parsed at all.
802- self.assertEqual(
803- 'foo_bin,\n bar_bin,\n zed_bin', parser.Section['Binary'])
804+ self.assertEqual('foo_bin,\n bar_bin,\n zed_bin', section['Binary'])
805
806
807 class TestIndexStanzaFieldsHelper(unittest.TestCase):
808@@ -409,7 +405,6 @@
809 Provides an method to format the option in a ready-to-use string.
810 """
811
812-
813 def test_simple(self):
814 fields = IndexStanzaFields()
815 fields.append('breakfast', 'coffee')
816
817=== modified file 'lib/lp_sitecustomize.py'
818--- lib/lp_sitecustomize.py 2011-12-24 17:49:30 +0000
819+++ lib/lp_sitecustomize.py 2011-12-26 18:09:24 +0000
820@@ -129,10 +129,6 @@
821 filter_pattern = '.*(Zope 3.6|provide.*global site manager).*'
822 warnings.filterwarnings(
823 'ignore', filter_pattern, category=DeprecationWarning)
824- # XXX wgrant 2010-03-30 bug=551510:
825- # Also filter apt_pkg warnings, since Lucid's python-apt has a new API.
826- warnings.filterwarnings(
827- 'ignore', '.*apt_pkg.*', category=DeprecationWarning)
828
829
830 def customize_logger():
831
832=== modified file 'scripts/ftpmaster-tools/sync-source.py'
833--- scripts/ftpmaster-tools/sync-source.py 2011-10-15 00:25:33 +0000
834+++ scripts/ftpmaster-tools/sync-source.py 2011-12-26 18:09:24 +0000
835@@ -121,7 +121,7 @@
836 is_debian_changelog = 1
837 if previous_version is None:
838 previous_version = "9999:9999"
839- elif apt_pkg.VersionCompare(
840+ elif apt_pkg.version_compare(
841 match.group('version'), previous_version) > 0:
842 urgency = max(
843 urgency_to_numeric(match.group('urgency')), urgency)
844@@ -192,13 +192,13 @@
845 raise LaunchpadScriptFailure(
846 "debian/control not found in extracted source.")
847 control_filehandle = open(control_filename)
848- Control = apt_pkg.ParseTagFile(control_filehandle)
849- while Control.Step():
850- source = Control.Section.Find("Source")
851- package = Control.Section.Find("Package")
852- section = Control.Section.Find("Section")
853- priority = Control.Section.Find("Priority")
854- description = Control.Section.Find("Description")
855+ control = apt_pkg.TagFile(control_filehandle)
856+ for control_section in control:
857+ source = control_section.find("Source")
858+ package = control_section.find("Package")
859+ section = control_section.find("Section")
860+ priority = control_section.find("Priority")
861+ description = control_section.find("Description")
862 if source is not None:
863 if section is not None:
864 source_section = section
865@@ -398,7 +398,7 @@
866 if pkg not in S:
867 S[pkg] = [version, component]
868 else:
869- if apt_pkg.VersionCompare(S[pkg][0], version) < 0:
870+ if apt_pkg.version_compare(S[pkg][0], version) < 0:
871 Log.warning(
872 "%s: skipping because %s is < %s" % (
873 pkg, version, S[pkg][0]))
874@@ -434,7 +434,7 @@
875 # if pkg not in B:
876 # B[pkg] = [version, component]
877 # else:
878- # if apt_pkg.VersionCompare(B[pkg][0], version) < 0:
879+ # if apt_pkg.version_compare(B[pkg][0], version) < 0:
880 # B[pkg] = [version, component]
881
882 # XXX James Troup 2006-02-22: so... let's fall back on raw SQL
883@@ -462,7 +462,7 @@
884 if pkg not in B:
885 B[pkg] = [version, component]
886 else:
887- if apt_pkg.VersionCompare(B[pkg][0], version) < 0:
888+ if apt_pkg.version_compare(B[pkg][0], version) < 0:
889 B[pkg] = [version, component]
890 return B
891
892@@ -479,21 +479,21 @@
893
894 filename = "%s%s%s_%s" % (origin["name"], suite, component, filename)
895 sources_filehandle = open(filename)
896- Sources = apt_pkg.ParseTagFile(sources_filehandle)
897- while Sources.Step():
898- pkg = Sources.Section.Find("Package")
899- version = Sources.Section.Find("Version")
900+ sources = apt_pkg.TagFile(sources_filehandle)
901+ for sources_section in sources:
902+ pkg = sources_section.find("Package")
903+ version = sources_section.find("Version")
904
905- if pkg in S and apt_pkg.VersionCompare(
906+ if pkg in S and apt_pkg.version_compare(
907 S[pkg]["version"], version) > 0:
908 continue
909
910 S[pkg] = {}
911 S[pkg]["version"] = version
912
913- directory = Sources.Section.Find("Directory", "")
914+ directory = sources_section.find("Directory", "")
915 files = {}
916- for line in Sources.Section.Find("Files").split('\n'):
917+ for line in sources_section.find("Files").split('\n'):
918 (md5sum, size, filename) = line.strip().split()
919 files[filename] = {}
920 files[filename]["md5sum"] = md5sum
921@@ -577,7 +577,7 @@
922
923 source_version = Sources[pkg]["version"]
924 if (dest_version is None
925- or apt_pkg.VersionCompare(dest_version, source_version) < 0):
926+ or apt_pkg.version_compare(dest_version, source_version) < 0):
927 if (dest_version is not None
928 and (not Options.force
929 and dest_version.find("ubuntu") != -1)):