py3: get rid of __cmp__

This commit is contained in:
Kovid Goyal 2019-03-28 11:24:37 +05:30
parent 775ffdee21
commit 57e11977b7
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
7 changed files with 137 additions and 51 deletions

View File

@ -11,7 +11,7 @@ import os, traceback, random, shutil, operator
from io import BytesIO
from collections import defaultdict, Set, MutableSet
from functools import wraps, partial
from polyglot.builtins import iteritems, itervalues, unicode_type, zip, string_or_bytes
from polyglot.builtins import iteritems, itervalues, unicode_type, zip, string_or_bytes, cmp
from time import time
from calibre import isbytestring, as_unicode
@ -956,14 +956,14 @@ class Cache(object):
class SortKey(object):
__slots__ = ('book_id', 'sort_key')
__slots__ = 'book_id', 'sort_key'
def __init__(self, book_id):
self.book_id = book_id
# Calculate only the first sub-sort key since that will always be used
self.sort_key = [key(book_id) if i == 0 else Lazy for i, key in enumerate(sort_key_funcs)]
def __cmp__(self, other):
def compare_to_other(self, other):
for i, (order, self_key, other_key) in enumerate(zip(orders, self.sort_key, other.sort_key)):
if self_key is Lazy:
self_key = self.sort_key[i] = sort_key_funcs[i](self.book_id)
@ -974,6 +974,24 @@ class Cache(object):
return ans * order
return 0
def __eq__(self, other):
return self.compare_to_other(other) == 0
def __ne__(self, other):
return self.compare_to_other(other) != 0
def __lt__(self, other):
return self.compare_to_other(other) < 0
def __le__(self, other):
return self.compare_to_other(other) <= 0
def __gt__(self, other):
return self.compare_to_other(other) > 0
def __ge__(self, other):
return self.compare_to_other(other) >= 0
return sorted(ids_to_sort, key=SortKey)
@read_api

View File

