Merge lp:~james-w/linaro-image-tools/add-other-relations-to-packages-file into lp:linaro-image-tools/11.11
- add-other-relations-to-packages-file
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 77 |
Proposed branch: | lp:~james-w/linaro-image-tools/add-other-relations-to-packages-file |
Merge into: | lp:linaro-image-tools/11.11 |
Prerequisite: | lp:~james-w/linaro-image-tools/add-relations-to-packages-file |
Diff against target: |
563 lines (+283/-113) 5 files modified
hwpack/packages.py (+75/-25) hwpack/tarfile_matchers.py (+4/-6) hwpack/testing.py (+5/-1) hwpack/tests/test_packages.py (+197/-36) hwpack/tests/test_tarfile_matchers.py (+2/-45) |
To merge this branch: | bzr merge lp:~james-w/linaro-image-tools/add-other-relations-to-packages-file |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Zygmunt Krynicki (community) | Approve | ||
Review via email: mp+35172@code.launchpad.net |
Commit message
Description of the change
Hi,
This is similar to the last branch, just extends it to Pre-Depends,
Conflicts and Recommends as well. I didn't bother with Suggests, as
I doubt anyone would ever want to install a hwpack and pull in the
suggested packages at the same time. It would be easy to add
though.
There's some small refactorings thrown in now that code is shared
between these different paths.
Thanks,
James
- 139. By James Westby
-
Merge add-relations-
to-packages- file into add-other- relations- to-packages- file. - 140. By James Westby
-
Merged add-relations-
to-packages- file into add-other- relations- to-packages- file.
James Westby (james-w) wrote : | # |
On Tue, 14 Sep 2010 19:47:43 -0000, Zygmunt Krynicki <email address hidden> wrote:
> Review: Needs Fixing
> You seem to have changed FetchedPackage.
> __hash__ (it still refers to the old set of fields).
Because content() was never in the __hash__ calculation.
> In addition you should not define __eq__ but __cmp__ unless you are
> prepared to define __ne__. Moreover you should not define __hash__ as
> your instances are not immutable.
__cmp__ doesn't really make sense as there is no natural ordering. Your
other points make sense though.
Thanks,
James
James Westby (james-w) wrote : | # |
Changed, thanks.
James
- 141. By James Westby
-
Define __ne__ and remove __hash__ on FetchedPackage. Thanks Zygmunt.
- 142. By James Westby
-
Add __ne__ and remove __hash__ from the Mismatches. Thanks Zygmunt.
Zygmunt Krynicki (zyga) wrote : | # |
Looks fine now, please merge!
Preview Diff
1 | === modified file 'hwpack/packages.py' |
2 | --- hwpack/packages.py 2010-09-10 21:51:33 +0000 |
3 | +++ hwpack/packages.py 2010-09-14 20:36:09 +0000 |
4 | @@ -25,12 +25,52 @@ |
5 | parts.append('Architecture: %s' % package.architecture) |
6 | if package.depends: |
7 | parts.append('Depends: %s' % package.depends) |
8 | + if package.pre_depends: |
9 | + parts.append('Pre-Depends: %s' % package.pre_depends) |
10 | + if package.conflicts: |
11 | + parts.append('Conflicts: %s' % package.conflicts) |
12 | + if package.recommends: |
13 | + parts.append('Recommends: %s' % package.recommends) |
14 | parts.append('MD5sum: %s' % package.md5) |
15 | content += "\n".join(parts) |
16 | content += "\n\n" |
17 | return content |
18 | |
19 | |
20 | +def stringify_relationship(pkg, relationship): |
21 | + """Given a Package, return a string of the specified relationship. |
22 | + |
23 | + apt.package.Version stores the relationship information of the |
24 | + package as objects. This function will convert those objects |
25 | + in to the string form that we are used to from debian/control |
26 | + or Packages files. |
27 | + |
28 | + :param pkg: the package to take the relationship information from. |
29 | + :type pkg: apt.package.Version |
30 | + :param relationship: the relationship to stringify, as understood |
31 | + by apt.package.Package.get_dependencies, e.g. "Depends", |
32 | + "PreDepends". |
33 | + :type relationship: str or None if the package has no relationships |
34 | + of that type. |
35 | + """ |
36 | + relationship_str = None |
37 | + pkg_dependencies = pkg.get_dependencies(relationship) |
38 | + if pkg_dependencies: |
39 | + relationship_list = [] |
40 | + for or_dep in pkg_dependencies: |
41 | + or_list = [] |
42 | + for or_alternative in or_dep.or_dependencies: |
43 | + suffix = "" |
44 | + if or_alternative.relation: |
45 | + suffix = " (%s %s)" % ( |
46 | + or_alternative.relation, |
47 | + or_alternative.version) |
48 | + or_list.append("%s%s" % (or_alternative.name, suffix)) |
49 | + relationship_list.append(" | ".join(or_list)) |
50 | + relationship_str = ", ".join(relationship_list) |
51 | + return relationship_str |
52 | + |
53 | + |
54 | class DummyProgress(object): |
55 | """An AcquireProgress that silences all output. |
56 | |
57 | @@ -79,14 +119,27 @@ |
58 | :ivar architecture: the architecture that the package is for, may be |
59 | 'all'. |
60 | :type architecture: str |
61 | - :ivar depends: the depends string that the package has, i.e. the |
62 | + :ivar depends: the Depends string that the package has, i.e. the |
63 | dependencies as specified in debian/control. May be None if the |
64 | package has none. |
65 | :type depends: str or None |
66 | + :ivar pre_depends: the Pre-Depends string that the package has, i.e. the |
67 | + pre-dependencies as specified in debian/control. May be None if the |
68 | + package has none. |
69 | + :type pre_depends: str or None |
70 | + :ivar conflicts: the Conflicts string that the package has, i.e. the |
71 | + conflicts as specified in debian/control. May be None if the |
72 | + package has none. |
73 | + :type conflicts: str or None |
74 | + :ivar recommends: the Recommends string that the package has, i.e. the |
75 | + recommends as specified in debian/control. May be None if the |
76 | + package has none. |
77 | + :type recommends: str or None |
78 | """ |
79 | |
80 | def __init__(self, name, version, filename, content, size, md5, |
81 | - architecture, depends=None): |
82 | + architecture, depends=None, pre_depends=None, |
83 | + conflicts=None, recommends=None): |
84 | """Create a FetchedPackage. |
85 | |
86 | See the instance variables for the arguments. |
87 | @@ -99,6 +152,9 @@ |
88 | self.md5 = md5 |
89 | self.architecture = architecture |
90 | self.depends = depends |
91 | + self.pre_depends = pre_depends |
92 | + self.conflicts = conflicts |
93 | + self.recommends = recommends |
94 | |
95 | @classmethod |
96 | def from_apt(cls, pkg, filename, content): |
97 | @@ -116,23 +172,15 @@ |
98 | :param content: the content of the package. |
99 | :type content: file-like object |
100 | """ |
101 | - depends = None |
102 | - pkg_dependencies = pkg.get_dependencies("Depends") |
103 | - if pkg_dependencies: |
104 | - depends_list = [] |
105 | - for or_dep in pkg_dependencies: |
106 | - or_list = [] |
107 | - for or_alternative in or_dep.or_dependencies: |
108 | - suffix = "" |
109 | - if or_alternative.relation: |
110 | - suffix = " (%s %s)" % ( |
111 | - or_alternative.relation, or_alternative.version) |
112 | - or_list.append("%s%s" % (or_alternative.name, suffix)) |
113 | - depends_list.append(" | ".join(or_list)) |
114 | - depends = ", ".join(depends_list) |
115 | + depends = stringify_relationship(pkg, "Depends") |
116 | + pre_depends = stringify_relationship(pkg, "PreDepends") |
117 | + conflicts = stringify_relationship(pkg, "Conflicts") |
118 | + recommends = stringify_relationship(pkg, "Recommends") |
119 | return cls( |
120 | pkg.package.name, pkg.version, filename, content, pkg.size, |
121 | - pkg.md5, pkg.architecture, depends=depends) |
122 | + pkg.md5, pkg.architecture, depends=depends, |
123 | + pre_depends=pre_depends, conflicts=conflicts, |
124 | + recommends=recommends) |
125 | |
126 | def __eq__(self, other): |
127 | return (self.name == other.name |
128 | @@ -142,19 +190,21 @@ |
129 | and self.size == other.size |
130 | and self.md5 == other.md5 |
131 | and self.architecture == other.architecture |
132 | - and self.depends == other.depends) |
133 | + and self.depends == other.depends |
134 | + and self.pre_depends == other.pre_depends |
135 | + and self.conflicts == other.conflicts |
136 | + and self.recommends == other.recommends) |
137 | |
138 | - def __hash__(self): |
139 | - return hash( |
140 | - (self.name, self.version, self.filename, self.size, self.md5, |
141 | - self.depends)) |
142 | + def __ne__(self, other): |
143 | + return not self.__eq__(other) |
144 | |
145 | def __repr__(self): |
146 | return ( |
147 | '<%s name=%s version=%s size=%s md5=%s architecture=%s ' |
148 | - 'depends="%s">' % (self.__class__.__name__, self.name, |
149 | - self.version, self.size, self.md5, self.architecture, |
150 | - self.depends)) |
151 | + 'depends="%s" pre_depends="%s" conflicts="%s" recommends="%s">' |
152 | + % (self.__class__.__name__, self.name, self.version, self.size, |
153 | + self.md5, self.architecture, self.depends, self.pre_depends, |
154 | + self.conflicts, self.recommends)) |
155 | |
156 | |
157 | class IsolatedAptCache(object): |
158 | |
159 | === modified file 'hwpack/tarfile_matchers.py' |
160 | --- hwpack/tarfile_matchers.py 2010-08-31 16:33:16 +0000 |
161 | +++ hwpack/tarfile_matchers.py 2010-09-14 20:36:09 +0000 |
162 | @@ -20,8 +20,8 @@ |
163 | def __eq__(self, other): |
164 | return self.tarball == other.tarball and self.path == other.path |
165 | |
166 | - def __hash__(self): |
167 | - return hash((self.tarball, self.path)) |
168 | + def __ne__(self, other): |
169 | + return not self.__eq__(other) |
170 | |
171 | |
172 | class TarfileWrongValueMismatch(Mismatch): |
173 | @@ -56,10 +56,8 @@ |
174 | and self.expected == other.expected |
175 | and self.actual == other.actual) |
176 | |
177 | - def __hash__(self): |
178 | - return hash( |
179 | - (self.attribute, self.tarball, self.path, self.expected, |
180 | - self.actual)) |
181 | + def __ne__(self, other): |
182 | + return not self.__eq__(other) |
183 | |
184 | |
185 | class TarfileHasFile(Matcher): |
186 | |
187 | === modified file 'hwpack/testing.py' |
188 | --- hwpack/testing.py 2010-09-10 18:58:06 +0000 |
189 | +++ hwpack/testing.py 2010-09-14 20:36:09 +0000 |
190 | @@ -54,11 +54,15 @@ |
191 | See FetchedPackage for the instance variables. |
192 | """ |
193 | |
194 | - def __init__(self, name, version, architecture="all", depends=None): |
195 | + def __init__(self, name, version, architecture="all", depends=None, |
196 | + pre_depends=None, conflicts=None, recommends=None): |
197 | self.name = name |
198 | self.version = version |
199 | self.architecture = architecture |
200 | self.depends = depends |
201 | + self.pre_depends = pre_depends |
202 | + self.conflicts = conflicts |
203 | + self.recommends = recommends |
204 | |
205 | @property |
206 | def filename(self): |
207 | |
208 | === modified file 'hwpack/tests/test_packages.py' |
209 | --- hwpack/tests/test_packages.py 2010-09-10 20:53:42 +0000 |
210 | +++ hwpack/tests/test_packages.py 2010-09-14 20:36:09 +0000 |
211 | @@ -9,6 +9,7 @@ |
212 | FetchedPackage, |
213 | get_packages_file, |
214 | PackageFetcher, |
215 | + stringify_relationship, |
216 | ) |
217 | from hwpack.testing import ( |
218 | AptSourceFixture, |
219 | @@ -41,21 +42,89 @@ |
220 | get_packages_file([package1]) + get_packages_file([package2]), |
221 | get_packages_file([package1, package2])) |
222 | |
223 | + def get_stanza(self, package, relationships=""): |
224 | + stanza = textwrap.dedent("""\ |
225 | + Package: foo |
226 | + Version: 1.1 |
227 | + Filename: %(filename)s |
228 | + Size: %(size)d |
229 | + Architecture: all |
230 | + """ % { |
231 | + 'filename': package.filename, |
232 | + 'size': package.size, |
233 | + }) |
234 | + stanza += relationships |
235 | + stanza += "MD5sum: %s\n\n" % package.md5 |
236 | + return stanza |
237 | + |
238 | def test_with_depends(self): |
239 | package = DummyFetchedPackage("foo", "1.1", depends="bar | baz") |
240 | - self.assertEqual(textwrap.dedent("""\ |
241 | - Package: foo |
242 | - Version: 1.1 |
243 | - Filename: %(filename)s |
244 | - Size: %(size)d |
245 | - Architecture: all |
246 | - Depends: bar | baz |
247 | - MD5sum: %(md5)s |
248 | - \n""" % { |
249 | - 'filename': package.filename, |
250 | - 'size': package.size, |
251 | - 'md5': package.md5, |
252 | - }), get_packages_file([package])) |
253 | + self.assertEqual( |
254 | + self.get_stanza(package, "Depends: bar | baz\n"), |
255 | + get_packages_file([package])) |
256 | + |
257 | + def test_with_pre_depends(self): |
258 | + package = DummyFetchedPackage("foo", "1.1", pre_depends="bar | baz") |
259 | + self.assertEqual( |
260 | + self.get_stanza(package, "Pre-Depends: bar | baz\n"), |
261 | + get_packages_file([package])) |
262 | + |
263 | + def test_with_conflicts(self): |
264 | + package = DummyFetchedPackage("foo", "1.1", conflicts="bar | baz") |
265 | + self.assertEqual( |
266 | + self.get_stanza(package, "Conflicts: bar | baz\n"), |
267 | + get_packages_file([package])) |
268 | + |
269 | + def test_with_recommends(self): |
270 | + package = DummyFetchedPackage("foo", "1.1", recommends="bar | baz") |
271 | + self.assertEqual( |
272 | + self.get_stanza(package, "Recommends: bar | baz\n"), |
273 | + get_packages_file([package])) |
274 | + |
275 | + |
276 | +class StringifyRelationshipTests(TestCaseWithFixtures): |
277 | + |
278 | + def test_no_relationship(self): |
279 | + target_package = DummyFetchedPackage("foo", "1.0") |
280 | + source = self.useFixture(AptSourceFixture([target_package])) |
281 | + with IsolatedAptCache([source.sources_entry]) as cache: |
282 | + candidate = cache.cache['foo'].candidate |
283 | + self.assertEqual( |
284 | + None, stringify_relationship(candidate, "Depends")) |
285 | + |
286 | + def test_single_package(self): |
287 | + target_package = DummyFetchedPackage("foo", "1.0", depends="bar") |
288 | + source = self.useFixture(AptSourceFixture([target_package])) |
289 | + with IsolatedAptCache([source.sources_entry]) as cache: |
290 | + candidate = cache.cache['foo'].candidate |
291 | + self.assertEqual( |
292 | + "bar", stringify_relationship(candidate, "Depends")) |
293 | + |
294 | + def test_multiple_package(self): |
295 | + target_package = DummyFetchedPackage("foo", "1.0", depends="bar, baz") |
296 | + source = self.useFixture(AptSourceFixture([target_package])) |
297 | + with IsolatedAptCache([source.sources_entry]) as cache: |
298 | + candidate = cache.cache['foo'].candidate |
299 | + self.assertEqual( |
300 | + "bar, baz", stringify_relationship(candidate, "Depends")) |
301 | + |
302 | + def test_alternative_packages(self): |
303 | + target_package = DummyFetchedPackage( |
304 | + "foo", "1.0", depends="bar | baz") |
305 | + source = self.useFixture(AptSourceFixture([target_package])) |
306 | + with IsolatedAptCache([source.sources_entry]) as cache: |
307 | + candidate = cache.cache['foo'].candidate |
308 | + self.assertEqual( |
309 | + "bar | baz", stringify_relationship(candidate, "Depends")) |
310 | + |
311 | + def test_package_with_version(self): |
312 | + target_package = DummyFetchedPackage( |
313 | + "foo", "1.0", depends="baz (<= 2.0)") |
314 | + source = self.useFixture(AptSourceFixture([target_package])) |
315 | + with IsolatedAptCache([source.sources_entry]) as cache: |
316 | + candidate = cache.cache['foo'].candidate |
317 | + self.assertEqual( |
318 | + "baz (<= 2.0)", stringify_relationship(candidate, "Depends")) |
319 | |
320 | |
321 | class FetchedPackageTests(TestCaseWithFixtures): |
322 | @@ -78,6 +147,7 @@ |
323 | package2 = FetchedPackage( |
324 | "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel") |
325 | self.assertEqual(package1, package2) |
326 | + self.assertFalse(package1 != package2) |
327 | |
328 | def test_not_equal_different_name(self): |
329 | package1 = FetchedPackage( |
330 | @@ -155,21 +225,86 @@ |
331 | depends="bar") |
332 | self.assertEqual(package1, package2) |
333 | |
334 | - def test_equal_hash_equal(self): |
335 | - package1 = FetchedPackage( |
336 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel") |
337 | - package2 = FetchedPackage( |
338 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel") |
339 | - self.assertEqual(hash(package1), hash(package2)) |
340 | - |
341 | - def test_equal_hash_equal_with_depends(self): |
342 | - package1 = FetchedPackage( |
343 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
344 | - depends="bar") |
345 | - package2 = FetchedPackage( |
346 | - "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
347 | - depends="bar") |
348 | - self.assertEqual(hash(package1), hash(package2)) |
349 | + def test_not_equal_different_pre_depends(self): |
350 | + package1 = FetchedPackage( |
351 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
352 | + pre_depends="bar") |
353 | + package2 = FetchedPackage( |
354 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
355 | + pre_depends="baz") |
356 | + self.assertNotEqual(package1, package2) |
357 | + |
358 | + def test_not_equal_different_pre_depends_one_None(self): |
359 | + package1 = FetchedPackage( |
360 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
361 | + pre_depends="bar") |
362 | + package2 = FetchedPackage( |
363 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
364 | + pre_depends=None) |
365 | + self.assertNotEqual(package1, package2) |
366 | + |
367 | + def test_equal_same_pre_depends(self): |
368 | + package1 = FetchedPackage( |
369 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
370 | + pre_depends="bar") |
371 | + package2 = FetchedPackage( |
372 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
373 | + pre_depends="bar") |
374 | + self.assertEqual(package1, package2) |
375 | + |
376 | + def test_not_equal_different_conflicts(self): |
377 | + package1 = FetchedPackage( |
378 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
379 | + conflicts="bar") |
380 | + package2 = FetchedPackage( |
381 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
382 | + conflicts="baz") |
383 | + self.assertNotEqual(package1, package2) |
384 | + |
385 | + def test_not_equal_different_conflicts_one_None(self): |
386 | + package1 = FetchedPackage( |
387 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
388 | + conflicts="bar") |
389 | + package2 = FetchedPackage( |
390 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
391 | + conflicts=None) |
392 | + self.assertNotEqual(package1, package2) |
393 | + |
394 | + def test_equal_same_conflicts(self): |
395 | + package1 = FetchedPackage( |
396 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
397 | + conflicts="bar") |
398 | + package2 = FetchedPackage( |
399 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
400 | + conflicts="bar") |
401 | + self.assertEqual(package1, package2) |
402 | + |
403 | + def test_not_equal_different_recommends(self): |
404 | + package1 = FetchedPackage( |
405 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
406 | + recommends="bar") |
407 | + package2 = FetchedPackage( |
408 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
409 | + recommends="baz") |
410 | + self.assertNotEqual(package1, package2) |
411 | + |
412 | + def test_not_equal_different_recommends_one_None(self): |
413 | + package1 = FetchedPackage( |
414 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
415 | + recommends="bar") |
416 | + package2 = FetchedPackage( |
417 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
418 | + recommends=None) |
419 | + self.assertNotEqual(package1, package2) |
420 | + |
421 | + def test_equal_same_recommends(self): |
422 | + package1 = FetchedPackage( |
423 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
424 | + recommends="bar") |
425 | + package2 = FetchedPackage( |
426 | + "foo", "1.1", "foo_1.1.deb", StringIO("xxxx"), 4, "aaaa", "armel", |
427 | + recommends="bar") |
428 | + self.assertEqual(package1, package2) |
429 | |
430 | def test_from_apt(self): |
431 | target_package = DummyFetchedPackage("foo", "1.0") |
432 | @@ -180,15 +315,28 @@ |
433 | candidate, target_package.filename, target_package.content) |
434 | self.assertEqual(target_package, created_package) |
435 | |
436 | + def assert_from_apt_translates_relationship(self, relationship): |
437 | + kwargs = {} |
438 | + kwargs[relationship] = "bar | baz (>= 1.0), zap" |
439 | + target_package = DummyFetchedPackage("foo", "1.0", **kwargs) |
440 | + source = self.useFixture(AptSourceFixture([target_package])) |
441 | + with IsolatedAptCache([source.sources_entry]) as cache: |
442 | + candidate = cache.cache['foo'].candidate |
443 | + created_package = FetchedPackage.from_apt( |
444 | + candidate, target_package.filename, target_package.content) |
445 | + self.assertEqual(target_package, created_package) |
446 | + |
447 | def test_from_apt_with_depends(self): |
448 | - target_package = DummyFetchedPackage( |
449 | - "foo", "1.0", depends="bar | baz (>= 1.0), zap") |
450 | - source = self.useFixture(AptSourceFixture([target_package])) |
451 | - with IsolatedAptCache([source.sources_entry]) as cache: |
452 | - candidate = cache.cache['foo'].candidate |
453 | - created_package = FetchedPackage.from_apt( |
454 | - candidate, target_package.filename, target_package.content) |
455 | - self.assertEqual(target_package, created_package) |
456 | + self.assert_from_apt_translates_relationship('depends') |
457 | + |
458 | + def test_from_apt_with_pre_depends(self): |
459 | + self.assert_from_apt_translates_relationship('pre_depends') |
460 | + |
461 | + def test_from_apt_with_conflicts(self): |
462 | + self.assert_from_apt_translates_relationship('conflicts') |
463 | + |
464 | + def test_from_apt_with_recommends(self): |
465 | + self.assert_from_apt_translates_relationship('recommends') |
466 | |
467 | |
468 | class AptCacheTests(TestCaseWithFixtures): |
469 | @@ -386,3 +534,16 @@ |
470 | fetcher = self.get_fetcher([source], architecture="arch1") |
471 | self.assertEqual( |
472 | wanted_package, fetcher.fetch_packages(["foo"])[0]) |
473 | + |
474 | + def test_fetch_package_fetches_with_relationships(self): |
475 | + depends = "foo" |
476 | + pre_depends = "bar (>= 1.0)" |
477 | + conflicts = "baz | zap" |
478 | + recommends = "zing, zang" |
479 | + wanted_package = DummyFetchedPackage( |
480 | + "foo", "1.0", depends=depends, pre_depends=pre_depends, |
481 | + conflicts=conflicts, recommends=recommends) |
482 | + source = self.useFixture(AptSourceFixture([wanted_package])) |
483 | + fetcher = self.get_fetcher([source]) |
484 | + self.assertEqual( |
485 | + wanted_package, fetcher.fetch_packages(["foo"])[0]) |
486 | |
487 | === modified file 'hwpack/tests/test_tarfile_matchers.py' |
488 | --- hwpack/tests/test_tarfile_matchers.py 2010-08-31 16:35:41 +0000 |
489 | +++ hwpack/tests/test_tarfile_matchers.py 2010-09-14 20:36:09 +0000 |
490 | @@ -21,6 +21,7 @@ |
491 | mismatch1 = TarfileMissingPathMismatch("foo", "bar") |
492 | mismatch2 = TarfileMissingPathMismatch("foo", "bar") |
493 | self.assertEqual(mismatch1, mismatch2) |
494 | + self.assertFalse(mismatch1 != mismatch2) |
495 | |
496 | def test_no_eq_different_tarball(self): |
497 | mismatch1 = TarfileMissingPathMismatch("foo", "bar") |
498 | @@ -32,21 +33,6 @@ |
499 | mismatch2 = TarfileMissingPathMismatch("foo", "baz") |
500 | self.assertNotEqual(mismatch1, mismatch2) |
501 | |
502 | - def test_hash_equal(self): |
503 | - mismatch1 = TarfileMissingPathMismatch("foo", "bar") |
504 | - mismatch2 = TarfileMissingPathMismatch("foo", "bar") |
505 | - self.assertEqual(hash(mismatch1), hash(mismatch2)) |
506 | - |
507 | - def test_different_tarball_different_hash(self): |
508 | - mismatch1 = TarfileMissingPathMismatch("foo", "bar") |
509 | - mismatch2 = TarfileMissingPathMismatch("baz", "bar") |
510 | - self.assertNotEqual(hash(mismatch1), hash(mismatch2)) |
511 | - |
512 | - def test_different_path_different_hash(self): |
513 | - mismatch1 = TarfileMissingPathMismatch("foo", "bar") |
514 | - mismatch2 = TarfileMissingPathMismatch("foo", "baz") |
515 | - self.assertNotEqual(hash(mismatch1), hash(mismatch2)) |
516 | - |
517 | |
518 | class TarfileWrongTypeMismatchTests(TestCase): |
519 | |
520 | @@ -60,6 +46,7 @@ |
521 | mismatch1 = TarfileWrongValueMismatch("type", "foo", "bar", 1, 2) |
522 | mismatch2 = TarfileWrongValueMismatch("type", "foo", "bar", 1, 2) |
523 | self.assertEqual(mismatch1, mismatch2) |
524 | + self.assertFalse(mismatch1 != mismatch2) |
525 | |
526 | def test_not_eq_different_attribute(self): |
527 | mismatch1 = TarfileWrongValueMismatch("type", "foo", "bar", 1, 2) |
528 | @@ -86,36 +73,6 @@ |
529 | mismatch2 = TarfileWrongValueMismatch("type", "foo", "bar", 1, 3) |
530 | self.assertNotEqual(mismatch1, mismatch2) |
531 | |
532 | - def test_hash_equal(self): |
533 | - mismatch1 = TarfileWrongValueMismatch("type", "foo", "bar", 1, 2) |
534 | - mismatch2 = TarfileWrongValueMismatch("type", "foo", "bar", 1, 2) |
535 | - self.assertEqual(hash(mismatch1), hash(mismatch2)) |
536 | - |
537 | - def test_different_attribute_different_hash(self): |
538 | - mismatch1 = TarfileWrongValueMismatch("type", "foo", "bar", 1, 2) |
539 | - mismatch2 = TarfileWrongValueMismatch("size", "foo", "bar", 1, 2) |
540 | - self.assertNotEqual(hash(mismatch1), hash(mismatch2)) |
541 | - |
542 | - def test_different_tarball_different_hash(self): |
543 | - mismatch1 = TarfileWrongValueMismatch("type", "foo", "bar", 1, 2) |
544 | - mismatch2 = TarfileWrongValueMismatch("type", "baz", "bar", 1, 2) |
545 | - self.assertNotEqual(hash(mismatch1), hash(mismatch2)) |
546 | - |
547 | - def test_different_path_different_hash(self): |
548 | - mismatch1 = TarfileWrongValueMismatch("type", "foo", "bar", 1, 2) |
549 | - mismatch2 = TarfileWrongValueMismatch("type", "foo", "baz", 1, 2) |
550 | - self.assertNotEqual(hash(mismatch1), hash(mismatch2)) |
551 | - |
552 | - def test_different_expected_different_hash(self): |
553 | - mismatch1 = TarfileWrongValueMismatch("type", "foo", "bar", 1, 2) |
554 | - mismatch2 = TarfileWrongValueMismatch("type", "foo", "bar", 3, 2) |
555 | - self.assertNotEqual(hash(mismatch1), hash(mismatch2)) |
556 | - |
557 | - def test_different_actual_different_hash(self): |
558 | - mismatch1 = TarfileWrongValueMismatch("type", "foo", "bar", 1, 2) |
559 | - mismatch2 = TarfileWrongValueMismatch("type", "foo", "bar", 1, 3) |
560 | - self.assertNotEqual(hash(mismatch1), hash(mismatch2)) |
561 | - |
562 | |
563 | class TarfileHasFileTests(TestCase): |
564 |
You seem to have changed FetchedPackage. __eq__ but did not change __hash__ (it still refers to the old set of fields).
In addition you should not define __eq__ but __cmp__ unless you are prepared to define __ne__. Moreover you should not define __hash__ as your instances are not immutable.
Currently you can create two identical FetchedPackage objects A and B and the following will hold:
assert A == B # because we have __eq__ that works
assert A != B # because __ne__ compares id() by default
The same issue affects TarfileWrongVal ueMismatch and TarfileMissingP athMismatch
From pydoc SPECIALMETHODS
There are no implied relationships among the comparison operators.
The truth of ``x==y`` does not imply that ``x!=y`` is false.
Accordingly, when defining ``__eq__()``, one should also define
``__ne__()`` so that the operators will behave as expected. See
the paragraph on ``__hash__()`` for some important notes on
creating *hashable* objects which support custom comparison
operations and are usable as dictionary keys.
If a class does not define a ``__cmp__()`` or ``__eq__()`` method
it should not define a ``__hash__()`` operation either; if it
defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its
instances will not be usable in hashed collections. If a class
defines mutable objects and implements a ``__cmp__()`` or
``__eq__()`` method, it should not implement ``__hash__()``, since
hashable collection implementations require that a object's hash
value is immutable (if the object's hash value changes, it will be
in the wrong hash bucket).