Merge ~cjwatson/launchpad:py3-cmp into launchpad:master
- Git
- lp:~cjwatson/launchpad
- py3-cmp
- Merge into master
Proposed by
Colin Watson
Status: | Merged |
---|---|
Approved by: | Colin Watson |
Approved revision: | 688851cb3b5ebb14c232712a95400bafe078aef7 |
Merge reported by: | Otto Co-Pilot |
Merged at revision: | not available |
Proposed branch: | ~cjwatson/launchpad:py3-cmp |
Merge into: | launchpad:master |
Diff against target: |
406 lines (+64/-77) 10 files modified
lib/lp/archivepublisher/domination.py (+8/-4) lib/lp/archivepublisher/tests/test_dominator.py (+10/-6) lib/lp/archiveuploader/tests/nascentupload-announcements.txt (+1/-4) lib/lp/bugs/doc/initial-bug-contacts.txt (+2/-4) lib/lp/registry/browser/product.py (+5/-8) lib/lp/registry/doc/distribution-mirror.txt (+2/-1) lib/lp/registry/doc/teammembership-email-notification.txt (+3/-4) lib/lp/registry/tests/test_distroseriesdifferencecomment.py (+2/-7) lib/lp/services/doc/orderingcheck.txt (+1/-4) lib/lp/services/webapp/sorting.py (+30/-35) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ioana Lasc (community) | Approve | ||
Review via email: mp+394483@code.launchpad.net |
Commit message
Stop using cmp() and sorted(cmp=...)
Description of the change
These are no longer supported in Python 3; we need to use constructions involving sorted(key=...) instead.
To post a comment you must log in.
Revision history for this message
Ioana Lasc (ilasc) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/lib/lp/archivepublisher/domination.py b/lib/lp/archivepublisher/domination.py | |||
2 | index 356a2ee..0e9a8b0 100644 | |||
3 | --- a/lib/lp/archivepublisher/domination.py | |||
4 | +++ b/lib/lp/archivepublisher/domination.py | |||
5 | @@ -54,6 +54,7 @@ __all__ = ['Dominator'] | |||
6 | 54 | 54 | ||
7 | 55 | from collections import defaultdict | 55 | from collections import defaultdict |
8 | 56 | from datetime import timedelta | 56 | from datetime import timedelta |
9 | 57 | from functools import cmp_to_key | ||
10 | 57 | from operator import ( | 58 | from operator import ( |
11 | 58 | attrgetter, | 59 | attrgetter, |
12 | 59 | itemgetter, | 60 | itemgetter, |
13 | @@ -198,14 +199,16 @@ class GeneralizedPublication: | |||
14 | 198 | self.getPackageVersion(pub1), self.getPackageVersion(pub2)) | 199 | self.getPackageVersion(pub1), self.getPackageVersion(pub2)) |
15 | 199 | 200 | ||
16 | 200 | if version_comparison == 0: | 201 | if version_comparison == 0: |
19 | 201 | # Use dates as tie breaker. | 202 | # Use dates as tie breaker (idiom equivalent to Python 2's cmp). |
20 | 202 | return cmp(pub1.datecreated, pub2.datecreated) | 203 | return ( |
21 | 204 | (pub1.datecreated > pub2.datecreated) - | ||
22 | 205 | (pub1.datecreated < pub2.datecreated)) | ||
23 | 203 | else: | 206 | else: |
24 | 204 | return version_comparison | 207 | return version_comparison |
25 | 205 | 208 | ||
26 | 206 | def sortPublications(self, publications): | 209 | def sortPublications(self, publications): |
27 | 207 | """Sort publications from most to least current versions.""" | 210 | """Sort publications from most to least current versions.""" |
29 | 208 | return sorted(publications, cmp=self.compare, reverse=True) | 211 | return sorted(publications, key=cmp_to_key(self.compare), reverse=True) |
30 | 209 | 212 | ||
31 | 210 | 213 | ||
32 | 211 | def find_live_source_versions(sorted_pubs): | 214 | def find_live_source_versions(sorted_pubs): |
33 | @@ -417,7 +420,8 @@ class Dominator: | |||
34 | 417 | len(sorted_pubs), live_versions) | 420 | len(sorted_pubs), live_versions) |
35 | 418 | 421 | ||
36 | 419 | # Verify that the publications are really sorted properly. | 422 | # Verify that the publications are really sorted properly. |
38 | 420 | check_order = OrderingCheck(cmp=generalization.compare, reverse=True) | 423 | check_order = OrderingCheck( |
39 | 424 | key=cmp_to_key(generalization.compare), reverse=True) | ||
40 | 421 | 425 | ||
41 | 422 | current_dominant = None | 426 | current_dominant = None |
42 | 423 | dominant_version = None | 427 | dominant_version = None |
43 | diff --git a/lib/lp/archivepublisher/tests/test_dominator.py b/lib/lp/archivepublisher/tests/test_dominator.py | |||
44 | index 4d073e0..b35596e 100755 | |||
45 | --- a/lib/lp/archivepublisher/tests/test_dominator.py | |||
46 | +++ b/lib/lp/archivepublisher/tests/test_dominator.py | |||
47 | @@ -8,6 +8,7 @@ from __future__ import absolute_import, print_function, unicode_literals | |||
48 | 8 | __metaclass__ = type | 8 | __metaclass__ = type |
49 | 9 | 9 | ||
50 | 10 | import datetime | 10 | import datetime |
51 | 11 | from functools import cmp_to_key | ||
52 | 11 | from operator import attrgetter | 12 | from operator import attrgetter |
53 | 12 | 13 | ||
54 | 13 | import apt_pkg | 14 | import apt_pkg |
55 | @@ -559,7 +560,8 @@ class TestGeneralizedPublication(TestCaseWithFactory): | |||
56 | 559 | '1.1v3', | 560 | '1.1v3', |
57 | 560 | ] | 561 | ] |
58 | 561 | spphs = make_spphs_for_versions(self.factory, versions) | 562 | spphs = make_spphs_for_versions(self.factory, versions) |
60 | 562 | sorted_spphs = sorted(spphs, cmp=GeneralizedPublication().compare) | 563 | sorted_spphs = sorted( |
61 | 564 | spphs, key=cmp_to_key(GeneralizedPublication().compare)) | ||
62 | 563 | self.assertEqual( | 565 | self.assertEqual( |
63 | 564 | sorted(versions), list_source_versions(sorted_spphs)) | 566 | sorted(versions), list_source_versions(sorted_spphs)) |
64 | 565 | 567 | ||
65 | @@ -572,16 +574,18 @@ class TestGeneralizedPublication(TestCaseWithFactory): | |||
66 | 572 | ] | 574 | ] |
67 | 573 | spphs = make_spphs_for_versions(self.factory, versions) | 575 | spphs = make_spphs_for_versions(self.factory, versions) |
68 | 574 | 576 | ||
70 | 575 | debian_sorted_versions = sorted(versions, cmp=apt_pkg.version_compare) | 577 | debian_sorted_versions = sorted( |
71 | 578 | versions, key=cmp_to_key(apt_pkg.version_compare)) | ||
72 | 576 | 579 | ||
73 | 577 | # Assumption: in this case, Debian version ordering is not the | 580 | # Assumption: in this case, Debian version ordering is not the |
74 | 578 | # same as alphabetical version ordering. | 581 | # same as alphabetical version ordering. |
75 | 579 | self.assertNotEqual(sorted(versions), debian_sorted_versions) | 582 | self.assertNotEqual(sorted(versions), debian_sorted_versions) |
76 | 580 | 583 | ||
77 | 581 | # The compare method produces the Debian ordering. | 584 | # The compare method produces the Debian ordering. |
79 | 582 | sorted_spphs = sorted(spphs, cmp=GeneralizedPublication().compare) | 585 | sorted_spphs = sorted( |
80 | 586 | spphs, key=cmp_to_key(GeneralizedPublication().compare)) | ||
81 | 583 | self.assertEqual( | 587 | self.assertEqual( |
83 | 584 | sorted(versions, cmp=apt_pkg.version_compare), | 588 | sorted(versions, key=cmp_to_key(apt_pkg.version_compare)), |
84 | 585 | list_source_versions(sorted_spphs)) | 589 | list_source_versions(sorted_spphs)) |
85 | 586 | 590 | ||
86 | 587 | def test_compare_breaks_tie_with_creation_date(self): | 591 | def test_compare_breaks_tie_with_creation_date(self): |
87 | @@ -605,7 +609,7 @@ class TestGeneralizedPublication(TestCaseWithFactory): | |||
88 | 605 | 609 | ||
89 | 606 | self.assertEqual( | 610 | self.assertEqual( |
90 | 607 | [spphs[2], spphs[0], spphs[1]], | 611 | [spphs[2], spphs[0], spphs[1]], |
92 | 608 | sorted(spphs, cmp=GeneralizedPublication().compare)) | 612 | sorted(spphs, key=cmp_to_key(GeneralizedPublication().compare))) |
93 | 609 | 613 | ||
94 | 610 | def test_compare_breaks_tie_for_releases_with_same_version(self): | 614 | def test_compare_breaks_tie_for_releases_with_same_version(self): |
95 | 611 | # When two publications are tied for comparison because they | 615 | # When two publications are tied for comparison because they |
96 | @@ -629,7 +633,7 @@ class TestGeneralizedPublication(TestCaseWithFactory): | |||
97 | 629 | 633 | ||
98 | 630 | self.assertEqual( | 634 | self.assertEqual( |
99 | 631 | [spphs[2], spphs[0], spphs[1]], | 635 | [spphs[2], spphs[0], spphs[1]], |
101 | 632 | sorted(spphs, cmp=GeneralizedPublication().compare)) | 636 | sorted(spphs, key=cmp_to_key(GeneralizedPublication().compare))) |
102 | 633 | 637 | ||
103 | 634 | 638 | ||
104 | 635 | def jumble(ordered_list): | 639 | def jumble(ordered_list): |
105 | diff --git a/lib/lp/archiveuploader/tests/nascentupload-announcements.txt b/lib/lp/archiveuploader/tests/nascentupload-announcements.txt | |||
106 | index 017601f..cd512c3 100644 | |||
107 | --- a/lib/lp/archiveuploader/tests/nascentupload-announcements.txt | |||
108 | +++ b/lib/lp/archiveuploader/tests/nascentupload-announcements.txt | |||
109 | @@ -38,14 +38,11 @@ We need to be logged into the security model in order to get any further | |||
110 | 38 | >>> switch_dbuser('launchpad') | 38 | >>> switch_dbuser('launchpad') |
111 | 39 | >>> login('foo.bar@canonical.com') | 39 | >>> login('foo.bar@canonical.com') |
112 | 40 | 40 | ||
114 | 41 | Helper functions to examine emails that were sent: | 41 | A helper function to examine emails that were sent: |
115 | 42 | 42 | ||
116 | 43 | >>> from lp.services.mail import stub | 43 | >>> from lp.services.mail import stub |
117 | 44 | >>> from lp.testing.mail_helpers import pop_notifications | 44 | >>> from lp.testing.mail_helpers import pop_notifications |
118 | 45 | 45 | ||
119 | 46 | >>> def by_to_addrs(a, b): | ||
120 | 47 | ... return cmp(a[1], b[1]) | ||
121 | 48 | |||
122 | 49 | >>> def print_addrlist(field): | 46 | >>> def print_addrlist(field): |
123 | 50 | ... for entry in sorted([addr.strip() for addr in field.split(',')]): | 47 | ... for entry in sorted([addr.strip() for addr in field.split(',')]): |
124 | 51 | ... print entry | 48 | ... print entry |
125 | diff --git a/lib/lp/bugs/doc/initial-bug-contacts.txt b/lib/lp/bugs/doc/initial-bug-contacts.txt | |||
126 | index 468658c..cd88e6f 100644 | |||
127 | --- a/lib/lp/bugs/doc/initial-bug-contacts.txt | |||
128 | +++ b/lib/lp/bugs/doc/initial-bug-contacts.txt | |||
129 | @@ -157,12 +157,10 @@ track why daf received the email. The rational is repeated in the footer | |||
130 | 157 | of the email with the bug title and URL. | 157 | of the email with the bug title and URL. |
131 | 158 | 158 | ||
132 | 159 | >>> import email | 159 | >>> import email |
136 | 160 | 160 | >>> from operator import itemgetter | |
134 | 161 | >>> def by_to_addrs(a, b): | ||
135 | 162 | ... return cmp(a[1], b[1]) | ||
137 | 163 | 161 | ||
138 | 164 | >>> test_emails = list(stub.test_emails) | 162 | >>> test_emails = list(stub.test_emails) |
140 | 165 | >>> test_emails.sort(by_to_addrs) | 163 | >>> test_emails.sort(key=itemgetter(1)) |
141 | 166 | 164 | ||
142 | 167 | >>> len(test_emails) | 165 | >>> len(test_emails) |
143 | 168 | 1 | 166 | 1 |
144 | diff --git a/lib/lp/registry/browser/product.py b/lib/lp/registry/browser/product.py | |||
145 | index e7dbe7e..36109fe 100644 | |||
146 | --- a/lib/lp/registry/browser/product.py | |||
147 | +++ b/lib/lp/registry/browser/product.py | |||
148 | @@ -664,14 +664,12 @@ class ProductSpecificationsMenu(NavigationMenu, ProductEditLinksMixin, | |||
149 | 664 | 'register_sprint'] | 664 | 'register_sprint'] |
150 | 665 | 665 | ||
151 | 666 | 666 | ||
153 | 667 | def _cmp_distros(a, b): | 667 | def _distro_name_sort_key(name): |
154 | 668 | """Put Ubuntu first, otherwise in alpha order.""" | 668 | """Put Ubuntu first, otherwise in alpha order.""" |
159 | 669 | if a == 'ubuntu': | 669 | if name == 'ubuntu': |
160 | 670 | return -1 | 670 | return (0, ) |
157 | 671 | elif b == 'ubuntu': | ||
158 | 672 | return 1 | ||
161 | 673 | else: | 671 | else: |
163 | 674 | return cmp(a, b) | 672 | return (1, name) |
164 | 675 | 673 | ||
165 | 676 | 674 | ||
166 | 677 | class ProductSetBreadcrumb(Breadcrumb): | 675 | class ProductSetBreadcrumb(Breadcrumb): |
167 | @@ -1227,8 +1225,7 @@ class ProductPackagesView(LaunchpadView): | |||
168 | 1227 | distros[distribution.name] = distro | 1225 | distros[distribution.name] = distro |
169 | 1228 | distro['packagings'].append(packaging) | 1226 | distro['packagings'].append(packaging) |
170 | 1229 | # Now we sort the resulting list of "distro" objects, and return that. | 1227 | # Now we sort the resulting list of "distro" objects, and return that. |
173 | 1230 | distro_names = distros.keys() | 1228 | distro_names = sorted(distros, key=_distro_name_sort_key) |
172 | 1231 | distro_names.sort(cmp=_cmp_distros) | ||
174 | 1232 | results = [distros[name] for name in distro_names] | 1229 | results = [distros[name] for name in distro_names] |
175 | 1233 | return results | 1230 | return results |
176 | 1234 | 1231 | ||
177 | diff --git a/lib/lp/registry/doc/distribution-mirror.txt b/lib/lp/registry/doc/distribution-mirror.txt | |||
178 | index 90bc89e..43e129c 100644 | |||
179 | --- a/lib/lp/registry/doc/distribution-mirror.txt | |||
180 | +++ b/lib/lp/registry/doc/distribution-mirror.txt | |||
181 | @@ -341,10 +341,11 @@ up on the public mirror listings. | |||
182 | 341 | >>> transaction.commit() | 341 | >>> transaction.commit() |
183 | 342 | 342 | ||
184 | 343 | >>> import email | 343 | >>> import email |
185 | 344 | >>> from operator import itemgetter | ||
186 | 344 | >>> from lp.services.mail import stub | 345 | >>> from lp.services.mail import stub |
187 | 345 | >>> len(stub.test_emails) | 346 | >>> len(stub.test_emails) |
188 | 346 | 2 | 347 | 2 |
190 | 347 | >>> stub.test_emails.sort(lambda a, b: cmp(a[1], b[1])) # sort by to_addr | 348 | >>> stub.test_emails.sort(key=itemgetter(1)) # sort by to_addr |
191 | 348 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() | 349 | >>> from_addr, to_addr, raw_message = stub.test_emails.pop() |
192 | 349 | >>> msg = email.message_from_string(raw_message) | 350 | >>> msg = email.message_from_string(raw_message) |
193 | 350 | >>> msg['To'] | 351 | >>> msg['To'] |
194 | diff --git a/lib/lp/registry/doc/teammembership-email-notification.txt b/lib/lp/registry/doc/teammembership-email-notification.txt | |||
195 | index c1c323f..201cc48 100644 | |||
196 | --- a/lib/lp/registry/doc/teammembership-email-notification.txt | |||
197 | +++ b/lib/lp/registry/doc/teammembership-email-notification.txt | |||
198 | @@ -7,8 +7,7 @@ where we might want to notify only the team admins, but in most of the | |||
199 | 7 | cases we'll be sending two similar (but not identical) notifications: | 7 | cases we'll be sending two similar (but not identical) notifications: |
200 | 8 | one for all team admins and another for the member. | 8 | one for all team admins and another for the member. |
201 | 9 | 9 | ||
204 | 10 | >>> def by_to_addrs(a, b): | 10 | >>> from operator import itemgetter |
203 | 11 | ... return cmp(a[1], b[1]) | ||
205 | 12 | 11 | ||
206 | 13 | >>> def setStatus(membership, status, reviewer=None, comment=None, | 12 | >>> def setStatus(membership, status, reviewer=None, comment=None, |
207 | 14 | ... silent=False): | 13 | ... silent=False): |
208 | @@ -186,7 +185,7 @@ The same goes for approving a proposed member. | |||
209 | 186 | >>> setStatus(daf_membership, TeamMembershipStatus.APPROVED, | 185 | >>> setStatus(daf_membership, TeamMembershipStatus.APPROVED, |
210 | 187 | ... reviewer=mark, comment='This is a nice guy; I like him') | 186 | ... reviewer=mark, comment='This is a nice guy; I like him') |
211 | 188 | >>> run_mail_jobs() | 187 | >>> run_mail_jobs() |
213 | 189 | >>> stub.test_emails.sort(by_to_addrs) | 188 | >>> stub.test_emails.sort(key=itemgetter(1)) |
214 | 190 | >>> len(stub.test_emails) | 189 | >>> len(stub.test_emails) |
215 | 191 | 6 | 190 | 6 |
216 | 192 | 191 | ||
217 | @@ -236,7 +235,7 @@ The same for deactivating a membership. | |||
218 | 236 | >>> setStatus(daf_membership, TeamMembershipStatus.DEACTIVATED, | 235 | >>> setStatus(daf_membership, TeamMembershipStatus.DEACTIVATED, |
219 | 237 | ... reviewer=mark) | 236 | ... reviewer=mark) |
220 | 238 | >>> run_mail_jobs() | 237 | >>> run_mail_jobs() |
222 | 239 | >>> stub.test_emails.sort(by_to_addrs) | 238 | >>> stub.test_emails.sort(key=itemgetter(1)) |
223 | 240 | >>> len(stub.test_emails) | 239 | >>> len(stub.test_emails) |
224 | 241 | 6 | 240 | 6 |
225 | 242 | 241 | ||
226 | diff --git a/lib/lp/registry/tests/test_distroseriesdifferencecomment.py b/lib/lp/registry/tests/test_distroseriesdifferencecomment.py | |||
227 | index beeaecd..f95aac7 100644 | |||
228 | --- a/lib/lp/registry/tests/test_distroseriesdifferencecomment.py | |||
229 | +++ b/lib/lp/registry/tests/test_distroseriesdifferencecomment.py | |||
230 | @@ -6,7 +6,7 @@ | |||
231 | 6 | __metaclass__ = type | 6 | __metaclass__ = type |
232 | 7 | 7 | ||
233 | 8 | from datetime import timedelta | 8 | from datetime import timedelta |
235 | 9 | from random import randint | 9 | from random import random |
236 | 10 | 10 | ||
237 | 11 | from storm.store import Store | 11 | from storm.store import Store |
238 | 12 | from zope.component import getUtility | 12 | from zope.component import getUtility |
239 | @@ -31,14 +31,9 @@ def get_comment_source(): | |||
240 | 31 | return getUtility(IDistroSeriesDifferenceCommentSource) | 31 | return getUtility(IDistroSeriesDifferenceCommentSource) |
241 | 32 | 32 | ||
242 | 33 | 33 | ||
243 | 34 | def flip_coin(*args): | ||
244 | 35 | """Random comparison function. Returns -1 or 1 randomly.""" | ||
245 | 36 | return 1 - 2 * randint(0, 1) | ||
246 | 37 | |||
247 | 38 | |||
248 | 39 | def randomize_list(original_list): | 34 | def randomize_list(original_list): |
249 | 40 | """Sort a list (or other iterable) in random order. Return list.""" | 35 | """Sort a list (or other iterable) in random order. Return list.""" |
251 | 41 | return sorted(original_list, cmp=flip_coin) | 36 | return sorted(original_list, key=lambda _: random) |
252 | 42 | 37 | ||
253 | 43 | 38 | ||
254 | 44 | class DistroSeriesDifferenceCommentTestCase(TestCaseWithFactory): | 39 | class DistroSeriesDifferenceCommentTestCase(TestCaseWithFactory): |
255 | diff --git a/lib/lp/services/doc/orderingcheck.txt b/lib/lp/services/doc/orderingcheck.txt | |||
256 | index 9ed2b0b..fe9294f 100644 | |||
257 | --- a/lib/lp/services/doc/orderingcheck.txt | |||
258 | +++ b/lib/lp/services/doc/orderingcheck.txt | |||
259 | @@ -29,10 +29,7 @@ Sorting criteria | |||
260 | 29 | The OrderingCheck accepts all the same sorting options (as keyword args) | 29 | The OrderingCheck accepts all the same sorting options (as keyword args) |
261 | 30 | as Python's built-in sorting functions. | 30 | as Python's built-in sorting functions. |
262 | 31 | 31 | ||
267 | 32 | >>> def sort_cmp(left_item, right_item): | 32 | >>> checker = OrderingCheck(key=lambda v: v, reverse=True) |
264 | 33 | ... return left_item - right_item | ||
265 | 34 | |||
266 | 35 | >>> checker = OrderingCheck(cmp=sort_cmp, reverse=True) | ||
268 | 36 | >>> for number in (3, 2, 1): | 33 | >>> for number in (3, 2, 1): |
269 | 37 | ... checker.check(number) | 34 | ... checker.check(number) |
270 | 38 | 35 | ||
271 | diff --git a/lib/lp/services/webapp/sorting.py b/lib/lp/services/webapp/sorting.py | |||
272 | index dc1a453..6d34142 100644 | |||
273 | --- a/lib/lp/services/webapp/sorting.py | |||
274 | +++ b/lib/lp/services/webapp/sorting.py | |||
275 | @@ -16,14 +16,14 @@ import six | |||
276 | 16 | def expand_numbers(unicode_text, fill_digits=4): | 16 | def expand_numbers(unicode_text, fill_digits=4): |
277 | 17 | """Return a copy of the string with numbers zero filled. | 17 | """Return a copy of the string with numbers zero filled. |
278 | 18 | 18 | ||
287 | 19 | >>> expand_numbers(u'hello world') | 19 | >>> print(expand_numbers(u'hello world')) |
288 | 20 | u'hello world' | 20 | hello world |
289 | 21 | >>> expand_numbers(u'0.12.1') | 21 | >>> print(expand_numbers(u'0.12.1')) |
290 | 22 | u'0000.0012.0001' | 22 | 0000.0012.0001 |
291 | 23 | >>> expand_numbers(u'0.12.1', 2) | 23 | >>> print(expand_numbers(u'0.12.1', 2)) |
292 | 24 | u'00.12.01' | 24 | 00.12.01 |
293 | 25 | >>> expand_numbers(u'branch-2-3.12') | 25 | >>> print(expand_numbers(u'branch-2-3.12')) |
294 | 26 | u'branch-0002-0003.0012' | 26 | branch-0002-0003.0012 |
295 | 27 | 27 | ||
296 | 28 | """ | 28 | """ |
297 | 29 | assert(isinstance(unicode_text, six.text_type)) | 29 | assert(isinstance(unicode_text, six.text_type)) |
298 | @@ -40,26 +40,22 @@ reversed_numbers_table = dict( | |||
299 | 40 | zip(map(ord, u'0123456789'), reversed(u'0123456789'))) | 40 | zip(map(ord, u'0123456789'), reversed(u'0123456789'))) |
300 | 41 | 41 | ||
301 | 42 | 42 | ||
303 | 43 | def _reversed_number_comparator(lhs_text, rhs_text): | 43 | def _reversed_number_sort_key(text): |
304 | 44 | """Return comparison value reversed for numbers only. | 44 | """Return comparison value reversed for numbers only. |
305 | 45 | 45 | ||
316 | 46 | >>> _reversed_number_comparator(u'9.3', u'2.4') | 46 | >>> print(_reversed_number_sort_key(u'9.3')) |
317 | 47 | -1 | 47 | 0.6 |
318 | 48 | >>> _reversed_number_comparator(u'world', u'hello') | 48 | >>> print(_reversed_number_sort_key(u'2.4')) |
319 | 49 | 1 | 49 | 7.5 |
320 | 50 | >>> _reversed_number_comparator(u'hello world', u'hello world') | 50 | >>> print(_reversed_number_sort_key(u'hello')) |
321 | 51 | 0 | 51 | hello |
322 | 52 | >>> _reversed_number_comparator(u'dev', u'development') | 52 | >>> print(_reversed_number_sort_key(u'bzr-0.13')) |
323 | 53 | -1 | 53 | bzr-9.86 |
314 | 54 | >>> _reversed_number_comparator(u'bzr-0.13', u'bzr-0.08') | ||
315 | 55 | -1 | ||
324 | 56 | 54 | ||
325 | 57 | """ | 55 | """ |
331 | 58 | assert isinstance(lhs_text, six.text_type) | 56 | assert isinstance(text, six.text_type) |
332 | 59 | assert isinstance(rhs_text, six.text_type) | 57 | assert isinstance(text, six.text_type) |
333 | 60 | translated_lhs_text = lhs_text.translate(reversed_numbers_table) | 58 | return text.translate(reversed_numbers_table) |
329 | 61 | translated_rhs_text = rhs_text.translate(reversed_numbers_table) | ||
330 | 62 | return cmp(translated_lhs_text, translated_rhs_text) | ||
334 | 63 | 59 | ||
335 | 64 | 60 | ||
336 | 65 | def _identity(x): | 61 | def _identity(x): |
337 | @@ -71,13 +67,13 @@ def sorted_version_numbers(sequence, key=_identity): | |||
338 | 71 | 67 | ||
339 | 72 | >>> bzr_versions = [u'0.9', u'0.10', u'0.11'] | 68 | >>> bzr_versions = [u'0.9', u'0.10', u'0.11'] |
340 | 73 | >>> for version in sorted_version_numbers(bzr_versions): | 69 | >>> for version in sorted_version_numbers(bzr_versions): |
342 | 74 | ... print version | 70 | ... print(version) |
343 | 75 | 0.11 | 71 | 0.11 |
344 | 76 | 0.10 | 72 | 0.10 |
345 | 77 | 0.9 | 73 | 0.9 |
346 | 78 | >>> bzr_versions = [u'bzr-0.9', u'bzr-0.10', u'bzr-0.11'] | 74 | >>> bzr_versions = [u'bzr-0.9', u'bzr-0.10', u'bzr-0.11'] |
347 | 79 | >>> for version in sorted_version_numbers(bzr_versions): | 75 | >>> for version in sorted_version_numbers(bzr_versions): |
349 | 80 | ... print version | 76 | ... print(version) |
350 | 81 | bzr-0.11 | 77 | bzr-0.11 |
351 | 82 | bzr-0.10 | 78 | bzr-0.10 |
352 | 83 | bzr-0.9 | 79 | bzr-0.9 |
353 | @@ -91,7 +87,7 @@ def sorted_version_numbers(sequence, key=_identity): | |||
354 | 91 | >>> from operator import attrgetter | 87 | >>> from operator import attrgetter |
355 | 92 | >>> for version in sorted_version_numbers(bzr_versions, | 88 | >>> for version in sorted_version_numbers(bzr_versions, |
356 | 93 | ... key=attrgetter('name')): | 89 | ... key=attrgetter('name')): |
358 | 94 | ... print version.name | 90 | ... print(version.name) |
359 | 95 | 0.11 | 91 | 0.11 |
360 | 96 | 0.10 | 92 | 0.10 |
361 | 97 | 0.9 | 93 | 0.9 |
362 | @@ -101,9 +97,9 @@ def sorted_version_numbers(sequence, key=_identity): | |||
363 | 101 | foo | 97 | foo |
364 | 102 | 98 | ||
365 | 103 | """ | 99 | """ |
369 | 104 | expanded_key = lambda x: expand_numbers(key(x)) | 100 | return sorted( |
370 | 105 | return sorted(sequence, key=expanded_key, | 101 | sequence, |
371 | 106 | cmp=_reversed_number_comparator) | 102 | key=lambda x: _reversed_number_sort_key(expand_numbers(key(x)))) |
372 | 107 | 103 | ||
373 | 108 | 104 | ||
374 | 109 | def sorted_dotted_numbers(sequence, key=_identity): | 105 | def sorted_dotted_numbers(sequence, key=_identity): |
375 | @@ -117,13 +113,13 @@ def sorted_dotted_numbers(sequence, key=_identity): | |||
376 | 117 | 113 | ||
377 | 118 | >>> bzr_versions = [u'0.9', u'0.10', u'0.11'] | 114 | >>> bzr_versions = [u'0.9', u'0.10', u'0.11'] |
378 | 119 | >>> for version in sorted_dotted_numbers(bzr_versions): | 115 | >>> for version in sorted_dotted_numbers(bzr_versions): |
380 | 120 | ... print version | 116 | ... print(version) |
381 | 121 | 0.9 | 117 | 0.9 |
382 | 122 | 0.10 | 118 | 0.10 |
383 | 123 | 0.11 | 119 | 0.11 |
384 | 124 | >>> bzr_versions = [u'bzr-0.9', u'bzr-0.10', u'bzr-0.11'] | 120 | >>> bzr_versions = [u'bzr-0.9', u'bzr-0.10', u'bzr-0.11'] |
385 | 125 | >>> for version in sorted_dotted_numbers(bzr_versions): | 121 | >>> for version in sorted_dotted_numbers(bzr_versions): |
387 | 126 | ... print version | 122 | ... print(version) |
388 | 127 | bzr-0.9 | 123 | bzr-0.9 |
389 | 128 | bzr-0.10 | 124 | bzr-0.10 |
390 | 129 | bzr-0.11 | 125 | bzr-0.11 |
391 | @@ -137,7 +133,7 @@ def sorted_dotted_numbers(sequence, key=_identity): | |||
392 | 137 | >>> from operator import attrgetter | 133 | >>> from operator import attrgetter |
393 | 138 | >>> for version in sorted_dotted_numbers(bzr_versions, | 134 | >>> for version in sorted_dotted_numbers(bzr_versions, |
394 | 139 | ... key=attrgetter('name')): | 135 | ... key=attrgetter('name')): |
396 | 140 | ... print version.name | 136 | ... print(version.name) |
397 | 141 | 0.9 | 137 | 0.9 |
398 | 142 | 0.10 | 138 | 0.10 |
399 | 143 | 0.11 | 139 | 0.11 |
400 | @@ -147,5 +143,4 @@ def sorted_dotted_numbers(sequence, key=_identity): | |||
401 | 147 | foo | 143 | foo |
402 | 148 | 144 | ||
403 | 149 | """ | 145 | """ |
406 | 150 | expanded_key = lambda x: expand_numbers(key(x)) | 146 | return sorted(sequence, key=lambda x: expand_numbers(key(x))) |
405 | 151 | return sorted(sequence, key=expanded_key) |