@ -8,13 +8,14 @@ __copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import re, threading
from functools import total_ordering
from calibre import browser, random_user_agent
from calibre.customize import Plugin
from calibre.ebooks.metadata import check_isbn
from calibre.ebooks.metadata.author_mapper import cap_author_token
from calibre.utils.localization import canonicalize_lang, get_lang
from polyglot.builtins import iteritems
from polyglot.builtins import iteritems, cmp
def create_log(ostream=None):
@ -41,6 +42,7 @@ def cleanup_title(s):
return s.strip()
@total_ordering
class InternalMetadataCompareKeyGen(object):
'''
@ -86,21 +88,38 @@ class InternalMetadataCompareKeyGen(object):
source_plugin.get_cached_cover_url(mi.identifiers) is None) else 1
self.base = (same_identifier, has_cover, all_fields, language, exact_title)
self.comments_len = len(mi.comments.strip() if mi.comments else '')
self.extra = (getattr(mi, 'source_relevance', 0), )
self.comments_len = len((mi.comments or '').strip())
self.extra = getattr(mi, 'source_relevance', 0)
def __cmp__(self, other):
result = cmp(self.base, other.base)
if result == 0:
# Now prefer results with the longer comments, within 10%
def compare_to_other(self, other):
a = cmp(self.base, other.base)
if a != 0:
return a
cx, cy = self.comments_len, other.comments_len
if cx and cy:
t = (cx + cy) / 20
delta = cy - cx
if abs(delta) > t:
result = delta
else:
result = cmp(self.extra, other.extra)
return result
return -1 if delta < 0 else 1
return cmp(self.extra, other.extra)
def __eq__(self, other):
return self.compare_to_other(other) == 0
def __ne__(self, other):
return self.compare_to_other(other) != 0
def __lt__(self, other):
return self.compare_to_other(other) < 0
def __le__(self, other):
return self.compare_to_other(other) <= 0
def __gt__(self, other):
return self.compare_to_other(other) > 0
def __ge__(self, other):
return self.compare_to_other(other) >= 0
# }}}

View File

@ -6,6 +6,7 @@
import textwrap
from collections import OrderedDict
from functools import partial
from operator import attrgetter
from PyQt5.Qt import (
QAbstractListModel, QApplication, QDialog, QDialogButtonBox, QFont, QGridLayout,
@ -104,9 +105,9 @@ class Tweak(object): # {{{
ans = ans.encode('utf-8')
return ans
def __cmp__(self, other):
return -1 * cmp(self.is_customized,
getattr(other, 'is_customized', False))
@property
def sort_key(self):
return 0 if self.is_customized else 1
@property
def is_customized(self):
@ -190,7 +191,7 @@ class Tweaks(QAbstractListModel, AdaptSQP): # {{{
pos = self.read_tweak(lines, pos, default_tweaks, custom_tweaks)
pos += 1
self.tweaks.sort()
self.tweaks.sort(key=attrgetter('sort_key'))
default_keys = set(default_tweaks)
custom_keys = set(custom_tweaks)

View File

@ -1113,13 +1113,31 @@ class SortKey(object):
def __init__(self, orders, values):
self.orders, self.values = orders, values
def __cmp__(self, other):
def compare_to_other(self, other):
for i, ascending in enumerate(self.orders):
ans = cmp(self.values[i], other.values[i])
if ans != 0:
return ans * ascending
return 0
def __eq__(self, other):
return self.compare_to_other(other) == 0
def __ne__(self, other):
return self.compare_to_other(other) != 0
def __lt__(self, other):
return self.compare_to_other(other) < 0
def __le__(self, other):
return self.compare_to_other(other) <= 0
def __gt__(self, other):
return self.compare_to_other(other) > 0
def __ge__(self, other):
return self.compare_to_other(other) >= 0
class SortKeyGenerator(object):

View File

@ -6,13 +6,17 @@ __license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
_count = 0
import time, io
from itertools import count
from calibre import prints
from calibre.constants import DEBUG
from polyglot.queue import Queue, Empty
from polyglot.builtins import cmp
job_counter = count()
class BaseJob(object):
@ -22,10 +26,7 @@ class BaseJob(object):
FINISHED = 2
def __init__(self, description, done=lambda x: x):
global _count
_count += 1
self.id = _count
self.id = next(job_counter)
self.description = description
self.done = done
self.done2 = None
@ -125,22 +126,36 @@ class BaseJob(object):
def is_running(self):
return self.is_started and not self.is_finished
def __cmp__(self, other):
if self.is_finished == other.is_finished:
def __eq__(self, other):
return self is other
def __ne__(self, other):
return self is not other
def __lt__(self, other):
return self.compare_to_other(other) < 0
def __le__(self, other):
return self.compare_to_other(other) <= 0
def __gt__(self, other):
return self.compare_to_other(other) > 0
def __ge__(self, other):
return self.compare_to_other(other) >= 0
def compare_to_other(self, other):
if self.is_finished != other.is_finished:
return 1 if self.is_finished else -1
if self.start_time is None:
if other.start_time is None: # Both waiting
return cmp(other.id, self.id)
else:
return 1
else:
if other.start_time is None:
return -1
else: # Both running
return cmp(other.start_time, self.start_time)
else:
return 1 if self.is_finished else -1
return 0
# Both running
return cmp((other.start_time, id(other)), (self.start_time, id(self)))
@property
def log_file(self):

View File

@ -7,6 +7,7 @@ __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import copy, zipfile
from functools import total_ordering
from PyQt5.Qt import QAbstractItemModel, Qt, QColor, QFont, QIcon, \
QModelIndex, pyqtSignal, QPixmap
@ -18,6 +19,8 @@ from calibre.web.feeds.recipes.collection import \
SchedulerConfig, download_builtin_recipe, update_custom_recipe, \
update_custom_recipes, add_custom_recipe, add_custom_recipes, \
remove_custom_recipe, get_custom_recipe, get_builtin_recipe
from calibre import force_unicode
from calibre.utils.icu import primary_sort_key
from calibre.utils.search_query_parser import ParseException
from polyglot.builtins import iteritems, unicode_type
@ -59,12 +62,19 @@ class NewsTreeItem(object):
child.parent = None
@total_ordering
class NewsCategory(NewsTreeItem):
def __init__(self, category, builtin, custom, scheduler_config, parent):
NewsTreeItem.__init__(self, builtin, custom, scheduler_config, parent)
self.category = category
self.cdata = get_language(self.category)
if self.category == _('Scheduled'):
self.sortq = 0, ''
elif self.category == _('Custom'):
self.sortq = 1, ''
else:
self.sortq = 2, self.cdata
self.bold_font = QFont()
self.bold_font.setBold(True)
self.bold_font = (self.bold_font)
@ -81,25 +91,23 @@ class NewsCategory(NewsTreeItem):
def flags(self):
return Qt.ItemIsEnabled
def __cmp__(self, other):
def decorate(x):
if x == _('Scheduled'):
x = '0' + x
elif x == _('Custom'):
x = '1' + x
else:
x = '2' + x
return x
def __eq__(self, other):
return self.cdata == other.cdata
return cmp(decorate(self.cdata), decorate(getattr(other, 'cdata', '')))
def __lt__(self, other):
return self.sortq < getattr(other, 'sortq', (3, ''))
@total_ordering
class NewsItem(NewsTreeItem):
def __init__(self, urn, title, default_icon, custom_icon, favicons, zf,
builtin, custom, scheduler_config, parent):
NewsTreeItem.__init__(self, builtin, custom, scheduler_config, parent)
self.urn, self.title = urn, title
if isinstance(self.title, bytes):
self.title = force_unicode(self.title)
self.sortq = primary_sort_key(self.title)
self.icon = self.default_icon = None
self.default_icon = default_icon
self.favicons, self.zf = favicons, zf
@ -126,8 +134,11 @@ class NewsItem(NewsTreeItem):
return self.icon
return None
def __cmp__(self, other):
return cmp(self.title.lower(), getattr(other, 'title', '').lower())
def __eq__(self, other):
return self.urn == other.urn
def __lt__(self, other):
return self.sortq < other.sortq
class AdaptSQP(SearchQueryParser):

View File

@ -56,6 +56,9 @@ if is_py3:
code = compile(code, f.name, 'exec')
exec(code, ctx)
def cmp(a, b):
return (a > b) - (a < b)
else:
exec("""def reraise(tp, value, tb=None):
try:
@ -74,6 +77,7 @@ else:
long_type = long
exec_path = execfile
raw_input = builtins.raw_input
cmp = builtins.cmp
def iteritems(d):
return d.iteritems()