|
9 | 9 | import datetime
|
10 | 10 | import json
|
11 | 11 | import os
|
| 12 | +import itertools |
12 | 13 |
|
13 | 14 | import aniso8601
|
14 | 15 | import sqlalchemy
|
@@ -208,8 +209,8 @@ class Order(self.base, ParameterizedMixin):
|
208 | 209 | __tablename__ = db_key_name + '_Order'
|
209 | 210 |
|
210 | 211 | # We guarantee that our fields are stored in the order they are
|
211 |
| - # supposed to be lexicographically compared, the __cmp__ method |
212 |
| - # relies on this. |
| 212 | + # supposed to be lexicographically compared, the rich comparison |
| 213 | + # methods rely on this. |
213 | 214 | fields = sorted(self.order_fields,
|
214 | 215 | key=lambda of: of.ordinal)
|
215 | 216 |
|
@@ -274,17 +275,58 @@ def as_ordered_string(self):
|
274 | 275 | def name(self):
|
275 | 276 | return self.as_ordered_string()
|
276 | 277 |
|
277 |
| - def __cmp__(self, b): |
| 278 | + def _get_comparison_discriminant(self, b): |
| 279 | + """Return a representative pair of converted revision from self |
| 280 | + and b. Order of the element on this pair is the same as the |
| 281 | + order of self relative to b. |
| 282 | + """ |
278 | 283 | # SA occasionally uses comparison to check model instances
|
279 |
| - # verse some sentinels, so we ensure we support comparison |
| 284 | + # versus some sentinels, so we ensure we support comparison |
280 | 285 | # against non-instances.
|
281 | 286 | if self.__class__ is not b.__class__:
|
282 |
| - return -1 |
283 |
| - # Compare every field in lexicographic order. |
284 |
| - return cmp([convert_revision(self.get_field(item), cache=Order.order_name_cache) |
285 |
| - for item in self.fields], |
286 |
| - [convert_revision(b.get_field(item), cache=Order.order_name_cache) |
287 |
| - for item in self.fields]) |
| 287 | + return (0, 1) |
| 288 | + |
| 289 | + # Pair converted revision from self and b. |
| 290 | + converted_revisions = map( |
| 291 | + lambda item: ( |
| 292 | + convert_revision( |
| 293 | + self.get_field(item), cache=Order.order_name_cache |
| 294 | + ), |
| 295 | + convert_revision( |
| 296 | + b.get_field(item), cache=Order.order_name_cache |
| 297 | + ), |
| 298 | + ), |
| 299 | + self.fields, |
| 300 | + ) |
| 301 | + # Return the first unequal pair, or (0, 0) otherwise. |
| 302 | + return next( |
| 303 | + itertools.dropwhile(lambda x: x[0] == x[1], converted_revisions), |
| 304 | + (0, 0), |
| 305 | + ) |
| 306 | + |
| 307 | + def __eq__(self, b): |
| 308 | + discriminant = self._get_comparison_discriminant(b) |
| 309 | + return discriminant[0] == discriminant[1] |
| 310 | + |
| 311 | + def __ne__(self, b): |
| 312 | + discriminant = self._get_comparison_discriminant(b) |
| 313 | + return discriminant[0] != discriminant[1] |
| 314 | + |
| 315 | + def __lt__(self, b): |
| 316 | + discriminant = self._get_comparison_discriminant(b) |
| 317 | + return discriminant[0] < discriminant[1] |
| 318 | + |
| 319 | + def __le__(self, b): |
| 320 | + discriminant = self._get_comparison_discriminant(b) |
| 321 | + return discriminant[0] <= discriminant[1] |
| 322 | + |
| 323 | + def __gt__(self, b): |
| 324 | + discriminant = self._get_comparison_discriminant(b) |
| 325 | + return discriminant[0] > discriminant[1] |
| 326 | + |
| 327 | + def __ge__(self, b): |
| 328 | + discriminant = self._get_comparison_discriminant(b) |
| 329 | + return discriminant[0] >= discriminant[1] |
288 | 330 |
|
289 | 331 | def __json__(self, include_id=True):
|
290 | 332 | result = {}
|
|
0 commit comments