diff --git a/manual/epub.py b/manual/epub.py
index f16652b56d..dd93e34817 100644
--- a/manual/epub.py
+++ b/manual/epub.py
@@ -15,6 +15,7 @@ from calibre.ebooks.oeb.polish.container import get_container, OEB_DOCS
from calibre.ebooks.oeb.polish.check.links import check_links, UnreferencedResource
from calibre.ebooks.oeb.polish.pretty import pretty_html_tree, pretty_opf
from calibre.utils.imghdr import identify
+from polyglot.builtins import iteritems
class EPUBHelpBuilder(EpubBuilder):
@@ -28,7 +29,7 @@ class EPUBHelpBuilder(EpubBuilder):
def fix_epub(self, container):
' Fix all the brokenness that sphinx\'s epub builder creates '
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_DOCS:
self.workaround_ade_quirks(container, name)
pretty_html_tree(container, container.parsed(name))
@@ -49,9 +50,9 @@ class EPUBHelpBuilder(EpubBuilder):
def fix_opf(self, container):
spine_names = {n for n, l in container.spine_names}
spine = container.opf_xpath('//opf:spine')[0]
- rmap = {v:k for k, v in container.manifest_id_map.iteritems()}
+ rmap = {v:k for k, v in iteritems(container.manifest_id_map)}
# Add unreferenced text files to the spine
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_DOCS and name not in spine_names:
spine_names.add(name)
container.insert_into_xml(spine, spine.makeelement(OPF('itemref'), idref=rmap[name]))
diff --git a/setup.cfg b/setup.cfg
index af4550aa0a..2198e55434 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -2,6 +2,8 @@
max-line-length = 160
builtins = _,dynamic_property,__,P,I,lopen,icu_lower,icu_upper,icu_title,ngettext,connect_lambda
ignore = E12,E203,E22,E231,E241,E401,E402,E731,W391,E722,E741,W504
+per-file-ignores =
+ src/polyglot/*:F401
[yapf]
based_on_style = pep8
diff --git a/setup/browser_data.py b/setup/browser_data.py
index 16b3f1fbab..7ee2e6263f 100644
--- a/setup/browser_data.py
+++ b/setup/browser_data.py
@@ -10,11 +10,13 @@ from datetime import datetime
from setup import download_securely
+from polyglot.builtins import filter
+
is_ci = os.environ.get('CI', '').lower() == 'true'
def filter_ans(ans):
- return filter(None, (x.strip() for x in ans))
+ return list(filter(None, (x.strip() for x in ans)))
def common_user_agents():
diff --git a/setup/plugins_mirror.py b/setup/plugins_mirror.py
index 0d799cb3ab..f2424384b5 100644
--- a/setup/plugins_mirror.py
+++ b/setup/plugins_mirror.py
@@ -33,6 +33,7 @@ from email.utils import parsedate
from functools import partial
from multiprocessing.pool import ThreadPool
from xml.sax.saxutils import escape, quoteattr
+from polyglot.builtins import iteritems, itervalues
# }}}
USER_AGENT = 'calibre mirror'
@@ -292,7 +293,7 @@ def get_plugin_info(raw, check_for_qt5=False):
metadata = names[inits[0]]
else:
# Legacy plugin
- for name, val in names.iteritems():
+ for name, val in iteritems(names):
if name.endswith('plugin.py'):
metadata = val
break
@@ -331,7 +332,7 @@ def update_plugin_from_entry(plugin, entry):
def fetch_plugin(old_index, entry):
- lm_map = {plugin['thread_id']:plugin for plugin in old_index.itervalues()}
+ lm_map = {plugin['thread_id']:plugin for plugin in itervalues(old_index)}
raw = read(entry.url)
url, name = parse_plugin_zip_url(raw)
if url is None:
@@ -373,10 +374,10 @@ def parallel_fetch(old_index, entry):
def log(*args, **kwargs):
- print (*args, **kwargs)
+ print(*args, **kwargs)
with open('log', 'a') as f:
kwargs['file'] = f
- print (*args, **kwargs)
+ print(*args, **kwargs)
def atomic_write(raw, name):
@@ -403,7 +404,7 @@ def fetch_plugins(old_index):
log('Failed to get plugin', entry.name, 'at', datetime.utcnow().isoformat(), 'with error:')
log(plugin)
# Move staged files
- for plugin in ans.itervalues():
+ for plugin in itervalues(ans):
if plugin['file'].startswith('staging_'):
src = plugin['file']
plugin['file'] = src.partition('_')[-1]
@@ -411,7 +412,7 @@ def fetch_plugins(old_index):
raw = bz2.compress(json.dumps(ans, sort_keys=True, indent=4, separators=(',', ': ')))
atomic_write(raw, PLUGINS)
# Cleanup any extra .zip files
- all_plugin_files = {p['file'] for p in ans.itervalues()}
+ all_plugin_files = {p['file'] for p in itervalues(ans)}
extra = set(glob.glob('*.zip')) - all_plugin_files
for x in extra:
os.unlink(x)
@@ -498,7 +499,7 @@ h1 { text-align: center }
name, count = x
return '
%s
%s
\n' % (escape(name), count)
- pstats = map(plugin_stats, sorted(stats.iteritems(), reverse=True, key=lambda x:x[1]))
+ pstats = map(plugin_stats, sorted(iteritems(stats), reverse=True, key=lambda x:x[1]))
stats = '''\
@@ -681,7 +682,7 @@ def test_parse(): # {{{
new_entries = tuple(parse_index(raw))
for i, entry in enumerate(old_entries):
if entry != new_entries[i]:
- print ('The new entry: %s != %s' % (new_entries[i], entry))
+ print('The new entry: %s != %s' % (new_entries[i], entry))
raise SystemExit(1)
pool = ThreadPool(processes=20)
urls = [e.url for e in new_entries]
@@ -698,7 +699,7 @@ def test_parse(): # {{{
break
new_url, aname = parse_plugin_zip_url(raw)
if new_url != full_url:
- print ('new url (%s): %s != %s for plugin at: %s' % (aname, new_url, full_url, url))
+ print('new url (%s): %s != %s for plugin at: %s' % (aname, new_url, full_url, url))
raise SystemExit(1)
# }}}
diff --git a/setup/resources.py b/setup/resources.py
index 7f9fc7e1db..9855dad9dc 100644
--- a/setup/resources.py
+++ b/setup/resources.py
@@ -64,7 +64,7 @@ class Coffee(Command): # {{{
for src in self.COFFEE_DIRS:
for f in glob.glob(self.j(self.SRC, __appname__, src,
'*.coffee')):
- bn = os.path.basename(f).rpartition('.')[0]
+ bn = self.b(f).rpartition('.')[0]
arcname = src.replace('/', '.') + '.' + bn + '.js'
try:
with open(f, 'rb') as fs:
@@ -270,7 +270,7 @@ class RecentUAs(Command): # {{{
from setup.browser_data import get_data
data = get_data()
with open(self.UA_PATH, 'wb') as f:
- f.write(json.dumps(data, indent=2))
+ f.write(json.dumps(data, indent=2).encode('utf-8'))
# }}}
@@ -300,7 +300,7 @@ class Resources(Command): # {{{
dest = self.j(self.RESOURCES, 'scripts.calibre_msgpack')
if self.newer(dest, self.j(self.SRC, 'calibre', 'linux.py')):
- self.info('\tCreating ' + os.path.basename(dest))
+ self.info('\tCreating ' + self.b(dest))
with open(dest, 'wb') as f:
f.write(msgpack_dumps(scripts))
@@ -325,7 +325,7 @@ class Resources(Command): # {{{
with zipfile.ZipFile(dest, 'w', zipfile.ZIP_STORED) as zf:
for n in sorted(files, key=self.b):
with open(n, 'rb') as f:
- zf.writestr(os.path.basename(n), f.read())
+ zf.writestr(self.b(n), f.read())
dest = self.j(self.RESOURCES, 'ebook-convert-complete.calibre_msgpack')
files = []
@@ -334,7 +334,7 @@ class Resources(Command): # {{{
if f.endswith('.py'):
files.append(self.j(x[0], f))
if self.newer(dest, files):
- self.info('\tCreating ' + dest)
+ self.info('\tCreating ' + self.b(dest))
complete = {}
from calibre.ebooks.conversion.plumber import supported_input_formats
complete['input_fmts'] = set(supported_input_formats())
diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py
index 5f441311e4..e17ab12edb 100644
--- a/src/calibre/__init__.py
+++ b/src/calibre/__init__.py
@@ -4,7 +4,8 @@ __copyright__ = '2008, Kovid Goyal '
__docformat__ = 'restructuredtext en'
import sys, os, re, time, random, warnings
-from polyglot.builtins import builtins, codepoint_to_chr, unicode_type, range
+from polyglot.builtins import (builtins, codepoint_to_chr, iteritems,
+ itervalues, unicode_type, range)
builtins.__dict__['dynamic_property'] = lambda func: func(None)
from math import floor
from functools import partial
@@ -706,7 +707,7 @@ def remove_bracketed_text(src,
counts = Counter()
buf = []
src = force_unicode(src)
- rmap = dict([(v, k) for k, v in brackets.iteritems()])
+ rmap = dict([(v, k) for k, v in iteritems(brackets)])
for char in src:
if char in brackets:
counts[char] += 1
@@ -714,7 +715,7 @@ def remove_bracketed_text(src,
idx = rmap[char]
if counts[idx] > 0:
counts[idx] -= 1
- elif sum(counts.itervalues()) < 1:
+ elif sum(itervalues(counts)) < 1:
buf.append(char)
return u''.join(buf)
diff --git a/src/calibre/customize/__init__.py b/src/calibre/customize/__init__.py
index 2a6135fae5..15568991f7 100644
--- a/src/calibre/customize/__init__.py
+++ b/src/calibre/customize/__init__.py
@@ -212,7 +212,7 @@ class Plugin(object): # {{{
For example to load an image::
pixmap = QPixmap()
- pixmap.loadFromData(self.load_resources(['images/icon.png']).itervalues().next())
+ next(pixmap.loadFromData(self.load_resources(['images/icon.png']).itervalues())
icon = QIcon(pixmap)
:param names: List of paths to resources in the ZIP file using / as separator
diff --git a/src/calibre/customize/ui.py b/src/calibre/customize/ui.py
index 74a729c135..1229cbf712 100644
--- a/src/calibre/customize/ui.py
+++ b/src/calibre/customize/ui.py
@@ -23,6 +23,7 @@ from calibre.utils.config import (make_config_dir, Config, ConfigProxy,
plugin_dir, OptionParser)
from calibre.ebooks.metadata.sources.base import Source
from calibre.constants import DEBUG, numeric_version
+from polyglot.builtins import iteritems, itervalues
builtin_names = frozenset(p.name for p in builtin_plugins)
BLACKLISTED_PLUGINS = frozenset({'Marvin XD', 'iOS reader applications'})
@@ -195,7 +196,7 @@ def run_plugins_on_postimport(db, book_id, fmt):
try:
plugin.postimport(book_id, fmt, db)
except:
- print ('Running file type plugin %s failed with traceback:'%
+ print('Running file type plugin %s failed with traceback:'%
plugin.name)
traceback.print_exc()
@@ -210,7 +211,7 @@ def run_plugins_on_postadd(db, book_id, fmt_map):
try:
plugin.postadd(book_id, fmt_map, db)
except Exception:
- print ('Running file type plugin %s failed with traceback:'%
+ print('Running file type plugin %s failed with traceback:'%
plugin.name)
traceback.print_exc()
@@ -347,7 +348,7 @@ def reread_metadata_plugins():
return (1 if plugin.plugin_path is None else 0), plugin.name
for group in (_metadata_readers, _metadata_writers):
- for plugins in group.itervalues():
+ for plugins in itervalues(group):
if len(plugins) > 1:
plugins.sort(key=key)
@@ -640,7 +641,7 @@ def patch_metadata_plugins(possibly_updated_plugins):
# Metadata source plugins dont use initialize() but that
# might change in the future, so be safe.
patches[i].initialize()
- for i, pup in patches.iteritems():
+ for i, pup in iteritems(patches):
_initialized_plugins[i] = pup
# }}}
@@ -727,7 +728,7 @@ def initialize_plugins(perf=False):
sys.stdout, sys.stderr = ostdout, ostderr
if perf:
for x in sorted(times, key=lambda x:times[x]):
- print ('%50s: %.3f'%(x, times[x]))
+ print('%50s: %.3f'%(x, times[x]))
_initialized_plugins.sort(cmp=lambda x,y:cmp(x.priority, y.priority), reverse=True)
reread_filetype_plugins()
reread_metadata_plugins()
diff --git a/src/calibre/customize/zipplugin.py b/src/calibre/customize/zipplugin.py
index 95c18da1b2..fec7842afd 100644
--- a/src/calibre/customize/zipplugin.py
+++ b/src/calibre/customize/zipplugin.py
@@ -2,7 +2,6 @@
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import (unicode_literals, division, absolute_import,
print_function)
-from polyglot.builtins import map, unicode_type
__license__ = 'GPL v3'
__copyright__ = '2011, Kovid Goyal '
@@ -15,7 +14,8 @@ from functools import partial
from calibre import as_unicode
from calibre.customize import (Plugin, numeric_version, platform,
InvalidPlugin, PluginNotFound)
-from polyglot.builtins import string_or_bytes
+from polyglot.builtins import (itervalues, iterkeys, map,
+ string_or_bytes, unicode_type)
# PEP 302 based plugin loading mechanism, works around the bug in zipimport in
# python 2.x that prevents importing from zip files in locations whose paths
@@ -202,7 +202,7 @@ class PluginLoader(object):
else:
m = importlib.import_module(plugin_module)
plugin_classes = []
- for obj in m.__dict__.itervalues():
+ for obj in itervalues(m.__dict__):
if isinstance(obj, type) and issubclass(obj, Plugin) and \
obj.name != 'Trivial Plugin':
plugin_classes.append(obj)
@@ -281,7 +281,7 @@ class PluginLoader(object):
# Legacy plugins
if '__init__' not in names:
- for name in list(names.iterkeys()):
+ for name in list(iterkeys(names)):
if '.' not in name and name.endswith('plugin'):
names['__init__'] = names[name]
break
diff --git a/src/calibre/db/__init__.py b/src/calibre/db/__init__.py
index 87144e4890..82ff46b5e4 100644
--- a/src/calibre/db/__init__.py
+++ b/src/calibre/db/__init__.py
@@ -10,7 +10,7 @@ __docformat__ = 'restructuredtext en'
SPOOL_SIZE = 30*1024*1024
import numbers
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, range
def _get_next_series_num_for_list(series_indices, unwrap=True):
@@ -82,7 +82,7 @@ def get_data_as_dict(self, prefix=None, authors_as_string=False, ids=None, conve
'rating', 'timestamp', 'size', 'tags', 'comments', 'series',
'series_index', 'uuid', 'pubdate', 'last_modified', 'identifiers',
'languages']).union(set(fdata))
- for x, data in fdata.iteritems():
+ for x, data in iteritems(fdata):
if data['datatype'] == 'series':
FIELDS.add('%d_index'%x)
data = []
diff --git a/src/calibre/db/adding.py b/src/calibre/db/adding.py
index 44fa239ed5..febd2dda5c 100644
--- a/src/calibre/db/adding.py
+++ b/src/calibre/db/adding.py
@@ -8,7 +8,7 @@ __copyright__ = '2013, Kovid Goyal '
import os, time, re
from collections import defaultdict
-from polyglot.builtins import map, unicode_type
+from polyglot.builtins import itervalues, map, unicode_type
from contextlib import contextmanager
from functools import partial
@@ -137,7 +137,7 @@ def find_books_in_directory(dirpath, single_book_per_directory, compiled_rules=(
if allow_path(path, ext, compiled_rules):
formats[ext] = path
if formats_ok(formats):
- yield list(formats.itervalues())
+ yield list(itervalues(formats))
else:
books = defaultdict(dict)
for path in listdir_impl(dirpath, sort_by_mtime=True):
@@ -145,9 +145,9 @@ def find_books_in_directory(dirpath, single_book_per_directory, compiled_rules=(
if allow_path(path, ext, compiled_rules):
books[icu_lower(key) if isinstance(key, unicode_type) else key.lower()][ext] = path
- for formats in books.itervalues():
+ for formats in itervalues(books):
if formats_ok(formats):
- yield list(formats.itervalues())
+ yield list(itervalues(formats))
def create_format_map(formats):
diff --git a/src/calibre/db/backend.py b/src/calibre/db/backend.py
index e7b5b55ac4..ba9e696ce5 100644
--- a/src/calibre/db/backend.py
+++ b/src/calibre/db/backend.py
@@ -12,7 +12,8 @@ import os, shutil, uuid, json, glob, time, hashlib, errno, sys
from functools import partial
import apsw
-from polyglot.builtins import unicode_type, reraise, string_or_bytes
+from polyglot.builtins import (iteritems, iterkeys, itervalues,
+ unicode_type, reraise, string_or_bytes)
from calibre import isbytestring, force_unicode, prints, as_unicode
from calibre.constants import (iswindows, filesystem_encoding,
@@ -46,7 +47,7 @@ from calibre.db.tables import (OneToOneTable, ManyToOneTable, ManyToManyTable,
Differences in semantics from pysqlite:
1. execute/executemany operate in autocommit mode
- 2. There is no fetchone() method on cursor objects, instead use next()
+ 2. There is no fetchone() method on cursor objects, instead use next(cursor)
3. There is no executescript
'''
@@ -120,7 +121,7 @@ class DBPrefs(dict): # {{{
raw = self.to_raw(val)
with self.db.conn:
try:
- dbraw = self.db.execute('SELECT id,val FROM preferences WHERE key=?', (key,)).next()
+ dbraw = next(self.db.execute('SELECT id,val FROM preferences WHERE key=?', (key,)))
except StopIteration:
dbraw = None
if dbraw is None or dbraw[1] != raw:
@@ -222,7 +223,7 @@ def SortedConcatenate(sep=','):
def finalize(ctxt):
if len(ctxt) == 0:
return None
- return sep.join(map(ctxt.get, sorted(ctxt.iterkeys())))
+ return sep.join(map(ctxt.get, sorted(iterkeys(ctxt))))
return ({}, step, finalize)
@@ -247,7 +248,7 @@ def AumSortedConcatenate():
ctxt[ndx] = ':::'.join((author, sort, link))
def finalize(ctxt):
- keys = list(ctxt.iterkeys())
+ keys = list(iterkeys(ctxt))
l = len(keys)
if l == 0:
return None
@@ -271,7 +272,7 @@ class Connection(apsw.Connection): # {{{
self.execute('pragma cache_size=-5000')
self.execute('pragma temp_store=2')
- encoding = self.execute('pragma encoding').next()[0]
+ encoding = next(self.execute('pragma encoding'))[0]
self.createcollation('PYNOCASE', partial(pynocase,
encoding=encoding))
@@ -306,7 +307,7 @@ class Connection(apsw.Connection): # {{{
if kw.get('all', True):
return ans.fetchall()
try:
- return ans.next()[0]
+ return next(ans)[0]
except (StopIteration, IndexError):
return None
@@ -733,7 +734,7 @@ class DB(object):
}
# Create Tag Browser categories for custom columns
- for k in sorted(self.custom_column_label_map.iterkeys()):
+ for k in sorted(iterkeys(self.custom_column_label_map)):
v = self.custom_column_label_map[k]
if v['normalized']:
is_category = True
@@ -786,10 +787,10 @@ class DB(object):
'last_modified':19, 'identifiers':20, 'languages':21,
}
- for k,v in self.FIELD_MAP.iteritems():
+ for k,v in iteritems(self.FIELD_MAP):
self.field_metadata.set_field_record_index(k, v, prefer_custom=False)
- base = max(self.FIELD_MAP.itervalues())
+ base = max(itervalues(self.FIELD_MAP))
for label_ in sorted(self.custom_column_label_map):
data = self.custom_column_label_map[label_]
@@ -875,7 +876,7 @@ class DB(object):
if kw.get('all', True):
return ans.fetchall()
try:
- return ans.next()[0]
+ return next(ans)[0]
except (StopIteration, IndexError):
return None
@@ -1263,7 +1264,7 @@ class DB(object):
'''
with self.conn: # Use a single transaction, to ensure nothing modifies the db while we are reading
- for table in self.tables.itervalues():
+ for table in itervalues(self.tables):
try:
table.read(self)
except:
@@ -1327,7 +1328,7 @@ class DB(object):
def remove_formats(self, remove_map):
paths = []
- for book_id, removals in remove_map.iteritems():
+ for book_id, removals in iteritems(remove_map):
for fmt, fname, path in removals:
path = self.format_abspath(book_id, fmt, fname, path)
if path is not None:
@@ -1585,7 +1586,7 @@ class DB(object):
if samefile(spath, tpath):
# The format filenames may have changed while the folder
# name remains the same
- for fmt, opath in original_format_map.iteritems():
+ for fmt, opath in iteritems(original_format_map):
npath = format_map.get(fmt, None)
if npath and os.path.abspath(npath.lower()) != os.path.abspath(opath.lower()) and samefile(opath, npath):
# opath and npath are different hard links to the same file
@@ -1648,7 +1649,7 @@ class DB(object):
def remove_books(self, path_map, permanent=False):
self.executemany(
'DELETE FROM books WHERE id=?', [(x,) for x in path_map])
- paths = {os.path.join(self.library_path, x) for x in path_map.itervalues() if x}
+ paths = {os.path.join(self.library_path, x) for x in itervalues(path_map) if x}
paths = {x for x in paths if os.path.exists(x) and self.is_deletable(x)}
if permanent:
for path in paths:
@@ -1663,7 +1664,7 @@ class DB(object):
self.executemany(
'INSERT OR REPLACE INTO books_plugin_data (book, name, val) VALUES (?, ?, ?)',
[(book_id, name, json.dumps(val, default=to_json))
- for book_id, val in val_map.iteritems()])
+ for book_id, val in iteritems(val_map)])
def get_custom_book_data(self, name, book_ids, default=None):
book_ids = frozenset(book_ids)
@@ -1722,7 +1723,7 @@ class DB(object):
def set_conversion_options(self, options, fmt):
options = [(book_id, fmt.upper(), buffer(pickle_binary_string(data.encode('utf-8') if isinstance(data, unicode_type) else data)))
- for book_id, data in options.iteritems()]
+ for book_id, data in iteritems(options)]
self.executemany('INSERT OR REPLACE INTO conversion_options(book,format,data) VALUES (?,?,?)', options)
def get_top_level_move_items(self, all_paths):
diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py
index e7f1f14aa6..f04f16edeb 100644
--- a/src/calibre/db/cache.py
+++ b/src/calibre/db/cache.py
@@ -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 unicode_type, zip, string_or_bytes
+from polyglot.builtins import iteritems, iterkeys, itervalues, unicode_type, zip, string_or_bytes
from time import time
from calibre import isbytestring, as_unicode
@@ -170,7 +170,7 @@ class Cache(object):
# Reconstruct the user categories, putting them into field_metadata
fm = self.field_metadata
fm.remove_dynamic_categories()
- for user_cat in sorted(self._pref('user_categories', {}).iterkeys(), key=sort_key):
+ for user_cat in sorted(iterkeys(self._pref('user_categories', {})), key=sort_key):
cat_name = '@' + user_cat # add the '@' to avoid name collision
while cat_name:
try:
@@ -181,7 +181,7 @@ class Cache(object):
# add grouped search term user categories
muc = frozenset(self._pref('grouped_search_make_user_categories', []))
- for cat in sorted(self._pref('grouped_search_terms', {}).iterkeys(), key=sort_key):
+ for cat in sorted(iterkeys(self._pref('grouped_search_terms', {})), key=sort_key):
if cat in muc:
# There is a chance that these can be duplicates of an existing
# user category. Print the exception and continue.
@@ -200,7 +200,7 @@ class Cache(object):
self.dirtied_cache = {x:i for i, (x,) in enumerate(
self.backend.execute('SELECT book FROM metadata_dirtied'))}
if self.dirtied_cache:
- self.dirtied_sequence = max(self.dirtied_cache.itervalues())+1
+ self.dirtied_sequence = max(itervalues(self.dirtied_cache))+1
self._initialize_dynamic_categories()
@write_api
@@ -213,7 +213,7 @@ class Cache(object):
@write_api
def clear_composite_caches(self, book_ids=None):
- for field in self.composites.itervalues():
+ for field in itervalues(self.composites):
field.clear_caches(book_ids=book_ids)
@write_api
@@ -229,7 +229,7 @@ class Cache(object):
def clear_caches(self, book_ids=None, template_cache=True, search_cache=True):
if template_cache:
self._initialize_template_cache() # Clear the formatter template cache
- for field in self.fields.itervalues():
+ for field in itervalues(self.fields):
if hasattr(field, 'clear_caches'):
field.clear_caches(book_ids=book_ids) # Clear the composite cache and ondevice caches
if book_ids:
@@ -247,7 +247,7 @@ class Cache(object):
with self.backend.conn: # Prevent other processes, such as calibredb from interrupting the reload by locking the db
self.backend.prefs.load_from_db()
self._search_api.saved_searches.load_from_db()
- for field in self.fields.itervalues():
+ for field in itervalues(self.fields):
if hasattr(field, 'table'):
field.table.read(self.backend) # Reread data from metadata.db
@@ -358,7 +358,7 @@ class Cache(object):
self.backend.read_tables()
bools_are_tristate = self.backend.prefs['bools_are_tristate']
- for field, table in self.backend.tables.iteritems():
+ for field, table in iteritems(self.backend.tables):
self.fields[field] = create_field(field, table, bools_are_tristate,
self.backend.get_template_functions)
if table.metadata['datatype'] == 'composite':
@@ -368,7 +368,7 @@ class Cache(object):
VirtualTable('ondevice'), bools_are_tristate,
self.backend.get_template_functions)
- for name, field in self.fields.iteritems():
+ for name, field in iteritems(self.fields):
if name[0] == '#' and name.endswith('_index'):
field.series_field = self.fields[name[:-len('_index')]]
self.fields[name[:-len('_index')]].index_field = field
@@ -494,7 +494,7 @@ class Cache(object):
return frozenset(self.fields[field].table.col_book_map)
try:
- return frozenset(self.fields[field].table.id_map.itervalues())
+ return frozenset(itervalues(self.fields[field].table.id_map))
except AttributeError:
raise ValueError('%s is not a many-one or many-many field' % field)
@@ -503,7 +503,7 @@ class Cache(object):
''' Return a mapping of id to usage count for all values of the specified
field, which must be a many-one or many-many field. '''
try:
- return {k:len(v) for k, v in self.fields[field].table.col_book_map.iteritems()}
+ return {k:len(v) for k, v in iteritems(self.fields[field].table.col_book_map)}
except AttributeError:
raise ValueError('%s is not a many-one or many-many field' % field)
@@ -528,13 +528,13 @@ class Cache(object):
@read_api
def get_item_id(self, field, item_name):
' Return the item id for item_name (case-insensitive) '
- rmap = {icu_lower(v) if isinstance(v, unicode_type) else v:k for k, v in self.fields[field].table.id_map.iteritems()}
+ rmap = {icu_lower(v) if isinstance(v, unicode_type) else v:k for k, v in iteritems(self.fields[field].table.id_map)}
return rmap.get(icu_lower(item_name) if isinstance(item_name, unicode_type) else item_name, None)
@read_api
def get_item_ids(self, field, item_names):
' Return the item id for item_name (case-insensitive) '
- rmap = {icu_lower(v) if isinstance(v, unicode_type) else v:k for k, v in self.fields[field].table.id_map.iteritems()}
+ rmap = {icu_lower(v) if isinstance(v, unicode_type) else v:k for k, v in iteritems(self.fields[field].table.id_map)}
return {name:rmap.get(icu_lower(name) if isinstance(name, unicode_type) else name, None) for name in item_names}
@read_api
@@ -1038,13 +1038,13 @@ class Cache(object):
new_dirtied = book_ids - already_dirtied
already_dirtied = {book_id:self.dirtied_sequence+i for i, book_id in enumerate(already_dirtied)}
if already_dirtied:
- self.dirtied_sequence = max(already_dirtied.itervalues()) + 1
+ self.dirtied_sequence = max(itervalues(already_dirtied)) + 1
self.dirtied_cache.update(already_dirtied)
if new_dirtied:
self.backend.executemany('INSERT OR IGNORE INTO metadata_dirtied (book) VALUES (?)',
((x,) for x in new_dirtied))
new_dirtied = {book_id:self.dirtied_sequence+i for i, book_id in enumerate(new_dirtied)}
- self.dirtied_sequence = max(new_dirtied.itervalues()) + 1
+ self.dirtied_sequence = max(itervalues(new_dirtied)) + 1
self.dirtied_cache.update(new_dirtied)
@write_api
@@ -1075,7 +1075,7 @@ class Cache(object):
if is_series:
bimap, simap = {}, {}
sfield = self.fields[name + '_index']
- for k, v in book_id_to_val_map.iteritems():
+ for k, v in iteritems(book_id_to_val_map):
if isinstance(v, string_or_bytes):
v, sid = get_series_values(v)
else:
@@ -1117,7 +1117,7 @@ class Cache(object):
@read_api
def get_a_dirtied_book(self):
if self.dirtied_cache:
- return random.choice(tuple(self.dirtied_cache.iterkeys()))
+ return random.choice(tuple(iterkeys(self.dirtied_cache)))
return None
@read_api
@@ -1220,7 +1220,7 @@ class Cache(object):
QPixmap, file object or bytestring. It can also be None, in which
case any existing cover is removed. '''
- for book_id, data in book_id_data_map.iteritems():
+ for book_id, data in iteritems(book_id_data_map):
try:
path = self._field_for('path', book_id).replace('/', os.sep)
except AttributeError:
@@ -1231,7 +1231,7 @@ class Cache(object):
for cc in self.cover_caches:
cc.invalidate(book_id_data_map)
return self._set_field('cover', {
- book_id:(0 if data is None else 1) for book_id, data in book_id_data_map.iteritems()})
+ book_id:(0 if data is None else 1) for book_id, data in iteritems(book_id_data_map)})
@write_api
def add_cover_cache(self, cover_cache):
@@ -1332,14 +1332,14 @@ class Cache(object):
protected_set_field('identifiers', mi_idents)
elif mi_idents:
identifiers = self._field_for('identifiers', book_id, default_value={})
- for key, val in mi_idents.iteritems():
+ for key, val in iteritems(mi_idents):
if val and val.strip(): # Don't delete an existing identifier
identifiers[icu_lower(key)] = val
protected_set_field('identifiers', identifiers)
user_mi = mi.get_all_user_metadata(make_copy=False)
fm = self.field_metadata
- for key in user_mi.iterkeys():
+ for key in iterkeys(user_mi):
if (key in fm and user_mi[key]['datatype'] == fm[key]['datatype'] and (
user_mi[key]['datatype'] != 'text' or (
user_mi[key]['is_multiple'] == fm[key]['is_multiple']))):
@@ -1433,15 +1433,15 @@ class Cache(object):
:param db_only: If True, only remove the record for the format from the db, do not delete the actual format file from the filesystem.
'''
table = self.fields['formats'].table
- formats_map = {book_id:frozenset((f or '').upper() for f in fmts) for book_id, fmts in formats_map.iteritems()}
+ formats_map = {book_id:frozenset((f or '').upper() for f in fmts) for book_id, fmts in iteritems(formats_map)}
- for book_id, fmts in formats_map.iteritems():
+ for book_id, fmts in iteritems(formats_map):
for fmt in fmts:
self.format_metadata_cache[book_id].pop(fmt, None)
if not db_only:
removes = defaultdict(set)
- for book_id, fmts in formats_map.iteritems():
+ for book_id, fmts in iteritems(formats_map):
try:
path = self._field_for('path', book_id).replace('/', os.sep)
except:
@@ -1458,7 +1458,7 @@ class Cache(object):
size_map = table.remove_formats(formats_map, self.backend)
self.fields['size'].table.update_sizes(size_map)
- self._update_last_modified(tuple(formats_map.iterkeys()))
+ self._update_last_modified(tuple(iterkeys(formats_map)))
@read_api
def get_next_series_num_for(self, series, field='series', current_indices=False):
@@ -1481,7 +1481,7 @@ class Cache(object):
index_map = {book_id:self._fast_field_for(idf, book_id, default_value=1.0) for book_id in books}
if current_indices:
return index_map
- series_indices = sorted(index_map.itervalues())
+ series_indices = sorted(itervalues(index_map))
return _get_next_series_num_for_list(tuple(series_indices), unwrap=False)
@read_api
@@ -1491,7 +1491,7 @@ class Cache(object):
string. '''
table = self.fields['authors'].table
result = []
- rmap = {key_func(v):k for k, v in table.id_map.iteritems()}
+ rmap = {key_func(v):k for k, v in iteritems(table.id_map)}
for aut in authors:
aid = rmap.get(key_func(aut), None)
result.append(author_to_author_sort(aut) if aid is None else table.asort_map[aid])
@@ -1503,10 +1503,10 @@ class Cache(object):
implementation of :meth:`has_book` in a worker process without access to the
db. '''
try:
- return {icu_lower(title) for title in self.fields['title'].table.book_col_map.itervalues()}
+ return {icu_lower(title) for title in itervalues(self.fields['title'].table.book_col_map)}
except TypeError:
# Some non-unicode titles in the db
- return {icu_lower(as_unicode(title)) for title in self.fields['title'].table.book_col_map.itervalues()}
+ return {icu_lower(as_unicode(title)) for title in itervalues(self.fields['title'].table.book_col_map)}
@read_api
def has_book(self, mi):
@@ -1518,7 +1518,7 @@ class Cache(object):
if isbytestring(title):
title = title.decode(preferred_encoding, 'replace')
q = icu_lower(title).strip()
- for title in self.fields['title'].table.book_col_map.itervalues():
+ for title in itervalues(self.fields['title'].table.book_col_map):
if q == icu_lower(title):
return True
return False
@@ -1599,7 +1599,7 @@ class Cache(object):
duplicates.append((mi, format_map))
else:
ids.append(book_id)
- for fmt, stream_or_path in format_map.iteritems():
+ for fmt, stream_or_path in iteritems(format_map):
if self.add_format(book_id, fmt, stream_or_path, dbapi=dbapi, run_hooks=run_hooks):
fmt_map[fmt.lower()] = getattr(stream_or_path, 'name', stream_or_path) or ''
run_plugins_on_postadd(dbapi or self, book_id, fmt_map)
@@ -1618,11 +1618,11 @@ class Cache(object):
path = None
path_map[book_id] = path
if iswindows:
- paths = (x.replace(os.sep, '/') for x in path_map.itervalues() if x)
+ paths = (x.replace(os.sep, '/') for x in itervalues(path_map) if x)
self.backend.windows_check_if_files_in_use(paths)
self.backend.remove_books(path_map, permanent=permanent)
- for field in self.fields.itervalues():
+ for field in itervalues(self.fields):
try:
table = field.table
except AttributeError:
@@ -1665,7 +1665,7 @@ class Cache(object):
restrict_to_book_ids = frozenset(restrict_to_book_ids)
id_map = {}
default_process_map = {}
- for old_id, new_name in item_id_to_new_name_map.iteritems():
+ for old_id, new_name in iteritems(item_id_to_new_name_map):
new_names = tuple(x.strip() for x in new_name.split(sv)) if sv else (new_name,)
# Get a list of books in the VL with the item
books_with_id = f.books_for(old_id)
@@ -1720,7 +1720,7 @@ class Cache(object):
raise ValueError('Cannot rename items for one-one fields: %s' % field)
moved_books = set()
id_map = {}
- for item_id, new_name in item_id_to_new_name_map.iteritems():
+ for item_id, new_name in iteritems(item_id_to_new_name_map):
new_names = tuple(x.strip() for x in new_name.split(sv)) if sv else (new_name,)
books, new_id = func(item_id, new_names[0], self.backend)
affected_books.update(books)
@@ -1735,7 +1735,7 @@ class Cache(object):
if affected_books:
if field == 'authors':
self._set_field('author_sort',
- {k:' & '.join(v) for k, v in self._author_sort_strings_for_books(affected_books).iteritems()})
+ {k:' & '.join(v) for k, v in iteritems(self._author_sort_strings_for_books(affected_books))})
self._update_path(affected_books, mark_as_dirtied=False)
elif change_index and hasattr(f, 'index_field') and tweaks['series_index_auto_increment'] != 'no_change':
for book_id in moved_books:
@@ -1835,7 +1835,7 @@ class Cache(object):
insensitive).
'''
- tag_map = {icu_lower(v):k for k, v in self._get_id_map('tags').iteritems()}
+ tag_map = {icu_lower(v):k for k, v in iteritems(self._get_id_map('tags'))}
tag = icu_lower(tag.strip())
mht = icu_lower(must_have_tag.strip()) if must_have_tag else None
tag_id, mht_id = tag_map.get(tag, None), tag_map.get(mht, None)
@@ -1848,7 +1848,7 @@ class Cache(object):
tagged_books = tagged_books.intersection(self._books_for_field('tags', mht_id))
if tagged_books:
if must_have_authors is not None:
- amap = {icu_lower(v):k for k, v in self._get_id_map('authors').iteritems()}
+ amap = {icu_lower(v):k for k, v in iteritems(self._get_id_map('authors'))}
books = None
for author in must_have_authors:
abooks = self._books_for_field('authors', amap.get(icu_lower(author), None))
@@ -1934,7 +1934,7 @@ class Cache(object):
db. See db.utils for an implementation. '''
at = self.fields['authors'].table
author_map = defaultdict(set)
- for aid, author in at.id_map.iteritems():
+ for aid, author in iteritems(at.id_map):
author_map[icu_lower(author)].add(aid)
return (author_map, at.col_book_map.copy(), self.fields['title'].table.book_col_map.copy(), self.fields['languages'].book_value_map.copy())
@@ -2079,12 +2079,12 @@ class Cache(object):
def virtual_libraries_for_books(self, book_ids):
libraries = self._pref('virtual_libraries', {})
ans = {book_id:[] for book_id in book_ids}
- for lib, expr in libraries.iteritems():
+ for lib, expr in iteritems(libraries):
books = self._search(expr) # We deliberately dont use book_ids as we want to use the search cache
for book in book_ids:
if book in books:
ans[book].append(lib)
- return {k:tuple(sorted(v, key=sort_key)) for k, v in ans.iteritems()}
+ return {k:tuple(sorted(v, key=sort_key)) for k, v in iteritems(ans)}
@read_api
def user_categories_for_books(self, book_ids, proxy_metadata_map=None):
@@ -2101,7 +2101,7 @@ class Cache(object):
for book_id in book_ids:
proxy_metadata = pmm.get(book_id) or self._get_proxy_metadata(book_id)
user_cat_vals = ans[book_id] = {}
- for ucat, categories in user_cats.iteritems():
+ for ucat, categories in iteritems(user_cats):
user_cat_vals[ucat] = res = []
for name, cat, ign in categories:
try:
@@ -2240,15 +2240,15 @@ def import_library(library_key, importer, library_path, progress=None, abort=Non
src.close()
cache = Cache(DB(library_path, load_user_formatter_functions=False))
cache.init()
- format_data = {int(book_id):data for book_id, data in metadata['format_data'].iteritems()}
- for i, (book_id, fmt_key_map) in enumerate(format_data.iteritems()):
+ format_data = {int(book_id):data for book_id, data in iteritems(metadata['format_data'])}
+ for i, (book_id, fmt_key_map) in enumerate(iteritems(format_data)):
if abort is not None and abort.is_set():
return
title = cache._field_for('title', book_id)
if progress is not None:
progress(title, i + 1, total)
cache._update_path((book_id,), mark_as_dirtied=False)
- for fmt, fmtkey in fmt_key_map.iteritems():
+ for fmt, fmtkey in iteritems(fmt_key_map):
if fmt == '.cover':
stream = importer.start_file(fmtkey, _('Cover for %s') % title)
path = cache._field_for('path', book_id).replace('/', os.sep)
diff --git a/src/calibre/db/categories.py b/src/calibre/db/categories.py
index 0ae1cee97f..38489a40fb 100644
--- a/src/calibre/db/categories.py
+++ b/src/calibre/db/categories.py
@@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en'
import copy
from functools import partial
-from polyglot.builtins import unicode_type, map
+from polyglot.builtins import iteritems, iterkeys, unicode_type, map
from calibre.constants import ispy3
from calibre.ebooks.metadata import author_to_author_sort
@@ -75,7 +75,7 @@ class Tag(object):
def find_categories(field_metadata):
- for category, cat in field_metadata.iteritems():
+ for category, cat in iteritems(field_metadata):
if (cat['is_category'] and cat['kind'] not in {'user', 'search'}):
yield (category, cat['is_multiple'].get('cache_to_list', None), False)
elif (cat['datatype'] == 'composite' and
@@ -215,11 +215,11 @@ def get_categories(dbcache, sort='name', book_ids=None, first_letter_sort=False)
# do the verification in the category loop much faster, at the cost of
# temporarily duplicating the categories lists.
taglist = {}
- for c, items in categories.iteritems():
+ for c, items in iteritems(categories):
taglist[c] = dict(map(lambda t:(icu_lower(t.name), t), items))
# Add the category values to the user categories
- for user_cat in sorted(user_categories.iterkeys(), key=sort_key):
+ for user_cat in sorted(iterkeys(user_categories), key=sort_key):
items = []
names_seen = {}
user_cat_is_gst = user_cat in gst
diff --git a/src/calibre/db/cli/cmd_custom_columns.py b/src/calibre/db/cli/cmd_custom_columns.py
index 0e8a0b5813..b8c54bad2c 100644
--- a/src/calibre/db/cli/cmd_custom_columns.py
+++ b/src/calibre/db/cli/cmd_custom_columns.py
@@ -7,6 +7,7 @@ from __future__ import absolute_import, division, print_function, unicode_litera
from pprint import pformat
from calibre import prints
+from polyglot.builtins import iteritems
readonly = True
version = 0 # change this if you change signature of implementation()
@@ -37,7 +38,7 @@ List available custom columns. Shows column labels and ids.
def main(opts, args, dbctx):
- for col, data in dbctx.run('custom_columns').iteritems():
+ for col, data in iteritems(dbctx.run('custom_columns')):
if opts.details:
prints(col)
print()
diff --git a/src/calibre/db/cli/cmd_list.py b/src/calibre/db/cli/cmd_list.py
index 570271c351..a6635236d4 100644
--- a/src/calibre/db/cli/cmd_list.py
+++ b/src/calibre/db/cli/cmd_list.py
@@ -13,6 +13,7 @@ from calibre import prints
from calibre.db.cli.utils import str_width
from calibre.ebooks.metadata import authors_to_string
from calibre.utils.date import isoformat
+from polyglot.builtins import iteritems
readonly = True
version = 0 # change this if you change signature of implementation()
@@ -64,7 +65,7 @@ def implementation(
continue
if field == 'isbn':
x = db.all_field_for('identifiers', book_ids, default_value={})
- data[field] = {k: v.get('isbn') or '' for k, v in x.iteritems()}
+ data[field] = {k: v.get('isbn') or '' for k, v in iteritems(x)}
continue
field = field.replace('*', '#')
metadata[field] = fm[field]
@@ -80,37 +81,37 @@ def implementation(
def stringify(data, metadata, for_machine):
- for field, m in metadata.iteritems():
+ for field, m in iteritems(metadata):
if field == 'authors':
data[field] = {
k: authors_to_string(v)
- for k, v in data[field].iteritems()
+ for k, v in iteritems(data[field])
}
else:
dt = m['datatype']
if dt == 'datetime':
data[field] = {
k: isoformat(v, as_utc=for_machine) if v else 'None'
- for k, v in data[field].iteritems()
+ for k, v in iteritems(data[field])
}
elif not for_machine:
ism = m['is_multiple']
if ism:
data[field] = {
k: ism['list_to_ui'].join(v)
- for k, v in data[field].iteritems()
+ for k, v in iteritems(data[field])
}
if field == 'formats':
data[field] = {
k: '[' + v + ']'
- for k, v in data[field].iteritems()
+ for k, v in iteritems(data[field])
}
def as_machine_data(book_ids, data, metadata):
for book_id in book_ids:
ans = {'id': book_id}
- for field, val_map in data.iteritems():
+ for field, val_map in iteritems(data):
val = val_map.get(book_id)
if val is not None:
ans[field.replace('#', '*')] = val
diff --git a/src/calibre/db/cli/cmd_saved_searches.py b/src/calibre/db/cli/cmd_saved_searches.py
index fd31051782..b06585d48e 100644
--- a/src/calibre/db/cli/cmd_saved_searches.py
+++ b/src/calibre/db/cli/cmd_saved_searches.py
@@ -9,6 +9,7 @@ version = 0 # change this if you change signature of implementation()
from calibre import prints
from calibre.srv.changes import saved_searches
+from polyglot.builtins import iteritems
def implementation(db, notify_changes, action, *args):
@@ -56,7 +57,7 @@ Syntax for removing:
def main(opts, args, dbctx):
args = args or ['list']
if args[0] == 'list':
- for name, value in dbctx.run('saved_searches', 'list').iteritems():
+ for name, value in iteritems(dbctx.run('saved_searches', 'list')):
prints(_('Name:'), name)
prints(_('Search string:'), value)
print()
diff --git a/src/calibre/db/cli/cmd_set_metadata.py b/src/calibre/db/cli/cmd_set_metadata.py
index 18a09bafb9..02ac4462de 100644
--- a/src/calibre/db/cli/cmd_set_metadata.py
+++ b/src/calibre/db/cli/cmd_set_metadata.py
@@ -11,7 +11,7 @@ from calibre.ebooks.metadata.book.base import field_from_string
from calibre.ebooks.metadata.book.serialize import read_cover
from calibre.ebooks.metadata.opf import get_metadata
from calibre.srv.changes import metadata
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
readonly = False
version = 0 # change this if you change signature of implementation()
@@ -170,7 +170,7 @@ def main(opts, args, dbctx):
vals[field] = val
fvals = []
for field, val in sorted( # ensure series_index fields are set last
- vals.iteritems(), key=lambda k: 1 if k[0].endswith('_index') else 0):
+ iteritems(vals), key=lambda k: 1 if k[0].endswith('_index') else 0):
if field.endswith('_index'):
try:
val = float(val)
diff --git a/src/calibre/db/cli/tests.py b/src/calibre/db/cli/tests.py
index 3c5ad650b0..1f7f960e2c 100644
--- a/src/calibre/db/cli/tests.py
+++ b/src/calibre/db/cli/tests.py
@@ -13,14 +13,14 @@ import csv
import unittest
from cStringIO import StringIO
-
from calibre.db.cli.cmd_check_library import _print_check_library_results
+from polyglot.builtins import iteritems
class Checker(object):
def __init__(self, kw):
- for k, v in kw.iteritems():
+ for k, v in iteritems(kw):
setattr(self, k, v)
diff --git a/src/calibre/db/fields.py b/src/calibre/db/fields.py
index 1ecf43319c..d42ab52db9 100644
--- a/src/calibre/db/fields.py
+++ b/src/calibre/db/fields.py
@@ -2,7 +2,6 @@
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import (unicode_literals, division, absolute_import,
print_function)
-# from polyglot.builtins import map
__license__ = 'GPL v3'
__copyright__ = '2011, Kovid Goyal '
@@ -20,6 +19,7 @@ from calibre.utils.config_base import tweaks
from calibre.utils.icu import sort_key
from calibre.utils.date import UNDEFINED_DATE, clean_date_for_sort, parse_date
from calibre.utils.localization import calibre_langcode_to_name
+from polyglot.builtins import iteritems, iterkeys
def bool_sort_key(bools_are_tristate):
@@ -150,7 +150,7 @@ class Field(object):
id_map = self.table.id_map
special_sort = hasattr(self, 'category_sort_value')
- for item_id, item_book_ids in self.table.col_book_map.iteritems():
+ for item_id, item_book_ids in iteritems(self.table.col_book_map):
if book_ids is not None:
item_book_ids = item_book_ids.intersection(book_ids)
if item_book_ids:
@@ -184,7 +184,7 @@ class OneToOneField(Field):
return {item_id}
def __iter__(self):
- return self.table.book_col_map.iterkeys()
+ return iterkeys(self.table.book_col_map)
def sort_keys_for_books(self, get_metadata, lang_map):
bcmg = self.table.book_col_map.get
@@ -315,7 +315,7 @@ class CompositeField(OneToOneField):
for v in vals:
if v:
val_map[v].add(book_id)
- for val, book_ids in val_map.iteritems():
+ for val, book_ids in iteritems(val_map):
yield val, book_ids
def get_composite_categories(self, tag_class, book_rating_map, book_ids,
@@ -328,7 +328,7 @@ class CompositeField(OneToOneField):
for val in vals:
if val:
id_map[val].add(book_id)
- for item_id, item_book_ids in id_map.iteritems():
+ for item_id, item_book_ids in iteritems(id_map):
ratings = tuple(r for r in (book_rating_map.get(book_id, 0) for
book_id in item_book_ids) if r > 0)
avg = sum(ratings)/len(ratings) if ratings else 0
@@ -409,7 +409,7 @@ class OnDeviceField(OneToOneField):
val_map = defaultdict(set)
for book_id in candidates:
val_map[self.for_book(book_id, default_value=default_value)].add(book_id)
- for val, book_ids in val_map.iteritems():
+ for val, book_ids in iteritems(val_map):
yield val, book_ids
@@ -456,7 +456,7 @@ class ManyToOneField(Field):
return self.table.col_book_map.get(item_id, set())
def __iter__(self):
- return self.table.id_map.iterkeys()
+ return iterkeys(self.table.id_map)
def sort_keys_for_books(self, get_metadata, lang_map):
sk_map = LazySortMap(self._default_sort_key, self._sort_key, self.table.id_map)
@@ -466,7 +466,7 @@ class ManyToOneField(Field):
def iter_searchable_values(self, get_metadata, candidates, default_value=None):
cbm = self.table.col_book_map
empty = set()
- for item_id, val in self.table.id_map.iteritems():
+ for item_id, val in iteritems(self.table.id_map):
book_ids = cbm.get(item_id, empty).intersection(candidates)
if book_ids:
yield val, book_ids
@@ -475,7 +475,7 @@ class ManyToOneField(Field):
def book_value_map(self):
try:
return {book_id:self.table.id_map[item_id] for book_id, item_id in
- self.table.book_col_map.iteritems()}
+ iteritems(self.table.book_col_map)}
except KeyError:
raise InvalidLinkTable(self.name)
@@ -507,7 +507,7 @@ class ManyToManyField(Field):
return self.table.col_book_map.get(item_id, set())
def __iter__(self):
- return self.table.id_map.iterkeys()
+ return iterkeys(self.table.id_map)
def sort_keys_for_books(self, get_metadata, lang_map):
sk_map = LazySortMap(self._default_sort_key, self._sort_key, self.table.id_map)
@@ -524,7 +524,7 @@ class ManyToManyField(Field):
def iter_searchable_values(self, get_metadata, candidates, default_value=None):
cbm = self.table.col_book_map
empty = set()
- for item_id, val in self.table.id_map.iteritems():
+ for item_id, val in iteritems(self.table.id_map):
book_ids = cbm.get(item_id, empty).intersection(candidates)
if book_ids:
yield val, book_ids
@@ -534,14 +534,14 @@ class ManyToManyField(Field):
cbm = self.table.book_col_map
for book_id in candidates:
val_map[len(cbm.get(book_id, ()))].add(book_id)
- for count, book_ids in val_map.iteritems():
+ for count, book_ids in iteritems(val_map):
yield count, book_ids
@property
def book_value_map(self):
try:
return {book_id:tuple(self.table.id_map[item_id] for item_id in item_ids)
- for book_id, item_ids in self.table.book_col_map.iteritems()}
+ for book_id, item_ids in iteritems(self.table.book_col_map)}
except KeyError:
raise InvalidLinkTable(self.name)
@@ -561,7 +561,7 @@ class IdentifiersField(ManyToManyField):
'Sort by identifier keys'
bcmg = self.table.book_col_map.get
dv = {self._default_sort_key:None}
- return lambda book_id: tuple(sorted(bcmg(book_id, dv).iterkeys()))
+ return lambda book_id: tuple(sorted(iterkeys(bcmg(book_id, dv))))
def iter_searchable_values(self, get_metadata, candidates, default_value=()):
bcm = self.table.book_col_map
@@ -573,7 +573,7 @@ class IdentifiersField(ManyToManyField):
def get_categories(self, tag_class, book_rating_map, lang_map, book_ids=None):
ans = []
- for id_key, item_book_ids in self.table.col_book_map.iteritems():
+ for id_key, item_book_ids in iteritems(self.table.col_book_map):
if book_ids is not None:
item_book_ids = item_book_ids.intersection(book_ids)
if item_book_ids:
@@ -618,13 +618,13 @@ class FormatsField(ManyToManyField):
for val in vals:
val_map[val].add(book_id)
- for val, book_ids in val_map.iteritems():
+ for val, book_ids in iteritems(val_map):
yield val, book_ids
def get_categories(self, tag_class, book_rating_map, lang_map, book_ids=None):
ans = []
- for fmt, item_book_ids in self.table.col_book_map.iteritems():
+ for fmt, item_book_ids in iteritems(self.table.col_book_map):
if book_ids is not None:
item_book_ids = item_book_ids.intersection(book_ids)
if item_book_ids:
@@ -665,7 +665,7 @@ class SeriesField(ManyToOneField):
return ssk(ts(val, order=sso, lang=lang))
sk_map = LazySeriesSortMap(self._default_sort_key, sk, self.table.id_map)
bcmg = self.table.book_col_map.get
- lang_map = {k:v[0] if v else None for k, v in lang_map.iteritems()}
+ lang_map = {k:v[0] if v else None for k, v in iteritems(lang_map)}
def key(book_id):
lang = lang_map.get(book_id, None)
@@ -694,8 +694,8 @@ class SeriesField(ManyToOneField):
sso = tweaks['title_series_sorting']
ts = title_sort
empty = set()
- lang_map = {k:v[0] if v else None for k, v in lang_map.iteritems()}
- for item_id, val in self.table.id_map.iteritems():
+ lang_map = {k:v[0] if v else None for k, v in iteritems(lang_map)}
+ for item_id, val in iteritems(self.table.id_map):
book_ids = cbm.get(item_id, empty).intersection(candidates)
if book_ids:
lang_counts = Counter()
@@ -712,7 +712,7 @@ class TagsField(ManyToManyField):
def get_news_category(self, tag_class, book_ids=None):
news_id = None
ans = []
- for item_id, val in self.table.id_map.iteritems():
+ for item_id, val in iteritems(self.table.id_map):
if val == _('News'):
news_id = item_id
break
@@ -724,7 +724,7 @@ class TagsField(ManyToManyField):
news_books = news_books.intersection(book_ids)
if not news_books:
return ans
- for item_id, item_book_ids in self.table.col_book_map.iteritems():
+ for item_id, item_book_ids in iteritems(self.table.col_book_map):
item_book_ids = item_book_ids.intersection(news_books)
if item_book_ids:
name = self.category_formatter(self.table.id_map[item_id])
diff --git a/src/calibre/db/lazy.py b/src/calibre/db/lazy.py
index ffa71f8612..e3c5128ed4 100644
--- a/src/calibre/db/lazy.py
+++ b/src/calibre/db/lazy.py
@@ -15,7 +15,7 @@ from copy import deepcopy
from calibre.ebooks.metadata.book.base import Metadata, SIMPLE_GET, TOP_LEVEL_IDENTIFIERS, NULL_VALUES, ALL_METADATA_FIELDS
from calibre.ebooks.metadata.book.formatter import SafeFormat
from calibre.utils.date import utcnow
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iterkeys, unicode_type
# Lazy format metadata retrieval {{{
'''
@@ -393,7 +393,7 @@ class ProxyMetadata(Metadata):
def all_field_keys(self):
um = ga(self, '_user_metadata')
- return frozenset(ALL_METADATA_FIELDS.union(um.iterkeys()))
+ return frozenset(ALL_METADATA_FIELDS.union(iterkeys(um)))
@property
def _proxy_metadata(self):
diff --git a/src/calibre/db/legacy.py b/src/calibre/db/legacy.py
index 60b2f083d8..3eff229a68 100644
--- a/src/calibre/db/legacy.py
+++ b/src/calibre/db/legacy.py
@@ -7,7 +7,7 @@ __license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal '
import os, traceback, types
-from polyglot.builtins import zip
+from polyglot.builtins import iteritems, zip
from calibre import force_unicode, isbytestring
from calibre.constants import preferred_encoding
@@ -171,14 +171,14 @@ class LibraryDatabase(object):
return not bool(self.new_api.fields['title'].table.book_col_map)
def get_usage_count_by_id(self, field):
- return [[k, v] for k, v in self.new_api.get_usage_count_by_id(field).iteritems()]
+ return [[k, v] for k, v in iteritems(self.new_api.get_usage_count_by_id(field))]
def field_id_map(self, field):
- return [(k, v) for k, v in self.new_api.get_id_map(field).iteritems()]
+ return [(k, v) for k, v in iteritems(self.new_api.get_id_map(field))]
def get_custom_items_with_ids(self, label=None, num=None):
try:
- return [[k, v] for k, v in self.new_api.get_id_map(self.custom_field_name(label, num)).iteritems()]
+ return [[k, v] for k, v in iteritems(self.new_api.get_id_map(self.custom_field_name(label, num)))]
except ValueError:
return []
@@ -233,7 +233,7 @@ class LibraryDatabase(object):
paths, formats, metadata = [], [], []
for mi, format_map in duplicates:
metadata.append(mi)
- for fmt, path in format_map.iteritems():
+ for fmt, path in iteritems(format_map):
formats.append(fmt)
paths.append(path)
duplicates = (paths, formats, metadata)
@@ -416,7 +416,7 @@ class LibraryDatabase(object):
ans = set()
if title:
title = icu_lower(force_unicode(title))
- for book_id, x in self.new_api.get_id_map('title').iteritems():
+ for book_id, x in iteritems(self.new_api.get_id_map('title')):
if icu_lower(x) == title:
ans.add(book_id)
if not all_matches:
@@ -521,7 +521,7 @@ class LibraryDatabase(object):
def delete_tags(self, tags):
with self.new_api.write_lock:
- tag_map = {icu_lower(v):k for k, v in self.new_api._get_id_map('tags').iteritems()}
+ tag_map = {icu_lower(v):k for k, v in iteritems(self.new_api._get_id_map('tags'))}
tag_ids = (tag_map.get(icu_lower(tag), None) for tag in tags)
tag_ids = tuple(tid for tid in tag_ids if tid is not None)
if tag_ids:
@@ -547,7 +547,7 @@ class LibraryDatabase(object):
def format_files(self, index, index_is_id=False):
book_id = index if index_is_id else self.id(index)
- return [(v, k) for k, v in self.new_api.format_files(book_id).iteritems()]
+ return [(v, k) for k, v in iteritems(self.new_api.format_files(book_id))]
def format_metadata(self, book_id, fmt, allow_cache=True, update_db=False, commit=False):
return self.new_api.format_metadata(book_id, fmt, allow_cache=allow_cache, update_db=update_db)
@@ -632,7 +632,7 @@ class LibraryDatabase(object):
def delete_item_from_multiple(self, item, label=None, num=None):
field = self.custom_field_name(label, num)
existing = self.new_api.get_id_map(field)
- rmap = {icu_lower(v):k for k, v in existing.iteritems()}
+ rmap = {icu_lower(v):k for k, v in iteritems(existing)}
item_id = rmap.get(icu_lower(item), None)
if item_id is None:
return []
@@ -854,7 +854,7 @@ for field in ('authors', 'tags', 'publisher', 'series'):
LibraryDatabase.all_formats = MT(lambda self:self.new_api.all_field_names('formats'))
LibraryDatabase.all_custom = MT(lambda self, label=None, num=None:self.new_api.all_field_names(self.custom_field_name(label, num)))
-for func, field in {'all_authors':'authors', 'all_titles':'title', 'all_tags2':'tags', 'all_series':'series', 'all_publishers':'publisher'}.iteritems():
+for func, field in iteritems({'all_authors':'authors', 'all_titles':'title', 'all_tags2':'tags', 'all_series':'series', 'all_publishers':'publisher'}):
def getter(field):
def func(self):
return self.field_id_map(field)
@@ -864,16 +864,16 @@ for func, field in {'all_authors':'authors', 'all_titles':'title', 'all_tags2':'
LibraryDatabase.all_tags = MT(lambda self: list(self.all_tag_names()))
LibraryDatabase.get_all_identifier_types = MT(lambda self: list(self.new_api.fields['identifiers'].table.all_identifier_types()))
LibraryDatabase.get_authors_with_ids = MT(
- lambda self: [[aid, adata['name'], adata['sort'], adata['link']] for aid, adata in self.new_api.author_data().iteritems()])
+ lambda self: [[aid, adata['name'], adata['sort'], adata['link']] for aid, adata in iteritems(self.new_api.author_data())])
LibraryDatabase.get_author_id = MT(
- lambda self, author: {icu_lower(v):k for k, v in self.new_api.get_id_map('authors').iteritems()}.get(icu_lower(author), None))
+ lambda self, author: {icu_lower(v):k for k, v in iteritems(self.new_api.get_id_map('authors'))}.get(icu_lower(author), None))
for field in ('tags', 'series', 'publishers', 'ratings', 'languages'):
def getter(field):
fname = field[:-1] if field in {'publishers', 'ratings'} else field
def func(self):
- return [[tid, tag] for tid, tag in self.new_api.get_id_map(fname).iteritems()]
+ return [[tid, tag] for tid, tag in iteritems(self.new_api.get_id_map(fname))]
return func
setattr(LibraryDatabase, 'get_%s_with_ids' % field, MT(getter(field)))
diff --git a/src/calibre/db/restore.py b/src/calibre/db/restore.py
index 11526cea34..7db2ad78d1 100644
--- a/src/calibre/db/restore.py
+++ b/src/calibre/db/restore.py
@@ -16,6 +16,7 @@ from calibre.db.cache import Cache
from calibre.constants import filesystem_encoding
from calibre.utils.date import utcfromtimestamp
from calibre import isbytestring, force_unicode
+from polyglot.builtins import iteritems
NON_EBOOK_EXTENSIONS = frozenset([
'jpg', 'jpeg', 'gif', 'png', 'bmp',
@@ -206,7 +207,7 @@ class Restore(Thread):
self.mismatched_dirs.append(dirpath)
alm = mi.get('author_link_map', {})
- for author, link in alm.iteritems():
+ for author, link in iteritems(alm):
existing_link, timestamp = self.authors_links.get(author, (None, None))
if existing_link is None or existing_link != link and timestamp < mi.timestamp:
self.authors_links[author] = (link, mi.timestamp)
@@ -259,7 +260,7 @@ class Restore(Thread):
self.progress_callback(book['mi'].title, i+1)
id_map = db.get_item_ids('authors', [author for author in self.authors_links])
- link_map = {aid:self.authors_links[name][0] for name, aid in id_map.iteritems() if aid is not None}
+ link_map = {aid:self.authors_links[name][0] for name, aid in iteritems(id_map) if aid is not None}
if link_map:
db.set_link_for_authors(link_map)
db.close()
diff --git a/src/calibre/db/schema_upgrades.py b/src/calibre/db/schema_upgrades.py
index 7ad9d2d7c9..7b5dc28832 100644
--- a/src/calibre/db/schema_upgrades.py
+++ b/src/calibre/db/schema_upgrades.py
@@ -11,7 +11,7 @@ import os
from calibre import prints
from calibre.utils.date import isoformat, DEFAULT_DATE
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iterkeys, itervalues, unicode_type
class SchemaUpgrade(object):
@@ -24,7 +24,7 @@ class SchemaUpgrade(object):
# Upgrade database
try:
while True:
- uv = self.db.execute('pragma user_version').next()[0]
+ uv = next(self.db.execute('pragma user_version'))[0]
meth = getattr(self, 'upgrade_version_%d'%uv, None)
if meth is None:
break
@@ -299,7 +299,7 @@ class SchemaUpgrade(object):
'''.format(tn=table_name, cn=column_name, vcn=view_column_name))
self.db.execute(script)
- for field in self.field_metadata.itervalues():
+ for field in itervalues(self.field_metadata):
if field['is_category'] and not field['is_custom'] and 'link_column' in field:
table = self.db.get(
'SELECT name FROM sqlite_master WHERE type="table" AND name=?',
@@ -375,7 +375,7 @@ class SchemaUpgrade(object):
'''.format(lt=link_table_name, table=table_name)
self.db.execute(script)
- for field in self.field_metadata.itervalues():
+ for field in itervalues(self.field_metadata):
if field['is_category'] and not field['is_custom'] and 'link_column' in field:
table = self.db.get(
'SELECT name FROM sqlite_master WHERE type="table" AND name=?',
@@ -596,7 +596,7 @@ class SchemaUpgrade(object):
custom_recipe_filename)
bdir = os.path.dirname(custom_recipes.file_path)
for id_, title, script in recipes:
- existing = frozenset(map(int, custom_recipes.iterkeys()))
+ existing = frozenset(map(int, iterkeys(custom_recipes)))
if id_ in existing:
id_ = max(existing) + 1000
id_ = str(id_)
diff --git a/src/calibre/db/search.py b/src/calibre/db/search.py
index cc70ec4a39..b4cea09c71 100644
--- a/src/calibre/db/search.py
+++ b/src/calibre/db/search.py
@@ -19,7 +19,7 @@ from calibre.utils.date import parse_date, UNDEFINED_DATE, now, dt_as_local
from calibre.utils.icu import primary_contains, sort_key
from calibre.utils.localization import lang_map, canonicalize_lang
from calibre.utils.search_query_parser import SearchQueryParser, ParseException
-from polyglot.builtins import unicode_type, string_or_bytes
+from polyglot.builtins import iteritems, iterkeys, unicode_type, string_or_bytes
CONTAINS_MATCH = 0
EQUALS_MATCH = 1
@@ -167,7 +167,7 @@ class DateSearch(object): # {{{
matches |= book_ids
return matches
- for k, relop in self.operators.iteritems():
+ for k, relop in iteritems(self.operators):
if query.startswith(k):
query = query[len(k):]
break
@@ -254,7 +254,7 @@ class NumericSearch(object): # {{{
else:
relop = lambda x,y: x is not None
else:
- for k, relop in self.operators.iteritems():
+ for k, relop in iteritems(self.operators):
if query.startswith(k):
query = query[len(k):]
break
@@ -372,7 +372,7 @@ class KeyPairSearch(object): # {{{
return found if valq == 'true' else candidates - found
for m, book_ids in field_iter():
- for key, val in m.iteritems():
+ for key, val in iteritems(m):
if (keyq and not _match(keyq, (key,), keyq_mkind,
use_primary_find_in_search=use_primary_find)):
continue
@@ -445,7 +445,7 @@ class SavedSearchQueries(object): # {{{
db._set_pref(self.opt_name, smap)
def names(self):
- return sorted(self.queries.iterkeys(), key=sort_key)
+ return sorted(iterkeys(self.queries), key=sort_key)
# }}}
@@ -632,7 +632,7 @@ class Parser(SearchQueryParser): # {{{
text_fields = set()
field_metadata = {}
- for x, fm in self.field_metadata.iteritems():
+ for x, fm in iteritems(self.field_metadata):
if x.startswith('@'):
continue
if fm['search_terms'] and x not in {'series_sort', 'id'}:
@@ -670,7 +670,7 @@ class Parser(SearchQueryParser): # {{{
q = canonicalize_lang(query)
if q is None:
lm = lang_map()
- rm = {v.lower():k for k,v in lm.iteritems()}
+ rm = {v.lower():k for k,v in iteritems(lm)}
q = rm.get(query, query)
if matchkind == CONTAINS_MATCH and q.lower() in {'true', 'false'}:
@@ -799,7 +799,7 @@ class LRUCache(object): # {{{
return self.get(key)
def __iter__(self):
- return self.item_map.iteritems()
+ return iteritems(self.item_map)
# }}}
diff --git a/src/calibre/db/tables.py b/src/calibre/db/tables.py
index 1dfd722ff0..b22b53a5b7 100644
--- a/src/calibre/db/tables.py
+++ b/src/calibre/db/tables.py
@@ -14,7 +14,7 @@ from collections import defaultdict
from calibre.constants import plugins
from calibre.utils.date import parse_date, UNDEFINED_DATE, utc_tz
from calibre.ebooks.metadata import author_to_author_sort
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, itervalues, range
_c_speedup = plugins['speedup'][0].parse_date
@@ -154,10 +154,10 @@ class UUIDTable(OneToOneTable):
def read(self, db):
OneToOneTable.read(self, db)
- self.uuid_to_id_map = {v:k for k, v in self.book_col_map.iteritems()}
+ self.uuid_to_id_map = {v:k for k, v in iteritems(self.book_col_map)}
def update_uuid_cache(self, book_id_val_map):
- for book_id, uuid in book_id_val_map.iteritems():
+ for book_id, uuid in iteritems(book_id_val_map):
self.uuid_to_id_map.pop(self.book_col_map.get(book_id, None), None) # discard old uuid
self.uuid_to_id_map[uuid] = book_id
@@ -226,7 +226,7 @@ class ManyToOneTable(Table):
bcm[book] = item_id
def fix_link_table(self, db):
- linked_item_ids = {item_id for item_id in self.book_col_map.itervalues()}
+ linked_item_ids = {item_id for item_id in itervalues(self.book_col_map)}
extra_item_ids = linked_item_ids - set(self.id_map)
if extra_item_ids:
for item_id in extra_item_ids:
@@ -238,10 +238,10 @@ class ManyToOneTable(Table):
def fix_case_duplicates(self, db):
case_map = defaultdict(set)
- for item_id, val in self.id_map.iteritems():
+ for item_id, val in iteritems(self.id_map):
case_map[icu_lower(val)].add(item_id)
- for v in case_map.itervalues():
+ for v in itervalues(case_map):
if len(v) > 1:
main_id = min(v)
v.discard(main_id)
@@ -322,7 +322,7 @@ class ManyToOneTable(Table):
return affected_books
def rename_item(self, item_id, new_name, db):
- rmap = {icu_lower(v):k for k, v in self.id_map.iteritems()}
+ rmap = {icu_lower(v):k for k, v in iteritems(self.id_map)}
existing_item = rmap.get(icu_lower(new_name), None)
table, col, lcol = self.metadata['table'], self.metadata['column'], self.metadata['link_column']
affected_books = self.col_book_map.get(item_id, set())
@@ -353,9 +353,9 @@ class RatingTable(ManyToOneTable):
ManyToOneTable.read_id_maps(self, db)
# Ensure there are no records with rating=0 in the table. These should
# be represented as rating:None instead.
- bad_ids = {item_id for item_id, rating in self.id_map.iteritems() if rating == 0}
+ bad_ids = {item_id for item_id, rating in iteritems(self.id_map) if rating == 0}
if bad_ids:
- self.id_map = {item_id:rating for item_id, rating in self.id_map.iteritems() if rating != 0}
+ self.id_map = {item_id:rating for item_id, rating in iteritems(self.id_map) if rating != 0}
db.executemany('DELETE FROM {0} WHERE {1}=?'.format(self.link_table, self.metadata['link_column']),
tuple((x,) for x in bad_ids))
db.execute('DELETE FROM {0} WHERE {1}=0'.format(
@@ -382,10 +382,10 @@ class ManyToManyTable(ManyToOneTable):
cbm[item_id].add(book)
bcm[book].append(item_id)
- self.book_col_map = {k:tuple(v) for k, v in bcm.iteritems()}
+ self.book_col_map = {k:tuple(v) for k, v in iteritems(bcm)}
def fix_link_table(self, db):
- linked_item_ids = {item_id for item_ids in self.book_col_map.itervalues() for item_id in item_ids}
+ linked_item_ids = {item_id for item_ids in itervalues(self.book_col_map) for item_id in item_ids}
extra_item_ids = linked_item_ids - set(self.id_map)
if extra_item_ids:
for item_id in extra_item_ids:
@@ -461,7 +461,7 @@ class ManyToManyTable(ManyToOneTable):
return affected_books
def rename_item(self, item_id, new_name, db):
- rmap = {icu_lower(v):k for k, v in self.id_map.iteritems()}
+ rmap = {icu_lower(v):k for k, v in iteritems(self.id_map)}
existing_item = rmap.get(icu_lower(new_name), None)
table, col, lcol = self.metadata['table'], self.metadata['column'], self.metadata['link_column']
affected_books = self.col_book_map.get(item_id, set())
@@ -490,10 +490,10 @@ class ManyToManyTable(ManyToOneTable):
def fix_case_duplicates(self, db):
from calibre.db.write import uniq
case_map = defaultdict(set)
- for item_id, val in self.id_map.iteritems():
+ for item_id, val in iteritems(self.id_map):
case_map[icu_lower(val)].add(item_id)
- for v in case_map.itervalues():
+ for v in itervalues(case_map):
if len(v) > 1:
done_books = set()
main_id = min(v)
@@ -541,19 +541,19 @@ class AuthorsTable(ManyToManyTable):
lm[aid] = link
def set_sort_names(self, aus_map, db):
- aus_map = {aid:(a or '').strip() for aid, a in aus_map.iteritems()}
- aus_map = {aid:a for aid, a in aus_map.iteritems() if a != self.asort_map.get(aid, None)}
+ aus_map = {aid:(a or '').strip() for aid, a in iteritems(aus_map)}
+ aus_map = {aid:a for aid, a in iteritems(aus_map) if a != self.asort_map.get(aid, None)}
self.asort_map.update(aus_map)
db.executemany('UPDATE authors SET sort=? WHERE id=?',
- [(v, k) for k, v in aus_map.iteritems()])
+ [(v, k) for k, v in iteritems(aus_map)])
return aus_map
def set_links(self, link_map, db):
- link_map = {aid:(l or '').strip() for aid, l in link_map.iteritems()}
- link_map = {aid:l for aid, l in link_map.iteritems() if l != self.alink_map.get(aid, None)}
+ link_map = {aid:(l or '').strip() for aid, l in iteritems(link_map)}
+ link_map = {aid:l for aid, l in iteritems(link_map) if l != self.alink_map.get(aid, None)}
self.alink_map.update(link_map)
db.executemany('UPDATE authors SET link=? WHERE id=?',
- [(v, k) for k, v in link_map.iteritems()])
+ [(v, k) for k, v in iteritems(link_map)])
return link_map
def remove_books(self, book_ids, db):
@@ -602,7 +602,7 @@ class FormatsTable(ManyToManyTable):
fnm[book][fmt] = name
sm[book][fmt] = sz
- self.book_col_map = {k:tuple(sorted(v)) for k, v in bcm.iteritems()}
+ self.book_col_map = {k:tuple(sorted(v)) for k, v in iteritems(bcm)}
def remove_books(self, book_ids, db):
clean = ManyToManyTable.remove_books(self, book_ids, db)
@@ -617,21 +617,21 @@ class FormatsTable(ManyToManyTable):
(fname, book_id, fmt))
def remove_formats(self, formats_map, db):
- for book_id, fmts in formats_map.iteritems():
+ for book_id, fmts in iteritems(formats_map):
self.book_col_map[book_id] = [fmt for fmt in self.book_col_map.get(book_id, []) if fmt not in fmts]
for m in (self.fname_map, self.size_map):
- m[book_id] = {k:v for k, v in m[book_id].iteritems() if k not in fmts}
+ m[book_id] = {k:v for k, v in iteritems(m[book_id]) if k not in fmts}
for fmt in fmts:
try:
self.col_book_map[fmt].discard(book_id)
except KeyError:
pass
db.executemany('DELETE FROM data WHERE book=? AND format=?',
- [(book_id, fmt) for book_id, fmts in formats_map.iteritems() for fmt in fmts])
+ [(book_id, fmt) for book_id, fmts in iteritems(formats_map) for fmt in fmts])
def zero_max(book_id):
try:
- return max(self.size_map[book_id].itervalues())
+ return max(itervalues(self.size_map[book_id]))
except ValueError:
return 0
@@ -661,7 +661,7 @@ class FormatsTable(ManyToManyTable):
self.size_map[book_id][fmt] = size
db.execute('INSERT OR REPLACE INTO data (book,format,uncompressed_size,name) VALUES (?,?,?,?)',
(book_id, fmt, size, fname))
- return max(self.size_map[book_id].itervalues())
+ return max(itervalues(self.size_map[book_id]))
class IdentifiersTable(ManyToManyTable):
@@ -702,4 +702,4 @@ class IdentifiersTable(ManyToManyTable):
raise NotImplementedError('Cannot rename identifiers')
def all_identifier_types(self):
- return frozenset(k for k, v in self.col_book_map.iteritems() if v)
+ return frozenset(k for k, v in iteritems(self.col_book_map) if v)
diff --git a/src/calibre/db/tests/add_remove.py b/src/calibre/db/tests/add_remove.py
index 7dee5d33ec..a39a698f8b 100644
--- a/src/calibre/db/tests/add_remove.py
+++ b/src/calibre/db/tests/add_remove.py
@@ -15,6 +15,7 @@ from datetime import timedelta
from calibre.db.tests.base import BaseTest, IMG
from calibre.ptempfile import PersistentTemporaryFile
from calibre.utils.date import now, UNDEFINED_DATE
+from polyglot.builtins import iteritems, itervalues
def import_test(replacement_data, replacement_fmt=None):
@@ -217,14 +218,14 @@ class AddRemoveTest(BaseTest):
authors = cache.fields['authors'].table
# Delete a single book, with no formats and check cleaning
- self.assertIn(_('Unknown'), set(authors.id_map.itervalues()))
+ self.assertIn(_('Unknown'), set(itervalues(authors.id_map)))
olen = len(authors.id_map)
- item_id = {v:k for k, v in authors.id_map.iteritems()}[_('Unknown')]
+ item_id = {v:k for k, v in iteritems(authors.id_map)}[_('Unknown')]
cache.remove_books((3,))
for c in (cache, self.init_cache()):
table = c.fields['authors'].table
self.assertNotIn(3, c.all_book_ids())
- self.assertNotIn(_('Unknown'), set(table.id_map.itervalues()))
+ self.assertNotIn(_('Unknown'), set(itervalues(table.id_map)))
self.assertNotIn(item_id, table.asort_map)
self.assertNotIn(item_id, table.alink_map)
ae(len(table.id_map), olen-1)
@@ -235,17 +236,17 @@ class AddRemoveTest(BaseTest):
authorpath = os.path.dirname(bookpath)
os.mkdir(os.path.join(authorpath, '.DS_Store'))
open(os.path.join(authorpath, 'Thumbs.db'), 'wb').close()
- item_id = {v:k for k, v in cache.fields['#series'].table.id_map.iteritems()}['My Series Two']
+ item_id = {v:k for k, v in iteritems(cache.fields['#series'].table.id_map)}['My Series Two']
cache.remove_books((1,), permanent=True)
for x in (fmtpath, bookpath, authorpath):
af(os.path.exists(x), 'The file %s exists, when it should not' % x)
for c in (cache, self.init_cache()):
table = c.fields['authors'].table
self.assertNotIn(1, c.all_book_ids())
- self.assertNotIn('Author Two', set(table.id_map.itervalues()))
- self.assertNotIn(6, set(c.fields['rating'].table.id_map.itervalues()))
- self.assertIn('A Series One', set(c.fields['series'].table.id_map.itervalues()))
- self.assertNotIn('My Series Two', set(c.fields['#series'].table.id_map.itervalues()))
+ self.assertNotIn('Author Two', set(itervalues(table.id_map)))
+ self.assertNotIn(6, set(itervalues(c.fields['rating'].table.id_map)))
+ self.assertIn('A Series One', set(itervalues(c.fields['series'].table.id_map)))
+ self.assertNotIn('My Series Two', set(itervalues(c.fields['#series'].table.id_map)))
self.assertNotIn(item_id, c.fields['#series'].table.col_book_map)
self.assertNotIn(1, c.fields['#series'].table.book_col_map)
@@ -264,7 +265,7 @@ class AddRemoveTest(BaseTest):
fmtpath = cache.format_abspath(1, 'FMT1')
bookpath = os.path.dirname(fmtpath)
authorpath = os.path.dirname(bookpath)
- item_id = {v:k for k, v in cache.fields['#series'].table.id_map.iteritems()}['My Series Two']
+ item_id = {v:k for k, v in iteritems(cache.fields['#series'].table.id_map)}['My Series Two']
cache.remove_books((1,))
delete_service().wait()
for x in (fmtpath, bookpath, authorpath):
diff --git a/src/calibre/db/tests/filesystem.py b/src/calibre/db/tests/filesystem.py
index c426f024c0..11c9fbe0d7 100644
--- a/src/calibre/db/tests/filesystem.py
+++ b/src/calibre/db/tests/filesystem.py
@@ -13,6 +13,7 @@ from io import BytesIO
from calibre.constants import iswindows
from calibre.db.tests.base import BaseTest
from calibre.ptempfile import TemporaryDirectory
+from polyglot.builtins import iterkeys
class FilesystemTest(BaseTest):
@@ -55,7 +56,7 @@ class FilesystemTest(BaseTest):
cache2 = self.init_cache(cl)
for c in (cache, cache2):
data = self.get_filesystem_data(c, 1)
- ae(set(orig_data.iterkeys()), set(data.iterkeys()))
+ ae(set(iterkeys(orig_data)), set(iterkeys(data)))
ae(orig_data, data, 'Filesystem data does not match')
ae(c.field_for('path', 1), 'Moved/Moved (1)')
ae(c.field_for('path', 3), 'Moved1/Moved1 (3)')
diff --git a/src/calibre/db/tests/legacy.py b/src/calibre/db/tests/legacy.py
index 919f817b00..9310392882 100644
--- a/src/calibre/db/tests/legacy.py
+++ b/src/calibre/db/tests/legacy.py
@@ -14,7 +14,7 @@ from operator import itemgetter
from calibre.library.field_metadata import fm_as_dict
from calibre.db.tests.base import BaseTest
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, iterkeys, range
# Utils {{{
@@ -81,7 +81,7 @@ class LegacyTest(BaseTest):
# We ignore the key rec_index, since it is not stable for
# custom columns (it is created by iterating over a dict)
return {k.decode('utf-8') if isinstance(k, bytes) else k:to_unicode(v)
- for k, v in x.iteritems() if k != 'rec_index'}
+ for k, v in iteritems(x) if k != 'rec_index'}
return x
def get_props(db):
@@ -108,7 +108,7 @@ class LegacyTest(BaseTest):
'Test the get_property interface for reading data'
def get_values(db):
ans = {}
- for label, loc in db.FIELD_MAP.iteritems():
+ for label, loc in iteritems(db.FIELD_MAP):
if isinstance(label, numbers.Integral):
label = '#'+db.custom_column_num_map[label]['label']
label = type('')(label)
@@ -186,7 +186,7 @@ class LegacyTest(BaseTest):
self.assertEqual(dict(db.prefs), dict(ndb.prefs))
- for meth, args in {
+ for meth, args in iteritems({
'find_identical_books': [(Metadata('title one', ['author one']),), (Metadata('unknown'),), (Metadata('xxxx'),)],
'get_books_for_category': [('tags', newstag), ('#formats', 'FMT1')],
'get_next_series_num_for': [('A Series One',)],
@@ -251,7 +251,7 @@ class LegacyTest(BaseTest):
'book_on_device_string':[(1,), (2,), (3,)],
'books_in_series_of':[(0,), (1,), (2,)],
'books_with_same_title':[(Metadata(db.title(0)),), (Metadata(db.title(1)),), (Metadata('1234'),)],
- }.iteritems():
+ }):
fmt = lambda x: x
if meth[0] in {'!', '@'}:
fmt = {'!':dict, '@':frozenset}[meth[0]]
@@ -277,8 +277,8 @@ class LegacyTest(BaseTest):
old = db.get_data_as_dict(prefix='test-prefix')
new = ndb.get_data_as_dict(prefix='test-prefix')
for o, n in zip(old, new):
- o = {type('')(k) if isinstance(k, bytes) else k:set(v) if isinstance(v, list) else v for k, v in o.iteritems()}
- n = {k:set(v) if isinstance(v, list) else v for k, v in n.iteritems()}
+ o = {type('')(k) if isinstance(k, bytes) else k:set(v) if isinstance(v, list) else v for k, v in iteritems(o)}
+ n = {k:set(v) if isinstance(v, list) else v for k, v in iteritems(n)}
self.assertEqual(o, n)
ndb.search('title:Unknown')
@@ -316,9 +316,9 @@ class LegacyTest(BaseTest):
db = self.init_old()
cache = ndb.new_api
tmap = cache.get_id_map('tags')
- t = next(tmap.iterkeys())
+ t = next(iterkeys(tmap))
pmap = cache.get_id_map('publisher')
- p = next(pmap.iterkeys())
+ p = next(iterkeys(pmap))
run_funcs(self, db, ndb, (
('delete_tag_using_id', t),
('delete_publisher_using_id', p),
@@ -647,10 +647,10 @@ class LegacyTest(BaseTest):
ndb = self.init_legacy(self.cloned_library)
db = self.init_old(self.cloned_library)
- a = {v:k for k, v in ndb.new_api.get_id_map('authors').iteritems()}['Author One']
- t = {v:k for k, v in ndb.new_api.get_id_map('tags').iteritems()}['Tag One']
- s = {v:k for k, v in ndb.new_api.get_id_map('series').iteritems()}['A Series One']
- p = {v:k for k, v in ndb.new_api.get_id_map('publisher').iteritems()}['Publisher One']
+ a = {v:k for k, v in iteritems(ndb.new_api.get_id_map('authors'))}['Author One']
+ t = {v:k for k, v in iteritems(ndb.new_api.get_id_map('tags'))}['Tag One']
+ s = {v:k for k, v in iteritems(ndb.new_api.get_id_map('series'))}['A Series One']
+ p = {v:k for k, v in iteritems(ndb.new_api.get_id_map('publisher'))}['Publisher One']
run_funcs(self, db, ndb, (
('rename_author', a, 'Author Two'),
('rename_tag', t, 'News'),
@@ -688,11 +688,11 @@ class LegacyTest(BaseTest):
run_funcs(self, db, ndb, [(func, idx, label) for idx in range(3)])
# Test renaming/deleting
- t = {v:k for k, v in ndb.new_api.get_id_map('#tags').iteritems()}['My Tag One']
- t2 = {v:k for k, v in ndb.new_api.get_id_map('#tags').iteritems()}['My Tag Two']
- a = {v:k for k, v in ndb.new_api.get_id_map('#authors').iteritems()}['My Author Two']
- a2 = {v:k for k, v in ndb.new_api.get_id_map('#authors').iteritems()}['Custom One']
- s = {v:k for k, v in ndb.new_api.get_id_map('#series').iteritems()}['My Series One']
+ t = {v:k for k, v in iteritems(ndb.new_api.get_id_map('#tags'))}['My Tag One']
+ t2 = {v:k for k, v in iteritems(ndb.new_api.get_id_map('#tags'))}['My Tag Two']
+ a = {v:k for k, v in iteritems(ndb.new_api.get_id_map('#authors'))}['My Author Two']
+ a2 = {v:k for k, v in iteritems(ndb.new_api.get_id_map('#authors'))}['Custom One']
+ s = {v:k for k, v in iteritems(ndb.new_api.get_id_map('#series'))}['My Series One']
run_funcs(self, db, ndb, (
('delete_custom_item_using_id', t, 'tags'),
('delete_custom_item_using_id', a, 'authors'),
diff --git a/src/calibre/db/tests/reading.py b/src/calibre/db/tests/reading.py
index 4c95644e1a..3b90b4d93d 100644
--- a/src/calibre/db/tests/reading.py
+++ b/src/calibre/db/tests/reading.py
@@ -13,7 +13,7 @@ from time import time
from calibre.utils.date import utc_tz
from calibre.db.tests.base import BaseTest
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, iterkeys, itervalues, range
class ReadingTest(BaseTest):
@@ -116,8 +116,8 @@ class ReadingTest(BaseTest):
},
}
- for book_id, test in tests.iteritems():
- for field, expected_val in test.iteritems():
+ for book_id, test in iteritems(tests):
+ for field, expected_val in iteritems(test):
val = cache.field_for(field, book_id)
if isinstance(val, tuple) and 'authors' not in field and 'languages' not in field:
val, expected_val = set(val), set(expected_val)
@@ -130,7 +130,7 @@ class ReadingTest(BaseTest):
'Test sorting'
cache = self.init_cache()
ae = self.assertEqual
- for field, order in {
+ for field, order in iteritems({
'title' : [2, 1, 3],
'authors': [2, 1, 3],
'series' : [3, 1, 2],
@@ -154,7 +154,7 @@ class ReadingTest(BaseTest):
'#yesno':[2, 1, 3],
'#comments':[3, 2, 1],
'id': [1, 2, 3],
- }.iteritems():
+ }):
x = list(reversed(order))
ae(order, cache.multisort([(field, True)],
ids_to_sort=x),
@@ -222,7 +222,7 @@ class ReadingTest(BaseTest):
old_metadata = {i:old.get_metadata(
i, index_is_id=True, get_cover=True, cover_as_data=True) for i in
range(1, 4)}
- for mi in old_metadata.itervalues():
+ for mi in itervalues(old_metadata):
mi.format_metadata = dict(mi.format_metadata)
if mi.formats:
mi.formats = tuple(mi.formats)
@@ -234,7 +234,7 @@ class ReadingTest(BaseTest):
new_metadata = {i:cache.get_metadata(
i, get_cover=True, cover_as_data=True) for i in range(1, 4)}
cache = None
- for mi2, mi1 in zip(new_metadata.values(), old_metadata.values()):
+ for mi2, mi1 in zip(list(new_metadata.values()), list(old_metadata.values())):
self.compare_metadata(mi1, mi2)
# }}}
@@ -262,7 +262,7 @@ class ReadingTest(BaseTest):
old.conn.close()
old = None
cache = self.init_cache(self.library_path)
- for book_id, cdata in covers.iteritems():
+ for book_id, cdata in iteritems(covers):
self.assertEqual(cdata, cache.cover(book_id), 'Reading of cover failed')
f = cache.cover(book_id, as_file=True)
self.assertEqual(cdata, f.read() if f else f, 'Reading of cover as file failed')
@@ -325,7 +325,7 @@ class ReadingTest(BaseTest):
old = None
cache = self.init_cache(self.cloned_library)
- for query, ans in oldvals.iteritems():
+ for query, ans in iteritems(oldvals):
nr = cache.search(query, '')
self.assertEqual(ans, nr,
'Old result: %r != New result: %r for search: %s'%(
@@ -407,11 +407,11 @@ class ReadingTest(BaseTest):
lf = {i:set(old.formats(i, index_is_id=True).split(',')) if old.formats(
i, index_is_id=True) else set() for i in ids}
formats = {i:{f:old.format(i, f, index_is_id=True) for f in fmts} for
- i, fmts in lf.iteritems()}
+ i, fmts in iteritems(lf)}
old.conn.close()
old = None
cache = self.init_cache(self.library_path)
- for book_id, fmts in lf.iteritems():
+ for book_id, fmts in iteritems(lf):
self.assertEqual(fmts, set(cache.formats(book_id)),
'Set of formats is not the same')
for fmt in fmts:
@@ -439,9 +439,9 @@ class ReadingTest(BaseTest):
'Test getting the author sort for authors from the db'
cache = self.init_cache()
table = cache.fields['authors'].table
- table.set_sort_names({next(table.id_map.iterkeys()): 'Fake Sort'}, cache.backend)
+ table.set_sort_names({next(iterkeys(table.id_map)): 'Fake Sort'}, cache.backend)
- authors = tuple(table.id_map.itervalues())
+ authors = tuple(itervalues(table.id_map))
nval = cache.author_sort_from_authors(authors)
self.assertIn('Fake Sort', nval)
@@ -458,7 +458,7 @@ class ReadingTest(BaseTest):
cache.set_field('series', {3:'test series'})
cache.set_field('series_index', {3:13})
table = cache.fields['series'].table
- series = tuple(table.id_map.itervalues())
+ series = tuple(itervalues(table.id_map))
nvals = {s:cache.get_next_series_num_for(s) for s in series}
db = self.init_old()
self.assertEqual({s:db.get_next_series_num_for(s) for s in series}, nvals)
@@ -471,7 +471,7 @@ class ReadingTest(BaseTest):
from calibre.ebooks.metadata.book.base import Metadata
cache = self.init_cache()
db = self.init_old()
- for title in cache.fields['title'].table.book_col_map.itervalues():
+ for title in itervalues(cache.fields['title'].table.book_col_map):
for x in (db, cache):
self.assertTrue(x.has_book(Metadata(title)))
self.assertTrue(x.has_book(Metadata(title.upper())))
diff --git a/src/calibre/db/tests/writing.py b/src/calibre/db/tests/writing.py
index 5806b060bd..e41b30c743 100644
--- a/src/calibre/db/tests/writing.py
+++ b/src/calibre/db/tests/writing.py
@@ -14,6 +14,7 @@ from io import BytesIO
from calibre.ebooks.metadata import author_to_author_sort
from calibre.utils.date import UNDEFINED_DATE
from calibre.db.tests.base import BaseTest, IMG
+from polyglot.builtins import iteritems, itervalues
class WritingTest(BaseTest):
@@ -166,7 +167,7 @@ class WritingTest(BaseTest):
self.assertEqual(cache.set_field('#enum', {1:None}), {1})
cache2 = self.init_cache(cl)
for c in (cache, cache2):
- for i, val in {1:None, 2:'One', 3:'Three'}.iteritems():
+ for i, val in iteritems({1:None, 2:'One', 3:'Three'}):
self.assertEqual(c.field_for('#enum', i), val)
del cache2
@@ -176,9 +177,9 @@ class WritingTest(BaseTest):
self.assertEqual(cache.set_field('#rating', {1:None, 2:4, 3:8}), {1, 2, 3})
cache2 = self.init_cache(cl)
for c in (cache, cache2):
- for i, val in {1:None, 2:4, 3:2}.iteritems():
+ for i, val in iteritems({1:None, 2:4, 3:2}):
self.assertEqual(c.field_for('rating', i), val)
- for i, val in {1:None, 2:4, 3:8}.iteritems():
+ for i, val in iteritems({1:None, 2:4, 3:8}):
self.assertEqual(c.field_for('#rating', i), val)
del cache2
@@ -191,14 +192,14 @@ class WritingTest(BaseTest):
self.assertEqual(cache.set_field('#series', {2:'Series [0]'}), {2})
cache2 = self.init_cache(cl)
for c in (cache, cache2):
- for i, val in {1:'A Series One', 2:'A Series One', 3:'Series'}.iteritems():
+ for i, val in iteritems({1:'A Series One', 2:'A Series One', 3:'Series'}):
self.assertEqual(c.field_for('series', i), val)
cs_indices = {1:c.field_for('#series_index', 1), 3:c.field_for('#series_index', 3)}
for i in (1, 2, 3):
self.assertEqual(c.field_for('#series', i), 'Series')
- for i, val in {1:2, 2:1, 3:3}.iteritems():
+ for i, val in iteritems({1:2, 2:1, 3:3}):
self.assertEqual(c.field_for('series_index', i), val)
- for i, val in {1:cs_indices[1], 2:0, 3:cs_indices[3]}.iteritems():
+ for i, val in iteritems({1:cs_indices[1], 2:0, 3:cs_indices[3]}):
self.assertEqual(c.field_for('#series_index', i), val)
del cache2
@@ -461,13 +462,13 @@ class WritingTest(BaseTest):
tmap = cache.get_id_map('tags')
self.assertEqual(cache.remove_items('tags', tmap), {1, 2})
tmap = cache.get_id_map('#tags')
- t = {v:k for k, v in tmap.iteritems()}['My Tag Two']
+ t = {v:k for k, v in iteritems(tmap)}['My Tag Two']
self.assertEqual(cache.remove_items('#tags', (t,)), {1, 2})
smap = cache.get_id_map('series')
self.assertEqual(cache.remove_items('series', smap), {1, 2})
smap = cache.get_id_map('#series')
- s = {v:k for k, v in smap.iteritems()}['My Series Two']
+ s = {v:k for k, v in iteritems(smap)}['My Series Two']
self.assertEqual(cache.remove_items('#series', (s,)), {1})
for c in (cache, self.init_cache()):
@@ -507,7 +508,7 @@ class WritingTest(BaseTest):
for c in (cache, c2):
self.assertEqual(c.field_for('tags', 1), ())
self.assertEqual(c.field_for('tags', 2), ('b', 'a'))
- self.assertNotIn('c', set(c.get_id_map('tags').itervalues()))
+ self.assertNotIn('c', set(itervalues(c.get_id_map('tags'))))
self.assertEqual(c.field_for('series', 1), None)
self.assertEqual(c.field_for('series', 2), 'a')
self.assertEqual(c.field_for('series_index', 1), 1.0)
@@ -520,9 +521,9 @@ class WritingTest(BaseTest):
cl = self.cloned_library
cache = self.init_cache(cl)
# Check that renaming authors updates author sort and path
- a = {v:k for k, v in cache.get_id_map('authors').iteritems()}['Unknown']
+ a = {v:k for k, v in iteritems(cache.get_id_map('authors'))}['Unknown']
self.assertEqual(cache.rename_items('authors', {a:'New Author'})[0], {3})
- a = {v:k for k, v in cache.get_id_map('authors').iteritems()}['Author One']
+ a = {v:k for k, v in iteritems(cache.get_id_map('authors'))}['Author One']
self.assertEqual(cache.rename_items('authors', {a:'Author Two'})[0], {1, 2})
for c in (cache, self.init_cache(cl)):
self.assertEqual(c.all_field_names('authors'), {'New Author', 'Author Two'})
@@ -531,7 +532,7 @@ class WritingTest(BaseTest):
self.assertEqual(c.field_for('authors', 1), ('Author Two',))
self.assertEqual(c.field_for('author_sort', 1), 'Two, Author')
- t = {v:k for k, v in cache.get_id_map('tags').iteritems()}['Tag One']
+ t = {v:k for k, v in iteritems(cache.get_id_map('tags'))}['Tag One']
# Test case change
self.assertEqual(cache.rename_items('tags', {t:'tag one'}), ({1, 2}, {t:t}))
for c in (cache, self.init_cache(cl)):
@@ -551,14 +552,14 @@ class WritingTest(BaseTest):
self.assertEqual(set(c.field_for('tags', 1)), {'Tag Two', 'News'})
self.assertEqual(set(c.field_for('tags', 2)), {'Tag Two'})
# Test on a custom column
- t = {v:k for k, v in cache.get_id_map('#tags').iteritems()}['My Tag One']
+ t = {v:k for k, v in iteritems(cache.get_id_map('#tags'))}['My Tag One']
self.assertEqual(cache.rename_items('#tags', {t:'My Tag Two'})[0], {2})
for c in (cache, self.init_cache(cl)):
self.assertEqual(c.all_field_names('#tags'), {'My Tag Two'})
self.assertEqual(set(c.field_for('#tags', 2)), {'My Tag Two'})
# Test a Many-one field
- s = {v:k for k, v in cache.get_id_map('series').iteritems()}['A Series One']
+ s = {v:k for k, v in iteritems(cache.get_id_map('series'))}['A Series One']
# Test case change
self.assertEqual(cache.rename_items('series', {s:'a series one'}), ({1, 2}, {s:s}))
for c in (cache, self.init_cache(cl)):
@@ -574,7 +575,7 @@ class WritingTest(BaseTest):
self.assertEqual(c.field_for('series', 2), 'series')
self.assertEqual(c.field_for('series_index', 1), 2.0)
- s = {v:k for k, v in cache.get_id_map('#series').iteritems()}['My Series One']
+ s = {v:k for k, v in iteritems(cache.get_id_map('#series'))}['My Series One']
# Test custom column with rename to existing
self.assertEqual(cache.rename_items('#series', {s:'My Series Two'})[0], {2})
for c in (cache, self.init_cache(cl)):
@@ -585,7 +586,7 @@ class WritingTest(BaseTest):
# Test renaming many-many items to multiple items
cache = self.init_cache(self.cloned_library)
- t = {v:k for k, v in cache.get_id_map('tags').iteritems()}['Tag One']
+ t = {v:k for k, v in iteritems(cache.get_id_map('tags'))}['Tag One']
affected_books, id_map = cache.rename_items('tags', {t:'Something, Else, Entirely'})
self.assertEqual({1, 2}, affected_books)
tmap = cache.get_id_map('tags')
@@ -600,7 +601,7 @@ class WritingTest(BaseTest):
# Test with restriction
cache = self.init_cache()
cache.set_field('tags', {1:'a,b,c', 2:'x,y,z', 3:'a,x,z'})
- tmap = {v:k for k, v in cache.get_id_map('tags').iteritems()}
+ tmap = {v:k for k, v in iteritems(cache.get_id_map('tags'))}
self.assertEqual(cache.rename_items('tags', {tmap['a']:'r'}, restrict_to_book_ids=()), (set(), {}))
self.assertEqual(cache.rename_items('tags', {tmap['a']:'r', tmap['b']:'q'}, restrict_to_book_ids=(1,))[0], {1})
self.assertEqual(cache.rename_items('tags', {tmap['x']:'X'}, restrict_to_book_ids=(2,))[0], {2})
@@ -657,7 +658,7 @@ class WritingTest(BaseTest):
ldata = {aid:str(aid) for aid in adata}
self.assertEqual({1,2,3}, cache.set_link_for_authors(ldata))
for c in (cache, self.init_cache()):
- self.assertEqual(ldata, {aid:d['link'] for aid, d in c.author_data().iteritems()})
+ self.assertEqual(ldata, {aid:d['link'] for aid, d in iteritems(c.author_data())})
self.assertEqual({3}, cache.set_link_for_authors({aid:'xxx' if aid == max(adata) else str(aid) for aid in adata}),
'Setting the author link to the same value as before, incorrectly marked some books as dirty')
sdata = {aid:'%s, changed' % aid for aid in adata}
@@ -709,7 +710,7 @@ class WritingTest(BaseTest):
conn.execute('INSERT INTO tags (name) VALUES ("t")')
norm = conn.last_insert_rowid()
conn.execute('DELETE FROM books_tags_link')
- for book_id, vals in {1:(lid, uid), 2:(uid, mid), 3:(lid, norm)}.iteritems():
+ for book_id, vals in iteritems({1:(lid, uid), 2:(uid, mid), 3:(lid, norm)}):
conn.executemany('INSERT INTO books_tags_link (book,tag) VALUES (?,?)',
tuple((book_id, x) for x in vals))
cache.reload_from_db()
diff --git a/src/calibre/db/utils.py b/src/calibre/db/utils.py
index 5d02367248..d9d2b48893 100644
--- a/src/calibre/db/utils.py
+++ b/src/calibre/db/utils.py
@@ -9,7 +9,7 @@ __copyright__ = '2013, Kovid Goyal '
import os, errno, sys, re
from locale import localeconv
from collections import OrderedDict, namedtuple
-from polyglot.builtins import map, unicode_type, string_or_bytes
+from polyglot.builtins import iteritems, itervalues, map, unicode_type, string_or_bytes
from threading import Lock
from calibre import as_unicode, prints
@@ -208,7 +208,7 @@ class ThumbnailCache(object):
def _invalidate_sizes(self):
if self.size_changed:
size = self.thumbnail_size
- remove = (key for key, entry in self.items.iteritems() if size != entry.thumbnail_size)
+ remove = (key for key, entry in iteritems(self.items) if size != entry.thumbnail_size)
for key in remove:
self._remove(key)
self.size_changed = False
@@ -365,7 +365,7 @@ class ThumbnailCache(object):
pass
if not hasattr(self, 'total_size'):
self._load_index()
- for entry in self.items.itervalues():
+ for entry in itervalues(self.items):
self._do_delete(entry.path)
self.total_size = 0
self.items = OrderedDict()
diff --git a/src/calibre/db/view.py b/src/calibre/db/view.py
index fc773ac680..7fd51e783d 100644
--- a/src/calibre/db/view.py
+++ b/src/calibre/db/view.py
@@ -9,7 +9,8 @@ __docformat__ = 'restructuredtext en'
import weakref, operator, numbers
from functools import partial
-from polyglot.builtins import map, unicode_type, range, zip
+from polyglot.builtins import (iteritems, iterkeys, itervalues, map,
+ unicode_type, range, zip)
from calibre.ebooks.metadata import title_sort
from calibre.utils.config_base import tweaks, prefs
@@ -71,7 +72,7 @@ def format_is_multiple(x, sep=',', repl=None):
def format_identifiers(x):
if not x:
return None
- return ','.join('%s:%s'%(k, v) for k, v in x.iteritems())
+ return ','.join('%s:%s'%(k, v) for k, v in iteritems(x))
class View(object):
@@ -88,7 +89,7 @@ class View(object):
self.search_restriction_name = self.base_restriction_name = ''
self._field_getters = {}
self.column_count = len(cache.backend.FIELD_MAP)
- for col, idx in cache.backend.FIELD_MAP.iteritems():
+ for col, idx in iteritems(cache.backend.FIELD_MAP):
label, fmt = col, lambda x:x
func = {
'id': self._get_id,
@@ -373,14 +374,14 @@ class View(object):
self.marked_ids = dict.fromkeys(id_dict, u'true')
else:
# Ensure that all the items in the dict are text
- self.marked_ids = dict(zip(id_dict.iterkeys(), map(unicode_type,
- id_dict.itervalues())))
+ self.marked_ids = dict(zip(iterkeys(id_dict), map(unicode_type,
+ itervalues(id_dict))))
# This invalidates all searches in the cache even though the cache may
# be shared by multiple views. This is not ideal, but...
cmids = set(self.marked_ids)
self.cache.clear_search_caches(old_marked_ids | cmids)
if old_marked_ids != cmids:
- for funcref in self.marked_listeners.itervalues():
+ for funcref in itervalues(self.marked_listeners):
func = funcref()
if func is not None:
func(old_marked_ids, cmids)
diff --git a/src/calibre/db/write.py b/src/calibre/db/write.py
index 5670fff3f5..abc89e3353 100644
--- a/src/calibre/db/write.py
+++ b/src/calibre/db/write.py
@@ -10,7 +10,7 @@ __docformat__ = 'restructuredtext en'
import re
from functools import partial
from datetime import datetime
-from polyglot.builtins import unicode_type, zip
+from polyglot.builtins import iteritems, itervalues, unicode_type, zip
from calibre.constants import preferred_encoding
from calibre.ebooks.metadata import author_to_author_sort, title_sort
@@ -131,7 +131,7 @@ def adapt_identifiers(to_tuple, x):
if not isinstance(x, dict):
x = {k:v for k, v in (y.partition(':')[0::2] for y in to_tuple(x))}
ans = {}
- for k, v in x.iteritems():
+ for k, v in iteritems(x):
k, v = clean_identifier(k, v)
if k and v:
ans[k] = v
@@ -194,7 +194,7 @@ def get_adapter(name, metadata):
def one_one_in_books(book_id_val_map, db, field, *args):
'Set a one-one field in the books table'
if book_id_val_map:
- sequence = ((sqlite_datetime(v), k) for k, v in book_id_val_map.iteritems())
+ sequence = ((sqlite_datetime(v), k) for k, v in iteritems(book_id_val_map))
db.executemany(
'UPDATE books SET %s=? WHERE id=?'%field.metadata['column'], sequence)
field.table.book_col_map.update(book_id_val_map)
@@ -210,23 +210,23 @@ def set_title(book_id_val_map, db, field, *args):
ans = one_one_in_books(book_id_val_map, db, field, *args)
# Set the title sort field
field.title_sort_field.writer.set_books(
- {k:title_sort(v) for k, v in book_id_val_map.iteritems()}, db)
+ {k:title_sort(v) for k, v in iteritems(book_id_val_map)}, db)
return ans
def one_one_in_other(book_id_val_map, db, field, *args):
'Set a one-one field in the non-books table, like comments'
- deleted = tuple((k,) for k, v in book_id_val_map.iteritems() if v is None)
+ deleted = tuple((k,) for k, v in iteritems(book_id_val_map) if v is None)
if deleted:
db.executemany('DELETE FROM %s WHERE book=?'%field.metadata['table'],
deleted)
for book_id in deleted:
field.table.book_col_map.pop(book_id[0], None)
- updated = {k:v for k, v in book_id_val_map.iteritems() if v is not None}
+ updated = {k:v for k, v in iteritems(book_id_val_map) if v is not None}
if updated:
db.executemany('INSERT OR REPLACE INTO %s(book,%s) VALUES (?,?)'%(
field.metadata['table'], field.metadata['column']),
- ((k, sqlite_datetime(v)) for k, v in updated.iteritems()))
+ ((k, sqlite_datetime(v)) for k, v in iteritems(updated)))
field.table.book_col_map.update(updated)
return set(book_id_val_map)
@@ -234,7 +234,7 @@ def one_one_in_other(book_id_val_map, db, field, *args):
def custom_series_index(book_id_val_map, db, field, *args):
series_field = field.series_field
sequence = []
- for book_id, sidx in book_id_val_map.iteritems():
+ for book_id, sidx in iteritems(book_id_val_map):
if sidx is None:
sidx = 1.0
ids = series_field.ids_for_book(book_id)
@@ -285,12 +285,12 @@ def get_db_id(val, db, m, table, kmap, rid_map, allow_case_change,
def change_case(case_changes, dirtied, db, table, m, is_authors=False):
if is_authors:
vals = ((val.replace(',', '|'), item_id) for item_id, val in
- case_changes.iteritems())
+ iteritems(case_changes))
else:
- vals = ((val, item_id) for item_id, val in case_changes.iteritems())
+ vals = ((val, item_id) for item_id, val in iteritems(case_changes))
db.executemany(
'UPDATE %s SET %s=? WHERE id=?'%(m['table'], m['column']), vals)
- for item_id, val in case_changes.iteritems():
+ for item_id, val in iteritems(case_changes):
table.id_map[item_id] = val
dirtied.update(table.col_book_map[item_id])
if is_authors:
@@ -306,14 +306,14 @@ def many_one(book_id_val_map, db, field, allow_case_change, *args):
# Map values to db ids, including any new values
kmap = safe_lower if dt in {'text', 'series'} else lambda x:x
- rid_map = {kmap(item):item_id for item_id, item in table.id_map.iteritems()}
+ rid_map = {kmap(item):item_id for item_id, item in iteritems(table.id_map)}
if len(rid_map) != len(table.id_map):
# table has some entries that differ only in case, fix it
table.fix_case_duplicates(db)
- rid_map = {kmap(item):item_id for item_id, item in table.id_map.iteritems()}
+ rid_map = {kmap(item):item_id for item_id, item in iteritems(table.id_map)}
val_map = {None:None}
case_changes = {}
- for val in book_id_val_map.itervalues():
+ for val in itervalues(book_id_val_map):
if val is not None:
get_db_id(val, db, m, table, kmap, rid_map, allow_case_change,
case_changes, val_map)
@@ -321,17 +321,17 @@ def many_one(book_id_val_map, db, field, allow_case_change, *args):
if case_changes:
change_case(case_changes, dirtied, db, table, m)
- book_id_item_id_map = {k:val_map[v] for k, v in book_id_val_map.iteritems()}
+ book_id_item_id_map = {k:val_map[v] for k, v in iteritems(book_id_val_map)}
# Ignore those items whose value is the same as the current value
- book_id_item_id_map = {k:v for k, v in book_id_item_id_map.iteritems()
+ book_id_item_id_map = {k:v for k, v in iteritems(book_id_item_id_map)
if v != table.book_col_map.get(k, None)}
dirtied |= set(book_id_item_id_map)
# Update the book->col and col->book maps
deleted = set()
updated = {}
- for book_id, item_id in book_id_item_id_map.iteritems():
+ for book_id, item_id in iteritems(book_id_item_id_map):
old_item_id = table.book_col_map.get(book_id, None)
if old_item_id is not None:
table.col_book_map[old_item_id].discard(book_id)
@@ -355,7 +355,7 @@ def many_one(book_id_val_map, db, field, allow_case_change, *args):
)
db.executemany(sql.format(table.link_table, m['link_column']),
((book_id, book_id, item_id) for book_id, item_id in
- updated.iteritems()))
+ iteritems(updated)))
# Remove no longer used items
remove = {item_id for item_id in table.id_map if not
@@ -392,15 +392,15 @@ def many_many(book_id_val_map, db, field, allow_case_change, *args):
# Map values to db ids, including any new values
kmap = safe_lower if dt == 'text' else lambda x:x
- rid_map = {kmap(item):item_id for item_id, item in table.id_map.iteritems()}
+ rid_map = {kmap(item):item_id for item_id, item in iteritems(table.id_map)}
if len(rid_map) != len(table.id_map):
# table has some entries that differ only in case, fix it
table.fix_case_duplicates(db)
- rid_map = {kmap(item):item_id for item_id, item in table.id_map.iteritems()}
+ rid_map = {kmap(item):item_id for item_id, item in iteritems(table.id_map)}
val_map = {}
case_changes = {}
- book_id_val_map = {k:uniq(vals, kmap) for k, vals in book_id_val_map.iteritems()}
- for vals in book_id_val_map.itervalues():
+ book_id_val_map = {k:uniq(vals, kmap) for k, vals in iteritems(book_id_val_map)}
+ for vals in itervalues(book_id_val_map):
for val in vals:
get_db_id(val, db, m, table, kmap, rid_map, allow_case_change,
case_changes, val_map, is_authors=is_authors)
@@ -408,7 +408,7 @@ def many_many(book_id_val_map, db, field, allow_case_change, *args):
if case_changes:
change_case(case_changes, dirtied, db, table, m, is_authors=is_authors)
if is_authors:
- for item_id, val in case_changes.iteritems():
+ for item_id, val in iteritems(case_changes):
for book_id in table.col_book_map[item_id]:
current_sort = field.db_author_sort_for_book(book_id)
new_sort = field.author_sort_for_book(book_id)
@@ -418,17 +418,17 @@ def many_many(book_id_val_map, db, field, allow_case_change, *args):
field.author_sort_field.writer.set_books({book_id:new_sort}, db)
book_id_item_id_map = {k:tuple(val_map[v] for v in vals)
- for k, vals in book_id_val_map.iteritems()}
+ for k, vals in iteritems(book_id_val_map)}
# Ignore those items whose value is the same as the current value
- book_id_item_id_map = {k:v for k, v in book_id_item_id_map.iteritems()
+ book_id_item_id_map = {k:v for k, v in iteritems(book_id_item_id_map)
if v != table.book_col_map.get(k, None)}
dirtied |= set(book_id_item_id_map)
# Update the book->col and col->book maps
deleted = set()
updated = {}
- for book_id, item_ids in book_id_item_id_map.iteritems():
+ for book_id, item_ids in iteritems(book_id_item_id_map):
old_item_ids = table.book_col_map.get(book_id, None)
if old_item_ids:
for old_item_id in old_item_ids:
@@ -448,7 +448,7 @@ def many_many(book_id_val_map, db, field, allow_case_change, *args):
((k,) for k in deleted))
if updated:
vals = (
- (book_id, val) for book_id, vals in updated.iteritems()
+ (book_id, val) for book_id, vals in iteritems(updated)
for val in vals
)
db.executemany('DELETE FROM %s WHERE book=?'%table.link_table,
@@ -481,7 +481,7 @@ def many_many(book_id_val_map, db, field, allow_case_change, *args):
def identifiers(book_id_val_map, db, field, *args): # {{{
table = field.table
updates = set()
- for book_id, identifiers in book_id_val_map.iteritems():
+ for book_id, identifiers in iteritems(book_id_val_map):
if book_id not in table.book_col_map:
table.book_col_map[book_id] = {}
current_ids = table.book_col_map[book_id]
@@ -490,7 +490,7 @@ def identifiers(book_id_val_map, db, field, *args): # {{{
table.col_book_map.get(key, set()).discard(book_id)
current_ids.pop(key, None)
current_ids.update(identifiers)
- for key, val in identifiers.iteritems():
+ for key, val in iteritems(identifiers):
if key not in table.col_book_map:
table.col_book_map[key] = set()
table.col_book_map[key].add(book_id)
@@ -538,7 +538,7 @@ class Writer(object):
def set_books(self, book_id_val_map, db, allow_case_change=True):
book_id_val_map = {k:self.adapter(v) for k, v in
- book_id_val_map.iteritems() if self.accept_vals(v)}
+ iteritems(book_id_val_map) if self.accept_vals(v)}
if not book_id_val_map:
return set()
dirtied = self.set_books_func(book_id_val_map, db, self.field,
@@ -548,7 +548,7 @@ class Writer(object):
def set_books_for_enum(self, book_id_val_map, db, field,
allow_case_change):
allowed = set(field.metadata['display']['enum_values'])
- book_id_val_map = {k:v for k, v in book_id_val_map.iteritems() if v is
+ book_id_val_map = {k:v for k, v in iteritems(book_id_val_map) if v is
None or v in allowed}
if not book_id_val_map:
return set()
diff --git a/src/calibre/debug.py b/src/calibre/debug.py
index 3b8c901377..6e67e19fce 100644
--- a/src/calibre/debug.py
+++ b/src/calibre/debug.py
@@ -248,7 +248,8 @@ def run_script(path, args):
g = globals()
g['__name__'] = '__main__'
g['__file__'] = ef
- execfile(ef, g)
+ with open(ef, 'rb') as f:
+ exec(compile(f.read(), ef, 'exec'), g)
def inspect_mobi(path):
@@ -346,7 +347,7 @@ def main(args=sys.argv):
elif ext in {'mobi', 'azw', 'azw3'}:
inspect_mobi(path)
else:
- print ('Cannot dump unknown filetype: %s' % path)
+ print('Cannot dump unknown filetype: %s' % path)
elif len(args) >= 2 and os.path.exists(os.path.join(args[1], '__main__.py')):
sys.path.insert(0, args[1])
run_script(os.path.join(args[1], '__main__.py'), args[2:])
diff --git a/src/calibre/devices/kobo/bookmark.py b/src/calibre/devices/kobo/bookmark.py
index a08f5573f9..8763915ff5 100644
--- a/src/calibre/devices/kobo/bookmark.py
+++ b/src/calibre/devices/kobo/bookmark.py
@@ -12,6 +12,7 @@ class Bookmark(): # {{{
A simple class fetching bookmark data
kobo-specific
'''
+
def __init__(self, db_connection, contentid, path, id, book_format, bookmark_extension):
self.book_format = book_format
self.bookmark_extension = bookmark_extension
@@ -62,7 +63,7 @@ class Bookmark(): # {{{
kepub_chapter_data = ('{0}-%'.format(row[1]), )
cursor2.execute(kepub_chapter_query, kepub_chapter_data)
try:
- kepub_chapter = cursor2.next()
+ kepub_chapter = next(cursor2)
chapter_title = kepub_chapter[0]
current_chapter = kepub_chapter[1]
except StopIteration:
diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py
index c9f9f295ac..7f8223b473 100644
--- a/src/calibre/devices/kobo/driver.py
+++ b/src/calibre/devices/kobo/driver.py
@@ -32,7 +32,7 @@ from calibre import prints, fsync
from calibre.ptempfile import PersistentTemporaryFile
from calibre.constants import DEBUG
from calibre.utils.config_base import prefs
-from polyglot.builtins import unicode_type, string_or_bytes
+from polyglot.builtins import iteritems, itervalues, unicode_type, string_or_bytes
EPUB_EXT = '.epub'
KEPUB_EXT = '.kepub'
@@ -185,7 +185,7 @@ class KOBO(USBMS):
cursor = connection.cursor()
cursor.execute('SELECT version FROM dbversion')
try:
- result = cursor.next()
+ result = next(cursor)
dbversion = result['version']
except StopIteration:
dbversion = 0
@@ -407,7 +407,7 @@ class KOBO(USBMS):
# Remove books that are no longer in the filesystem. Cache contains
# indices into the booklist if book not in filesystem, None otherwise
# Do the operation in reverse order so indices remain valid
- for idx in sorted(bl_cache.itervalues(), reverse=True):
+ for idx in sorted(itervalues(bl_cache), reverse=True):
if idx is not None:
need_sync = True
del bl[idx]
@@ -572,7 +572,7 @@ class KOBO(USBMS):
metadata = iter(metadata)
for i, location in enumerate(locations):
self.report_progress((i+1) / float(len(locations)), _('Adding books to device metadata listing...'))
- info = metadata.next()
+ info = next(metadata)
debug_print("KoboTouch::add_books_to_metadata - info=%s" % info)
blist = 2 if location[1] == 'cardb' else 1 if location[1] == 'carda' else 0
@@ -790,7 +790,7 @@ class KOBO(USBMS):
t = (ContentID,)
cursor.execute('select DateLastRead, ReadStatus from Content where BookID is Null and ContentID = ?', t)
try:
- result = cursor.next()
+ result = next(cursor)
datelastread = result['DateLastRead']
current_ReadStatus = result['ReadStatus']
except StopIteration:
@@ -908,13 +908,13 @@ class KOBO(USBMS):
ContentID = self.contentid_from_path(book.path, ContentType)
- if category in readstatuslist.keys():
+ if category in list(readstatuslist.keys()):
# Manage ReadStatus
self.set_readstatus(connection, ContentID, readstatuslist.get(category))
elif category == 'Shortlist' and self.dbversion >= 14:
# Manage FavouritesIndex/Shortlist
self.set_favouritesindex(connection, ContentID)
- elif category in accessibilitylist.keys():
+ elif category in list(accessibilitylist.keys()):
# Do not manage the Accessibility List
pass
else: # No collections
@@ -1020,7 +1020,7 @@ class KOBO(USBMS):
t = (ContentID,)
cursor.execute('select ImageId from Content where BookID is Null and ContentID = ?', t)
try:
- result = cursor.next()
+ result = next(cursor)
# debug_print("ImageId: ", result[0])
ImageID = result[0]
except StopIteration:
@@ -1962,7 +1962,7 @@ class KOBOTOUCH(KOBO):
# Remove books that are no longer in the filesystem. Cache contains
# indices into the booklist if book not in filesystem, None otherwise
# Do the operation in reverse order so indices remain valid
- for idx in sorted(bl_cache.itervalues(), reverse=True):
+ for idx in sorted(itervalues(bl_cache), reverse=True):
if idx is not None:
if not os.path.exists(self.normalize_path(os.path.join(prefix, bl[idx].lpath))) or not bl[idx].contentID:
need_sync = True
@@ -2136,7 +2136,7 @@ class KOBOTOUCH(KOBO):
from calibre.ebooks.oeb.base import OEB_STYLES
is_dirty = False
- for cssname, mt in container.mime_map.iteritems():
+ for cssname, mt in iteritems(container.mime_map):
if mt in OEB_STYLES:
newsheet = container.parsed(cssname)
oldrules = len(newsheet.cssRules)
@@ -2445,7 +2445,7 @@ class KOBOTOUCH(KOBO):
debug_print(' Setting bookshelf on device')
self.set_bookshelf(connection, book, category)
category_added = True
- elif category in readstatuslist.keys():
+ elif category in list(readstatuslist.keys()):
debug_print("KoboTouch:update_device_database_collections - about to set_readstatus - category='%s'"%(category, ))
# Manage ReadStatus
self.set_readstatus(connection, book.contentID, readstatuslist.get(category))
@@ -2460,7 +2460,7 @@ class KOBOTOUCH(KOBO):
debug_print(' and about to set it - %s'%book.title)
self.set_favouritesindex(connection, book.contentID)
category_added = True
- elif category in accessibilitylist.keys():
+ elif category in list(accessibilitylist.keys()):
# Do not manage the Accessibility List
pass
@@ -2647,7 +2647,7 @@ class KOBOTOUCH(KOBO):
t = (ContentID,)
cursor.execute('select ImageId from Content where BookID is Null and ContentID = ?', t)
try:
- result = cursor.next()
+ result = next(cursor)
ImageID = result[0]
except StopIteration:
ImageID = self.imageid_from_contentid(ContentID)
@@ -2750,7 +2750,7 @@ class KOBOTOUCH(KOBO):
cursor = connection.cursor()
cursor.execute(test_query, test_values)
try:
- result = cursor.next()
+ result = next(cursor)
except StopIteration:
result = None
@@ -2858,7 +2858,7 @@ class KOBOTOUCH(KOBO):
cursor = connection.cursor()
cursor.execute(test_query, test_values)
try:
- result = cursor.next()
+ result = next(cursor)
except StopIteration:
result = None
@@ -2907,7 +2907,7 @@ class KOBOTOUCH(KOBO):
cursor = connection.cursor()
cursor.execute(test_query, test_values)
try:
- result = cursor.next()
+ result = next(cursor)
except StopIteration:
result = None
diff --git a/src/calibre/devices/mtp/defaults.py b/src/calibre/devices/mtp/defaults.py
index ed72ddaad1..9bcd6f2909 100644
--- a/src/calibre/devices/mtp/defaults.py
+++ b/src/calibre/devices/mtp/defaults.py
@@ -10,6 +10,7 @@ __docformat__ = 'restructuredtext en'
import traceback, re
from calibre.constants import iswindows
+from polyglot.builtins import iteritems
class DeviceDefaults(object):
@@ -47,7 +48,7 @@ class DeviceDefaults(object):
for rule in self.rules:
tests = rule[0]
matches = True
- for k, v in tests.iteritems():
+ for k, v in iteritems(tests):
if k == 'vendor' and v != vid:
matches = False
break
diff --git a/src/calibre/devices/mtp/driver.py b/src/calibre/devices/mtp/driver.py
index 725f497baa..58a19b19c7 100644
--- a/src/calibre/devices/mtp/driver.py
+++ b/src/calibre/devices/mtp/driver.py
@@ -17,7 +17,7 @@ from calibre.devices.mtp.base import debug
from calibre.devices.mtp.defaults import DeviceDefaults
from calibre.ptempfile import SpooledTemporaryFile, PersistentTemporaryDirectory
from calibre.utils.filenames import shorten_components_to
-from polyglot.builtins import unicode_type, zip
+from polyglot.builtins import iteritems, itervalues, unicode_type, zip
BASE = importlib.import_module('calibre.devices.mtp.%s.driver'%(
'windows' if iswindows else 'unix')).MTP_DEVICE
@@ -276,7 +276,7 @@ class MTP_DEVICE(BASE):
book.path = mtp_file.mtp_id_path
# Remove books in the cache that no longer exist
- for idx in sorted(relpath_cache.itervalues(), reverse=True):
+ for idx in sorted(itervalues(relpath_cache), reverse=True):
del bl[idx]
need_sync = True
@@ -546,7 +546,7 @@ class MTP_DEVICE(BASE):
def get_user_blacklisted_devices(self):
bl = frozenset(self.prefs['blacklist'])
ans = {}
- for dev, x in self.prefs['history'].iteritems():
+ for dev, x in iteritems(self.prefs['history']):
name = x[0]
if dev in bl:
ans[dev] = name
diff --git a/src/calibre/devices/mtp/filesystem_cache.py b/src/calibre/devices/mtp/filesystem_cache.py
index f5a3ef690d..1d2744ba98 100644
--- a/src/calibre/devices/mtp/filesystem_cache.py
+++ b/src/calibre/devices/mtp/filesystem_cache.py
@@ -10,7 +10,7 @@ __docformat__ = 'restructuredtext en'
import weakref, sys, json
from collections import deque
from operator import attrgetter
-from polyglot.builtins import map, unicode_type
+from polyglot.builtins import itervalues, map, unicode_type
from datetime import datetime
from calibre import human_readable, prints, force_unicode
@@ -201,7 +201,7 @@ class FilesystemCache(object):
for entry in entries:
FileOrFolder(entry, self)
- for item in self.id_map.itervalues():
+ for item in itervalues(self.id_map):
try:
p = item.parent
except KeyError:
@@ -227,7 +227,7 @@ class FilesystemCache(object):
return e
def iterebooks(self, storage_id):
- for x in self.id_map.itervalues():
+ for x in itervalues(self.id_map):
if x.storage_id == storage_id and x.is_ebook:
if x.parent_id == storage_id and x.name.lower().endswith('.txt'):
continue # Ignore .txt files in the root
diff --git a/src/calibre/devices/mtp/windows/driver.py b/src/calibre/devices/mtp/windows/driver.py
index 23c445570b..f99a0309c6 100644
--- a/src/calibre/devices/mtp/windows/driver.py
+++ b/src/calibre/devices/mtp/windows/driver.py
@@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en'
import time, threading, traceback
from functools import wraps, partial
-from polyglot.builtins import unicode_type, zip
+from polyglot.builtins import iteritems, iterkeys, itervalues, unicode_type, zip
from itertools import chain
from calibre import as_unicode, prints, force_unicode
@@ -107,7 +107,7 @@ class MTP_DEVICE(MTPDeviceBase):
# Get device data for detected devices. If there is an error, we will
# try again for that device the next time this method is called.
- for dev in tuple(self.detected_devices.iterkeys()):
+ for dev in tuple(iterkeys(self.detected_devices)):
data = self.detected_devices.get(dev, None)
if data is None or data is False:
try:
@@ -130,7 +130,7 @@ class MTP_DEVICE(MTPDeviceBase):
self.currently_connected_pnp_id in self.detected_devices
else None)
- for dev, data in self.detected_devices.iteritems():
+ for dev, data in iteritems(self.detected_devices):
if dev in self.blacklisted_devices or dev in self.ejected_devices:
# Ignore blacklisted and ejected devices
continue
@@ -267,10 +267,10 @@ class MTP_DEVICE(MTPDeviceBase):
self._currently_getting_sid = unicode_type(storage_id)
id_map = self.dev.get_filesystem(storage_id, partial(
self._filesystem_callback, {}))
- for x in id_map.itervalues():
+ for x in itervalues(id_map):
x['storage_id'] = storage_id
all_storage.append(storage)
- items.append(id_map.itervalues())
+ items.append(itervalues(id_map))
self._filesystem_cache = FilesystemCache(all_storage, chain(*items))
debug('Filesystem metadata loaded in %g seconds (%d objects)'%(
time.time()-st, len(self._filesystem_cache)))
diff --git a/src/calibre/devices/prs505/sony_cache.py b/src/calibre/devices/prs505/sony_cache.py
index 132ff00b6d..c8db25b73a 100644
--- a/src/calibre/devices/prs505/sony_cache.py
+++ b/src/calibre/devices/prs505/sony_cache.py
@@ -705,8 +705,8 @@ class XMLCache(object):
child.text = '\n'+'\t'*(level+1)
for gc in child:
gc.tail = '\n'+'\t'*(level+1)
- child.iterchildren(reversed=True).next().tail = '\n'+'\t'*level
- root.iterchildren(reversed=True).next().tail = '\n'+'\t'*(level-1)
+ next(child.iterchildren(reversed=True)).tail = '\n'+'\t'*level
+ next(root.iterchildren(reversed=True)).tail = '\n'+'\t'*(level-1)
def move_playlists_to_bottom(self):
for root in self.record_roots.values():
@@ -799,4 +799,3 @@ class XMLCache(object):
self.namespaces[i] = ns
# }}}
-
diff --git a/src/calibre/devices/scanner.py b/src/calibre/devices/scanner.py
index ca3014cda9..1eb5a24b95 100644
--- a/src/calibre/devices/scanner.py
+++ b/src/calibre/devices/scanner.py
@@ -13,7 +13,7 @@ from threading import Lock
from calibre import prints, as_unicode
from calibre.constants import (iswindows, isosx, plugins, islinux, isfreebsd,
isnetbsd)
-from polyglot.builtins import range
+from polyglot.builtins import iterkeys, range
osx_scanner = linux_scanner = freebsd_scanner = netbsd_scanner = None
@@ -77,7 +77,7 @@ class LibUSBScanner(object):
dev = USBDevice(*dev)
dev.busnum, dev.devnum = fingerprint[:2]
ans.add(dev)
- extra = set(self.libusb.cache.iterkeys()) - seen
+ extra = set(iterkeys(self.libusb.cache)) - seen
for x in extra:
self.libusb.cache.pop(x, None)
return ans
diff --git a/src/calibre/devices/smart_device_app/driver.py b/src/calibre/devices/smart_device_app/driver.py
index 7d52dc76c8..8dfe3f468e 100644
--- a/src/calibre/devices/smart_device_app/driver.py
+++ b/src/calibre/devices/smart_device_app/driver.py
@@ -1471,7 +1471,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
metadata = iter(metadata)
for i, infile in enumerate(files):
- mdata, fname = metadata.next(), names.next()
+ mdata, fname = next(metadata), next(names)
lpath = self._create_upload_path(mdata, fname, create_dirs=False)
self._debug('lpath', lpath)
if not hasattr(infile, 'read'):
@@ -1497,7 +1497,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
for i, location in enumerate(locations):
self.report_progress((i + 1) / float(len(locations)),
_('Adding books to device metadata listing...'))
- info = metadata.next()
+ info = next(metadata)
lpath = location[0]
length = location[1]
lpath = self._strip_prefix(lpath)
diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py
index 401728928e..a7eb0b3567 100644
--- a/src/calibre/devices/usbms/device.py
+++ b/src/calibre/devices/usbms/device.py
@@ -23,7 +23,7 @@ from calibre.devices.errors import DeviceError
from calibre.devices.usbms.deviceconfig import DeviceConfig
from calibre.constants import iswindows, islinux, isosx, isfreebsd, plugins
from calibre.utils.filenames import ascii_filename as sanitize
-from polyglot.builtins import string_or_bytes
+from polyglot.builtins import iteritems, string_or_bytes
if isosx:
usbobserver, usbobserver_err = plugins['usbobserver']
@@ -404,7 +404,7 @@ class Device(DeviceConfig, DevicePlugin):
bsd_drives = self.osx_bsd_names()
drives = self.osx_sort_names(bsd_drives.copy())
mount_map = usbobserver.get_mounted_filesystems()
- drives = {k: mount_map.get(v) for k, v in drives.iteritems()}
+ drives = {k: mount_map.get(v) for k, v in iteritems(drives)}
if DEBUG:
print()
from pprint import pprint
diff --git a/src/calibre/devices/usbms/driver.py b/src/calibre/devices/usbms/driver.py
index 1c8e657b7d..c475800ab3 100644
--- a/src/calibre/devices/usbms/driver.py
+++ b/src/calibre/devices/usbms/driver.py
@@ -20,7 +20,7 @@ from calibre.devices.usbms.cli import CLI
from calibre.devices.usbms.device import Device
from calibre.devices.usbms.books import BookList, Book
from calibre.ebooks.metadata.book.json_codec import JsonCodec
-from polyglot.builtins import unicode_type, string_or_bytes
+from polyglot.builtins import itervalues, unicode_type, string_or_bytes
BASE_TIME = None
@@ -281,7 +281,7 @@ class USBMS(CLI, Device):
# Remove books that are no longer in the filesystem. Cache contains
# indices into the booklist if book not in filesystem, None otherwise
# Do the operation in reverse order so indices remain valid
- for idx in sorted(bl_cache.itervalues(), reverse=True):
+ for idx in sorted(itervalues(bl_cache), reverse=True):
if idx is not None:
need_sync = True
del bl[idx]
@@ -311,7 +311,7 @@ class USBMS(CLI, Device):
metadata = iter(metadata)
for i, infile in enumerate(files):
- mdata, fname = metadata.next(), names.next()
+ mdata, fname = next(metadata), next(names)
filepath = self.normalize_path(self.create_upload_path(path, mdata, fname))
if not hasattr(infile, 'read'):
infile = self.normalize_path(infile)
@@ -350,7 +350,7 @@ class USBMS(CLI, Device):
metadata = iter(metadata)
for i, location in enumerate(locations):
self.report_progress((i+1) / float(len(locations)), _('Adding books to device metadata listing...'))
- info = metadata.next()
+ info = next(metadata)
blist = 2 if location[1] == 'cardb' else 1 if location[1] == 'carda' else 0
# Extract the correct prefix from the pathname. To do this correctly,
diff --git a/src/calibre/devices/winusb.py b/src/calibre/devices/winusb.py
index 5b1a005328..0a7647cce0 100644
--- a/src/calibre/devices/winusb.py
+++ b/src/calibre/devices/winusb.py
@@ -15,7 +15,7 @@ from ctypes import (
)
from ctypes.wintypes import DWORD, WORD, ULONG, LPCWSTR, HWND, BOOL, LPWSTR, UINT, BYTE, HANDLE, USHORT
from pprint import pprint, pformat
-from polyglot.builtins import map
+from polyglot.builtins import iteritems, itervalues, map
from calibre import prints, as_unicode
@@ -652,13 +652,13 @@ def get_volume_information(drive_letter):
'max_component_length': max_component_length.value,
}
- for name, num in {'FILE_CASE_PRESERVED_NAMES':0x00000002, 'FILE_CASE_SENSITIVE_SEARCH':0x00000001, 'FILE_FILE_COMPRESSION':0x00000010,
+ for name, num in iteritems({'FILE_CASE_PRESERVED_NAMES':0x00000002, 'FILE_CASE_SENSITIVE_SEARCH':0x00000001, 'FILE_FILE_COMPRESSION':0x00000010,
'FILE_NAMED_STREAMS':0x00040000, 'FILE_PERSISTENT_ACLS':0x00000008, 'FILE_READ_ONLY_VOLUME':0x00080000,
'FILE_SEQUENTIAL_WRITE_ONCE':0x00100000, 'FILE_SUPPORTS_ENCRYPTION':0x00020000, 'FILE_SUPPORTS_EXTENDED_ATTRIBUTES':0x00800000,
'FILE_SUPPORTS_HARD_LINKS':0x00400000, 'FILE_SUPPORTS_OBJECT_IDS':0x00010000, 'FILE_SUPPORTS_OPEN_BY_FILE_ID':0x01000000,
'FILE_SUPPORTS_REPARSE_POINTS':0x00000080, 'FILE_SUPPORTS_SPARSE_FILES':0x00000040, 'FILE_SUPPORTS_TRANSACTIONS':0x00200000,
'FILE_SUPPORTS_USN_JOURNAL':0x02000000, 'FILE_UNICODE_ON_DISK':0x00000004, 'FILE_VOLUME_IS_COMPRESSED':0x00008000,
- 'FILE_VOLUME_QUOTAS':0x00000020}.iteritems():
+ 'FILE_VOLUME_QUOTAS':0x00000020}):
ans[name] = bool(num & flags)
return ans
@@ -809,7 +809,7 @@ def get_storage_number_map(drive_types=(DRIVE_REMOVABLE, DRIVE_FIXED), debug=Fal
' Get a mapping of drive letters to storage numbers for all drives on system (of the specified types) '
mask = GetLogicalDrives()
type_map = {letter:GetDriveType(letter + ':' + os.sep) for i, letter in enumerate(string.ascii_uppercase) if mask & (1 << i)}
- drives = (letter for letter, dt in type_map.iteritems() if dt in drive_types)
+ drives = (letter for letter, dt in iteritems(type_map) if dt in drive_types)
ans = defaultdict(list)
for letter in drives:
try:
@@ -819,7 +819,7 @@ def get_storage_number_map(drive_types=(DRIVE_REMOVABLE, DRIVE_FIXED), debug=Fal
if debug:
prints('Failed to get storage number for drive: %s with error: %s' % (letter, as_unicode(err)))
continue
- for val in ans.itervalues():
+ for val in itervalues(ans):
val.sort(key=itemgetter(0))
return dict(ans)
@@ -859,7 +859,7 @@ def get_storage_number_map_alt(debug=False):
if debug:
prints('Failed to get storage number for drive: %s with error: %s' % (name[0], as_unicode(err)))
continue
- for val in ans.itervalues():
+ for val in itervalues(ans):
val.sort(key=itemgetter(0))
return dict(ans)
diff --git a/src/calibre/ebooks/conversion/cli.py b/src/calibre/ebooks/conversion/cli.py
index a1394b592b..10e9ce6b8f 100644
--- a/src/calibre/ebooks/conversion/cli.py
+++ b/src/calibre/ebooks/conversion/cli.py
@@ -17,6 +17,7 @@ from calibre.customize.conversion import OptionRecommendation
from calibre import patheq
from calibre.ebooks.conversion import ConversionUserFeedBack
from calibre.utils.localization import localize_user_manual_link
+from polyglot.builtins import iteritems
USAGE = '%prog ' + _('''\
input_file output_file [options]
@@ -254,7 +255,7 @@ def add_pipeline_options(parser, plumber):
))
- for group, (desc, options) in groups.iteritems():
+ for group, (desc, options) in iteritems(groups):
if group:
group = OptionGroup(parser, group, desc)
parser.add_option_group(group)
diff --git a/src/calibre/ebooks/conversion/plugins/epub_input.py b/src/calibre/ebooks/conversion/plugins/epub_input.py
index a94e02150e..a72571cf12 100644
--- a/src/calibre/ebooks/conversion/plugins/epub_input.py
+++ b/src/calibre/ebooks/conversion/plugins/epub_input.py
@@ -18,7 +18,7 @@ def decrypt_font_data(key, data, algorithm):
crypt_len = 1024 if is_adobe else 1040
crypt = bytearray(data[:crypt_len])
key = cycle(iter(bytearray(key)))
- decrypt = bytes(bytearray(x^key.next() for x in crypt))
+ decrypt = bytes(bytearray(x^next(key) for x in crypt))
return decrypt + data[crypt_len:]
diff --git a/src/calibre/ebooks/conversion/plugins/epub_output.py b/src/calibre/ebooks/conversion/plugins/epub_output.py
index 25f6c3b2aa..294c7afcfc 100644
--- a/src/calibre/ebooks/conversion/plugins/epub_output.py
+++ b/src/calibre/ebooks/conversion/plugins/epub_output.py
@@ -218,7 +218,7 @@ class EPUBOutput(OutputFormatPlugin):
if self.oeb.toc.count() == 0:
self.log.warn('This EPUB file has no Table of Contents. '
'Creating a default TOC')
- first = iter(self.oeb.spine).next()
+ first = next(iter(self.oeb.spine))
self.oeb.toc.add(_('Start'), first.href)
from calibre.ebooks.oeb.base import OPF
@@ -422,7 +422,7 @@ class EPUBOutput(OutputFormatPlugin):
if br.getparent() is None:
continue
try:
- prior = br.itersiblings(preceding=True).next()
+ prior = next(br.itersiblings(preceding=True))
priortag = barename(prior.tag)
priortext = prior.tail
except:
diff --git a/src/calibre/ebooks/conversion/plugins/fb2_input.py b/src/calibre/ebooks/conversion/plugins/fb2_input.py
index 879836aa85..42122d3a50 100644
--- a/src/calibre/ebooks/conversion/plugins/fb2_input.py
+++ b/src/calibre/ebooks/conversion/plugins/fb2_input.py
@@ -8,7 +8,7 @@ import os, re
from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation
from calibre import guess_type
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
FB2NS = 'http://www.gribuser.ru/xml/fictionbook/2.0'
FB21NS = 'http://www.gribuser.ru/xml/fictionbook/2.1'
@@ -103,7 +103,7 @@ class FB2Input(InputFormatPlugin):
notes = {a.get('href')[1:]: a for a in result.xpath('//a[@link_note and @href]') if a.get('href').startswith('#')}
cites = {a.get('link_cite'): a for a in result.xpath('//a[@link_cite]') if not a.get('href', '')}
all_ids = {x for x in result.xpath('//*/@id')}
- for cite, a in cites.iteritems():
+ for cite, a in iteritems(cites):
note = notes.get(cite, None)
if note:
c = 1
diff --git a/src/calibre/ebooks/conversion/plugins/pdf_output.py b/src/calibre/ebooks/conversion/plugins/pdf_output.py
index b0b4ad6bae..ee20c0f1ac 100644
--- a/src/calibre/ebooks/conversion/plugins/pdf_output.py
+++ b/src/calibre/ebooks/conversion/plugins/pdf_output.py
@@ -14,7 +14,7 @@ from calibre.constants import iswindows
from calibre.customize.conversion import (OutputFormatPlugin,
OptionRecommendation)
from calibre.ptempfile import TemporaryDirectory
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
UNITS = ['millimeter', 'centimeter', 'point', 'inch' , 'pica' , 'didot',
'cicero', 'devicepixel']
@@ -263,7 +263,7 @@ class PDFOutput(OutputFormatPlugin):
self.process_fonts()
if self.opts.pdf_use_document_margins and self.stored_page_margins:
import json
- for href, margins in self.stored_page_margins.iteritems():
+ for href, margins in iteritems(self.stored_page_margins):
item = oeb_book.manifest.hrefs.get(href)
if item is not None:
root = item.data
diff --git a/src/calibre/ebooks/conversion/plugins/rtf_input.py b/src/calibre/ebooks/conversion/plugins/rtf_input.py
index e38c76b2d5..98059a3eca 100644
--- a/src/calibre/ebooks/conversion/plugins/rtf_input.py
+++ b/src/calibre/ebooks/conversion/plugins/rtf_input.py
@@ -5,6 +5,7 @@ __copyright__ = '2008, Kovid Goyal '
import os, glob, re, textwrap
from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation
+from polyglot.builtins import iteritems
border_style_map = {
'single' : 'solid',
@@ -145,7 +146,7 @@ class RTFInput(InputFormatPlugin):
def convert_images(self, imap):
self.default_img = None
- for count, val in imap.iteritems():
+ for count, val in iteritems(imap):
try:
imap[count] = self.convert_image(val)
except:
@@ -210,7 +211,7 @@ class RTFInput(InputFormatPlugin):
css += '\n'+'\n'.join(font_size_classes)
css += '\n' +'\n'.join(color_classes)
- for cls, val in border_styles.iteritems():
+ for cls, val in iteritems(border_styles):
css += '\n\n.%s {\n%s\n}'%(cls, val)
with open(u'styles.css', 'ab') as f:
diff --git a/src/calibre/ebooks/conversion/plugins/snb_output.py b/src/calibre/ebooks/conversion/plugins/snb_output.py
index 3861286a96..00d0b0dc34 100644
--- a/src/calibre/ebooks/conversion/plugins/snb_output.py
+++ b/src/calibre/ebooks/conversion/plugins/snb_output.py
@@ -125,10 +125,10 @@ class SNBOutput(OutputFormatPlugin):
if oeb_book.toc.count() == 0:
log.warn('This SNB file has no Table of Contents. '
'Creating a default TOC')
- first = iter(oeb_book.spine).next()
+ first = next(iter(oeb_book.spine))
oeb_book.toc.add(_('Start page'), first.href)
else:
- first = iter(oeb_book.spine).next()
+ first = next(iter(oeb_book.spine))
if oeb_book.toc[0].href != first.href:
# The pages before the fist item in toc will be stored as
# "Cover Pages".
diff --git a/src/calibre/ebooks/covers.py b/src/calibre/ebooks/covers.py
index 035ca9ad39..a5a1c7df2d 100644
--- a/src/calibre/ebooks/covers.py
+++ b/src/calibre/ebooks/covers.py
@@ -10,7 +10,7 @@ import re, random, unicodedata, numbers
from collections import namedtuple
from contextlib import contextmanager
from math import ceil, sqrt, cos, sin, atan2
-from polyglot.builtins import map, zip, string_or_bytes
+from polyglot.builtins import iteritems, itervalues, map, zip, string_or_bytes
from itertools import chain
from PyQt5.Qt import (
@@ -282,7 +282,7 @@ def preserve_fields(obj, fields):
try:
yield
finally:
- for f, val in mem.iteritems():
+ for f, val in iteritems(mem):
if val is null:
delattr(obj, f)
else:
@@ -324,10 +324,10 @@ def load_color_themes(prefs):
t = default_color_themes.copy()
t.update(prefs.color_themes)
disabled = frozenset(prefs.disabled_color_themes)
- ans = [theme_to_colors(v) for k, v in t.iteritems() if k not in disabled]
+ ans = [theme_to_colors(v) for k, v in iteritems(t) if k not in disabled]
if not ans:
# Ignore disabled and return only the builtin color themes
- ans = [theme_to_colors(v) for k, v in default_color_themes.iteritems()]
+ ans = [theme_to_colors(v) for k, v in iteritems(default_color_themes)]
return ans
@@ -557,14 +557,14 @@ class Blocks(Style):
def all_styles():
return set(
- x.NAME for x in globals().itervalues() if
+ x.NAME for x in itervalues(globals()) if
isinstance(x, type) and issubclass(x, Style) and x is not Style
)
def load_styles(prefs, respect_disabled=True):
disabled = frozenset(prefs.disabled_styles) if respect_disabled else ()
- ans = tuple(x for x in globals().itervalues() if
+ ans = tuple(x for x in itervalues(globals()) if
isinstance(x, type) and issubclass(x, Style) and x is not Style and x.NAME not in disabled)
if not ans and disabled:
# If all styles have been disabled, ignore the disabling and return all
diff --git a/src/calibre/ebooks/css_transform_rules.py b/src/calibre/ebooks/css_transform_rules.py
index 58fc483047..3bd8428c2d 100644
--- a/src/calibre/ebooks/css_transform_rules.py
+++ b/src/calibre/ebooks/css_transform_rules.py
@@ -13,6 +13,7 @@ from css_parser.css import Property, CSSRule
from calibre import force_unicode
from calibre.ebooks import parse_css_length
from calibre.ebooks.oeb.normalize_css import normalizers, safe_parser
+from polyglot.builtins import iteritems
def compile_pat(pat):
@@ -44,7 +45,7 @@ class StyleDeclaration(object):
yield p, None
else:
if p not in self.expanded_properties:
- self.expanded_properties[p] = [Property(k, v, p.literalpriority) for k, v in n(p.name, p.propertyValue).iteritems()]
+ self.expanded_properties[p] = [Property(k, v, p.literalpriority) for k, v in iteritems(n(p.name, p.propertyValue))]
for ep in self.expanded_properties[p]:
yield ep, p
@@ -338,7 +339,7 @@ def export_rules(serialized_rules):
lines = []
for rule in serialized_rules:
lines.extend('# ' + l for l in rule_to_text(rule).splitlines())
- lines.extend('%s: %s' % (k, v.replace('\n', ' ')) for k, v in rule.iteritems() if k in allowed_keys)
+ lines.extend('%s: %s' % (k, v.replace('\n', ' ')) for k, v in iteritems(rule) if k in allowed_keys)
lines.append('')
return '\n'.join(lines).encode('utf-8')
diff --git a/src/calibre/ebooks/docx/block_styles.py b/src/calibre/ebooks/docx/block_styles.py
index 480738fa06..05f5f54692 100644
--- a/src/calibre/ebooks/docx/block_styles.py
+++ b/src/calibre/ebooks/docx/block_styles.py
@@ -8,6 +8,7 @@ __copyright__ = '2013, Kovid Goyal '
import numbers
from collections import OrderedDict
+from polyglot.builtins import iteritems
class Inherit:
@@ -115,11 +116,11 @@ def read_border(parent, dest, XPath, get, border_edges=border_edges, name='pBdr'
for border in XPath('./w:' + name)(parent):
for edge in border_edges:
- for prop, val in read_single_border(border, edge, XPath, get).iteritems():
+ for prop, val in iteritems(read_single_border(border, edge, XPath, get)):
if val is not None:
vals[prop % edge] = val
- for key, val in vals.iteritems():
+ for key, val in iteritems(vals):
setattr(dest, key, val)
diff --git a/src/calibre/ebooks/docx/cleanup.py b/src/calibre/ebooks/docx/cleanup.py
index 30fd9d25d9..6d71805fc0 100644
--- a/src/calibre/ebooks/docx/cleanup.py
+++ b/src/calibre/ebooks/docx/cleanup.py
@@ -7,7 +7,7 @@ __license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal '
import os
-from polyglot.builtins import range
+from polyglot.builtins import iterkeys, itervalues, range
NBSP = '\xa0'
@@ -54,7 +54,7 @@ def merge_run(run):
def liftable(css):
# A is liftable if all its styling would work just as well if it is
# specified on the parent element.
- prefixes = {x.partition('-')[0] for x in css.iterkeys()}
+ prefixes = {x.partition('-')[0] for x in iterkeys(css)}
return not (prefixes - {'text', 'font', 'letter', 'color', 'background'})
@@ -134,7 +134,7 @@ def cleanup_markup(log, root, styles, dest_dir, detect_cover, XPath):
current_run = [span]
# Process dir attributes
- class_map = dict(styles.classes.itervalues())
+ class_map = dict(itervalues(styles.classes))
parents = ('p', 'div') + tuple('h%d' % i for i in range(1, 7))
for parent in root.xpath('//*[(%s)]' % ' or '.join('name()="%s"' % t for t in parents)):
# Ensure that children of rtl parents that are not rtl have an
diff --git a/src/calibre/ebooks/docx/fields.py b/src/calibre/ebooks/docx/fields.py
index 3d7e457019..286588371e 100644
--- a/src/calibre/ebooks/docx/fields.py
+++ b/src/calibre/ebooks/docx/fields.py
@@ -9,6 +9,7 @@ __copyright__ = '2013, Kovid Goyal '
import re
from calibre.ebooks.docx.index import process_index, polish_index_markup
+from polyglot.builtins import iteritems
class Field(object):
@@ -38,6 +39,7 @@ class Field(object):
self.instructions = ''.join(self.buf)
del self.buf
+
WORD, FLAG = 0, 1
scanner = re.Scanner([
(r'\\\S{1}', lambda s, t: (t, FLAG)), # A flag of the form \x
@@ -76,6 +78,7 @@ def parser(name, field_map, default_field_name=None):
return parse
+
parse_hyperlink = parser('hyperlink',
'l:anchor m:image-map n:target o:title t:target', 'url')
@@ -222,7 +225,7 @@ class Fields(object):
def polish_markup(self, object_map):
if not self.index_fields:
return
- rmap = {v:k for k, v in object_map.iteritems()}
+ rmap = {v:k for k, v in iteritems(object_map)}
for idx, blocks in self.index_fields:
polish_index_markup(idx, [rmap[b] for b in blocks])
@@ -256,5 +259,6 @@ def test_parse_fields(return_tests=False):
return suite
unittest.TextTestRunner(verbosity=4).run(suite)
+
if __name__ == '__main__':
test_parse_fields()
diff --git a/src/calibre/ebooks/docx/fonts.py b/src/calibre/ebooks/docx/fonts.py
index 0aed536cab..9532d7c078 100644
--- a/src/calibre/ebooks/docx/fonts.py
+++ b/src/calibre/ebooks/docx/fonts.py
@@ -14,7 +14,7 @@ from calibre.utils.filenames import ascii_filename
from calibre.utils.fonts.scanner import font_scanner, NoFonts
from calibre.utils.fonts.utils import panose_to_css_generic_family, is_truetype_font
from calibre.utils.icu import ord_string
-from polyglot.builtins import codepoint_to_chr, range
+from polyglot.builtins import codepoint_to_chr, iteritems, range
Embed = namedtuple('Embed', 'name key subsetted')
@@ -172,7 +172,7 @@ class Fonts(object):
d['font-weight'] = 'bold'
if 'Italic' in variant:
d['font-style'] = 'italic'
- d = ['%s: %s' % (k, v) for k, v in d.iteritems()]
+ d = ['%s: %s' % (k, v) for k, v in iteritems(d)]
d = ';\n\t'.join(d)
defs.append('@font-face {\n\t%s\n}\n' % d)
return '\n'.join(defs)
diff --git a/src/calibre/ebooks/docx/footnotes.py b/src/calibre/ebooks/docx/footnotes.py
index a078b9f57c..15f40fb092 100644
--- a/src/calibre/ebooks/docx/footnotes.py
+++ b/src/calibre/ebooks/docx/footnotes.py
@@ -7,6 +7,7 @@ __license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal '
from collections import OrderedDict
+from polyglot.builtins import iteritems
class Note(object):
@@ -57,10 +58,9 @@ class Footnotes(object):
return None, None
def __iter__(self):
- for anchor, (counter, note) in self.notes.iteritems():
+ for anchor, (counter, note) in iteritems(self.notes):
yield anchor, counter, note
@property
def has_notes(self):
return bool(self.notes)
-
diff --git a/src/calibre/ebooks/docx/images.py b/src/calibre/ebooks/docx/images.py
index a3fcfc8efb..17a4bb08f0 100644
--- a/src/calibre/ebooks/docx/images.py
+++ b/src/calibre/ebooks/docx/images.py
@@ -15,6 +15,7 @@ from calibre.ebooks.docx.names import barename
from calibre.utils.filenames import ascii_filename
from calibre.utils.img import resize_to_fit, image_to_data
from calibre.utils.imghdr import what
+from polyglot.builtins import iteritems, itervalues
class LinkedImageNotFound(ValueError):
@@ -66,7 +67,7 @@ def get_image_properties(parent, XPath, get):
def get_image_margins(elem):
ans = {}
- for w, css in {'L':'left', 'T':'top', 'R':'right', 'B':'bottom'}.iteritems():
+ for w, css in iteritems({'L':'left', 'T':'top', 'R':'right', 'B':'bottom'}):
val = elem.get('dist%s' % w, None)
if val is not None:
try:
@@ -157,7 +158,7 @@ class Images(object):
return raw, base
def unique_name(self, base):
- exists = frozenset(self.used.itervalues())
+ exists = frozenset(itervalues(self.used))
c = 1
name = base
while name in exists:
@@ -242,7 +243,7 @@ class Images(object):
ans = self.pic_to_img(pic, alt, inline, title)
if ans is not None:
if style:
- ans.set('style', '; '.join('%s: %s' % (k, v) for k, v in style.iteritems()))
+ ans.set('style', '; '.join('%s: %s' % (k, v) for k, v in iteritems(style)))
yield ans
# Now process the floats
@@ -253,7 +254,7 @@ class Images(object):
ans = self.pic_to_img(pic, alt, anchor, title)
if ans is not None:
if style:
- ans.set('style', '; '.join('%s: %s' % (k, v) for k, v in style.iteritems()))
+ ans.set('style', '; '.join('%s: %s' % (k, v) for k, v in iteritems(style)))
yield ans
def pict_to_html(self, pict, page):
@@ -275,7 +276,7 @@ class Images(object):
style['margin-left'] = '0' if align == 'left' else 'auto'
style['margin-right'] = 'auto' if align == 'left' else '0'
if style:
- hr.set('style', '; '.join(('%s:%s' % (k, v) for k, v in style.iteritems())))
+ hr.set('style', '; '.join(('%s:%s' % (k, v) for k, v in iteritems(style))))
yield hr
for imagedata in XPath('descendant::v:imagedata[@r:id]')(pict):
diff --git a/src/calibre/ebooks/docx/index.py b/src/calibre/ebooks/docx/index.py
index a4e8e0ec60..38220a1c86 100644
--- a/src/calibre/ebooks/docx/index.py
+++ b/src/calibre/ebooks/docx/index.py
@@ -11,7 +11,7 @@ from operator import itemgetter
from lxml import etree
from calibre.utils.icu import partition_by_first_letter, sort_key
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
def get_applicable_xe_fields(index, xe_fields, XPath, expand):
@@ -103,7 +103,7 @@ def process_index(field, index, xe_fields, log, XPath, expand):
if heading_text is not None:
groups = partition_by_first_letter(xe_fields, key=itemgetter('text'))
items = []
- for key, fields in groups.iteritems():
+ for key, fields in iteritems(groups):
items.append(key), items.extend(fields)
if styles:
heading_style = styles[0]
diff --git a/src/calibre/ebooks/docx/names.py b/src/calibre/ebooks/docx/names.py
index 3db3f5e961..3238743b65 100644
--- a/src/calibre/ebooks/docx/names.py
+++ b/src/calibre/ebooks/docx/names.py
@@ -11,6 +11,7 @@ import re
from lxml.etree import XPath as X
from calibre.utils.filenames import ascii_text
+from polyglot.builtins import iteritems
# Names {{{
TRANSITIONAL_NAMES = {
@@ -32,7 +33,7 @@ TRANSITIONAL_NAMES = {
STRICT_NAMES = {
k:v.replace('http://schemas.openxmlformats.org/officeDocument/2006', 'http://purl.oclc.org/ooxml/officeDocument')
- for k, v in TRANSITIONAL_NAMES.iteritems()
+ for k, v in iteritems(TRANSITIONAL_NAMES)
}
TRANSITIONAL_NAMESPACES = {
@@ -72,7 +73,7 @@ STRICT_NAMESPACES = {
'http://schemas.openxmlformats.org/officeDocument/2006', 'http://purl.oclc.org/ooxml/officeDocument').replace(
'http://schemas.openxmlformats.org/wordprocessingml/2006', 'http://purl.oclc.org/ooxml/wordprocessingml').replace(
'http://schemas.openxmlformats.org/drawingml/2006', 'http://purl.oclc.org/ooxml/drawingml')
- for k, v in TRANSITIONAL_NAMESPACES.iteritems()
+ for k, v in iteritems(TRANSITIONAL_NAMESPACES)
}
# }}}
@@ -138,7 +139,7 @@ class DOCXNamespace(object):
return self.XPath('|'.join('descendant::%s' % a for a in args))(elem)
def makeelement(self, root, tag, append=True, **attrs):
- ans = root.makeelement(self.expand(tag), **{self.expand(k, sep='_'):v for k, v in attrs.iteritems()})
+ ans = root.makeelement(self.expand(tag), **{self.expand(k, sep='_'):v for k, v in iteritems(attrs)})
if append:
root.append(ans)
return ans
diff --git a/src/calibre/ebooks/docx/numbering.py b/src/calibre/ebooks/docx/numbering.py
index a132cf2233..f2956db261 100644
--- a/src/calibre/ebooks/docx/numbering.py
+++ b/src/calibre/ebooks/docx/numbering.py
@@ -15,6 +15,7 @@ from lxml.html.builder import OL, UL, SPAN
from calibre.ebooks.docx.block_styles import ParagraphStyle
from calibre.ebooks.docx.char_styles import RunStyle, inherit
from calibre.ebooks.metadata import roman
+from polyglot.builtins import iteritems
STYLE_MAP = {
'aiueo': 'hiragana',
@@ -36,6 +37,7 @@ def alphabet(val, lower=True):
x = string.ascii_lowercase if lower else string.ascii_uppercase
return x[(abs(val - 1)) % len(x)]
+
alphabet_map = {
'lower-alpha':alphabet, 'upper-alpha':partial(alphabet, lower=False),
'lower-roman':lambda x:roman(x).lower(), 'upper-roman':roman,
@@ -168,7 +170,7 @@ class NumberingDefinition(object):
def copy(self):
ans = NumberingDefinition(self.namespace, an_id=self.abstract_numbering_definition_id)
- for l, lvl in self.levels.iteritems():
+ for l, lvl in iteritems(self.levels):
ans.levels[l] = lvl.copy()
return ans
@@ -224,7 +226,7 @@ class Numbering(object):
if alvl is None:
alvl = Level(self.namespace)
alvl.read_from_xml(lvl, override=True)
- for ilvl, so in start_overrides.iteritems():
+ for ilvl, so in iteritems(start_overrides):
try:
nd.levels[ilvl].start = start_override
except KeyError:
@@ -244,22 +246,22 @@ class Numbering(object):
self.instances[num_id] = create_instance(n, d)
numbering_links = styles.numbering_style_links
- for an_id, style_link in lazy_load.iteritems():
+ for an_id, style_link in iteritems(lazy_load):
num_id = numbering_links[style_link]
self.definitions[an_id] = self.instances[num_id].copy()
- for num_id, (an_id, n) in next_pass.iteritems():
+ for num_id, (an_id, n) in iteritems(next_pass):
d = self.definitions.get(an_id, None)
if d is not None:
self.instances[num_id] = create_instance(n, d)
- for num_id, d in self.instances.iteritems():
+ for num_id, d in iteritems(self.instances):
self.starts[num_id] = {lvl:d.levels[lvl].start for lvl in d.levels}
def get_pstyle(self, num_id, style_id):
d = self.instances.get(num_id, None)
if d is not None:
- for ilvl, lvl in d.levels.iteritems():
+ for ilvl, lvl in iteritems(d.levels):
if lvl.para_link == style_id:
return ilvl
@@ -271,7 +273,7 @@ class Numbering(object):
def update_counter(self, counter, levelnum, levels):
counter[levelnum] += 1
- for ilvl, lvl in levels.iteritems():
+ for ilvl, lvl in iteritems(levels):
restart = lvl.restart
if (restart is None and ilvl == levelnum + 1) or restart == levelnum + 1:
counter[ilvl] = lvl.start
diff --git a/src/calibre/ebooks/docx/styles.py b/src/calibre/ebooks/docx/styles.py
index 1b1847236d..56b5b9a4e3 100644
--- a/src/calibre/ebooks/docx/styles.py
+++ b/src/calibre/ebooks/docx/styles.py
@@ -12,6 +12,7 @@ from collections import OrderedDict, Counter
from calibre.ebooks.docx.block_styles import ParagraphStyle, inherit, twips
from calibre.ebooks.docx.char_styles import RunStyle
from calibre.ebooks.docx.tables import TableStyle
+from polyglot.builtins import iteritems, itervalues
class PageProperties(object):
@@ -124,7 +125,7 @@ class Styles(object):
self.default_paragraph_style = self.default_character_style = None
def __iter__(self):
- for s in self.id_map.itervalues():
+ for s in itervalues(self.id_map):
yield s
def __getitem__(self, key):
@@ -341,7 +342,7 @@ class Styles(object):
setattr(s, prop, inherit)
setattr(block_style, prop, next(iter(vals)))
- for p, runs in layers.iteritems():
+ for p, runs in iteritems(layers):
has_links = '1' in {r.get('is-link', None) for r in runs}
char_styles = [self.resolve_run(r) for r in runs]
block_style = self.resolve_paragraph(p)
@@ -421,7 +422,7 @@ class Styles(object):
ps.pageBreakBefore = True
def register(self, css, prefix):
- h = hash(frozenset(css.iteritems()))
+ h = hash(frozenset(iteritems(css)))
ans, _ = self.classes.get(h, (None, None))
if ans is None:
self.counter[prefix] += 1
@@ -430,17 +431,17 @@ class Styles(object):
return ans
def generate_classes(self):
- for bs in self.para_cache.itervalues():
+ for bs in itervalues(self.para_cache):
css = bs.css
if css:
self.register(css, 'block')
- for bs in self.run_cache.itervalues():
+ for bs in itervalues(self.run_cache):
css = bs.css
if css:
self.register(css, 'text')
def class_name(self, css):
- h = hash(frozenset(css.iteritems()))
+ h = hash(frozenset(iteritems(css)))
return self.classes.get(h, (None, None))[0]
def generate_css(self, dest_dir, docx, notes_nopb, nosupsub):
@@ -495,8 +496,8 @@ class Styles(object):
prefix = ef + '\n' + prefix
ans = []
- for (cls, css) in sorted(self.classes.itervalues(), key=lambda x:x[0]):
- b = ('\t%s: %s;' % (k, v) for k, v in css.iteritems())
+ for (cls, css) in sorted(itervalues(self.classes), key=lambda x:x[0]):
+ b = ('\t%s: %s;' % (k, v) for k, v in iteritems(css))
b = '\n'.join(b)
ans.append('.%s {\n%s\n}\n' % (cls, b.rstrip(';')))
return prefix + '\n' + '\n'.join(ans)
diff --git a/src/calibre/ebooks/docx/tables.py b/src/calibre/ebooks/docx/tables.py
index b21d723ce4..a6b5f8ef69 100644
--- a/src/calibre/ebooks/docx/tables.py
+++ b/src/calibre/ebooks/docx/tables.py
@@ -10,7 +10,7 @@ from lxml.html.builder import TABLE, TR, TD
from calibre.ebooks.docx.block_styles import inherit, read_shd as rs, read_border, binary_property, border_props, ParagraphStyle, border_to_css
from calibre.ebooks.docx.char_styles import RunStyle
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, itervalues, range
# Read from XML {{{
read_shd = rs
@@ -86,7 +86,7 @@ def read_spacing(parent, dest, XPath, get):
def read_float(parent, dest, XPath, get):
ans = inherit
for x in XPath('./w:tblpPr')(parent):
- ans = {k.rpartition('}')[-1]: v for k, v in x.attrib.iteritems()}
+ ans = {k.rpartition('}')[-1]: v for k, v in iteritems(x.attrib)}
setattr(dest, 'float', ans)
@@ -618,7 +618,7 @@ class Table(object):
def __iter__(self):
for p in self.paragraphs:
yield p
- for t in self.sub_tables.itervalues():
+ for t in itervalues(self.sub_tables):
for p in t:
yield p
@@ -665,7 +665,7 @@ class Table(object):
table_style = self.table_style.css
if table_style:
table.set('class', self.styles.register(table_style, 'table'))
- for elem, style in style_map.iteritems():
+ for elem, style in iteritems(style_map):
css = style.css
if css:
elem.set('class', self.styles.register(css, elem.tag))
@@ -686,7 +686,7 @@ class Tables(object):
self.sub_tables |= set(self.tables[-1].sub_tables)
def apply_markup(self, object_map, page_map):
- rmap = {v:k for k, v in object_map.iteritems()}
+ rmap = {v:k for k, v in iteritems(object_map)}
for table in self.tables:
table.apply_markup(rmap, page_map[table.tbl])
diff --git a/src/calibre/ebooks/docx/to_html.py b/src/calibre/ebooks/docx/to_html.py
index f1301f1f93..85ab2554bc 100644
--- a/src/calibre/ebooks/docx/to_html.py
+++ b/src/calibre/ebooks/docx/to_html.py
@@ -29,6 +29,8 @@ from calibre.ebooks.docx.fields import Fields
from calibre.ebooks.docx.settings import Settings
from calibre.ebooks.metadata.opf2 import OPFCreator
from calibre.utils.localization import canonicalize_lang, lang_as_iso639_1
+from polyglot.builtins import iteritems, itervalues
+
NBSP = '\xa0'
@@ -122,7 +124,7 @@ class Convert(object):
self.read_page_properties(doc)
self.resolve_alternate_content(doc)
self.current_rels = relationships_by_id
- for wp, page_properties in self.page_map.iteritems():
+ for wp, page_properties in iteritems(self.page_map):
self.current_page = page_properties
if wp.tag.endswith('}p'):
p = self.convert_p(wp)
@@ -162,7 +164,7 @@ class Convert(object):
self.styles.apply_contextual_spacing(paras)
self.mark_block_runs(paras)
- for p, wp in self.object_map.iteritems():
+ for p, wp in iteritems(self.object_map):
if len(p) > 0 and not p.text and len(p[0]) > 0 and not p[0].text and p[0][0].get('class', None) == 'tab':
# Paragraph uses tabs for indentation, convert to text-indent
parent = p[0]
@@ -192,7 +194,7 @@ class Convert(object):
self.tables.apply_markup(self.object_map, self.page_map)
numbered = []
- for html_obj, obj in self.object_map.iteritems():
+ for html_obj, obj in iteritems(self.object_map):
raw = obj.get('calibre_num_id', None)
if raw is not None:
lvl, num_id = raw.partition(':')[0::2]
@@ -212,7 +214,7 @@ class Convert(object):
self.log.debug('Converting styles to CSS')
self.styles.generate_classes()
- for html_obj, obj in self.object_map.iteritems():
+ for html_obj, obj in iteritems(self.object_map):
style = self.styles.resolve(obj)
if style is not None:
css = style.css
@@ -220,7 +222,7 @@ class Convert(object):
cls = self.styles.class_name(css)
if cls:
html_obj.set('class', cls)
- for html_obj, css in self.framed_map.iteritems():
+ for html_obj, css in iteritems(self.framed_map):
cls = self.styles.class_name(css)
if cls:
html_obj.set('class', cls)
@@ -407,13 +409,13 @@ class Convert(object):
doc_anchors = frozenset(self.namespace.XPath('./w:body/w:bookmarkStart[@w:name]')(doc))
if doc_anchors:
current_bm = set()
- rmap = {v:k for k, v in self.object_map.iteritems()}
+ rmap = {v:k for k, v in iteritems(self.object_map)}
for p in self.namespace.descendants(doc, 'w:p', 'w:bookmarkStart[@w:name]'):
if p.tag.endswith('}p'):
if current_bm and p in rmap:
para = rmap[p]
if 'id' not in para.attrib:
- para.set('id', generate_anchor(next(iter(current_bm)), frozenset(self.anchor_map.itervalues())))
+ para.set('id', generate_anchor(next(iter(current_bm)), frozenset(itervalues(self.anchor_map))))
for name in current_bm:
self.anchor_map[name] = para.get('id')
current_bm = set()
@@ -469,10 +471,10 @@ class Convert(object):
# _GoBack is a special bookmark inserted by Word 2010 for
# the return to previous edit feature, we ignore it
old_anchor = current_anchor
- self.anchor_map[anchor] = current_anchor = generate_anchor(anchor, frozenset(self.anchor_map.itervalues()))
+ self.anchor_map[anchor] = current_anchor = generate_anchor(anchor, frozenset(itervalues(self.anchor_map)))
if old_anchor is not None:
# The previous anchor was not applied to any element
- for a, t in tuple(self.anchor_map.iteritems()):
+ for a, t in tuple(iteritems(self.anchor_map)):
if t == old_anchor:
self.anchor_map[a] = current_anchor
elif x.tag.endswith('}hyperlink'):
@@ -480,11 +482,11 @@ class Convert(object):
elif x.tag.endswith('}instrText') and x.text and x.text.strip().startswith('TOC '):
old_anchor = current_anchor
anchor = str(uuid.uuid4())
- self.anchor_map[anchor] = current_anchor = generate_anchor('toc', frozenset(self.anchor_map.itervalues()))
+ self.anchor_map[anchor] = current_anchor = generate_anchor('toc', frozenset(itervalues(self.anchor_map)))
self.toc_anchor = current_anchor
if old_anchor is not None:
# The previous anchor was not applied to any element
- for a, t in tuple(self.anchor_map.iteritems()):
+ for a, t in tuple(iteritems(self.anchor_map)):
if t == old_anchor:
self.anchor_map[a] = current_anchor
if current_anchor is not None:
@@ -559,7 +561,7 @@ class Convert(object):
def resolve_links(self):
self.resolved_link_map = {}
- for hyperlink, spans in self.link_map.iteritems():
+ for hyperlink, spans in iteritems(self.link_map):
relationships_by_id = self.link_source_map[hyperlink]
span = spans[0]
if len(spans) > 1:
@@ -585,7 +587,7 @@ class Convert(object):
# hrefs that point nowhere give epubcheck a hernia. The element
# should be styled explicitly by Word anyway.
# span.set('href', '#')
- rmap = {v:k for k, v in self.object_map.iteritems()}
+ rmap = {v:k for k, v in iteritems(self.object_map)}
for hyperlink, runs in self.fields.hyperlink_fields:
spans = [rmap[r] for r in runs if r in rmap]
if not spans:
@@ -744,7 +746,7 @@ class Convert(object):
if not self.block_runs:
return
- rmap = {v:k for k, v in self.object_map.iteritems()}
+ rmap = {v:k for k, v in iteritems(self.object_map)}
for border_style, blocks in self.block_runs:
paras = tuple(rmap[p] for p in blocks)
for p in paras:
diff --git a/src/calibre/ebooks/docx/toc.py b/src/calibre/ebooks/docx/toc.py
index 53caff03e9..ec40071980 100644
--- a/src/calibre/ebooks/docx/toc.py
+++ b/src/calibre/ebooks/docx/toc.py
@@ -13,7 +13,7 @@ from lxml.etree import tostring
from calibre.ebooks.metadata.toc import TOC
from calibre.ebooks.oeb.polish.toc import elem_to_toc_text
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, unicode_type, range
def from_headings(body, log, namespace):
@@ -25,7 +25,7 @@ def from_headings(body, log, namespace):
level_prev = {i+1:None for i in range(len(xpaths))}
level_prev[0] = tocroot
level_item_map = {i+1:frozenset(xp(body)) for i, xp in enumerate(xpaths)}
- item_level_map = {e:i for i, elems in level_item_map.iteritems() for e in elems}
+ item_level_map = {e:i for i, elems in iteritems(level_item_map) for e in elems}
idcount = count()
diff --git a/src/calibre/ebooks/docx/writer/container.py b/src/calibre/ebooks/docx/writer/container.py
index 4d45910bc7..82ae0bd8f7 100644
--- a/src/calibre/ebooks/docx/writer/container.py
+++ b/src/calibre/ebooks/docx/writer/container.py
@@ -19,6 +19,7 @@ from calibre.utils.date import utcnow
from calibre.utils.localization import canonicalize_lang, lang_as_iso639_1
from calibre.utils.zipfile import ZipFile
from calibre.ebooks.pdf.render.common import PAPER_SIZES
+from polyglot.builtins import iteritems
def xml2str(root, pretty_print=False, with_tail=False):
@@ -55,7 +56,7 @@ def create_skeleton(opts, namespaces=None):
def w(x):
return '{%s}%s' % (namespaces['w'], x)
- dn = {k:v for k, v in namespaces.iteritems() if k in {'w', 'r', 'm', 've', 'o', 'wp', 'w10', 'wne', 'a', 'pic'}}
+ dn = {k:v for k, v in iteritems(namespaces) if k in {'w', 'r', 'm', 've', 'o', 'wp', 'w10', 'wne', 'a', 'pic'}}
E = ElementMaker(namespace=dn['w'], nsmap=dn)
doc = E.document()
body = E.body()
@@ -73,7 +74,7 @@ def create_skeleton(opts, namespaces=None):
E.docGrid(**{w('linePitch'):"360"}),
))
- dn = {k:v for k, v in namespaces.iteritems() if k in tuple('wra') + ('wp',)}
+ dn = {k:v for k, v in iteritems(namespaces) if k in tuple('wra') + ('wp',)}
E = ElementMaker(namespace=dn['w'], nsmap=dn)
styles = E.styles(
E.docDefaults(
@@ -120,12 +121,12 @@ class DocumentRelationships(object):
def __init__(self, namespace):
self.rmap = {}
self.namespace = namespace
- for typ, target in {
+ for typ, target in iteritems({
namespace.names['STYLES']: 'styles.xml',
namespace.names['NUMBERING']: 'numbering.xml',
namespace.names['WEB_SETTINGS']: 'webSettings.xml',
namespace.names['FONTS']: 'fontTable.xml',
- }.iteritems():
+ }):
self.add_relationship(target, typ)
def get_relationship_id(self, target, rtype, target_mode=None):
@@ -145,7 +146,7 @@ class DocumentRelationships(object):
namespaces = self.namespace.namespaces
E = ElementMaker(namespace=namespaces['pr'], nsmap={None:namespaces['pr']})
relationships = E.Relationships()
- for (target, rtype, target_mode), rid in self.rmap.iteritems():
+ for (target, rtype, target_mode), rid in iteritems(self.rmap):
r = E.Relationship(Id=rid, Type=rtype, Target=target)
if target_mode is not None:
r.set('TargetMode', target_mode)
@@ -172,7 +173,7 @@ class DOCX(object):
def contenttypes(self):
E = ElementMaker(namespace=self.namespace.namespaces['ct'], nsmap={None:self.namespace.namespaces['ct']})
types = E.Types()
- for partname, mt in {
+ for partname, mt in iteritems({
"/word/footnotes.xml": "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml",
"/word/document.xml": "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",
"/word/numbering.xml": "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml",
@@ -184,15 +185,15 @@ class DOCX(object):
"/word/webSettings.xml": "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml",
"/docProps/core.xml": "application/vnd.openxmlformats-package.core-properties+xml",
"/docProps/app.xml": "application/vnd.openxmlformats-officedocument.extended-properties+xml",
- }.iteritems():
+ }):
types.append(E.Override(PartName=partname, ContentType=mt))
added = {'png', 'gif', 'jpeg', 'jpg', 'svg', 'xml'}
for ext in added:
types.append(E.Default(Extension=ext, ContentType=guess_type('a.'+ext)[0]))
- for ext, mt in {
+ for ext, mt in iteritems({
"rels": "application/vnd.openxmlformats-package.relationships+xml",
"odttf": "application/vnd.openxmlformats-officedocument.obfuscatedFont",
- }.iteritems():
+ }):
added.add(ext)
types.append(E.Default(Extension=ext, ContentType=mt))
for fname in self.images:
@@ -270,12 +271,12 @@ class DOCX(object):
zf.writestr('word/fontTable.xml', xml2str(self.font_table))
zf.writestr('word/_rels/document.xml.rels', self.document_relationships.serialize())
zf.writestr('word/_rels/fontTable.xml.rels', xml2str(self.embedded_fonts))
- for fname, data_getter in self.images.iteritems():
+ for fname, data_getter in iteritems(self.images):
zf.writestr(fname, data_getter())
- for fname, data in self.fonts.iteritems():
+ for fname, data in iteritems(self.fonts):
zf.writestr(fname, data)
if __name__ == '__main__':
d = DOCX(None, None)
- print (d.websettings)
+ print(d.websettings)
diff --git a/src/calibre/ebooks/docx/writer/images.py b/src/calibre/ebooks/docx/writer/images.py
index 94d762a4e3..6aa6ff8bbb 100644
--- a/src/calibre/ebooks/docx/writer/images.py
+++ b/src/calibre/ebooks/docx/writer/images.py
@@ -10,7 +10,7 @@ import os
import posixpath
from collections import namedtuple
from functools import partial
-from polyglot.builtins import map
+from polyglot.builtins import iteritems, itervalues, map
from lxml import etree
@@ -131,7 +131,7 @@ class ImagesManager(object):
if fake_margins:
# DOCX does not support setting margins for inline images, so we
# fake it by using effect extents to simulate margins
- makeelement(parent, 'wp:effectExtent', **{k[-1].lower():v for k, v in get_image_margins(style).iteritems()})
+ makeelement(parent, 'wp:effectExtent', **{k[-1].lower():v for k, v in iteritems(get_image_margins(style))})
else:
makeelement(parent, 'wp:effectExtent', l='0', r='0', t='0', b='0')
if floating is not None:
@@ -175,7 +175,7 @@ class ImagesManager(object):
return fname
def serialize(self, images_map):
- for img in self.images.itervalues():
+ for img in itervalues(self.images):
images_map['word/' + img.fname] = partial(self.get_data, img.item)
def get_data(self, item):
diff --git a/src/calibre/ebooks/docx/writer/lists.py b/src/calibre/ebooks/docx/writer/lists.py
index c9b0d930b4..e3c0d6eec9 100644
--- a/src/calibre/ebooks/docx/writer/lists.py
+++ b/src/calibre/ebooks/docx/writer/lists.py
@@ -9,6 +9,8 @@ __copyright__ = '2015, Kovid Goyal '
from collections import defaultdict
from operator import attrgetter
+from polyglot.builtins import iteritems, itervalues
+
LIST_STYLES = frozenset(
'disc circle square decimal decimal-leading-zero lower-roman upper-roman'
' lower-greek lower-alpha lower-latin upper-alpha upper-latin hiragana hebrew'
@@ -62,7 +64,7 @@ class NumberingDefinition(object):
items_for_level = defaultdict(list)
container_for_level = {}
type_for_level = {}
- for ilvl, items in self.level_map.iteritems():
+ for ilvl, items in iteritems(self.level_map):
for container, list_tag, block, list_type, tag_style in items:
items_for_level[ilvl].append(list_tag)
container_for_level[ilvl] = container
@@ -76,7 +78,7 @@ class NumberingDefinition(object):
return hash(self.levels)
def link_blocks(self):
- for ilvl, items in self.level_map.iteritems():
+ for ilvl, items in iteritems(self.level_map):
for container, list_tag, block, list_type, tag_style in items:
block.numbering_id = (self.num_id + 1, ilvl)
@@ -148,16 +150,16 @@ class ListsManager(object):
ilvl = len(container_tags) - 1
l.level_map[ilvl].append((container_tags[0], list_tag, block, list_type, tag_style))
- [nd.finalize() for nd in lists.itervalues()]
+ [nd.finalize() for nd in itervalues(lists)]
definitions = {}
- for defn in lists.itervalues():
+ for defn in itervalues(lists):
try:
defn = definitions[defn]
except KeyError:
definitions[defn] = defn
defn.num_id = len(definitions) - 1
defn.link_blocks()
- self.definitions = sorted(definitions.itervalues(), key=attrgetter('num_id'))
+ self.definitions = sorted(itervalues(definitions), key=attrgetter('num_id'))
def serialize(self, parent):
for defn in self.definitions:
diff --git a/src/calibre/ebooks/docx/writer/styles.py b/src/calibre/ebooks/docx/writer/styles.py
index fd8e4cabc9..f1c918ad6b 100644
--- a/src/calibre/ebooks/docx/writer/styles.py
+++ b/src/calibre/ebooks/docx/writer/styles.py
@@ -15,7 +15,7 @@ from lxml import etree
from calibre.ebooks import parse_css_length
from calibre.ebooks.docx.writer.utils import convert_color, int_or_zero
from calibre.utils.localization import lang_as_iso639_1
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, iterkeys, unicode_type
from tinycss.css21 import CSS21Parser
css_parser = CSS21Parser()
@@ -158,7 +158,7 @@ class DOCXStyle(object):
getattr(self, x) for x in self.ALL_PROPS))
def makeelement(self, parent, name, **attrs):
- return parent.makeelement(self.w(name), **{self.w(k):v for k, v in attrs.iteritems()})
+ return parent.makeelement(self.w(name), **{self.w(k):v for k, v in iteritems(attrs)})
def __hash__(self):
return self._hash
@@ -365,7 +365,7 @@ class DescendantTextStyle(object):
p = []
def add(name, **props):
- p.append((name, frozenset(props.iteritems())))
+ p.append((name, frozenset(iteritems(props))))
def vals(attr):
return getattr(parent_style, attr), getattr(child_style, attr)
@@ -562,7 +562,7 @@ class BlockStyle(DOCXStyle):
def serialize_properties(self, pPr, normal_style):
makeelement, w = self.makeelement, self.w
spacing = makeelement(pPr, 'spacing')
- for edge, attr in {'top':'before', 'bottom':'after'}.iteritems():
+ for edge, attr in iteritems({'top':'before', 'bottom':'after'}):
getter = attrgetter('css_margin_' + edge)
css_val, css_unit = parse_css_length(getter(self))
if css_unit in ('em', 'ex'):
@@ -696,7 +696,7 @@ class StylesManager(object):
counts = Counter()
smap = {}
- for (bs, rs), blocks in used_pairs.iteritems():
+ for (bs, rs), blocks in iteritems(used_pairs):
s = CombinedStyle(bs, rs, blocks, self.namespace)
smap[(bs, rs)] = s
counts[s] += sum(1 for b in blocks if not b.is_empty())
@@ -721,7 +721,7 @@ class StylesManager(object):
heading_styles.append(style)
style.id = style.name = val
style.seq = i
- self.combined_styles = sorted(counts.iterkeys(), key=attrgetter('seq'))
+ self.combined_styles = sorted(iterkeys(counts), key=attrgetter('seq'))
[ls.apply() for ls in self.combined_styles]
descendant_style_map = {}
diff --git a/src/calibre/ebooks/docx/writer/tables.py b/src/calibre/ebooks/docx/writer/tables.py
index b0ab81524a..de2d3f8382 100644
--- a/src/calibre/ebooks/docx/writer/tables.py
+++ b/src/calibre/ebooks/docx/writer/tables.py
@@ -10,7 +10,7 @@ from collections import namedtuple
from calibre.ebooks.docx.writer.utils import convert_color
from calibre.ebooks.docx.writer.styles import read_css_block_borders as rcbb, border_edges
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, range
class Dummy(object):
@@ -125,7 +125,7 @@ class Cell(object):
makeelement(tcPr, 'w:shd', w_val="clear", w_color="auto", w_fill=bc)
b = makeelement(tcPr, 'w:tcBorders', append=False)
- for edge, border in self.borders.iteritems():
+ for edge, border in iteritems(self.borders):
if border is not None and border.width > 0 and border.style != 'none':
makeelement(b, 'w:' + edge, w_val=border.style, w_sz=str(border.width), w_color=border.color)
if len(b) > 0:
diff --git a/src/calibre/ebooks/epub/cfi/tests.py b/src/calibre/ebooks/epub/cfi/tests.py
index 626660bd30..f6a6e2180b 100644
--- a/src/calibre/ebooks/epub/cfi/tests.py
+++ b/src/calibre/ebooks/epub/cfi/tests.py
@@ -10,7 +10,7 @@ import unittest, numbers
from polyglot.builtins import map
from calibre.ebooks.epub.cfi.parse import parser, cfi_sort_key, decode_cfi
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
class Tests(unittest.TestCase):
@@ -61,7 +61,7 @@ class Tests(unittest.TestCase):
if after is not None:
ta['after'] = after
if params:
- ta['params'] = {unicode_type(k):(v,) if isinstance(v, unicode_type) else v for k, v in params.iteritems()}
+ ta['params'] = {unicode_type(k):(v,) if isinstance(v, unicode_type) else v for k, v in iteritems(params)}
if ta:
step['text_assertion'] = ta
return ans
diff --git a/src/calibre/ebooks/epub/pages.py b/src/calibre/ebooks/epub/pages.py
index d76a4a8c12..200c5e03fe 100644
--- a/src/calibre/ebooks/epub/pages.py
+++ b/src/calibre/ebooks/epub/pages.py
@@ -32,7 +32,7 @@ def filter_name(name):
def build_name_for(expr):
if not expr:
counter = count(1)
- return lambda elem: str(counter.next())
+ return lambda elem: str(next(counter))
selector = XPath(expr, namespaces=NSMAP)
def name_for(elem):
@@ -55,7 +55,7 @@ def add_page_map(opfpath, opts):
name = name_for(elem)
id = elem.get('id', None)
if id is None:
- id = elem.attrib['id'] = idgen.next()
+ id = elem.attrib['id'] = next(idgen)
href = '#'.join((item.href, id))
oeb.pages.add(name, href)
writer = None # DirWriter(version='2.0', page_map=True)
diff --git a/src/calibre/ebooks/lrf/html/table.py b/src/calibre/ebooks/lrf/html/table.py
index 1bc14f1632..869febf632 100644
--- a/src/calibre/ebooks/lrf/html/table.py
+++ b/src/calibre/ebooks/lrf/html/table.py
@@ -349,7 +349,7 @@ class Table(object):
nc = self.rows[r].cell_iterator()
try:
while True:
- cell = nc.next()
+ cell = next(nc)
cellmatrix[r][rowpos[r]] = cell
rowpos[r] += cell.colspan
for k in range(1, cell.rowspan):
diff --git a/src/calibre/ebooks/lrf/pylrs/pylrf.py b/src/calibre/ebooks/lrf/pylrs/pylrf.py
index d8f8c42ddf..a29c0139d0 100644
--- a/src/calibre/ebooks/lrf/pylrs/pylrf.py
+++ b/src/calibre/ebooks/lrf/pylrs/pylrf.py
@@ -10,6 +10,7 @@ import codecs
import os
from pylrfopt import tagListOptimizer
+from polyglot.builtins import iteritems
PYLRF_VERSION = "1.0"
@@ -526,7 +527,7 @@ class LrfObject(object):
# belongs somewhere, so here it is.
#
composites = {}
- for name, value in tagDict.iteritems():
+ for name, value in iteritems(tagDict):
if name == 'rubyAlignAndAdjust':
continue
if name in {
@@ -651,7 +652,7 @@ class LrfWriter(object):
return self.sourceEncoding
def toUnicode(self, string):
- if type(string) is str:
+ if isinstance(string, str):
string = string.decode(self.sourceEncoding)
return string
diff --git a/src/calibre/ebooks/metadata/book/base.py b/src/calibre/ebooks/metadata/book/base.py
index 00f60a7298..4bb37b6c9b 100644
--- a/src/calibre/ebooks/metadata/book/base.py
+++ b/src/calibre/ebooks/metadata/book/base.py
@@ -14,7 +14,7 @@ from calibre.ebooks.metadata.book import (SC_COPYABLE_FIELDS,
TOP_LEVEL_IDENTIFIERS, ALL_METADATA_FIELDS)
from calibre.library.field_metadata import FieldMetadata
from calibre.utils.icu import sort_key
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, iterkeys, unicode_type
# Special sets used to optimize the performance of getting and setting
# attributes on Metadata objects
@@ -137,7 +137,7 @@ class Metadata(object):
return object.__getattribute__(self, field)
except AttributeError:
pass
- if field in _data['user_metadata'].iterkeys():
+ if field in iterkeys(_data['user_metadata']):
d = _data['user_metadata'][field]
val = d['#value#']
if d['datatype'] != 'composite':
@@ -180,7 +180,7 @@ class Metadata(object):
if val and val.lower() != 'und':
langs = [val]
_data['languages'] = langs
- elif field in _data['user_metadata'].iterkeys():
+ elif field in iterkeys(_data['user_metadata']):
_data['user_metadata'][field]['#value#'] = val
_data['user_metadata'][field]['#extra#'] = extra
else:
@@ -190,7 +190,7 @@ class Metadata(object):
self.__dict__[field] = val
def __iter__(self):
- return object.__getattribute__(self, '_data').iterkeys()
+ return iterkeys(object.__getattribute__(self, '_data'))
def has_key(self, key):
return key in object.__getattribute__(self, '_data')
@@ -219,7 +219,7 @@ class Metadata(object):
def get_extra(self, field, default=None):
_data = object.__getattribute__(self, '_data')
- if field in _data['user_metadata'].iterkeys():
+ if field in iterkeys(_data['user_metadata']):
try:
return _data['user_metadata'][field]['#extra#']
except:
@@ -255,7 +255,7 @@ class Metadata(object):
Set all identifiers. Note that if you previously set ISBN, calling
this method will delete it.
'''
- cleaned = {ck(k):cv(v) for k, v in identifiers.iteritems() if k and v}
+ cleaned = {ck(k):cv(v) for k, v in iteritems(identifiers) if k and v}
object.__getattribute__(self, '_data')['identifiers'] = cleaned
def set_identifier(self, typ, val):
@@ -287,14 +287,14 @@ class Metadata(object):
'''
return a list of the custom fields in this book
'''
- return object.__getattribute__(self, '_data')['user_metadata'].iterkeys()
+ return iterkeys(object.__getattribute__(self, '_data')['user_metadata'])
def all_field_keys(self):
'''
All field keys known by this instance, even if their value is None
'''
_data = object.__getattribute__(self, '_data')
- return frozenset(ALL_METADATA_FIELDS.union(_data['user_metadata'].iterkeys()))
+ return frozenset(ALL_METADATA_FIELDS.union(iterkeys(_data['user_metadata'])))
def metadata_for_field(self, key):
'''
@@ -320,7 +320,7 @@ class Metadata(object):
v = self.get(attr, None)
if v is not None:
result[attr] = v
- for attr in _data['user_metadata'].iterkeys():
+ for attr in iterkeys(_data['user_metadata']):
v = self.get(attr, None)
if v is not None:
result[attr] = v
@@ -396,7 +396,7 @@ class Metadata(object):
return
um = {}
- for key, meta in metadata.iteritems():
+ for key, meta in iteritems(metadata):
m = meta.copy()
if '#value#' not in m:
if m['datatype'] == 'text' and m['is_multiple']:
@@ -576,7 +576,7 @@ class Metadata(object):
if callable(getattr(other, 'get_identifiers', None)):
d = self.get_identifiers()
s = other.get_identifiers()
- d.update([v for v in s.iteritems() if v[1] is not None])
+ d.update([v for v in iteritems(s) if v[1] is not None])
self.set_identifiers(d)
else:
# other structure not Metadata. Copy the top-level identifiers
@@ -749,7 +749,7 @@ class Metadata(object):
fmt('Rights', unicode_type(self.rights))
if self.identifiers:
fmt('Identifiers', u', '.join(['%s:%s'%(k, v) for k, v in
- self.identifiers.iteritems()]))
+ iteritems(self.identifiers)]))
if self.comments:
fmt('Comments', self.comments)
diff --git a/src/calibre/ebooks/metadata/book/json_codec.py b/src/calibre/ebooks/metadata/book/json_codec.py
index 6d15eb5031..4a411b15a2 100644
--- a/src/calibre/ebooks/metadata/book/json_codec.py
+++ b/src/calibre/ebooks/metadata/book/json_codec.py
@@ -13,6 +13,7 @@ from calibre.ebooks.metadata.book import SERIALIZABLE_FIELDS
from calibre.constants import filesystem_encoding, preferred_encoding
from calibre.library.field_metadata import FieldMetadata
from calibre import isbytestring
+from polyglot.builtins import iteritems, itervalues
# Translate datetimes to and from strings. The string form is the datetime in
# UTC. The returned date is also UTC
@@ -149,7 +150,7 @@ class JsonCodec(object):
def encode_metadata_attr(self, book, key):
if key == 'user_metadata':
meta = book.get_all_user_metadata(make_copy=True)
- for fm in meta.itervalues():
+ for fm in itervalues(meta):
if fm['datatype'] == 'datetime':
fm['#value#'] = datetime_to_string(fm['#value#'])
encode_is_multiple(fm)
@@ -184,7 +185,7 @@ class JsonCodec(object):
def raw_to_book(self, json_book, book_class, prefix):
try:
book = book_class(prefix, json_book.get('lpath', None))
- for key,val in json_book.iteritems():
+ for key,val in iteritems(json_book):
meta = self.decode_metadata(key, val)
if key == 'user_metadata':
book.set_all_user_metadata(meta)
@@ -201,7 +202,7 @@ class JsonCodec(object):
if key == 'classifiers':
key = 'identifiers'
if key == 'user_metadata':
- for fm in value.itervalues():
+ for fm in itervalues(value):
if fm['datatype'] == 'datetime':
fm['#value#'] = string_to_datetime(fm['#value#'])
decode_is_multiple(fm)
diff --git a/src/calibre/ebooks/metadata/book/serialize.py b/src/calibre/ebooks/metadata/book/serialize.py
index e1a7189530..8c741cc70f 100644
--- a/src/calibre/ebooks/metadata/book/serialize.py
+++ b/src/calibre/ebooks/metadata/book/serialize.py
@@ -10,7 +10,7 @@ from calibre.constants import preferred_encoding
from calibre.ebooks.metadata.book import SERIALIZABLE_FIELDS
from calibre.ebooks.metadata.book.base import Metadata
from calibre.utils.imghdr import what
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
def ensure_unicode(obj, enc=preferred_encoding):
@@ -21,7 +21,7 @@ def ensure_unicode(obj, enc=preferred_encoding):
if isinstance(obj, (list, tuple)):
return [ensure_unicode(x) for x in obj]
if isinstance(obj, dict):
- return {ensure_unicode(k): ensure_unicode(v) for k, v in obj.iteritems()}
+ return {ensure_unicode(k): ensure_unicode(v) for k, v in iteritems(obj)}
return obj
@@ -63,7 +63,7 @@ def metadata_as_dict(mi, encode_cover_data=False):
def metadata_from_dict(src):
ans = Metadata('Unknown')
- for key, value in src.iteritems():
+ for key, value in iteritems(src):
if key == 'user_metadata':
ans.set_all_user_metadata(value)
else:
diff --git a/src/calibre/ebooks/metadata/cli.py b/src/calibre/ebooks/metadata/cli.py
index 5a7643c946..f6ca8ae1bc 100644
--- a/src/calibre/ebooks/metadata/cli.py
+++ b/src/calibre/ebooks/metadata/cli.py
@@ -16,7 +16,7 @@ from calibre.ebooks.metadata import string_to_authors, authors_to_sort_string, \
from calibre.ebooks.lrf.meta import LRFMetaFile
from calibre import prints
from calibre.utils.date import parse_date
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
USAGE=_('%prog ebook_file [options]\n') + \
_('''
@@ -150,7 +150,7 @@ def do_set_metadata(opts, mi, stream, stream_type):
if val:
orig = mi.get_identifiers()
orig.update(val)
- val = {k:v for k, v in orig.iteritems() if k and v}
+ val = {k:v for k, v in iteritems(orig) if k and v}
mi.set_identifiers(val)
if getattr(opts, 'cover', None) is not None:
diff --git a/src/calibre/ebooks/metadata/html.py b/src/calibre/ebooks/metadata/html.py
index 55c3849107..9d866fac55 100644
--- a/src/calibre/ebooks/metadata/html.py
+++ b/src/calibre/ebooks/metadata/html.py
@@ -16,6 +16,7 @@ from calibre.ebooks.metadata.book.base import Metadata
from calibre.ebooks.chardet import xml_to_unicode
from calibre import replace_entities, isbytestring
from calibre.utils.date import parse_date, is_date_undefined
+from polyglot.builtins import iteritems, itervalues
def get_metadata(stream):
@@ -60,16 +61,16 @@ attr_pat = r'''(?:(?P')|(?P"))(?P(?(sq)[^']+|[^"]+))(?(sq)'|")'
def parse_meta_tags(src):
rmap = {}
- for field, names in META_NAMES.iteritems():
+ for field, names in iteritems(META_NAMES):
for name in names:
rmap[name.lower()] = field
all_names = '|'.join(rmap)
ans = {}
npat = r'''name\s*=\s*['"]{0,1}(?P%s)['"]{0,1}''' % all_names
- cpat = 'content\s*=\s*%s' % attr_pat
+ cpat = r'content\s*=\s*%s' % attr_pat
for pat in (
- '%s)\s*=\s*%s''' % (all_names, attr_pat), src):
field = rmap[match.group('name')]
diff --git a/src/calibre/ebooks/metadata/opf.py b/src/calibre/ebooks/metadata/opf.py
index 90b94e727e..a27a31a951 100644
--- a/src/calibre/ebooks/metadata/opf.py
+++ b/src/calibre/ebooks/metadata/opf.py
@@ -11,6 +11,7 @@ from calibre.ebooks.metadata.opf2 import OPF, pretty_print
from calibre.ebooks.metadata.opf3 import apply_metadata, read_metadata
from calibre.ebooks.metadata.utils import parse_opf, normalize_languages, create_manifest_item, parse_opf_version
from calibre.ebooks.metadata import MetaInformation
+from polyglot.builtins import iteritems
class DummyFile(object):
@@ -61,7 +62,7 @@ def set_metadata_opf2(root, cover_prefix, mi, opf_version,
else:
orig = opf.get_identifiers()
orig.update(mi.get_identifiers())
- opf.set_identifiers({k:v for k, v in orig.iteritems() if k and v})
+ opf.set_identifiers({k:v for k, v in iteritems(orig) if k and v})
if update_timestamp and mi.timestamp is not None:
opf.timestamp = mi.timestamp
raster_cover = opf.raster_cover
diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py
index 4e5541ff1d..5468c0e72d 100644
--- a/src/calibre/ebooks/metadata/opf2.py
+++ b/src/calibre/ebooks/metadata/opf2.py
@@ -23,7 +23,7 @@ from calibre.utils.localization import get_lang, canonicalize_lang
from calibre import prints, guess_type
from calibre.utils.cleantext import clean_ascii_chars, clean_xml_chars
from calibre.utils.config import tweaks
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, unicode_type, range
from polyglot.urllib import unquote, urlparse
pretty_print_opf = False
@@ -977,7 +977,7 @@ class OPF(object): # {{{
'descendant::*[local-name() = "identifier" and text()]')(
self.metadata):
found_scheme = False
- for attr, val in x.attrib.iteritems():
+ for attr, val in iteritems(x.attrib):
if attr.endswith('scheme'):
typ = icu_lower(val)
val = etree.tostring(x, with_tail=False, encoding=unicode_type,
@@ -1010,7 +1010,7 @@ class OPF(object): # {{{
self.metadata):
xid = x.get('id', None)
is_package_identifier = uuid_id is not None and uuid_id == xid
- typ = {val for attr, val in x.attrib.iteritems() if attr.endswith('scheme')}
+ typ = {val for attr, val in iteritems(x.attrib) if attr.endswith('scheme')}
if is_package_identifier:
typ = tuple(typ)
if typ and typ[0].lower() in identifiers:
@@ -1019,7 +1019,7 @@ class OPF(object): # {{{
if typ and not (typ & {'calibre', 'uuid'}):
x.getparent().remove(x)
- for typ, val in identifiers.iteritems():
+ for typ, val in iteritems(identifiers):
attrib = {'{%s}scheme'%self.NAMESPACES['opf']: typ.upper()}
self.set_text(self.create_metadata_element(
'identifier', attrib=attrib), unicode_type(val))
@@ -1155,7 +1155,7 @@ class OPF(object): # {{{
def page_progression_direction(self):
spine = self.XPath('descendant::*[re:match(name(), "spine", "i")][1]')(self.root)
if spine:
- for k, v in spine[0].attrib.iteritems():
+ for k, v in iteritems(spine[0].attrib):
if k == 'page-progression-direction' or k.endswith('}page-progression-direction'):
return v
@@ -1525,7 +1525,7 @@ class OPFCreator(Metadata):
a(DC_ELEM('description', self.comments))
if self.publisher:
a(DC_ELEM('publisher', self.publisher))
- for key, val in self.get_identifiers().iteritems():
+ for key, val in iteritems(self.get_identifiers()):
a(DC_ELEM('identifier', val, opf_attrs={'scheme':icu_upper(key)}))
if self.rights:
a(DC_ELEM('rights', self.rights))
@@ -1651,7 +1651,7 @@ def metadata_to_opf(mi, as_string=True, default_lang=None):
try:
elem = metadata.makeelement(tag, attrib=attrib)
except ValueError:
- elem = metadata.makeelement(tag, attrib={k:clean_xml_chars(v) for k, v in attrib.iteritems()})
+ elem = metadata.makeelement(tag, attrib={k:clean_xml_chars(v) for k, v in iteritems(attrib)})
elem.tail = '\n'+(' '*8)
if text:
try:
@@ -1672,7 +1672,7 @@ def metadata_to_opf(mi, as_string=True, default_lang=None):
factory(DC('description'), clean_ascii_chars(mi.comments))
if mi.publisher:
factory(DC('publisher'), mi.publisher)
- for key, val in mi.get_identifiers().iteritems():
+ for key, val in iteritems(mi.get_identifiers()):
factory(DC('identifier'), val, scheme=icu_upper(key))
if mi.rights:
factory(DC('rights'), mi.rights)
diff --git a/src/calibre/ebooks/metadata/opf3.py b/src/calibre/ebooks/metadata/opf3.py
index 8d9bfbb9b0..26cde2b802 100644
--- a/src/calibre/ebooks/metadata/opf3.py
+++ b/src/calibre/ebooks/metadata/opf3.py
@@ -8,7 +8,7 @@ import json
import re
from collections import defaultdict, namedtuple
from functools import wraps
-from polyglot.builtins import map
+from polyglot.builtins import iteritems, map
from lxml import etree
@@ -190,9 +190,9 @@ def ensure_prefix(root, prefixes, prefix, value=None):
if prefixes is None:
prefixes = read_prefixes(root)
prefixes[prefix] = value or reserved_prefixes[prefix]
- prefixes = {k:v for k, v in prefixes.iteritems() if reserved_prefixes.get(k) != v}
+ prefixes = {k:v for k, v in iteritems(prefixes) if reserved_prefixes.get(k) != v}
if prefixes:
- root.set('prefix', ' '.join('%s: %s' % (k, v) for k, v in prefixes.iteritems()))
+ root.set('prefix', ' '.join('%s: %s' % (k, v) for k, v in iteritems(prefixes)))
else:
root.attrib.pop('prefix', None)
@@ -299,7 +299,7 @@ def set_identifiers(root, prefixes, refines, new_identifiers, force_identifiers=
remove_element(ident, refines)
continue
metadata = XPath('./opf:metadata')(root)[0]
- for scheme, val in new_identifiers.iteritems():
+ for scheme, val in iteritems(new_identifiers):
ident = metadata.makeelement(DC('identifier'))
ident.text = '%s:%s' % (scheme, val)
if package_identifier is None:
@@ -854,7 +854,7 @@ set_author_link_map = dict_writer('author_link_map')
def deserialize_user_metadata(val):
val = json.loads(val, object_hook=from_json)
ans = {}
- for name, fm in val.iteritems():
+ for name, fm in iteritems(val):
decode_is_multiple(fm)
ans[name] = fm
return ans
@@ -969,7 +969,7 @@ def read_metadata(root, ver=None, return_extra_data=False):
prefixes, refines = read_prefixes(root), read_refines(root)
identifiers = read_identifiers(root, prefixes, refines)
ids = {}
- for key, vals in identifiers.iteritems():
+ for key, vals in iteritems(identifiers):
if key == 'calibre':
ans.application_id = vals[0]
elif key == 'uuid':
@@ -1007,7 +1007,7 @@ def read_metadata(root, ver=None, return_extra_data=False):
ans.series, ans.series_index = s, si
ans.author_link_map = read_author_link_map(root, prefixes, refines) or ans.author_link_map
ans.user_categories = read_user_categories(root, prefixes, refines) or ans.user_categories
- for name, fm in (read_user_metadata(root, prefixes, refines) or {}).iteritems():
+ for name, fm in iteritems((read_user_metadata(root, prefixes, refines) or {})):
ans.set_user_metadata(name, fm)
if return_extra_data:
ans = ans, ver, read_raster_cover(root, prefixes, refines), first_spine_item(root, prefixes, refines)
diff --git a/src/calibre/ebooks/metadata/opf_2_to_3.py b/src/calibre/ebooks/metadata/opf_2_to_3.py
index 73566d8aba..da7d4a947d 100644
--- a/src/calibre/ebooks/metadata/opf_2_to_3.py
+++ b/src/calibre/ebooks/metadata/opf_2_to_3.py
@@ -13,6 +13,7 @@ from calibre.ebooks.metadata.opf3 import (
set_refines, set_user_metadata3
)
from calibre.ebooks.metadata.utils import parse_opf, pretty_print_opf
+from polyglot.builtins import itervalues
class Data(object):
@@ -140,7 +141,7 @@ def upgrade_series(root, data):
def upgrade_custom(root, data):
m = read_user_metadata2(root, remove_tags=True)
if m:
- for fm in m.itervalues():
+ for fm in itervalues(m):
encode_is_multiple(fm)
set_user_metadata3(root, data.prefixes, data.refines, m)
diff --git a/src/calibre/ebooks/metadata/pdf.py b/src/calibre/ebooks/metadata/pdf.py
index 01a524afcd..269e093634 100644
--- a/src/calibre/ebooks/metadata/pdf.py
+++ b/src/calibre/ebooks/metadata/pdf.py
@@ -12,7 +12,7 @@ from calibre.ptempfile import TemporaryDirectory
from calibre.ebooks.metadata import (
MetaInformation, string_to_authors, check_isbn, check_doi)
from calibre.utils.ipc.simple_worker import fork_job, WorkerError
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
def get_tools():
@@ -153,9 +153,9 @@ def get_metadata(stream, cover=True):
# Look for recognizable identifiers in the info dict, if they were not
# found in the XMP metadata
- for scheme, check_func in {'doi':check_doi, 'isbn':check_isbn}.iteritems():
+ for scheme, check_func in iteritems({'doi':check_doi, 'isbn':check_isbn}):
if scheme not in mi.get_identifiers():
- for k, v in info.iteritems():
+ for k, v in iteritems(info):
if k != 'xmp_metadata':
val = check_func(v)
if val:
diff --git a/src/calibre/ebooks/metadata/search_internet.py b/src/calibre/ebooks/metadata/search_internet.py
index 24f54d6990..d5d9a30ebe 100644
--- a/src/calibre/ebooks/metadata/search_internet.py
+++ b/src/calibre/ebooks/metadata/search_internet.py
@@ -4,6 +4,7 @@
from __future__ import absolute_import, division, print_function, unicode_literals
+from polyglot.builtins import iteritems
from polyglot.urllib import quote_plus
AUTHOR_SEARCHES = {
@@ -54,7 +55,7 @@ def qquote(val):
def url_for(template, data):
- return template.format(**{k: qquote(v) for k, v in data.iteritems()})
+ return template.format(**{k: qquote(v) for k, v in iteritems(data)})
def url_for_author_search(key, **kw):
diff --git a/src/calibre/ebooks/metadata/sources/base.py b/src/calibre/ebooks/metadata/sources/base.py
index 0513209277..349e104458 100644
--- a/src/calibre/ebooks/metadata/sources/base.py
+++ b/src/calibre/ebooks/metadata/sources/base.py
@@ -14,6 +14,7 @@ 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
def create_log(ostream=None):
@@ -65,7 +66,7 @@ class InternalMetadataCompareKeyGen(object):
def __init__(self, mi, source_plugin, title, authors, identifiers):
same_identifier = 2
idents = mi.get_identifiers()
- for k, v in identifiers.iteritems():
+ for k, v in iteritems(identifiers):
if idents.get(k) == v:
same_identifier = 1
break
@@ -280,7 +281,7 @@ class Source(Plugin):
def get_related_isbns(self, id_):
with self.cache_lock:
- for isbn, q in self._isbn_to_identifier_cache.iteritems():
+ for isbn, q in iteritems(self._isbn_to_identifier_cache):
if q == id_:
yield isbn
diff --git a/src/calibre/ebooks/metadata/sources/identify.py b/src/calibre/ebooks/metadata/sources/identify.py
index 44cdba029b..c807d0e87a 100644
--- a/src/calibre/ebooks/metadata/sources/identify.py
+++ b/src/calibre/ebooks/metadata/sources/identify.py
@@ -27,7 +27,7 @@ from calibre.utils.html2text import html2text
from calibre.utils.icu import lower
from calibre.utils.date import UNDEFINED_DATE
from calibre.utils.formatter import EvalFormatter
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, iterkeys, itervalues, unicode_type
# Download worker {{{
@@ -99,7 +99,7 @@ class ISBNMerge(object):
def isbn_in_pool(self, isbn):
if isbn:
- for isbns, pool in self.pools.iteritems():
+ for isbns, pool in iteritems(self.pools):
if isbn in isbns:
return pool
return None
@@ -147,7 +147,7 @@ class ISBNMerge(object):
def finalize(self):
has_isbn_result = False
- for results in self.pools.itervalues():
+ for results in itervalues(self.pools):
if results:
has_isbn_result = True
break
@@ -192,7 +192,7 @@ class ISBNMerge(object):
if len(groups) != len(self.results):
self.results = []
- for rgroup in groups.itervalues():
+ for rgroup in itervalues(groups):
rel = [r.average_source_relevance for r in rgroup]
if len(rgroup) > 1:
result = self.merge(rgroup, None, do_asr=False)
@@ -206,7 +206,7 @@ class ISBNMerge(object):
groups, empty = {}, []
for result in self.results:
key = set()
- for typ, val in result.identifiers.iteritems():
+ for typ, val in iteritems(result.identifiers):
if typ and val:
key.add((typ, val))
if key:
@@ -227,7 +227,7 @@ class ISBNMerge(object):
if len(groups) != len(self.results):
self.results = []
- for rgroup in groups.itervalues():
+ for rgroup in itervalues(groups):
rel = [r.average_source_relevance for r in rgroup]
if len(rgroup) > 1:
result = self.merge(rgroup, None, do_asr=False)
@@ -244,7 +244,7 @@ class ISBNMerge(object):
def merge_isbn_results(self):
self.results = []
sources = set()
- for min_year, results in self.pools.itervalues():
+ for min_year, results in itervalues(self.pools):
if results:
for r in results:
sources.add(r.identify_plugin)
@@ -362,7 +362,7 @@ class ISBNMerge(object):
def merge_identify_results(result_map, log):
isbn_merge = ISBNMerge(log)
- for plugin, results in result_map.iteritems():
+ for plugin, results in iteritems(result_map):
for result in results:
isbn_merge.add_result(result)
@@ -439,12 +439,12 @@ def identify(log, abort, # {{{
pass
sort_kwargs = dict(kwargs)
- for k in list(sort_kwargs.iterkeys()):
+ for k in list(iterkeys(sort_kwargs)):
if k not in ('title', 'authors', 'identifiers'):
sort_kwargs.pop(k)
longest, lp = -1, ''
- for plugin, presults in results.iteritems():
+ for plugin, presults in iteritems(results):
presults.sort(key=plugin.identify_results_keygen(**sort_kwargs))
# Throw away lower priority results from the same source that have exactly the same
@@ -542,7 +542,7 @@ def identify(log, abort, # {{{
def urls_from_identifiers(identifiers): # {{{
- identifiers = {k.lower():v for k, v in identifiers.iteritems()}
+ identifiers = {k.lower():v for k, v in iteritems(identifiers)}
ans = []
keys_left = set(identifiers)
@@ -553,7 +553,7 @@ def urls_from_identifiers(identifiers): # {{{
rules = msprefs['id_link_rules']
if rules:
formatter = EvalFormatter()
- for k, val in identifiers.iteritems():
+ for k, val in iteritems(identifiers):
val = val.replace('|', ',')
vals = {'id':quote(val if isinstance(val, bytes) else val.encode('utf-8')).decode('ascii')}
items = rules.get(k) or ()
@@ -592,7 +592,7 @@ def urls_from_identifiers(identifiers): # {{{
add(issn, 'issn', issn,
'https://www.worldcat.org/issn/'+issn)
q = {'http', 'https', 'file'}
- for k, url in identifiers.iteritems():
+ for k, url in iteritems(identifiers):
if url and re.match(r'ur[il]\d*$', k) is not None:
url = url[:8].replace('|', ':') + url[8:].replace('|', ',')
if url.partition(':')[0].lower() in q:
diff --git a/src/calibre/ebooks/metadata/sources/update.py b/src/calibre/ebooks/metadata/sources/update.py
index a2403d65a1..5088588647 100644
--- a/src/calibre/ebooks/metadata/sources/update.py
+++ b/src/calibre/ebooks/metadata/sources/update.py
@@ -17,6 +17,7 @@ from calibre.constants import DEBUG, numeric_version
from calibre.ebooks.metadata.sources.base import Source
from calibre.utils.config import JSONConfig
from calibre.utils.https import get_https_resource_securely
+from polyglot.builtins import iteritems, itervalues
cache = JSONConfig('metadata-sources-cache.json')
@@ -38,7 +39,7 @@ def load_plugin(src):
src = src.encode('utf-8')
ns = {}
exec(src, ns)
- for x in ns.itervalues():
+ for x in itervalues(ns):
if isinstance(x, type) and issubclass(x, Source) and x is not Source:
return x
@@ -76,7 +77,7 @@ def patch_search_engines(src):
def patch_plugins():
from calibre.customize.ui import patch_metadata_plugins
patches = {}
- for name, val in cache.iteritems():
+ for name, val in iteritems(cache):
if name == 'hashes':
continue
if name == 'search_engines':
@@ -94,7 +95,7 @@ def update_needed():
'https://code.calibre-ebook.com/metadata-sources/hashes.json')
hashes = bz2.decompress(hashes)
hashes = json.loads(hashes)
- for k, v in hashes.iteritems():
+ for k, v in iteritems(hashes):
if current_hashes.get(k) != v:
needed[k] = v
remove = set(current_hashes) - set(hashes)
@@ -132,7 +133,7 @@ def main(report_error=prints, report_action=prints):
cache.touch()
return
updated = {}
- for name, expected_hash in needed.iteritems():
+ for name, expected_hash in iteritems(needed):
report_action('Updating metadata source {}...'.format(name))
try:
update_plugin(name, updated, expected_hash)
diff --git a/src/calibre/ebooks/metadata/sources/worker.py b/src/calibre/ebooks/metadata/sources/worker.py
index 436d7014eb..cbfad164e0 100644
--- a/src/calibre/ebooks/metadata/sources/worker.py
+++ b/src/calibre/ebooks/metadata/sources/worker.py
@@ -18,6 +18,7 @@ from calibre.ebooks.metadata.sources.update import patch_plugins
from calibre.utils.date import as_utc
from calibre.utils.logging import GUILog
from polyglot.queue import Empty, Queue
+from polyglot.builtins import iteritems
def merge_result(oldmi, newmi, ensure_fields=None):
@@ -54,7 +55,7 @@ def main(do_identify, covers, metadata, ensure_fields, tdir):
log = GUILog()
patch_plugins()
- for book_id, mi in metadata.iteritems():
+ for book_id, mi in iteritems(metadata):
mi = OPF(BytesIO(mi), basedir=tdir,
populate_spine=False).to_book_metadata()
title, authors, identifiers = mi.title, mi.authors, mi.identifiers
diff --git a/src/calibre/ebooks/metadata/xmp.py b/src/calibre/ebooks/metadata/xmp.py
index 82329ee335..c9d6b94491 100644
--- a/src/calibre/ebooks/metadata/xmp.py
+++ b/src/calibre/ebooks/metadata/xmp.py
@@ -19,7 +19,7 @@ from calibre.ebooks.metadata.book.base import Metadata
from calibre.ebooks.metadata.opf2 import dump_dict
from calibre.utils.date import parse_date, isoformat, now
from calibre.utils.localization import canonicalize_lang, lang_as_iso639_1
-from polyglot.builtins import string_or_bytes
+from polyglot.builtins import iteritems, string_or_bytes
_xml_declaration = re.compile(r'<\?xml[^<>]+encoding\s*=\s*[\'"](.*?)[\'"][^<>]*>', re.IGNORECASE)
@@ -323,7 +323,7 @@ def metadata_from_xmp_packet(raw_bytes):
identifiers[scheme] = val
# Check Dublin Core for recognizable identifier types
- for scheme, check_func in {'doi':check_doi, 'isbn':check_isbn}.iteritems():
+ for scheme, check_func in iteritems({'doi':check_doi, 'isbn':check_isbn}):
if scheme not in identifiers:
val = check_func(first_simple('//dc:identifier', root))
if val:
@@ -407,7 +407,7 @@ def create_identifiers(xmp, identifiers):
xmp.append(xmpid)
bag = xmpid.makeelement(expand('rdf:Bag'))
xmpid.append(bag)
- for scheme, value in identifiers.iteritems():
+ for scheme, value in iteritems(identifiers):
li = bag.makeelement(expand('rdf:li'))
li.set(expand('rdf:parseType'), 'Resource')
bag.append(li)
@@ -443,7 +443,7 @@ def create_user_metadata(calibre, all_user_metadata):
calibre.append(s)
bag = s.makeelement(expand('rdf:Bag'))
s.append(bag)
- for name, fm in all_user_metadata.iteritems():
+ for name, fm in iteritems(all_user_metadata):
try:
fm = copy.copy(fm)
encode_is_multiple(fm)
@@ -473,12 +473,12 @@ def metadata_to_xmp_packet(mi):
dc = rdf.makeelement(expand('rdf:Description'), nsmap=nsmap('dc'))
dc.set(expand('rdf:about'), '')
rdf.append(dc)
- for prop, tag in {'title':'dc:title', 'comments':'dc:description'}.iteritems():
+ for prop, tag in iteritems({'title':'dc:title', 'comments':'dc:description'}):
val = mi.get(prop) or ''
create_alt_property(dc, tag, val)
- for prop, (tag, ordered) in {
+ for prop, (tag, ordered) in iteritems({
'authors':('dc:creator', True), 'tags':('dc:subject', False), 'publisher':('dc:publisher', False),
- }.iteritems():
+ }):
val = mi.get(prop) or ()
if isinstance(val, string_or_bytes):
val = [val]
@@ -502,9 +502,9 @@ def metadata_to_xmp_packet(mi):
identifiers = mi.get_identifiers()
if identifiers:
create_identifiers(xmp, identifiers)
- for scheme, val in identifiers.iteritems():
+ for scheme, val in iteritems(identifiers):
if scheme in {'isbn', 'doi'}:
- for prefix, parent in extra_ids.iteritems():
+ for prefix, parent in iteritems(extra_ids):
ie = parent.makeelement(expand('%s:%s'%(prefix, scheme)))
ie.text = val
parent.append(ie)
@@ -552,7 +552,7 @@ def find_used_namespaces(elem):
def find_preferred_prefix(namespace, elems):
for elem in elems:
- ans = {v:k for k, v in elem.nsmap.iteritems()}.get(namespace, None)
+ ans = {v:k for k, v in iteritems(elem.nsmap)}.get(namespace, None)
if ans is not None:
return ans
return find_preferred_prefix(namespace, elem.iterchildren(etree.Element))
@@ -564,7 +564,7 @@ def find_nsmap(elems):
used_namespaces |= find_used_namespaces(elem)
ans = {}
used_namespaces -= {NS_MAP['xml'], NS_MAP['x'], None, NS_MAP['rdf']}
- rmap = {v:k for k, v in NS_MAP.iteritems()}
+ rmap = {v:k for k, v in iteritems(NS_MAP)}
i = 0
for ns in used_namespaces:
if ns in rmap:
diff --git a/src/calibre/ebooks/mobi/debug/headers.py b/src/calibre/ebooks/mobi/debug/headers.py
index 97923ab579..99e2e3a1f8 100644
--- a/src/calibre/ebooks/mobi/debug/headers.py
+++ b/src/calibre/ebooks/mobi/debug/headers.py
@@ -14,7 +14,7 @@ from calibre.ebooks.mobi.reader.headers import NULL_INDEX
from calibre.ebooks.mobi.langcodes import main_language, sub_language
from calibre.ebooks.mobi.debug import format_bytes
from calibre.ebooks.mobi.utils import get_trailing_data
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, range
# PalmDB {{{
@@ -597,9 +597,9 @@ class TextRecord(object): # {{{
self.trailing_data['uncrossable_breaks'] = self.trailing_data.pop(2)
self.trailing_data['raw_bytes'] = raw_trailing_bytes
- for typ, val in self.trailing_data.iteritems():
+ for typ, val in iteritems(self.trailing_data):
if isinstance(typ, numbers.Integral):
- print ('Record %d has unknown trailing data of type: %d : %r'%
+ print('Record %d has unknown trailing data of type: %d : %r'%
(idx, typ, val))
self.idx = idx
@@ -609,7 +609,7 @@ class TextRecord(object): # {{{
with open(os.path.join(folder, name+'.txt'), 'wb') as f:
f.write(self.raw)
with open(os.path.join(folder, name+'.trailing_data'), 'wb') as f:
- for k, v in self.trailing_data.iteritems():
+ for k, v in iteritems(self.trailing_data):
raw = '%s : %r\n\n'%(k, v)
f.write(raw.encode('utf-8'))
diff --git a/src/calibre/ebooks/mobi/debug/index.py b/src/calibre/ebooks/mobi/debug/index.py
index e0868b9f49..e9446f266f 100644
--- a/src/calibre/ebooks/mobi/debug/index.py
+++ b/src/calibre/ebooks/mobi/debug/index.py
@@ -15,7 +15,7 @@ from calibre.ebooks.mobi.reader.headers import NULL_INDEX
from calibre.ebooks.mobi.reader.index import (CNCX, parse_indx_header,
parse_tagx_section, parse_index_record, INDEX_HEADER_FIELDS)
from calibre.ebooks.mobi.reader.ncx import (tag_fieldname_map, default_entry)
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, iterkeys, range
File = namedtuple('File',
'file_number name divtbl_count start_position length')
@@ -110,13 +110,13 @@ class Index(object):
if self.cncx:
a('*'*10 + ' CNCX ' + '*'*10)
- for offset, val in self.cncx.iteritems():
+ for offset, val in iteritems(self.cncx):
a('%10s: %s'%(offset, val))
ans.extend(['', ''])
if self.table is not None:
a('*'*10 + ' %d Index Entries '%len(self.table) + '*'*10)
- for k, v in self.table.iteritems():
+ for k, v in iteritems(self.table):
a('%s: %r'%(k, v))
if self.records:
@@ -140,11 +140,11 @@ class SKELIndex(Index):
self.records = []
if self.table is not None:
- for i, text in enumerate(self.table.iterkeys()):
+ for i, text in enumerate(iterkeys(self.table)):
tag_map = self.table[text]
- if set(tag_map.iterkeys()) != {1, 6}:
+ if set(iterkeys(tag_map)) != {1, 6}:
raise ValueError('SKEL Index has unknown tags: %s'%
- (set(tag_map.iterkeys())-{1,6}))
+ (set(iterkeys(tag_map))-{1,6}))
self.records.append(File(
i, # file_number
text, # name
@@ -161,11 +161,11 @@ class SECTIndex(Index):
self.records = []
if self.table is not None:
- for i, text in enumerate(self.table.iterkeys()):
+ for i, text in enumerate(iterkeys(self.table)):
tag_map = self.table[text]
- if set(tag_map.iterkeys()) != {2, 3, 4, 6}:
+ if set(iterkeys(tag_map)) != {2, 3, 4, 6}:
raise ValueError('Chunk Index has unknown tags: %s'%
- (set(tag_map.iterkeys())-{2, 3, 4, 6}))
+ (set(iterkeys(tag_map))-{2, 3, 4, 6}))
toc_text = self.cncx[tag_map[2][0]]
self.records.append(Elem(
@@ -186,9 +186,9 @@ class GuideIndex(Index):
self.records = []
if self.table is not None:
- for i, text in enumerate(self.table.iterkeys()):
+ for i, text in enumerate(iterkeys(self.table)):
tag_map = self.table[text]
- if set(tag_map.iterkeys()) not in ({1, 6}, {1, 2, 3}):
+ if set(iterkeys(tag_map)) not in ({1, 6}, {1, 2, 3}):
raise ValueError('Guide Index has unknown tags: %s'%
tag_map)
@@ -211,13 +211,13 @@ class NCXIndex(Index):
NCXEntry = namedtuple('NCXEntry', 'index start length depth parent '
'first_child last_child title pos_fid kind')
- for num, x in enumerate(self.table.iteritems()):
+ for num, x in enumerate(iteritems(self.table)):
text, tag_map = x
entry = e = default_entry.copy()
entry['name'] = text
entry['num'] = num
- for tag in tag_fieldname_map.iterkeys():
+ for tag in iterkeys(tag_fieldname_map):
fieldname, i = tag_fieldname_map[tag]
if tag in tag_map:
fieldvalue = tag_map[tag][i]
@@ -226,9 +226,9 @@ class NCXIndex(Index):
# offset
fieldvalue = tuple(tag_map[tag])
entry[fieldname] = fieldvalue
- for which, name in {3:'text', 5:'kind', 70:'description',
+ for which, name in iteritems({3:'text', 5:'kind', 70:'description',
71:'author', 72:'image_caption',
- 73:'image_attribution'}.iteritems():
+ 73:'image_attribution'}):
if tag == which:
entry[name] = self.cncx.get(fieldvalue,
default_entry[name])
diff --git a/src/calibre/ebooks/mobi/reader/index.py b/src/calibre/ebooks/mobi/reader/index.py
index 7e15c617ad..eb2ab5e31f 100644
--- a/src/calibre/ebooks/mobi/reader/index.py
+++ b/src/calibre/ebooks/mobi/reader/index.py
@@ -12,7 +12,7 @@ from collections import OrderedDict, namedtuple
from calibre.ebooks.mobi.utils import (decint, count_set_bits,
decode_string)
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, range
TagX = namedtuple('TagX', 'tag num_of_values bitmask eof')
PTagX = namedtuple('PTagX', 'tag value_count value_bytes num_of_values')
@@ -105,7 +105,7 @@ class CNCX(object): # {{{
except:
byts = raw[pos:]
r = format_bytes(byts)
- print ('CNCX entry at offset %d has unknown format %s'%(
+ print('CNCX entry at offset %d has unknown format %s'%(
pos+record_offset, r))
self.records[pos+record_offset] = r
pos = len(raw)
@@ -123,7 +123,7 @@ class CNCX(object): # {{{
__nonzero__ = __bool__
def iteritems(self):
- return self.records.iteritems()
+ return iteritems(self.records)
# }}}
@@ -216,7 +216,7 @@ def parse_index_record(table, data, control_byte_count, tags, codec,
header = parse_indx_header(data)
idxt_pos = header['start']
if data[idxt_pos:idxt_pos+4] != b'IDXT':
- print ('WARNING: Invalid INDX record')
+ print('WARNING: Invalid INDX record')
entry_count = header['count']
# loop through to build up the IDXT position starts
diff --git a/src/calibre/ebooks/mobi/reader/mobi6.py b/src/calibre/ebooks/mobi/reader/mobi6.py
index 43d575c832..c8d247a638 100644
--- a/src/calibre/ebooks/mobi/reader/mobi6.py
+++ b/src/calibre/ebooks/mobi/reader/mobi6.py
@@ -23,7 +23,7 @@ from calibre.ebooks.metadata.toc import TOC
from calibre.ebooks.mobi.reader.headers import BookHeader
from calibre.utils.img import save_cover_data_to
from calibre.utils.imghdr import what
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, unicode_type, range
class TopazError(ValueError):
@@ -500,7 +500,7 @@ class MobiReader(object):
try:
float(sz)
except ValueError:
- if sz in size_map.keys():
+ if sz in list(size_map.keys()):
attrib['size'] = size_map[sz]
elif tag.tag == 'img':
recindex = None
@@ -894,7 +894,7 @@ class MobiReader(object):
def test_mbp_regex():
- for raw, m in {
+ for raw, m in iteritems({
'':'',
'yyy':' xxxyyy',
'':'',
@@ -905,7 +905,7 @@ def test_mbp_regex():
'':'',
'':' sdf',
'xxx':'xxx',
- }.iteritems():
+ }):
ans = MobiReader.PAGE_BREAK_PAT.sub(r'\1', raw)
if ans != m:
raise Exception('%r != %r for %r'%(ans, m, raw))
diff --git a/src/calibre/ebooks/mobi/reader/mobi8.py b/src/calibre/ebooks/mobi/reader/mobi8.py
index 74b3447bd7..a1a0cfecc1 100644
--- a/src/calibre/ebooks/mobi/reader/mobi8.py
+++ b/src/calibre/ebooks/mobi/reader/mobi8.py
@@ -24,7 +24,7 @@ from calibre.ebooks.metadata.toc import TOC
from calibre.ebooks.mobi.utils import read_font_record
from calibre.ebooks.oeb.parse_utils import parse_html
from calibre.ebooks.oeb.base import XPath, XHTML, xml2text
-from polyglot.builtins import range, zip
+from polyglot.builtins import iterkeys, range, zip
from polyglot.urllib import urldefrag
Part = namedtuple('Part',
@@ -134,7 +134,7 @@ class Mobi8Reader(object):
File = namedtuple('File',
'file_number name divtbl_count start_position length')
- for i, text in enumerate(table.iterkeys()):
+ for i, text in enumerate(iterkeys(table)):
tag_map = table[text]
self.files.append(File(i, text, tag_map[1][0],
tag_map[6][0], tag_map[6][1]))
@@ -143,7 +143,7 @@ class Mobi8Reader(object):
if self.header.dividx != NULL_INDEX:
table, cncx = read_index(self.kf8_sections, self.header.dividx,
self.header.codec)
- for i, text in enumerate(table.iterkeys()):
+ for i, text in enumerate(iterkeys(table)):
tag_map = table[text]
toc_text = cncx[tag_map[2][0]]
self.elems.append(Elem(int(text), toc_text, tag_map[3][0],
@@ -156,14 +156,14 @@ class Mobi8Reader(object):
Item = namedtuple('Item',
'type title pos_fid')
- for i, ref_type in enumerate(table.iterkeys()):
+ for i, ref_type in enumerate(iterkeys(table)):
tag_map = table[ref_type]
# ref_type, ref_title, div/frag number
title = cncx[tag_map[1][0]]
fileno = None
- if 3 in tag_map.keys():
+ if 3 in list(tag_map.keys()):
fileno = tag_map[3][0]
- if 6 in tag_map.keys():
+ if 6 in list(tag_map.keys()):
fileno = tag_map[6]
self.guide.append(Item(ref_type.decode(self.header.codec),
title, fileno))
diff --git a/src/calibre/ebooks/mobi/reader/ncx.py b/src/calibre/ebooks/mobi/reader/ncx.py
index c20d795c6c..cc87ea1b07 100644
--- a/src/calibre/ebooks/mobi/reader/ncx.py
+++ b/src/calibre/ebooks/mobi/reader/ncx.py
@@ -13,6 +13,7 @@ from calibre import replace_entities
from calibre.ebooks.metadata.toc import TOC
from calibre.ebooks.mobi.reader.headers import NULL_INDEX
from calibre.ebooks.mobi.reader.index import read_index
+from polyglot.builtins import iteritems, iterkeys
tag_fieldname_map = {
1: ['pos',0],
@@ -56,13 +57,13 @@ def read_ncx(sections, index, codec):
if index != NULL_INDEX:
table, cncx = read_index(sections, index, codec)
- for num, x in enumerate(table.iteritems()):
+ for num, x in enumerate(iteritems(table)):
text, tag_map = x
entry = default_entry.copy()
entry['name'] = text
entry['num'] = num
- for tag in tag_fieldname_map.iterkeys():
+ for tag in iterkeys(tag_fieldname_map):
fieldname, i = tag_fieldname_map[tag]
if tag in tag_map:
fieldvalue = tag_map[tag][i]
@@ -71,9 +72,9 @@ def read_ncx(sections, index, codec):
# offset
fieldvalue = tuple(tag_map[tag])
entry[fieldname] = fieldvalue
- for which, name in {3:'text', 5:'kind', 70:'description',
+ for which, name in iteritems({3:'text', 5:'kind', 70:'description',
71:'author', 72:'image_caption',
- 73:'image_attribution'}.iteritems():
+ 73:'image_attribution'}):
if tag == which:
entry[name] = cncx.get(fieldvalue,
default_entry[name])
@@ -100,4 +101,3 @@ def build_toc(index_entries):
item.play_order = i
return ans
-
diff --git a/src/calibre/ebooks/mobi/utils.py b/src/calibre/ebooks/mobi/utils.py
index bd545e5ce0..6760605650 100644
--- a/src/calibre/ebooks/mobi/utils.py
+++ b/src/calibre/ebooks/mobi/utils.py
@@ -14,7 +14,7 @@ from io import BytesIO
from calibre.utils.img import save_cover_data_to, scale_image, image_to_data, image_from_data, resize_image
from calibre.utils.imghdr import what
from calibre.ebooks import normalize
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iterkeys, unicode_type, range
from tinycss.color3 import parse_color_string
IMAGE_MAX_SIZE = 10 * 1024 * 1024
@@ -589,7 +589,7 @@ class CNCX(object): # {{{
offset = 0
buf = BytesIO()
RECORD_LIMIT = 0x10000 - 1024 # kindlegen appears to use 1024, PDB limit is 0x10000
- for key in self.strings.iterkeys():
+ for key in iterkeys(self.strings):
utf8 = utf8_text(key[:self.MAX_STRING_LENGTH])
l = len(utf8)
sz_bytes = encint(l)
diff --git a/src/calibre/ebooks/mobi/writer2/indexer.py b/src/calibre/ebooks/mobi/writer2/indexer.py
index edb9abbe19..68ec0633c7 100644
--- a/src/calibre/ebooks/mobi/writer2/indexer.py
+++ b/src/calibre/ebooks/mobi/writer2/indexer.py
@@ -2,7 +2,6 @@
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import (unicode_literals, division, absolute_import,
print_function)
-from polyglot.builtins import filter, map
__license__ = 'GPL v3'
__copyright__ = '2011, Kovid Goyal '
@@ -15,7 +14,7 @@ from collections import OrderedDict, defaultdict
from calibre.ebooks.mobi.utils import (encint, encode_number_as_hex,
encode_tbs, align_block, RECORD_SIZE, CNCX as CNCX_)
-from polyglot.builtins import range
+from polyglot.builtins import filter, iteritems, iterkeys, itervalues, map, range
class CNCX(CNCX_): # {{{
@@ -109,7 +108,7 @@ class IndexEntry(object):
'author_offset': 71,
}
- RTAG_MAP = {v:k for k, v in TAG_VALUES.iteritems()} # noqa
+ RTAG_MAP = {v:k for k, v in iteritems(TAG_VALUES)} # noqa
def __init__(self, offset, label_offset):
self.offset, self.label_offset = offset, label_offset
@@ -227,7 +226,7 @@ class SecondaryIndexEntry(IndexEntry):
# The values for this index entry
# I dont know what the 5 means, it is not the number of entries
self.secondary = [5 if tag == min(
- self.INDEX_MAP.itervalues()) else 0, 0, tag]
+ itervalues(self.INDEX_MAP)) else 0, 0, tag]
@property
def tag_nums(self):
@@ -239,7 +238,7 @@ class SecondaryIndexEntry(IndexEntry):
@classmethod
def entries(cls):
- rmap = {v:k for k,v in cls.INDEX_MAP.iteritems()}
+ rmap = {v:k for k,v in iteritems(cls.INDEX_MAP)}
for tag in sorted(rmap, reverse=True):
yield cls(rmap[tag])
@@ -284,7 +283,7 @@ class TBS(object): # {{{
for x in ('starts', 'ends', 'completes'):
for idx in data[x]:
depth_map[idx.depth].append(idx)
- for l in depth_map.itervalues():
+ for l in itervalues(depth_map):
l.sort(key=lambda x:x.offset)
self.periodical_tbs(data, first, depth_map)
else:
@@ -318,7 +317,7 @@ class TBS(object): # {{{
if first_node is not None and first_node.depth > 0:
parent_section_index = (first_node.index if first_node.depth == 1 else first_node.parent_index)
else:
- parent_section_index = max(self.section_map.iterkeys())
+ parent_section_index = max(iterkeys(self.section_map))
else:
# Non terminal record
@@ -455,7 +454,7 @@ class Indexer(object): # {{{
self.is_periodical else 'book'))
self.is_flat_periodical = False
if self.is_periodical:
- periodical_node = iter(oeb.toc).next()
+ periodical_node = next(iter(oeb.toc))
sections = tuple(periodical_node)
self.is_flat_periodical = len(sections) == 1
@@ -681,7 +680,7 @@ class Indexer(object): # {{{
# }}}
def create_periodical_index(self): # {{{
- periodical_node = iter(self.oeb.toc).next()
+ periodical_node = next(iter(self.oeb.toc))
periodical_node_offset = self.serializer.body_start_offset
periodical_node_size = (self.serializer.body_end_offset -
periodical_node_offset)
diff --git a/src/calibre/ebooks/mobi/writer2/main.py b/src/calibre/ebooks/mobi/writer2/main.py
index 2bc19bfcdc..5edd7eebfe 100644
--- a/src/calibre/ebooks/mobi/writer2/main.py
+++ b/src/calibre/ebooks/mobi/writer2/main.py
@@ -19,7 +19,7 @@ from calibre.ebooks.mobi.writer2 import (PALMDOC, UNCOMPRESSED)
from calibre.ebooks.mobi.utils import (encint, encode_trailing_data,
align_block, detect_periodical, RECORD_SIZE, create_text_record)
from calibre.ebooks.mobi.writer2.indexer import Indexer
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, unicode_type, range
# Disabled as I dont care about uncrossable breaks
WRITE_UNCROSSABLE_BREAKS = False
@@ -425,10 +425,10 @@ class MobiWriter(object):
extra_data_flags |= 0b10
header_fields['extra_data_flags'] = extra_data_flags
- for k, v in {'last_text_record':'last_text_record_idx',
+ for k, v in iteritems({'last_text_record':'last_text_record_idx',
'first_non_text_record':'first_non_text_record_idx',
'ncx_index':'primary_index_record_idx',
- }.iteritems():
+ }):
header_fields[k] = getattr(self, v)
if header_fields['ncx_index'] is None:
header_fields['ncx_index'] = NULL_INDEX
diff --git a/src/calibre/ebooks/mobi/writer2/resources.py b/src/calibre/ebooks/mobi/writer2/resources.py
index ebb0d45c68..080a040102 100644
--- a/src/calibre/ebooks/mobi/writer2/resources.py
+++ b/src/calibre/ebooks/mobi/writer2/resources.py
@@ -16,7 +16,7 @@ from calibre.ebooks import generate_masthead
from calibre.ebooks.oeb.base import OEB_RASTER_IMAGES
from calibre.ptempfile import PersistentTemporaryFile
from calibre.utils.imghdr import what
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
PLACEHOLDER_GIF = b'GIF89a\x01\x00\x01\x00\xf0\x00\x00\x00\x00\x00\xff\xff\xff!\xf9\x04\x01\x00\x00\x00\x00!\xfe calibre-placeholder-gif-for-azw3\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;' # noqa
@@ -149,7 +149,7 @@ class Resources(object):
def serialize(self, records, used_images):
used_image_indices = self.used_image_indices | {
- v-1 for k, v in self.item_map.iteritems() if k in used_images}
+ v-1 for k, v in iteritems(self.item_map) if k in used_images}
for i in self.image_indices-used_image_indices:
self.records[i] = PLACEHOLDER_GIF
records.extend(self.records)
diff --git a/src/calibre/ebooks/mobi/writer8/exth.py b/src/calibre/ebooks/mobi/writer8/exth.py
index 300ccf302d..a25f1070c3 100644
--- a/src/calibre/ebooks/mobi/writer8/exth.py
+++ b/src/calibre/ebooks/mobi/writer8/exth.py
@@ -15,7 +15,7 @@ from calibre.constants import iswindows, isosx
from calibre.ebooks.mobi.utils import (utf8_text, to_base)
from calibre.utils.localization import lang_as_iso639_1
from calibre.ebooks.metadata import authors_to_sort_string
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
EXTH_CODES = {
'creator': 100,
@@ -163,7 +163,7 @@ def build_exth(metadata, prefer_author_sort=False, is_periodical=False,
else:
# Pretend to be kindlegen 1.2
vals = {204:201, 205:1, 206:2, 207:33307}
- for code, val in vals.iteritems():
+ for code, val in iteritems(vals):
exth.write(pack(b'>III', code, 12, val))
nrecs += 1
if be_kindlegen2:
diff --git a/src/calibre/ebooks/mobi/writer8/header.py b/src/calibre/ebooks/mobi/writer8/header.py
index ad77196517..6ac9f42076 100644
--- a/src/calibre/ebooks/mobi/writer8/header.py
+++ b/src/calibre/ebooks/mobi/writer8/header.py
@@ -13,6 +13,7 @@ from collections import OrderedDict
from struct import pack
from calibre.ebooks.mobi.utils import align_block
+from polyglot.builtins import iteritems
NULL = 0xffffffff
zeroes = lambda x: b'\0'*x
@@ -51,18 +52,18 @@ class Header(OrderedDict):
@property
def dynamic_fields(self):
- return tuple(k for k, v in self.iteritems() if v is None)
+ return tuple(k for k, v in iteritems(self) if v is None)
def __call__(self, **kwargs):
positions = {}
- for name, val in kwargs.iteritems():
+ for name, val in iteritems(kwargs):
if name not in self:
raise KeyError('Not a valid header field: %r'%name)
self[name] = val
buf = BytesIO()
buf.write(bytes(self.HEADER_NAME))
- for name, val in self.iteritems():
+ for name, val in iteritems(self):
val = self.format_value(name, val)
positions[name] = buf.tell()
if val is None:
@@ -72,7 +73,7 @@ class Header(OrderedDict):
val = pack(b'>'+fmt, val)
buf.write(val)
- for pos_field, field in self.POSITIONS.iteritems():
+ for pos_field, field in iteritems(self.POSITIONS):
buf.seek(positions[pos_field])
buf.write(pack(b'>I', positions[field]))
diff --git a/src/calibre/ebooks/mobi/writer8/main.py b/src/calibre/ebooks/mobi/writer8/main.py
index d66ec8b318..d31bca8b9f 100644
--- a/src/calibre/ebooks/mobi/writer8/main.py
+++ b/src/calibre/ebooks/mobi/writer8/main.py
@@ -31,7 +31,7 @@ from calibre.ebooks.mobi.writer8.index import (NCXIndex, SkelIndex,
from calibre.ebooks.mobi.writer8.mobi import KF8Book
from calibre.ebooks.mobi.writer8.tbs import apply_trailing_byte_sequences
from calibre.ebooks.mobi.writer8.toc import TOCAdder
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
XML_DOCS = OEB_DOCS | {SVG_MIME}
@@ -133,7 +133,7 @@ class KF8Writer(object):
if item.media_type in XML_DOCS:
root = self.data(item)
for tag in XPath('//h:img|//svg:image')(root):
- for attr, ref in tag.attrib.iteritems():
+ for attr, ref in iteritems(tag.attrib):
if attr.split('}')[-1].lower() in {'src', 'href'}:
tag.attrib[attr] = pointer(item, ref)
@@ -206,7 +206,7 @@ class KF8Writer(object):
extract(tag)
inlines[raw].append(repl)
- for raw, elems in inlines.iteritems():
+ for raw, elems in iteritems(inlines):
idx = to_ref(len(self.flows))
self.flows.append(raw)
for link in elems:
@@ -320,7 +320,7 @@ class KF8Writer(object):
def chunk_it_up(self):
placeholder_map = {}
- for placeholder, x in self.link_map.iteritems():
+ for placeholder, x in iteritems(self.link_map):
href, frag = x
aid = self.id_map.get(x, None)
if aid is None:
diff --git a/src/calibre/ebooks/mobi/writer8/skeleton.py b/src/calibre/ebooks/mobi/writer8/skeleton.py
index fd5f943e29..418c0858fc 100644
--- a/src/calibre/ebooks/mobi/writer8/skeleton.py
+++ b/src/calibre/ebooks/mobi/writer8/skeleton.py
@@ -17,7 +17,7 @@ from lxml import etree
from calibre.ebooks.oeb.base import XHTML_NS, extract
from calibre.constants import ispy3
from calibre.ebooks.mobi.utils import to_base
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
CHUNK_SIZE = 8192
@@ -214,7 +214,7 @@ class Chunker(object):
def remove_namespaces(self, root):
lang = None
- for attr, val in root.attrib.iteritems():
+ for attr, val in iteritems(root.attrib):
if attr.rpartition('}')[-1] == 'lang':
lang = val
@@ -248,11 +248,11 @@ class Chunker(object):
tn = tag.tag
if tn is not None:
tn = tn.rpartition('}')[-1]
- attrib = {k.rpartition('}')[-1]:v for k, v in tag.attrib.iteritems()}
+ attrib = {k.rpartition('}')[-1]:v for k, v in iteritems(tag.attrib)}
try:
elem = nroot.makeelement(tn, attrib=attrib)
except ValueError:
- attrib = {k:v for k, v in attrib.iteritems() if ':' not in k}
+ attrib = {k:v for k, v in iteritems(attrib) if ':' not in k}
elem = nroot.makeelement(tn, attrib=attrib)
elem.text = tag.text
elem.tail = tag.tail
@@ -402,7 +402,7 @@ class Chunker(object):
return bytes(':off:'.join((pos, fid)))
placeholder_map = {bytes(k):to_placeholder(v) for k, v in
- self.placeholder_map.iteritems()}
+ iteritems(self.placeholder_map)}
# Now update the links
def sub(match):
diff --git a/src/calibre/ebooks/mobi/writer8/tbs.py b/src/calibre/ebooks/mobi/writer8/tbs.py
index f8becc3f8e..50a7f60a3c 100644
--- a/src/calibre/ebooks/mobi/writer8/tbs.py
+++ b/src/calibre/ebooks/mobi/writer8/tbs.py
@@ -23,6 +23,7 @@ from operator import attrgetter
from calibre.ebooks.mobi.utils import (encode_trailing_data,
encode_tbs)
+from polyglot.builtins import iteritems, itervalues
Entry = namedtuple('IndexEntry', 'index start length depth parent '
'first_child last_child title action start_offset length_offset '
@@ -122,7 +123,7 @@ def encode_strands_as_sequences(strands, tbs_type=8):
max_length_offset = 0
first_entry = None
for strand in strands:
- for entries in strand.itervalues():
+ for entries in itervalues(strand):
for entry in entries:
if first_entry is None:
first_entry = entry
@@ -131,7 +132,7 @@ def encode_strands_as_sequences(strands, tbs_type=8):
for strand in strands:
strand_seqs = []
- for depth, entries in strand.iteritems():
+ for depth, entries in iteritems(strand):
extra = {}
if entries[-1].action == 'spans':
extra[0b1] = 0
@@ -207,9 +208,7 @@ def apply_trailing_byte_sequences(index_table, records, text_record_lengths):
except NegativeStrandIndex:
rmap = calculate_all_tbs(indexing_data, tbs_type=5)
- for i, tbs_bytes in rmap.iteritems():
+ for i, tbs_bytes in iteritems(rmap):
records[i] += encode_trailing_data(tbs_bytes)
return True
-
-
diff --git a/src/calibre/ebooks/oeb/base.py b/src/calibre/ebooks/oeb/base.py
index b6186b4fed..f5aee08109 100644
--- a/src/calibre/ebooks/oeb/base.py
+++ b/src/calibre/ebooks/oeb/base.py
@@ -20,7 +20,7 @@ from calibre.ebooks.oeb.parse_utils import (barename, XHTML_NS, RECOVER_PARSER,
namespace, XHTML, parse_html, NotHTML)
from calibre.utils.cleantext import clean_xml_chars
from calibre.utils.short_uuid import uuid4
-from polyglot.builtins import unicode_type, string_or_bytes, range
+from polyglot.builtins import iteritems, unicode_type, string_or_bytes, range
from polyglot.urllib import unquote, urldefrag, urljoin, urlparse, urlunparse
XML_NS = 'http://www.w3.org/XML/1998/namespace'
@@ -1479,7 +1479,7 @@ class Guide(object):
return self.refs.pop(type, None)
def remove_by_href(self, href):
- remove = [r for r, i in self.refs.iteritems() if i.href == href]
+ remove = [r for r, i in iteritems(self.refs) if i.href == href]
for r in remove:
self.remove(r)
@@ -1782,7 +1782,7 @@ class PageList(object):
for page in self.pages:
id = page.id or uuid_id()
type = page.type
- value = str(values[type].next())
+ value = str(next(values[type]))
attrib = {'id': id, 'value': value, 'type': type, 'playOrder': '0'}
if page.klass:
attrib['class'] = page.klass
diff --git a/src/calibre/ebooks/oeb/display/webview.py b/src/calibre/ebooks/oeb/display/webview.py
index c4403e7b41..4338f69baf 100644
--- a/src/calibre/ebooks/oeb/display/webview.py
+++ b/src/calibre/ebooks/oeb/display/webview.py
@@ -10,6 +10,7 @@ __docformat__ = 'restructuredtext en'
import re
from calibre import guess_type
+from polyglot.builtins import iteritems
class EntityDeclarationProcessor(object): # {{{
@@ -21,7 +22,7 @@ class EntityDeclarationProcessor(object): # {{{
if len(tokens) > 1:
self.declared_entities[tokens[0].strip()] = tokens[1].strip().replace('"', '')
self.processed_html = html
- for key, val in self.declared_entities.iteritems():
+ for key, val in iteritems(self.declared_entities):
self.processed_html = self.processed_html.replace('&%s;'%key, val)
# }}}
diff --git a/src/calibre/ebooks/oeb/normalize_css.py b/src/calibre/ebooks/oeb/normalize_css.py
index 02c377974c..8672abb5cc 100644
--- a/src/calibre/ebooks/oeb/normalize_css.py
+++ b/src/calibre/ebooks/oeb/normalize_css.py
@@ -7,7 +7,7 @@ __license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal '
import numbers
-from polyglot.builtins import zip, string_or_bytes
+from polyglot.builtins import iteritems, zip, string_or_bytes
from functools import wraps
from css_parser.css import PropertyValue
@@ -140,7 +140,7 @@ def normalize_border(name, cssvalue):
style = normalizers['border-' + EDGES[0]]('border-' + EDGES[0], cssvalue)
vals = style.copy()
for edge in EDGES[1:]:
- style.update({k.replace(EDGES[0], edge):v for k, v in vals.iteritems()})
+ style.update({k.replace(EDGES[0], edge):v for k, v in iteritems(vals)})
return style
@@ -254,7 +254,7 @@ def condense_rule(style):
if prop.name and prop.name.startswith(x):
expanded[x].append(prop)
break
- for prefix, vals in expanded.iteritems():
+ for prefix, vals in iteritems(expanded):
if len(vals) > 1 and {x.priority for x in vals} == {''}:
condensers[prefix[:-1]](style, vals)
@@ -280,7 +280,7 @@ def test_normalization(return_tests=False): # {{{
ans.update(expected)
return ans
- for raw, expected in {
+ for raw, expected in iteritems({
'some_font': {'font-family':'some_font'}, 'inherit':{k:'inherit' for k in font_composition},
'1.2pt/1.4 A_Font': {'font-family':'A_Font', 'font-size':'1.2pt', 'line-height':'1.4'},
'bad font': {'font-family':'"bad font"'}, '10% serif': {'font-family':'serif', 'font-size':'10%'},
@@ -291,7 +291,7 @@ def test_normalization(return_tests=False): # {{{
{'font-family':'serif', 'font-weight':'bold', 'font-style':'italic', 'font-size':'larger',
'line-height':'normal', 'font-variant':'small-caps'},
'2em A B': {'font-family': '"A B"', 'font-size': '2em'},
- }.iteritems():
+ }):
val = tuple(parseStyle('font: %s' % raw, validate=False))[0].cssValue
style = normalizers['font']('font', val)
self.assertDictEqual(font_dict(expected), style, raw)
@@ -299,7 +299,7 @@ def test_normalization(return_tests=False): # {{{
def test_border_normalization(self):
def border_edge_dict(expected, edge='right'):
ans = {'border-%s-%s' % (edge, x): DEFAULTS['border-%s-%s' % (edge, x)] for x in ('style', 'width', 'color')}
- for x, v in expected.iteritems():
+ for x, v in iteritems(expected):
ans['border-%s-%s' % (edge, x)] = v
return ans
@@ -315,39 +315,39 @@ def test_normalization(return_tests=False): # {{{
ans['border-%s-%s' % (edge, val)] = expected
return ans
- for raw, expected in {
+ for raw, expected in iteritems({
'solid 1px red': {'color':'red', 'width':'1px', 'style':'solid'},
'1px': {'width': '1px'}, '#aaa': {'color': '#aaa'},
'2em groove': {'width':'2em', 'style':'groove'},
- }.iteritems():
+ }):
for edge in EDGES:
br = 'border-%s' % edge
val = tuple(parseStyle('%s: %s' % (br, raw), validate=False))[0].cssValue
self.assertDictEqual(border_edge_dict(expected, edge), normalizers[br](br, val))
- for raw, expected in {
+ for raw, expected in iteritems({
'solid 1px red': {'color':'red', 'width':'1px', 'style':'solid'},
'1px': {'width': '1px'}, '#aaa': {'color': '#aaa'},
'thin groove': {'width':'thin', 'style':'groove'},
- }.iteritems():
+ }):
val = tuple(parseStyle('%s: %s' % ('border', raw), validate=False))[0].cssValue
self.assertDictEqual(border_dict(expected), normalizers['border']('border', val))
- for name, val in {
+ for name, val in iteritems({
'width': '10%', 'color': 'rgb(0, 1, 1)', 'style': 'double',
- }.iteritems():
+ }):
cval = tuple(parseStyle('border-%s: %s' % (name, val), validate=False))[0].cssValue
self.assertDictEqual(border_val_dict(val, name), normalizers['border-'+name]('border-'+name, cval))
def test_edge_normalization(self):
def edge_dict(prefix, expected):
return {'%s-%s' % (prefix, edge) : x for edge, x in zip(EDGES, expected)}
- for raw, expected in {
+ for raw, expected in iteritems({
'2px': ('2px', '2px', '2px', '2px'),
'1em 2em': ('1em', '2em', '1em', '2em'),
'1em 2em 3em': ('1em', '2em', '3em', '2em'),
'1 2 3 4': ('1', '2', '3', '4'),
- }.iteritems():
+ }):
for prefix in ('margin', 'padding'):
cval = tuple(parseStyle('%s: %s' % (prefix, raw), validate=False))[0].cssValue
self.assertDictEqual(edge_dict(prefix, expected), normalizers[prefix](prefix, cval))
@@ -355,14 +355,14 @@ def test_normalization(return_tests=False): # {{{
def test_list_style_normalization(self):
def ls_dict(expected):
ans = {'list-style-%s' % x : DEFAULTS['list-style-%s' % x] for x in ('type', 'image', 'position')}
- for k, v in expected.iteritems():
+ for k, v in iteritems(expected):
ans['list-style-%s' % k] = v
return ans
- for raw, expected in {
+ for raw, expected in iteritems({
'url(http://www.example.com/images/list.png)': {'image': 'url(http://www.example.com/images/list.png)'},
'inside square': {'position':'inside', 'type':'square'},
'upper-roman url(img) outside': {'position':'outside', 'type':'upper-roman', 'image':'url(img)'},
- }.iteritems():
+ }):
cval = tuple(parseStyle('list-style: %s' % raw, validate=False))[0].cssValue
self.assertDictEqual(ls_dict(expected), normalizers['list-style']('list-style', cval))
@@ -382,7 +382,7 @@ def test_normalization(return_tests=False): # {{{
ae({'list-style', 'list-style-image', 'list-style-type', 'list-style-position'}, normalize_filter_css({'list-style'}))
def test_edge_condensation(self):
- for s, v in {
+ for s, v in iteritems({
(1, 1, 3) : None,
(1, 2, 3, 4) : '2pt 3pt 4pt 1pt',
(1, 2, 3, 2) : '2pt 3pt 2pt 1pt',
@@ -391,10 +391,10 @@ def test_normalization(return_tests=False): # {{{
(1, 1, 1, 1) : '1pt',
('2%', '2%', '2%', '2%') : '2%',
tuple('0 0 0 0'.split()) : '0',
- }.iteritems():
+ }):
for prefix in ('margin', 'padding'):
css = {'%s-%s' % (prefix, x) : str(y)+'pt' if isinstance(y, numbers.Number) else y for x, y in zip(('left', 'top', 'right', 'bottom'), s)}
- css = '; '.join(('%s:%s' % (k, v) for k, v in css.iteritems()))
+ css = '; '.join(('%s:%s' % (k, v) for k, v in iteritems(css)))
style = parseStyle(css)
condense_rule(style)
val = getattr(style.getProperty(prefix), 'value', None)
diff --git a/src/calibre/ebooks/oeb/parse_utils.py b/src/calibre/ebooks/oeb/parse_utils.py
index 28bb10932a..86874a93ba 100644
--- a/src/calibre/ebooks/oeb/parse_utils.py
+++ b/src/calibre/ebooks/oeb/parse_utils.py
@@ -14,7 +14,7 @@ from lxml import etree, html
from calibre import xml_replace_entities, force_unicode
from calibre.constants import filesystem_encoding
from calibre.ebooks.chardet import xml_to_unicode, strip_encoding_declarations
-from polyglot.builtins import unicode_type, string_or_bytes
+from polyglot.builtins import iteritems, itervalues, unicode_type, string_or_bytes
RECOVER_PARSER = etree.XMLParser(recover=True, no_network=True)
XHTML_NS = 'http://www.w3.org/1999/xhtml'
@@ -144,8 +144,8 @@ def clean_word_doc(data, log):
def ensure_namespace_prefixes(node, nsmap):
- namespace_uris = frozenset(nsmap.itervalues())
- fnsmap = {k:v for k, v in node.nsmap.iteritems() if v not in namespace_uris}
+ namespace_uris = frozenset(itervalues(nsmap))
+ fnsmap = {k:v for k, v in iteritems(node.nsmap) if v not in namespace_uris}
fnsmap.update(nsmap)
if fnsmap != dict(node.nsmap):
node = clone_element(node, nsmap=fnsmap, in_context=False)
@@ -201,7 +201,7 @@ def parse_html(data, log=None, decoder=None, preprocessor=None,
val = val[1:-1]
user_entities[match.group(1)] = val
if user_entities:
- pat = re.compile(r'&(%s);'%('|'.join(user_entities.keys())))
+ pat = re.compile(r'&(%s);'%('|'.join(list(user_entities.keys()))))
data = pat.sub(lambda m:user_entities[m.group(1)], data)
if preprocessor is not None:
@@ -241,7 +241,7 @@ def parse_html(data, log=None, decoder=None, preprocessor=None,
for x in data.iterdescendants():
try:
x.tag = x.tag.lower()
- for key, val in list(x.attrib.iteritems()):
+ for key, val in list(iteritems(x.attrib)):
del x.attrib[key]
key = key.lower()
x.attrib[key] = val
diff --git a/src/calibre/ebooks/oeb/polish/cascade.py b/src/calibre/ebooks/oeb/polish/cascade.py
index e0f5d1602a..00fa8dd837 100644
--- a/src/calibre/ebooks/oeb/polish/cascade.py
+++ b/src/calibre/ebooks/oeb/polish/cascade.py
@@ -19,6 +19,7 @@ from calibre.ebooks.oeb.base import OEB_STYLES, XHTML
from calibre.ebooks.oeb.normalize_css import normalizers, DEFAULTS
from calibre.ebooks.oeb.stylizer import media_ok, INHERITED
from tinycss.fonts3 import serialize_font_family, parse_font_family
+from polyglot.builtins import iteritems, itervalues
_html_css_stylesheet = None
@@ -99,7 +100,7 @@ def iterdeclaration(decl):
if n is None:
yield p
else:
- for k, v in n(p.name, p.propertyValue).iteritems():
+ for k, v in iteritems(n(p.name, p.propertyValue)):
yield Property(k, v, p.literalpriority)
@@ -156,7 +157,7 @@ def resolve_pseudo_declarations(decls):
groups = defaultdict(list)
for d in decls:
groups[d.pseudo_element].append(d)
- return {k:resolve_declarations(v) for k, v in groups.iteritems()}
+ return {k:resolve_declarations(v) for k, v in iteritems(groups)}
def resolve_styles(container, name, select=None, sheet_callback=None):
@@ -218,11 +219,11 @@ def resolve_styles(container, name, select=None, sheet_callback=None):
style_map[elem].append(StyleDeclaration(Specificity(1, 0, 0, 0, 0), normalize_style_declaration(style, name), None))
for l in (style_map, pseudo_style_map):
- for x in l.itervalues():
+ for x in itervalues(l):
x.sort(key=itemgetter(0), reverse=True)
- style_map = {elem:resolve_declarations(x) for elem, x in style_map.iteritems()}
- pseudo_style_map = {elem:resolve_pseudo_declarations(x) for elem, x in pseudo_style_map.iteritems()}
+ style_map = {elem:resolve_declarations(x) for elem, x in iteritems(style_map)}
+ pseudo_style_map = {elem:resolve_pseudo_declarations(x) for elem, x in iteritems(pseudo_style_map)}
return partial(resolve_property, style_map), partial(resolve_pseudo_property, style_map, pseudo_style_map), select
@@ -234,7 +235,7 @@ def defvals():
global _defvals
if _defvals is None:
u = type('')
- _defvals = {k:Values(Property(k, u(val)).propertyValue) for k, val in DEFAULTS.iteritems()}
+ _defvals = {k:Values(Property(k, u(val)).propertyValue) for k, val in iteritems(DEFAULTS)}
return _defvals
diff --git a/src/calibre/ebooks/oeb/polish/check/fonts.py b/src/calibre/ebooks/oeb/polish/check/fonts.py
index c8d23b0d02..667820af61 100644
--- a/src/calibre/ebooks/oeb/polish/check/fonts.py
+++ b/src/calibre/ebooks/oeb/polish/check/fonts.py
@@ -16,6 +16,7 @@ from calibre.ebooks.oeb.polish.pretty import pretty_script_or_style
from calibre.ebooks.oeb.polish.fonts import change_font_in_declaration
from calibre.utils.fonts.utils import get_all_font_names, is_font_embeddable, UnsupportedFont
from tinycss.fonts3 import parse_font_family
+from polyglot.builtins import iteritems
class InvalidFont(BaseError):
@@ -58,7 +59,7 @@ class FontAliasing(BaseError):
def __call__(self, container):
changed = False
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_STYLES:
sheet = container.parsed(name)
if fix_sheet(sheet, self.css_name, self.font_name):
@@ -85,7 +86,7 @@ class FontAliasing(BaseError):
def check_fonts(container):
font_map = {}
errors = []
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_FONTS:
raw = container.raw_data(name)
try:
@@ -102,7 +103,7 @@ def check_fonts(container):
errors.append(NotEmbeddable(name, fs_type))
sheets = []
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_STYLES:
try:
sheets.append((name, container.parsed(name), None))
diff --git a/src/calibre/ebooks/oeb/polish/check/links.py b/src/calibre/ebooks/oeb/polish/check/links.py
index b581bc6418..610585677e 100644
--- a/src/calibre/ebooks/oeb/polish/check/links.py
+++ b/src/calibre/ebooks/oeb/polish/check/links.py
@@ -18,7 +18,7 @@ from calibre.ebooks.oeb.polish.replace import remove_links_to
from calibre.ebooks.oeb.polish.cover import get_raster_cover_name
from calibre.ebooks.oeb.polish.utils import guess_type, actual_case_for_name, corrected_case_for_name
from calibre.ebooks.oeb.polish.check.base import BaseError, WARN, INFO
-from polyglot.builtins import map, range
+from polyglot.builtins import iteritems, map, range
from polyglot.urllib import urlparse
from polyglot.queue import Queue, Empty
@@ -132,7 +132,7 @@ class UnreferencedDoc(UnreferencedResource):
def __call__(self, container):
from calibre.ebooks.oeb.base import OPF
- rmap = {v:k for k, v in container.manifest_id_map.iteritems()}
+ rmap = {v:k for k, v in iteritems(container.manifest_id_map)}
if self.name in rmap:
manifest_id = rmap[self.name]
else:
@@ -164,7 +164,7 @@ class Unmanifested(BadLink):
if self.file_action == 'remove':
container.remove_item(self.name)
else:
- rmap = {v:k for k, v in container.manifest_id_map.iteritems()}
+ rmap = {v:k for k, v in iteritems(container.manifest_id_map)}
if self.name not in rmap:
container.add_name_to_manifest(self.name)
return True
@@ -246,7 +246,7 @@ class MimetypeMismatch(BaseError):
def check_mimetypes(container):
errors = []
a = errors.append
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
gt = container.guess_type(name)
if mt != gt:
if mt == 'application/oebps-page-map+xml' and name.lower().endswith('.xml'):
@@ -284,7 +284,7 @@ def check_link_destinations(container):
dest_map = {}
opf_type = guess_type('a.opf')
ncx_type = guess_type('a.ncx')
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_DOCS:
for a in container.parsed(name).xpath('//*[local-name()="a" and @href]'):
href = a.get('href')
@@ -315,7 +315,7 @@ def check_links(container):
x = x[1:]
return x
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_DOCS or mt in OEB_STYLES or mt in xml_types:
for href, lnum, col in container.iterlinks(name):
if not href:
@@ -366,7 +366,7 @@ def check_links(container):
cover_name = container.guide_type_map.get('cover', None)
nav_items = frozenset(container.manifest_items_with_property('nav'))
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_STYLES and name not in spine_styles:
a(UnreferencedResource(name))
elif mt in OEB_DOCS and name not in spine_docs and name not in nav_items:
@@ -379,7 +379,7 @@ def check_links(container):
continue
unreferenced.add(name)
- manifest_names = set(container.manifest_id_map.itervalues())
+ manifest_names = set(itervalues(container.manifest_id_map))
for name in container.mime_map:
if name not in manifest_names and not container.ok_to_be_unmanifested(name):
a(Unmanifested(name, unreferenced=name in unreferenced))
@@ -401,7 +401,7 @@ def get_html_ids(raw_data):
def check_external_links(container, progress_callback=(lambda num, total:None), check_anchors=True):
progress_callback(0, 0)
external_links = defaultdict(list)
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_DOCS or mt in OEB_STYLES:
for href, lnum, col in container.iterlinks(name):
purl = urlparse(href)
@@ -411,7 +411,7 @@ def check_external_links(container, progress_callback=(lambda num, total:None),
return []
items = Queue()
ans = []
- tuple(map(items.put, external_links.iteritems()))
+ tuple(map(items.put, iteritems(external_links)))
progress_callback(0, len(external_links))
done = []
downloaded_html_ids = {}
diff --git a/src/calibre/ebooks/oeb/polish/check/main.py b/src/calibre/ebooks/oeb/polish/check/main.py
index 66017e312e..eb9ff10571 100644
--- a/src/calibre/ebooks/oeb/polish/check/main.py
+++ b/src/calibre/ebooks/oeb/polish/check/main.py
@@ -6,7 +6,7 @@ from __future__ import (unicode_literals, division, absolute_import,
__license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal '
-from polyglot.builtins import map
+from polyglot.builtins import iteritems, map
from calibre.ebooks.oeb.base import OEB_DOCS, OEB_STYLES
from calibre.ebooks.oeb.polish.utils import guess_type
@@ -29,7 +29,7 @@ def run_checks(container):
# Check parsing
xml_items, html_items, raster_images, stylesheets = [], [], [], []
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
items = None
if mt in XML_TYPES:
items = xml_items
diff --git a/src/calibre/ebooks/oeb/polish/check/opf.py b/src/calibre/ebooks/oeb/polish/check/opf.py
index 4e9a874b41..76f8418b4e 100644
--- a/src/calibre/ebooks/oeb/polish/check/opf.py
+++ b/src/calibre/ebooks/oeb/polish/check/opf.py
@@ -13,6 +13,7 @@ from calibre.ebooks.oeb.polish.check.base import BaseError, WARN
from calibre.ebooks.oeb.polish.toc import find_existing_nav_toc, parse_nav
from calibre.ebooks.oeb.polish.utils import guess_type
from calibre.ebooks.oeb.base import OPF, OPF2_NS, DC, DC11_NS, XHTML_MIME
+from polyglot.builtins import iteritems
class MissingSection(BaseError):
@@ -315,7 +316,7 @@ def check_opf(container):
dups[href].append(item.sourceline)
else:
seen[href] = item.sourceline
- errors.extend(DuplicateHref(container.opf_name, eid, locs) for eid, locs in dups.iteritems())
+ errors.extend(DuplicateHref(container.opf_name, eid, locs) for eid, locs in iteritems(dups))
seen, dups = {}, {}
for item in container.opf_xpath('/opf:package/opf:spine/opf:itemref[@idref]'):
@@ -326,7 +327,7 @@ def check_opf(container):
dups[ref].append(item.sourceline)
else:
seen[ref] = item.sourceline
- errors.extend(DuplicateHref(container.opf_name, eid, locs, for_spine=True) for eid, locs in dups.iteritems())
+ errors.extend(DuplicateHref(container.opf_name, eid, locs, for_spine=True) for eid, locs in iteritems(dups))
spine = container.opf_xpath('/opf:package/opf:spine[@toc]')
if spine:
@@ -345,7 +346,7 @@ def check_opf(container):
ncx = container.manifest_type_map.get(guess_type('a.ncx'))
if ncx:
ncx_name = ncx[0]
- rmap = {v:k for k, v in container.manifest_id_map.iteritems()}
+ rmap = {v:k for k, v in iteritems(container.manifest_id_map)}
ncx_id = rmap.get(ncx_name)
if ncx_id:
errors.append(MissingNCXRef(container.opf_name, spine.sourceline, ncx_id))
diff --git a/src/calibre/ebooks/oeb/polish/check/parsing.py b/src/calibre/ebooks/oeb/polish/check/parsing.py
index 1ffcfd68da..1ef9fef430 100644
--- a/src/calibre/ebooks/oeb/polish/check/parsing.py
+++ b/src/calibre/ebooks/oeb/polish/check/parsing.py
@@ -18,7 +18,7 @@ from calibre.ebooks.oeb.polish.pretty import pretty_script_or_style as fix_style
from calibre.ebooks.oeb.polish.utils import PositionFinder, guess_type
from calibre.ebooks.oeb.polish.check.base import BaseError, WARN, ERROR, INFO
from calibre.ebooks.oeb.base import OEB_DOCS, XHTML_NS, urlquote, URL_SAFE, XHTML
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
HTML_ENTITTIES = frozenset(html5_entities)
XML_ENTITIES = {'lt', 'gt', 'amp', 'apos', 'quot'}
@@ -103,7 +103,7 @@ class NamedEntities(BaseError):
changed = False
from calibre.ebooks.oeb.polish.check.main import XML_TYPES
check_types = XML_TYPES | OEB_DOCS
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in check_types:
raw = container.raw_data(name)
nraw = replace_pat.sub(lambda m:html5_entities[m.group(1)], raw)
@@ -496,7 +496,7 @@ valid_id = re.compile(r'^[a-zA-Z][a-zA-Z0-9_:.-]*$')
def check_ids(container):
errors = []
mts = set(OEB_DOCS) | {guess_type('a.opf'), guess_type('a.ncx')}
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in mts:
root = container.parsed(name)
seen_ids = {}
@@ -511,13 +511,13 @@ def check_ids(container):
seen_ids[eid] = elem.sourceline
if eid and valid_id.match(eid) is None:
errors.append(InvalidId(name, elem.sourceline, eid))
- errors.extend(DuplicateId(name, eid, locs) for eid, locs in dups.iteritems())
+ errors.extend(DuplicateId(name, eid, locs) for eid, locs in iteritems(dups))
return errors
def check_markup(container):
errors = []
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_DOCS:
lines = []
root = container.parsed(name)
diff --git a/src/calibre/ebooks/oeb/polish/container.py b/src/calibre/ebooks/oeb/polish/container.py
index da845d971f..ba4ce390a2 100644
--- a/src/calibre/ebooks/oeb/polish/container.py
+++ b/src/calibre/ebooks/oeb/polish/container.py
@@ -14,7 +14,7 @@ import time
import unicodedata
import uuid
from collections import defaultdict
-from polyglot.builtins import unicode_type, zip
+from polyglot.builtins import iteritems, unicode_type, zip
from io import BytesIO
from itertools import count
@@ -311,7 +311,7 @@ class Container(ContainerBase): # {{{
'tweak_mode': self.tweak_mode,
'name_path_map': {
name:os.path.join(dest_dir, os.path.relpath(path, self.root))
- for name, path in self.name_path_map.iteritems()}
+ for name, path in iteritems(self.name_path_map)}
}
def add_name_to_manifest(self, name, process_manifest_item=None):
@@ -658,7 +658,7 @@ class Container(ContainerBase): # {{{
for item in self.opf_xpath('//opf:manifest/opf:item[@href and @media-type]'):
ans[item.get('media-type').lower()].append(self.href_to_name(
item.get('href'), self.opf_name))
- return {mt:tuple(v) for mt, v in ans.iteritems()}
+ return {mt:tuple(v) for mt, v in iteritems(ans)}
def manifest_items_with_property(self, property_name):
' All manifest items that have the specified property '
@@ -676,7 +676,7 @@ class Container(ContainerBase): # {{{
predicate = predicate.__eq__
elif hasattr(predicate, '__contains__'):
predicate = predicate.__contains__
- for mt, names in self.manifest_type_map.iteritems():
+ for mt, names in iteritems(self.manifest_type_map):
if predicate(mt):
for name in names:
yield name
@@ -798,7 +798,7 @@ class Container(ContainerBase): # {{{
the form (name, linear). Will raise an error if one of the names is not
present in the manifest. '''
imap = self.manifest_id_map
- imap = {name:item_id for item_id, name in imap.iteritems()}
+ imap = {name:item_id for item_id, name in iteritems(imap)}
items = [item for item, name, linear in self.spine_iter]
tail, last_tail = (items[0].tail, items[-1].tail) if items else ('\n ', '\n ')
map(self.remove_from_xml, items)
@@ -1062,7 +1062,7 @@ class Container(ContainerBase): # {{{
if set(self.name_path_map) != set(other.name_path_map):
return 'Set of files is not the same'
mismatches = []
- for name, path in self.name_path_map.iteritems():
+ for name, path in iteritems(self.name_path_map):
opath = other.name_path_map[name]
with lopen(path, 'rb') as f1, lopen(opath, 'rb') as f2:
if f1.read() != f2.read():
@@ -1266,7 +1266,7 @@ class EpubContainer(Container):
return
package_id = raw_unique_identifier = idpf_key = None
- for attrib, val in self.opf.attrib.iteritems():
+ for attrib, val in iteritems(self.opf.attrib):
if attrib.endswith('unique-identifier'):
package_id = val
break
@@ -1295,7 +1295,7 @@ class EpubContainer(Container):
self.log.exception('Failed to parse obfuscation key')
key = None
- for font, alg in fonts.iteritems():
+ for font, alg in iteritems(fonts):
tkey = key if alg == ADOBE_OBFUSCATION else idpf_key
if not tkey:
raise ObfuscationKeyMissing('Failed to find obfuscation key')
@@ -1362,7 +1362,7 @@ class EpubContainer(Container):
with lopen(join(self.root, 'mimetype'), 'wb') as f:
f.write(guess_type('a.epub'))
zip_rebuilder(self.root, outpath)
- for name, data in restore_fonts.iteritems():
+ for name, data in iteritems(restore_fonts):
with self.open(name, 'wb') as f:
f.write(data)
@@ -1530,7 +1530,7 @@ def test_roundtrip():
ebook3 = get_container(p.name)
diff = ebook3.compare_to(ebook2)
if diff is not None:
- print (diff)
+ print(diff)
if __name__ == '__main__':
diff --git a/src/calibre/ebooks/oeb/polish/cover.py b/src/calibre/ebooks/oeb/polish/cover.py
index cb83820611..941ef71d17 100644
--- a/src/calibre/ebooks/oeb/polish/cover.py
+++ b/src/calibre/ebooks/oeb/polish/cover.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:fdm=marker:ai
from __future__ import (unicode_literals, division, absolute_import,
print_function)
@@ -12,6 +11,7 @@ import shutil, re, os
from calibre.ebooks.oeb.base import OPF, OEB_DOCS, XPath, XLINK, xml2text
from calibre.ebooks.oeb.polish.replace import replace_links, get_recommended_folders
from calibre.utils.imghdr import identify
+from polyglot.builtins import iteritems
def set_azw3_cover(container, cover_path, report, options=None):
@@ -135,7 +135,7 @@ def find_cover_image2(container, strict=False):
# First look for a guide item with type == 'cover'
guide_type_map = container.guide_type_map
- for ref_type, name in guide_type_map.iteritems():
+ for ref_type, name in iteritems(guide_type_map):
if ref_type.lower() == 'cover' and is_raster_image(mm.get(name, None)):
return name
@@ -144,7 +144,7 @@ def find_cover_image2(container, strict=False):
# Find the largest image from all possible guide cover items
largest_cover = (None, 0)
- for ref_type, name in guide_type_map.iteritems():
+ for ref_type, name in iteritems(guide_type_map):
if ref_type.lower() in COVER_TYPES and is_raster_image(mm.get(name, None)):
path = container.name_path_map.get(name, None)
if path:
@@ -188,7 +188,7 @@ def get_guides(container):
def mark_as_cover_epub(container, name):
- mmap = {v:k for k, v in container.manifest_id_map.iteritems()}
+ mmap = {v:k for k, v in iteritems(container.manifest_id_map)}
if name not in mmap:
raise ValueError('Cannot mark %s as cover as it is not in manifest' % name)
mid = mmap[name]
@@ -257,7 +257,7 @@ def find_cover_page(container):
mm = container.mime_map
if ver.major < 3:
guide_type_map = container.guide_type_map
- for ref_type, name in guide_type_map.iteritems():
+ for ref_type, name in iteritems(guide_type_map):
if ref_type.lower() == 'cover' and mm.get(name, '').lower() in OEB_DOCS:
return name
else:
@@ -341,7 +341,7 @@ def create_epub_cover(container, cover_path, existing_image, options=None):
if existing_image:
raster_cover = existing_image
- manifest_id = {v:k for k, v in container.manifest_id_map.iteritems()}[existing_image]
+ manifest_id = {v:k for k, v in iteritems(container.manifest_id_map)}[existing_image]
raster_cover_item = container.opf_xpath('//opf:manifest/*[@id="%s"]' % manifest_id)[0]
else:
folder = recommended_folders[cname]
@@ -503,9 +503,9 @@ def set_epub_cover(container, cover_path, report, options=None):
report(_('Cover updated') if updated else _('Cover inserted'))
# Replace links to the old cover image/cover page
- link_sub = {s:d for s, d in {
+ link_sub = {s:d for s, d in iteritems({
cover_page:titlepage, wrapped_image:raster_cover,
- cover_image:raster_cover, extra_cover_page:titlepage}.iteritems()
+ cover_image:raster_cover, extra_cover_page:titlepage})
if s is not None and s != d}
if link_sub:
replace_links(container, link_sub, frag_map=lambda x, y:None)
diff --git a/src/calibre/ebooks/oeb/polish/css.py b/src/calibre/ebooks/oeb/polish/css.py
index ba92f610b1..2d52bc9af4 100644
--- a/src/calibre/ebooks/oeb/polish/css.py
+++ b/src/calibre/ebooks/oeb/polish/css.py
@@ -18,7 +18,7 @@ from calibre.ebooks.oeb.normalize_css import normalize_filter_css, normalizers
from calibre.ebooks.oeb.polish.pretty import pretty_script_or_style, pretty_xml_tree, serialize
from calibre.utils.icu import numeric_sort_key
from css_selectors import Select, SelectorError
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, itervalues, unicode_type
def filter_used_rules(rules, log, select):
@@ -64,7 +64,7 @@ def merge_identical_selectors(sheet):
for rule in sheet.cssRules.rulesOfType(CSSRule.STYLE_RULE):
selector_map[rule.selectorText].append(rule)
remove = []
- for rule_group in selector_map.itervalues():
+ for rule_group in itervalues(selector_map):
if len(rule_group) > 1:
for i in range(1, len(rule_group)):
merge_declarations(rule_group[0].style, rule_group[i].style)
@@ -89,23 +89,23 @@ def remove_unused_css(container, report=None, remove_unused_classes=False, merge
return container.parsed(name)
except TypeError:
pass
- sheets = {name:safe_parse(name) for name, mt in container.mime_map.iteritems() if mt in OEB_STYLES}
- sheets = {k:v for k, v in sheets.iteritems() if v is not None}
+ sheets = {name:safe_parse(name) for name, mt in iteritems(container.mime_map) if mt in OEB_STYLES}
+ sheets = {k:v for k, v in iteritems(sheets) if v is not None}
num_merged = 0
if merge_rules:
- for name, sheet in sheets.iteritems():
+ for name, sheet in iteritems(sheets):
num = merge_identical_selectors(sheet)
if num:
container.dirty(name)
num_merged += num
import_map = {name:get_imported_sheets(name, container, sheets) for name in sheets}
if remove_unused_classes:
- class_map = {name:{icu_lower(x) for x in classes_in_rule_list(sheet.cssRules)} for name, sheet in sheets.iteritems()}
- style_rules = {name:tuple(sheet.cssRules.rulesOfType(CSSRule.STYLE_RULE)) for name, sheet in sheets.iteritems()}
+ class_map = {name:{icu_lower(x) for x in classes_in_rule_list(sheet.cssRules)} for name, sheet in iteritems(sheets)}
+ style_rules = {name:tuple(sheet.cssRules.rulesOfType(CSSRule.STYLE_RULE)) for name, sheet in iteritems(sheets)}
num_of_removed_rules = num_of_removed_classes = 0
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt not in OEB_DOCS:
continue
root = container.parsed(name)
@@ -162,7 +162,7 @@ def remove_unused_css(container, report=None, remove_unused_classes=False, merge
num_of_removed_classes += len(original_classes) - len(classes)
container.dirty(name)
- for name, sheet in sheets.iteritems():
+ for name, sheet in iteritems(sheets):
unused_rules = style_rules[name]
if unused_rules:
num_of_removed_rules += len(unused_rules)
@@ -226,7 +226,7 @@ def transform_css(container, transform_sheet=None, transform_style=None, names=(
if not names:
types = OEB_STYLES | OEB_DOCS
names = []
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in types:
names.append(name)
diff --git a/src/calibre/ebooks/oeb/polish/download.py b/src/calibre/ebooks/oeb/polish/download.py
index 0211b0ff0d..46fc78f22c 100644
--- a/src/calibre/ebooks/oeb/polish/download.py
+++ b/src/calibre/ebooks/oeb/polish/download.py
@@ -23,6 +23,7 @@ from calibre.ebooks.oeb.base import OEB_DOCS, OEB_STYLES, barename, iterlinks
from calibre.ebooks.oeb.polish.utils import guess_type
from calibre.ptempfile import TemporaryDirectory
from calibre.web import get_download_filename_from_response
+from polyglot.builtins import iteritems
from polyglot.urllib import urlopen, urlparse
@@ -43,7 +44,7 @@ def iterhtmllinks(container, name):
def get_external_resources(container):
ans = defaultdict(list)
- for name, media_type in container.mime_map.iteritems():
+ for name, media_type in iteritems(container.mime_map):
if container.has_name(name) and container.exists(name):
if media_type in OEB_DOCS:
for el, attr, link in iterhtmllinks(container, name):
@@ -185,12 +186,12 @@ def replacer(url_map):
def replace_resources(container, urls, replacements):
url_maps = defaultdict(dict)
changed = False
- for url, names in urls.iteritems():
+ for url, names in iteritems(urls):
replacement = replacements.get(url)
if replacement is not None:
for name in names:
url_maps[name][url] = container.name_to_href(replacement, name)
- for name, url_map in url_maps.iteritems():
+ for name, url_map in iteritems(url_maps):
r = replacer(url_map)
container.replace_links(name, r)
changed |= r.replaced
diff --git a/src/calibre/ebooks/oeb/polish/embed.py b/src/calibre/ebooks/oeb/polish/embed.py
index ad57d3f6ed..a815940b40 100644
--- a/src/calibre/ebooks/oeb/polish/embed.py
+++ b/src/calibre/ebooks/oeb/polish/embed.py
@@ -15,7 +15,7 @@ from lxml import etree
from calibre import prints
from calibre.ebooks.oeb.base import XHTML
from calibre.utils.filenames import ascii_filename
-from polyglot.builtins import string_or_bytes
+from polyglot.builtins import iteritems, itervalues, string_or_bytes
props = {'font-family':None, 'font-weight':'normal', 'font-style':'normal', 'font-stretch':'normal'}
@@ -79,7 +79,7 @@ def filter_by_stretch(fonts, val):
else:
candidates = expanded or condensed
distance_map = {i:abs(stretch_map[i] - val) for i in candidates}
- min_dist = min(distance_map.itervalues())
+ min_dist = min(itervalues(distance_map))
return [fonts[i] for i in candidates if distance_map[i] == min_dist]
@@ -127,7 +127,7 @@ def filter_by_weight(fonts, val):
return [fonts[rmap[400]]]
candidates = below or above
distance_map = {i:abs(weight_map[i] - val) for i in candidates}
- min_dist = min(distance_map.itervalues())
+ min_dist = min(itervalues(distance_map))
return [fonts[i] for i in candidates if distance_map[i] == min_dist]
@@ -154,7 +154,7 @@ def do_embed(container, font, report):
with container.open(name, 'wb') as out:
out.write(data)
href = container.name_to_href(name)
- rule = {k:font.get(k, v) for k, v in props.iteritems()}
+ rule = {k:font.get(k, v) for k, v in iteritems(props)}
rule['src'] = 'url(%s)' % href
rule['name'] = name
return rule
@@ -188,7 +188,7 @@ def embed_font(container, font, all_font_rules, report, warned):
else:
name = rule['src']
href = container.name_to_href(name)
- rule = {k:ff if k == 'font-family' else rule.get(k, v) for k, v in props.iteritems()}
+ rule = {k:ff if k == 'font-family' else rule.get(k, v) for k, v in iteritems(props)}
rule['src'] = 'url(%s)' % href
rule['name'] = name
return rule
@@ -199,7 +199,7 @@ def font_key(font):
def embed_all_fonts(container, stats, report):
- all_font_rules = tuple(stats.all_font_rules.itervalues())
+ all_font_rules = tuple(itervalues(stats.all_font_rules))
warned = set()
rules, nrules = [], {}
modified = set()
@@ -212,7 +212,7 @@ def embed_all_fonts(container, stats, report):
if None in (fs, fu, fr):
continue
fs = {icu_lower(x) for x in fs}
- for font in fu.itervalues():
+ for font in itervalues(fu):
if icu_lower(font['font-family']) not in fs:
continue
rule = matching_rule(font, fr)
@@ -239,7 +239,7 @@ def embed_all_fonts(container, stats, report):
# Write out CSS
rules = [';\n\t'.join('%s: %s' % (
- k, '"%s"' % v if k == 'font-family' else v) for k, v in rulel.iteritems() if (k in props and props[k] != v and v != '400') or k == 'src')
+ k, '"%s"' % v if k == 'font-family' else v) for k, v in iteritems(rulel) if (k in props and props[k] != v and v != '400') or k == 'src')
for rulel in rules]
css = '\n\n'.join(['@font-face {\n\t%s\n}' % r for r in rules])
item = container.generate_item('fonts.css', id_prefix='font_embed')
diff --git a/src/calibre/ebooks/oeb/polish/fonts.py b/src/calibre/ebooks/oeb/polish/fonts.py
index 774cbaf00b..d6e2443e4d 100644
--- a/src/calibre/ebooks/oeb/polish/fonts.py
+++ b/src/calibre/ebooks/oeb/polish/fonts.py
@@ -9,6 +9,7 @@ __copyright__ = '2014, Kovid Goyal '
from calibre.ebooks.oeb.polish.container import OEB_STYLES, OEB_DOCS
from calibre.ebooks.oeb.normalize_css import normalize_font
from tinycss.fonts3 import parse_font_family, parse_font, serialize_font_family, serialize_font
+from polyglot.builtins import iteritems
def unquote(x):
@@ -45,7 +46,7 @@ def font_family_data_from_sheet(sheet, families):
def font_family_data(container):
families = {}
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_STYLES:
sheet = container.parsed(name)
font_family_data_from_sheet(sheet, families)
@@ -128,7 +129,7 @@ def change_font(container, old_name, new_name=None):
new_name to None to remove the font family instead of changing it.
'''
changed = False
- for name, mt in tuple(container.mime_map.iteritems()):
+ for name, mt in tuple(iteritems(container.mime_map)):
if mt in OEB_STYLES:
sheet = container.parsed(name)
if change_font_in_sheet(container, sheet, old_name, new_name, name):
diff --git a/src/calibre/ebooks/oeb/polish/images.py b/src/calibre/ebooks/oeb/polish/images.py
index 680fb47af0..8e42466c2b 100644
--- a/src/calibre/ebooks/oeb/polish/images.py
+++ b/src/calibre/ebooks/oeb/polish/images.py
@@ -9,7 +9,7 @@ from functools import partial
from threading import Thread, Event
from calibre import detect_ncpus, human_readable, force_unicode, filesystem_encoding
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, range
from polyglot.queue import Queue, Empty
@@ -93,7 +93,7 @@ def compress_images(container, report=None, names=None, jpeg_quality=None, progr
queue.join()
before_total = after_total = 0
changed = False
- for name, (ok, res) in results.iteritems():
+ for name, (ok, res) in iteritems(results):
name = force_unicode(name, filesystem_encoding)
if ok:
before, after = res
diff --git a/src/calibre/ebooks/oeb/polish/import_book.py b/src/calibre/ebooks/oeb/polish/import_book.py
index 9f9cd3152d..a35b77f49f 100644
--- a/src/calibre/ebooks/oeb/polish/import_book.py
+++ b/src/calibre/ebooks/oeb/polish/import_book.py
@@ -14,15 +14,16 @@ from calibre.ebooks.oeb.polish.container import Container, OEB_DOCS, OEB_STYLES
from calibre.ebooks.epub import initialize_container
from calibre.utils.logging import default_log
+from polyglot.builtins import iteritems
IMPORTABLE = {'htm', 'xhtml', 'html', 'xhtm', 'docx'}
def auto_fill_manifest(container):
manifest_id_map = container.manifest_id_map
- manifest_name_map = {v:k for k, v in manifest_id_map.iteritems()}
+ manifest_name_map = {v:k for k, v in iteritems(manifest_id_map)}
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if name not in manifest_name_map and not container.ok_to_be_unmanifested(name):
mitem = container.generate_item(name, unique_href=False)
gname = container.href_to_name(mitem.get('href'), container.opf_name)
@@ -53,7 +54,7 @@ def import_book_as_epub(srcpath, destpath, log=default_log):
c = Container(tdir, pathtoopf, log)
auto_fill_manifest(c)
# Auto fix all HTML/CSS
- for name, mt in c.mime_map.iteritems():
+ for name, mt in iteritems(c.mime_map):
if mt in set(OEB_DOCS) | set(OEB_STYLES):
c.parsed(name)
c.dirty(name)
@@ -64,6 +65,6 @@ def import_book_as_epub(srcpath, destpath, log=default_log):
for name in c.name_path_map:
zf.writestr(name, c.raw_data(name, decode=False))
+
if __name__ == '__main__':
import_book_as_epub(sys.argv[-2], sys.argv[-1])
-
diff --git a/src/calibre/ebooks/oeb/polish/jacket.py b/src/calibre/ebooks/oeb/polish/jacket.py
index ac9cd14271..6d6cce3177 100644
--- a/src/calibre/ebooks/oeb/polish/jacket.py
+++ b/src/calibre/ebooks/oeb/polish/jacket.py
@@ -98,7 +98,7 @@ def add_or_replace_jacket(container):
if not found:
# Insert new jacket into spine
index = 0
- sp = container.abspath_to_name(container.spine_items.next())
+ sp = container.abspath_to_name(next(container.spine_items))
if sp == find_cover_page(container):
index = 1
itemref = container.opf.makeelement(OPF('itemref'),
diff --git a/src/calibre/ebooks/oeb/polish/main.py b/src/calibre/ebooks/oeb/polish/main.py
index af30ac1e30..655b80b24c 100644
--- a/src/calibre/ebooks/oeb/polish/main.py
+++ b/src/calibre/ebooks/oeb/polish/main.py
@@ -23,6 +23,7 @@ from calibre.ebooks.oeb.polish.jacket import (
replace_jacket, add_or_replace_jacket, find_existing_jacket, remove_jacket)
from calibre.ebooks.oeb.polish.css import remove_unused_css
from calibre.utils.logging import Log
+from polyglot.builtins import iteritems, iterkeys
ALL_OPTS = {
'embed': False,
@@ -131,7 +132,7 @@ def hfix(name, raw):
return raw
-CLI_HELP = {x:hfix(x, re.sub('<.*?>', '', y)) for x, y in HELP.iteritems()}
+CLI_HELP = {x:hfix(x, re.sub('<.*?>', '', y)) for x, y in iteritems(HELP)}
# }}}
@@ -242,7 +243,7 @@ def polish_one(ebook, opts, report, customization=None):
def polish(file_map, opts, log, report):
st = time.time()
- for inbook, outbook in file_map.iteritems():
+ for inbook, outbook in iteritems(file_map):
report(_('## Polishing: %s')%(inbook.rpartition('.')[-1].upper()))
ebook = get_container(inbook, log)
polish_one(ebook, opts, report)
@@ -263,7 +264,7 @@ def gui_polish(data):
file_map = {x:x for x in files}
opts = ALL_OPTS.copy()
opts.update(data)
- O = namedtuple('Options', ' '.join(ALL_OPTS.iterkeys()))
+ O = namedtuple('Options', ' '.join(iterkeys(ALL_OPTS)))
opts = O(**opts)
log = Log(level=Log.DEBUG)
report = []
@@ -278,7 +279,7 @@ def gui_polish(data):
def tweak_polish(container, actions, customization=None):
opts = ALL_OPTS.copy()
opts.update(actions)
- O = namedtuple('Options', ' '.join(ALL_OPTS.iterkeys()))
+ O = namedtuple('Options', ' '.join(iterkeys(ALL_OPTS)))
opts = O(**opts)
report = []
changed = polish_one(container, opts, report.append, customization=customization)
@@ -331,10 +332,10 @@ def main(args=None):
inbook, outbook = args
popts = ALL_OPTS.copy()
- for k, v in popts.iteritems():
+ for k, v in iteritems(popts):
popts[k] = getattr(opts, k, None)
- O = namedtuple('Options', ' '.join(popts.iterkeys()))
+ O = namedtuple('Options', ' '.join(iterkeys(popts)))
popts = O(**popts)
report = []
if not tuple(filter(None, (getattr(popts, name) for name in ALL_OPTS))):
diff --git a/src/calibre/ebooks/oeb/polish/pretty.py b/src/calibre/ebooks/oeb/polish/pretty.py
index b5423b251a..5d90fae260 100644
--- a/src/calibre/ebooks/oeb/polish/pretty.py
+++ b/src/calibre/ebooks/oeb/polish/pretty.py
@@ -7,7 +7,7 @@ __license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal '
import textwrap
-from polyglot.builtins import map
+from polyglot.builtins import iteritems, map
# from lxml.etree import Element
@@ -224,7 +224,7 @@ def pretty_xml(container, name, raw):
def fix_all_html(container):
' Fix any parsing errors in all HTML files in the container. Fixing is done using the HTML5 parsing algorithm. '
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_DOCS:
container.parsed(name)
container.dirty(name)
@@ -233,7 +233,7 @@ def fix_all_html(container):
def pretty_all(container):
' Pretty print all HTML/CSS/XML files in the container '
xml_types = {guess_type('a.ncx'), guess_type('a.xml'), guess_type('a.svg')}
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
prettied = False
if mt in OEB_DOCS:
pretty_html_tree(container, container.parsed(name))
diff --git a/src/calibre/ebooks/oeb/polish/replace.py b/src/calibre/ebooks/oeb/polish/replace.py
index a04623404c..4fc7f372f7 100644
--- a/src/calibre/ebooks/oeb/polish/replace.py
+++ b/src/calibre/ebooks/oeb/polish/replace.py
@@ -8,7 +8,7 @@ __copyright__ = '2013, Kovid Goyal '
__docformat__ = 'restructuredtext en'
import codecs, shutil, os, posixpath
-from polyglot.builtins import map
+from polyglot.builtins import iteritems, itervalues, map
from functools import partial
from collections import Counter, defaultdict
@@ -118,7 +118,7 @@ def replace_links(container, link_map, frag_map=lambda name, frag:frag, replace_
:param replace_in_opf: If False, links are not replaced in the OPF file.
'''
- for name, media_type in container.mime_map.iteritems():
+ for name, media_type in iteritems(container.mime_map):
if name == container.opf_name and not replace_in_opf:
continue
repl = LinkReplacer(name, container, link_map, frag_map)
@@ -134,7 +134,7 @@ def replace_ids(container, id_map):
'''
changed = False
- for name, media_type in container.mime_map.iteritems():
+ for name, media_type in iteritems(container.mime_map):
repl = IdReplacer(name, container, id_map)
container.replace_links(name, repl)
if name == container.opf_name:
@@ -186,19 +186,19 @@ def rename_files(container, file_map):
:param file_map: A mapping of old canonical name to new canonical name, for
example: :code:`{'text/chapter1.html': 'chapter1.html'}`.
'''
- overlap = set(file_map).intersection(set(file_map.itervalues()))
+ overlap = set(file_map).intersection(set(itervalues(file_map)))
if overlap:
raise ValueError('Circular rename detected. The files %s are both rename targets and destinations' % ', '.join(overlap))
- for name, dest in file_map.iteritems():
+ for name, dest in iteritems(file_map):
if container.exists(dest):
if name != dest and name.lower() == dest.lower():
# A case change on an OS with a case insensitive file-system.
continue
raise ValueError('Cannot rename {0} to {1} as {1} already exists'.format(name, dest))
- if len(tuple(file_map.itervalues())) != len(set(file_map.itervalues())):
+ if len(tuple(itervalues(file_map))) != len(set(itervalues(file_map))):
raise ValueError('Cannot rename, the set of destination files contains duplicates')
link_map = {}
- for current_name, new_name in file_map.iteritems():
+ for current_name, new_name in iteritems(file_map):
container.rename(current_name, new_name)
if new_name != container.opf_name: # OPF is handled by the container
link_map[current_name] = new_name
@@ -220,7 +220,7 @@ def replace_file(container, name, path, basename, force_mt=None):
rename_files(container, {name:nname})
mt = force_mt or container.guess_type(nname)
container.mime_map[nname] = mt
- for itemid, q in container.manifest_id_map.iteritems():
+ for itemid, q in iteritems(container.manifest_id_map):
if q == nname:
for item in container.opf_xpath('//opf:manifest/opf:item[@href and @id="%s"]' % itemid):
item.set('media-type', mt)
@@ -255,7 +255,7 @@ def get_recommended_folders(container, names):
recommended folder is assumed to be the folder containing the OPF file. '''
from calibre.ebooks.oeb.polish.utils import guess_type
counts = defaultdict(Counter)
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
folder = name.rpartition('/')[0] if '/' in name else ''
counts[mt_to_category(container, mt)][folder] += 1
@@ -264,7 +264,7 @@ def get_recommended_folders(container, names):
except KeyError:
opf_folder = ''
- recommendations = {category:counter.most_common(1)[0][0] for category, counter in counts.iteritems()}
+ recommendations = {category:counter.most_common(1)[0][0] for category, counter in iteritems(counts)}
return {n:recommendations.get(mt_to_category(container, guess_type(os.path.basename(n))), opf_folder) for n in names}
@@ -351,7 +351,7 @@ def remove_links_to(container, predicate):
stylepath = XPath('//h:style')
styleattrpath = XPath('//*[@style]')
changed = set()
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
removed = False
if mt in OEB_DOCS:
root = container.parsed(name)
diff --git a/src/calibre/ebooks/oeb/polish/report.py b/src/calibre/ebooks/oeb/polish/report.py
index 4a954ae660..57beaf7d73 100644
--- a/src/calibre/ebooks/oeb/polish/report.py
+++ b/src/calibre/ebooks/oeb/polish/report.py
@@ -17,6 +17,7 @@ from calibre.ebooks.oeb.polish.spell import get_all_words, count_all_chars
from calibre.utils.icu import numeric_sort_key, safe_chr
from calibre.utils.imghdr import identify
from css_selectors import Select, SelectorError
+from polyglot.builtins import iteritems
File = namedtuple('File', 'name dir basename size category')
@@ -60,7 +61,7 @@ def safe_img_data(container, name, mt):
def files_data(container, *args):
- for name, path in container.name_path_map.iteritems():
+ for name, path in iteritems(container.name_path_map):
yield File(name, posixpath.dirname(name), posixpath.basename(name), safe_size(container, name),
get_category(name, container.mime_map.get(name, '')))
@@ -88,7 +89,7 @@ def safe_href_to_name(container, href, base):
def images_data(container, *args):
image_usage = defaultdict(set)
link_sources = OEB_STYLES | OEB_DOCS
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in link_sources:
for href, line_number, offset in container.iterlinks(name):
target = safe_href_to_name(container, href, name)
@@ -98,7 +99,7 @@ def images_data(container, *args):
image_usage[target].add(LinkLocation(name, line_number, href))
image_data = []
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt.startswith('image/') and container.exists(name):
image_data.append(Image(name, mt, sort_locations(container, image_usage.get(name, set())), safe_size(container, name),
posixpath.basename(name), len(image_data), *safe_img_data(container, name, mt)))
@@ -158,7 +159,7 @@ def links_data(container, *args):
links = []
anchor_pat = XPath('//*[@id or @name]')
link_pat = XPath('//h:a[@href]')
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_DOCS:
root = container.parsed(name)
anchor_map[name] = create_anchor_map(root, anchor_pat, name)
@@ -200,7 +201,7 @@ Word = namedtuple('Word', 'id word locale usage')
def words_data(container, book_locale, *args):
count, words = get_all_words(container, book_locale, get_word_count=True)
- return (count, tuple(Word(i, word, locale, v) for i, ((word, locale), v) in enumerate(words.iteritems())))
+ return (count, tuple(Word(i, word, locale, v) for i, ((word, locale), v) in enumerate(iteritems(words))))
Char = namedtuple('Char', 'id char codepoint usage count')
@@ -213,7 +214,7 @@ def chars_data(container, book_locale, *args):
def sort_key(name):
return nmap.get(name, len(nmap)), numeric_sort_key(name)
- for i, (codepoint, usage) in enumerate(cc.chars.iteritems()):
+ for i, (codepoint, usage) in enumerate(iteritems(cc.chars)):
yield Char(i, safe_chr(codepoint), codepoint, sorted(usage, key=sort_key), cc.counter[codepoint])
@@ -252,7 +253,7 @@ def css_data(container, book_locale, result_data, *args):
spine_names = {name for name, is_linear in container.spine_names}
style_path, link_path = XPath('//h:style'), XPath('//h:link/@href')
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_STYLES:
importable_sheets[name] = css_rules(name, parser.parse_stylesheet(container.raw_data(name)).rules)
elif mt in OEB_DOCS and name in spine_names:
@@ -307,7 +308,7 @@ def css_data(container, book_locale, result_data, *args):
class_map = defaultdict(lambda : defaultdict(list))
- for name, inline_sheets in html_sheets.iteritems():
+ for name, inline_sheets in iteritems(html_sheets):
root = container.parsed(name)
cmap = defaultdict(lambda : defaultdict(list))
for elem in root.xpath('//*[@class]'):
@@ -317,21 +318,21 @@ def css_data(container, book_locale, result_data, *args):
for sheet in chain(sheets_for_html(name, root), inline_sheets):
for rule in rules_in_sheet(sheet):
rule_map[rule][name].extend(matches_for_selector(rule.selector, select, cmap, rule))
- for cls, elem_map in cmap.iteritems():
+ for cls, elem_map in iteritems(cmap):
class_elements = class_map[cls][name]
- for elem, usage in elem_map.iteritems():
+ for elem, usage in iteritems(elem_map):
class_elements.append(
ClassElement(name, elem.sourceline, elem.get('class'), tag_text(elem), tuple(usage)))
result_data['classes'] = ans = []
- for cls, name_map in class_map.iteritems():
- la = tuple(ClassFileMatch(name, tuple(class_elements), numeric_sort_key(name)) for name, class_elements in name_map.iteritems() if class_elements)
+ for cls, name_map in iteritems(class_map):
+ la = tuple(ClassFileMatch(name, tuple(class_elements), numeric_sort_key(name)) for name, class_elements in iteritems(name_map) if class_elements)
num_of_matches = sum(sum(len(ce.matched_rules) for ce in cfm.class_elements) for cfm in la)
ans.append(ClassEntry(cls, num_of_matches, la, numeric_sort_key(cls)))
ans = []
- for rule, loc_map in rule_map.iteritems():
- la = tuple(CSSFileMatch(name, tuple(locations), numeric_sort_key(name)) for name, locations in loc_map.iteritems() if locations)
+ for rule, loc_map in iteritems(rule_map):
+ la = tuple(CSSFileMatch(name, tuple(locations), numeric_sort_key(name)) for name, locations in iteritems(loc_map) if locations)
count = sum(len(fm.locations) for fm in la)
ans.append(CSSEntry(rule, count, la, numeric_sort_key(rule.selector)))
diff --git a/src/calibre/ebooks/oeb/polish/spell.py b/src/calibre/ebooks/oeb/polish/spell.py
index 4c9864fb2f..6d7fc5c53f 100644
--- a/src/calibre/ebooks/oeb/polish/spell.py
+++ b/src/calibre/ebooks/oeb/polish/spell.py
@@ -17,7 +17,7 @@ from calibre.ebooks.oeb.polish.container import OPF_NAMESPACES, get_container
from calibre.ebooks.oeb.polish.parsing import parse
from calibre.ebooks.oeb.polish.toc import find_existing_ncx_toc, find_existing_nav_toc
from calibre.utils.icu import ord_string
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
_patterns = None
@@ -144,7 +144,7 @@ def add_words_from_escaped_html(text, words, file_name, node, attr, locale):
ewords[None] = 0
read_words_from_html(root, ewords, file_name, locale)
words[None] += ewords.pop(None)
- for k, locs in ewords.iteritems():
+ for k, locs in iteritems(ewords):
for loc in locs:
loc.location_node, loc.node_item = node, (False, attr)
words[k].extend(locs)
@@ -287,7 +287,7 @@ def get_all_words(container, book_locale, get_word_count=False):
elif hasattr(root, 'xpath'):
read_words_from_html(root, words, file_name, book_locale)
count = words.pop(None)
- ans = {k:group_sort(v) for k, v in words.iteritems()}
+ ans = {k:group_sort(v) for k, v in iteritems(words)}
if get_word_count:
return count, ans
return ans
@@ -355,7 +355,7 @@ def replace_word(container, new_word, locations, locale, undo_cache=None):
def undo_replace_word(container, undo_cache):
changed = set()
- for (file_name, node, is_attr, attr), text in undo_cache.iteritems():
+ for (file_name, node, is_attr, attr), text in iteritems(undo_cache):
node.set(attr, text) if is_attr else setattr(node, attr, text)
container.replace(file_name, node.getroottree().getroot())
changed.add(file_name)
diff --git a/src/calibre/ebooks/oeb/polish/split.py b/src/calibre/ebooks/oeb/polish/split.py
index f06e32c37d..816ded8ba3 100644
--- a/src/calibre/ebooks/oeb/polish/split.py
+++ b/src/calibre/ebooks/oeb/polish/split.py
@@ -13,6 +13,7 @@ from calibre.ebooks.oeb.base import barename, XPNSMAP, XPath, OPF, XHTML, OEB_DO
from calibre.ebooks.oeb.polish.errors import MalformedMarkup
from calibre.ebooks.oeb.polish.toc import node_from_loc
from calibre.ebooks.oeb.polish.replace import LinkRebaser
+from polyglot.builtins import iteritems
from polyglot.urllib import urlparse
@@ -241,7 +242,7 @@ def split(container, name, loc_or_xpath, before=True, totals=None):
a.set('href', '#' + purl.fragment)
# Fix all links in the container that point to anchors in the bottom tree
- for fname, media_type in container.mime_map.iteritems():
+ for fname, media_type in iteritems(container.mime_map):
if fname not in {name, bottom_name}:
repl = SplitLinkReplacer(fname, anchors_in_bottom, name, bottom_name, container)
container.replace_links(fname, repl)
@@ -437,7 +438,7 @@ def merge_html(container, names, master):
container.remove_item(name, remove_from_guide=False)
# Fix all links in the container that point to merged files
- for fname, media_type in container.mime_map.iteritems():
+ for fname, media_type in iteritems(container.mime_map):
repl = MergeLinkReplacer(fname, anchor_map, master, container)
container.replace_links(fname, repl)
@@ -468,7 +469,7 @@ def merge_css(container, names, master):
# Remove links to merged stylesheets in the html files, replacing with a
# link to the master sheet
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_DOCS:
removed = False
root = p(name)
diff --git a/src/calibre/ebooks/oeb/polish/stats.py b/src/calibre/ebooks/oeb/polish/stats.py
index 45223bc317..4adfc4c3e9 100644
--- a/src/calibre/ebooks/oeb/polish/stats.py
+++ b/src/calibre/ebooks/oeb/polish/stats.py
@@ -18,7 +18,7 @@ from calibre.ebooks.oeb.polish.cascade import iterrules, resolve_styles, iterdec
from calibre.utils.icu import ord_string, safe_chr
from polyglot.builtins import unicode_type
from tinycss.fonts3 import parse_font_family
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, itervalues, range
def normalize_font_properties(font):
@@ -236,7 +236,7 @@ class StatsCollector(object):
return
ff = [icu_lower(x) for x in font.get('font-family', ())]
if ff and ff[0] not in bad_fonts:
- key = frozenset(((k, ff[0] if k == 'font-family' else v) for k, v in font.iteritems() if k in font_keys))
+ key = frozenset(((k, ff[0] if k == 'font-family' else v) for k, v in iteritems(font) if k in font_keys))
val = font_usage_map.get(key)
if val is None:
val = font_usage_map[key] = {'text': set()}
@@ -301,9 +301,9 @@ class StatsCollector(object):
self.font_usage_map[name] = {}
self.font_spec_map[name] = set()
self.get_font_usage(container, name, resolve_property, resolve_pseudo_property, font_face_rules, do_embed)
- self.font_stats = {k:{safe_chr(x) for x in v} for k, v in self.font_stats.iteritems()}
- for fum in self.font_usage_map.itervalues():
- for v in fum.itervalues():
+ self.font_stats = {k:{safe_chr(x) for x in v} for k, v in iteritems(self.font_stats)}
+ for fum in itervalues(self.font_usage_map):
+ for v in itervalues(fum):
v['text'] = {safe_chr(x) for x in v['text']}
diff --git a/src/calibre/ebooks/oeb/polish/subset.py b/src/calibre/ebooks/oeb/polish/subset.py
index 888e6d169c..2fddc9084b 100644
--- a/src/calibre/ebooks/oeb/polish/subset.py
+++ b/src/calibre/ebooks/oeb/polish/subset.py
@@ -16,6 +16,7 @@ from calibre.ebooks.oeb.polish.utils import guess_type
from calibre.utils.fonts.sfnt.subset import subset
from calibre.utils.fonts.sfnt.errors import UnsupportedFont
from calibre.utils.fonts.utils import get_font_names
+from polyglot.builtins import iteritems, itervalues
def remove_font_face_rules(container, sheet, remove_names, base):
@@ -35,7 +36,7 @@ def remove_font_face_rules(container, sheet, remove_names, base):
def iter_subsettable_fonts(container):
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if (mt in OEB_FONTS or name.rpartition('.')[-1].lower() in {'otf', 'ttf'}) and mt != guess_type('a.woff'):
yield name, mt
@@ -75,8 +76,8 @@ def subset_all_fonts(container, font_stats, report):
for w in warnings:
container.log.warn(w)
- olen = sum(old_sizes.itervalues())
- nlen = sum(new_sizes.itervalues())
+ olen = sum(itervalues(old_sizes))
+ nlen = sum(itervalues(new_sizes))
total_new += len(nraw)
if nlen == olen:
report(_('The font %s was already subset')%font_name)
@@ -91,7 +92,7 @@ def subset_all_fonts(container, font_stats, report):
changed = True
if remove:
- for name, mt in container.mime_map.iteritems():
+ for name, mt in iteritems(container.mime_map):
if mt in OEB_STYLES:
sheet = container.parsed(name)
if remove_font_face_rules(container, sheet, remove, name):
diff --git a/src/calibre/ebooks/oeb/polish/tests/base.py b/src/calibre/ebooks/oeb/polish/tests/base.py
index 41c0f013f6..b461a1771d 100644
--- a/src/calibre/ebooks/oeb/polish/tests/base.py
+++ b/src/calibre/ebooks/oeb/polish/tests/base.py
@@ -13,6 +13,7 @@ from calibre.ptempfile import TemporaryDirectory
from calibre.ptempfile import PersistentTemporaryDirectory
from calibre.utils.logging import DevNull
import calibre.ebooks.oeb.polish.container as pc
+from polyglot.builtins import iteritems
def get_cache():
@@ -42,7 +43,7 @@ def build_book(src, dest, args=()):
def add_resources(raw, rmap):
- for placeholder, path in rmap.iteritems():
+ for placeholder, path in iteritems(rmap):
fname = os.path.basename(path)
shutil.copy2(path, '.')
raw = raw.replace(placeholder, fname)
@@ -88,6 +89,7 @@ def get_split_book(fmt='epub'):
os.remove(x)
return ans
+
devnull = DevNull()
@@ -110,4 +112,3 @@ class BaseTest(unittest.TestCase):
dest = container.href_to_name(link, name)
if dest:
self.assertTrue(container.exists(dest), 'The link %s in %s does not exist' % (link, name))
-
diff --git a/src/calibre/ebooks/oeb/polish/tests/cascade.py b/src/calibre/ebooks/oeb/polish/tests/cascade.py
index 35a89bc580..be116a8d72 100644
--- a/src/calibre/ebooks/oeb/polish/tests/cascade.py
+++ b/src/calibre/ebooks/oeb/polish/tests/cascade.py
@@ -19,6 +19,7 @@ from calibre.ebooks.oeb.polish.container import ContainerBase, href_to_name
from calibre.ebooks.oeb.polish.stats import StatsCollector, font_keys, normalize_font_properties, prepare_font_rule
from calibre.ebooks.oeb.polish.tests.base import BaseTest
from calibre.utils.logging import Log, Stream
+from polyglot.builtins import iteritems
class VirtualContainer(ContainerBase):
@@ -155,7 +156,7 @@ class CascadeTest(BaseTest):
files = {'index.html':html, 'X.otf':b'xxx', 'XB.otf': b'xbxb'}
for font in fonts:
styles.append('@font-face {')
- for k, v in font.iteritems():
+ for k, v in iteritems(font):
if k == 'src':
files[v] = b'xxx'
v = 'url(%s)' % v
@@ -186,7 +187,7 @@ class CascadeTest(BaseTest):
def fkey(*args, **kw):
f = font(*args, **kw)
f['font-family'] = icu_lower(f['font-family'][0])
- return frozenset((k, v) for k, v in f.iteritems() if k in font_keys)
+ return frozenset((k, v) for k, v in iteritems(f) if k in font_keys)
def fu(text, *args, **kw):
key = fkey(*args, **kw)
diff --git a/src/calibre/ebooks/oeb/polish/tests/container.py b/src/calibre/ebooks/oeb/polish/tests/container.py
index deac24bb78..e438bd9a19 100644
--- a/src/calibre/ebooks/oeb/polish/tests/container.py
+++ b/src/calibre/ebooks/oeb/polish/tests/container.py
@@ -16,6 +16,7 @@ from calibre.ebooks.oeb.polish.replace import rename_files, rationalize_folders
from calibre.ebooks.oeb.polish.split import split, merge
from calibre.utils.filenames import nlinks_file
from calibre.ptempfile import TemporaryFile, TemporaryDirectory
+from polyglot.builtins import iteritems, itervalues
def get_container(*args, **kwargs):
@@ -38,7 +39,7 @@ class ContainerTests(BaseTest):
c2 = clone_container(c1, tdir)
for c in (c1, c2):
- for name, path in c.name_path_map.iteritems():
+ for name, path in iteritems(c.name_path_map):
self.assertEqual(2, nlinks_file(path), 'The file %s is not linked' % name)
for name in c1.name_path_map:
@@ -178,13 +179,13 @@ class ContainerTests(BaseTest):
name = 'folder/added file.html'
c.add_file(name, b'xxx')
self.assertEqual('xxx', c.raw_data(name))
- self.assertIn(name, set(c.manifest_id_map.itervalues()))
+ self.assertIn(name, set(itervalues(c.manifest_id_map)))
self.assertIn(name, {x[0] for x in c.spine_names})
name = 'added.css'
c.add_file(name, b'xxx')
self.assertEqual('xxx', c.raw_data(name))
- self.assertIn(name, set(c.manifest_id_map.itervalues()))
+ self.assertIn(name, set(itervalues(c.manifest_id_map)))
self.assertNotIn(name, {x[0] for x in c.spine_names})
self.assertEqual(c.make_name_unique(name), 'added-1.css')
c.add_file('added-1.css', b'xxx')
diff --git a/src/calibre/ebooks/oeb/polish/tests/parsing.py b/src/calibre/ebooks/oeb/polish/tests/parsing.py
index 5987821a28..c60bfa1f42 100644
--- a/src/calibre/ebooks/oeb/polish/tests/parsing.py
+++ b/src/calibre/ebooks/oeb/polish/tests/parsing.py
@@ -15,7 +15,7 @@ from calibre.ebooks.oeb.polish.tests.base import BaseTest
from calibre.ebooks.oeb.polish.parsing import parse_html5 as parse
from calibre.ebooks.oeb.base import XPath, XHTML_NS, SVG_NS, XLINK_NS
from calibre.ebooks.oeb.parse_utils import html5_parse
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, range
def nonvoid_cdata_elements(test, parse_function):
@@ -185,7 +185,7 @@ class ParsingTests(BaseTest):
for ds in (False, True):
src = '\n\n
\n '
root = parse(src, discard_namespaces=ds)
- for tag, lnum in {'html':2, 'head':3, 'body':3, 'p':3, 'svg':4, 'image':4, 'b':5}.iteritems():
+ for tag, lnum in iteritems({'html':2, 'head':3, 'body':3, 'p':3, 'svg':4, 'image':4, 'b':5}):
elem = root.xpath('//*[local-name()="%s"]' % tag)[0]
self.assertEqual(lnum, elem.sourceline, 'Line number incorrect for %s, source: %s:' % (tag, src))
@@ -220,4 +220,4 @@ def timing():
f(raw)
timings.append(monotonic() - st)
avg = sum(timings)/len(timings)
- print ('Average time for %s: %.2g' % (name, avg))
+ print('Average time for %s: %.2g' % (name, avg))
diff --git a/src/calibre/ebooks/oeb/polish/toc.py b/src/calibre/ebooks/oeb/polish/toc.py
index bcf274cf03..46b77329d2 100644
--- a/src/calibre/ebooks/oeb/polish/toc.py
+++ b/src/calibre/ebooks/oeb/polish/toc.py
@@ -10,7 +10,7 @@ __docformat__ = 'restructuredtext en'
import re
from collections import Counter, OrderedDict
from functools import partial
-from polyglot.builtins import map, unicode_type
+from polyglot.builtins import iteritems, map, unicode_type
from operator import itemgetter
from lxml import etree
@@ -168,7 +168,7 @@ def parse_ncx(container, ncx_name):
if navmaps:
process_ncx_node(container, navmaps[0], toc_root, ncx_name)
toc_root.lang = toc_root.uid = None
- for attr, val in root.attrib.iteritems():
+ for attr, val in iteritems(root.attrib):
if attr.endswith('lang'):
toc_root.lang = unicode_type(val)
break
@@ -415,14 +415,14 @@ def from_xpaths(container, xpaths):
name = container.abspath_to_name(spinepath)
root = container.parsed(name)
level_item_map = maps[name] = {i+1:frozenset(xp(root)) for i, xp in enumerate(xpaths)}
- for lvl, elems in level_item_map.iteritems():
+ for lvl, elems in iteritems(level_item_map):
if elems:
empty_levels.discard(lvl)
# Remove empty levels from all level_maps
if empty_levels:
- for name, lmap in tuple(maps.iteritems()):
- lmap = {lvl:items for lvl, items in lmap.iteritems() if lvl not in empty_levels}
- lmap = sorted(lmap.iteritems(), key=itemgetter(0))
+ for name, lmap in tuple(iteritems(maps)):
+ lmap = {lvl:items for lvl, items in iteritems(lmap) if lvl not in empty_levels}
+ lmap = sorted(iteritems(lmap), key=itemgetter(0))
lmap = {i+1:items for i, (l, items) in enumerate(lmap)}
maps[name] = lmap
@@ -440,9 +440,9 @@ def from_xpaths(container, xpaths):
return process_node(tocroot)
- for name, level_item_map in maps.iteritems():
+ for name, level_item_map in iteritems(maps):
root = container.parsed(name)
- item_level_map = {e:i for i, elems in level_item_map.iteritems() for e in elems}
+ item_level_map = {e:i for i, elems in iteritems(level_item_map) for e in elems}
item_dirtied = False
all_ids = set(root.xpath('//*/@id'))
diff --git a/src/calibre/ebooks/oeb/stylizer.py b/src/calibre/ebooks/oeb/stylizer.py
index 3c6d71c1ae..4e496a7b49 100644
--- a/src/calibre/ebooks/oeb/stylizer.py
+++ b/src/calibre/ebooks/oeb/stylizer.py
@@ -20,7 +20,7 @@ from calibre.ebooks import unit_convert
from calibre.ebooks.oeb.base import XHTML, XHTML_NS, CSS_MIME, OEB_STYLES, xpath, urlnormalize
from calibre.ebooks.oeb.normalize_css import DEFAULTS, normalizers
from css_selectors import Select, SelectorError, INAPPROPRIATE_PSEUDO_CLASSES
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
from tinycss.media3 import CSSMedia3Parser
css_parser_log.setLevel(logging.WARN)
@@ -753,7 +753,7 @@ class Style(object):
self._get('padding-right'), base=self.parent_width)
def __str__(self):
- items = sorted(self._style.iteritems())
+ items = sorted(iteritems(self._style))
return '; '.join("%s: %s" % (key, val) for key, val in items)
def cssdict(self):
@@ -762,12 +762,12 @@ class Style(object):
def pseudo_classes(self, filter_css):
if filter_css:
css = copy.deepcopy(self._pseudo_classes)
- for psel, cssdict in css.iteritems():
+ for psel, cssdict in iteritems(css):
for k in filter_css:
cssdict.pop(k, None)
else:
css = self._pseudo_classes
- return {k:v for k, v in css.iteritems() if v}
+ return {k:v for k, v in iteritems(css) if v}
@property
def is_hidden(self):
diff --git a/src/calibre/ebooks/oeb/transforms/embed_fonts.py b/src/calibre/ebooks/oeb/transforms/embed_fonts.py
index 9e669bc113..aa04c7ba62 100644
--- a/src/calibre/ebooks/oeb/transforms/embed_fonts.py
+++ b/src/calibre/ebooks/oeb/transforms/embed_fonts.py
@@ -18,7 +18,7 @@ from calibre.ebooks.oeb.transforms.subset import get_font_properties, find_font_
from calibre.utils.filenames import ascii_filename
from calibre.utils.fonts.scanner import font_scanner, NoFonts
from calibre.ebooks.oeb.polish.embed import font_key
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
def font_families_from_style(style):
@@ -138,7 +138,7 @@ class EmbedFonts(object):
if rule.type != rule.STYLE_RULE:
continue
props = {k:v for k,v in
- get_font_properties(rule).iteritems() if v}
+ iteritems(get_font_properties(rule)) if v}
if not props:
continue
for sel in rule.selectorList:
diff --git a/src/calibre/ebooks/oeb/transforms/flatcss.py b/src/calibre/ebooks/oeb/transforms/flatcss.py
index 14826539fe..a4efb4c9ac 100644
--- a/src/calibre/ebooks/oeb/transforms/flatcss.py
+++ b/src/calibre/ebooks/oeb/transforms/flatcss.py
@@ -21,7 +21,7 @@ from calibre.ebooks.oeb.base import (XHTML, XHTML_NS, CSS_MIME, OEB_STYLES,
from calibre.ebooks.oeb.stylizer import Stylizer
from calibre.utils.filenames import ascii_filename, ascii_text
from calibre.utils.icu import numeric_sort_key
-from polyglot.builtins import unicode_type, string_or_bytes
+from polyglot.builtins import iteritems, iterkeys, unicode_type, string_or_bytes
COLLAPSE = re.compile(r'[ \t\r\n\v]+')
STRIPNUM = re.compile(r'[-0-9]+$')
@@ -224,7 +224,7 @@ class CSSFlattener(object):
def store_page_margins(self):
self.opts._stored_page_margins = {}
- for item, stylizer in self.stylizers.iteritems():
+ for item, stylizer in iteritems(self.stylizers):
margins = self.opts._stored_page_margins[item.href] = {}
for prop, val in stylizer.page_rule.items():
p, w = prop.partition('-')[::2]
@@ -278,7 +278,7 @@ class CSSFlattener(object):
if font[k] != u'normal':
cfont[k] = font[k]
rule = '@font-face { %s }'%('; '.join(u'%s:%s'%(k, v) for k, v in
- cfont.iteritems()))
+ iteritems(cfont)))
rule = css_parser.parseString(rule)
efi.append(rule)
@@ -335,7 +335,7 @@ class CSSFlattener(object):
fsize = self.context.source.fbase
self.baseline_node(body, stylizer, sizes, fsize)
try:
- sbase = max(sizes.items(), key=operator.itemgetter(1))[0]
+ sbase = max(list(sizes.items()), key=operator.itemgetter(1))[0]
except:
sbase = 12.0
self.oeb.logger.info(
@@ -538,7 +538,7 @@ class CSSFlattener(object):
keep_classes = set()
if cssdict:
- items = sorted(cssdict.iteritems())
+ items = sorted(iteritems(cssdict))
css = u';\n'.join(u'%s: %s' % (key, val) for key, val in items)
classes = node.get('class', '').strip() or 'calibre'
# lower() because otherwise if the document uses the same class
@@ -554,8 +554,8 @@ class CSSFlattener(object):
node.attrib['class'] = match
keep_classes.add(match)
- for psel, cssdict in pseudo_classes.iteritems():
- items = sorted(cssdict.iteritems())
+ for psel, cssdict in iteritems(pseudo_classes):
+ items = sorted(iteritems(cssdict))
css = u';\n'.join(u'%s: %s' % (key, val) for key, val in items)
pstyles = pseudo_styles[psel]
if css in pstyles:
@@ -656,7 +656,7 @@ class CSSFlattener(object):
gc_map[css] = href
ans = {}
- for css, items in global_css.iteritems():
+ for css, items in iteritems(global_css):
for item in items:
ans[item] = gc_map[css]
return ans
@@ -672,15 +672,15 @@ class CSSFlattener(object):
body = html.find(XHTML('body'))
fsize = self.context.dest.fbase
self.flatten_node(body, stylizer, names, styles, pseudo_styles, fsize, item.id)
- items = sorted(((key, val) for (val, key) in styles.iteritems()), key=lambda x:numeric_sort_key(x[0]))
+ items = sorted(((key, val) for (val, key) in iteritems(styles)), key=lambda x:numeric_sort_key(x[0]))
# :hover must come after link and :active must come after :hover
- psels = sorted(pseudo_styles.iterkeys(), key=lambda x :
+ psels = sorted(iterkeys(pseudo_styles), key=lambda x :
{'hover':1, 'active':2}.get(x, 0))
for psel in psels:
styles = pseudo_styles[psel]
if not styles:
continue
- x = sorted(((k+':'+psel, v) for v, k in styles.iteritems()))
+ x = sorted(((k+':'+psel, v) for v, k in iteritems(styles)))
items.extend(x)
css = ''.join(".%s {\n%s;\n}\n\n" % (key, val) for key, val in items)
diff --git a/src/calibre/ebooks/oeb/transforms/metadata.py b/src/calibre/ebooks/oeb/transforms/metadata.py
index a405bd8991..e6b03f78cd 100644
--- a/src/calibre/ebooks/oeb/transforms/metadata.py
+++ b/src/calibre/ebooks/oeb/transforms/metadata.py
@@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en'
import os, re
from calibre.utils.date import isoformat, now
from calibre import guess_type
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
def meta_info_to_oeb_metadata(mi, m, log, override_input_metadata=False):
@@ -51,7 +51,7 @@ def meta_info_to_oeb_metadata(mi, m, log, override_input_metadata=False):
m.clear('series')
identifiers = mi.get_identifiers()
set_isbn = False
- for typ, val in identifiers.iteritems():
+ for typ, val in iteritems(identifiers):
has = False
if typ.lower() == 'isbn':
set_isbn = True
diff --git a/src/calibre/ebooks/oeb/transforms/page_margin.py b/src/calibre/ebooks/oeb/transforms/page_margin.py
index f56c97c155..f7fe1a0d02 100644
--- a/src/calibre/ebooks/oeb/transforms/page_margin.py
+++ b/src/calibre/ebooks/oeb/transforms/page_margin.py
@@ -11,6 +11,7 @@ import numbers
from collections import Counter
from calibre.ebooks.oeb.base import barename, XPath
+from polyglot.builtins import iteritems
class RemoveAdobeMargins(object):
@@ -152,7 +153,7 @@ class RemoveFakeMargins(object):
self.levels[level].append(p)
remove = set()
- for k, v in self.levels.iteritems():
+ for k, v in iteritems(self.levels):
num = len(v)
self.log.debug('Found %d items of level:'%num, k)
level = int(k.split('_')[-1])
diff --git a/src/calibre/ebooks/oeb/transforms/split.py b/src/calibre/ebooks/oeb/transforms/split.py
index 0c4f6c9ae3..65fdb91698 100644
--- a/src/calibre/ebooks/oeb/transforms/split.py
+++ b/src/calibre/ebooks/oeb/transforms/split.py
@@ -20,7 +20,7 @@ from calibre.ebooks.epub import rules
from calibre.ebooks.oeb.base import (OEB_STYLES, XPNSMAP as NAMESPACES,
urldefrag, rewrite_links, urlunquote, XHTML, urlnormalize)
from calibre.ebooks.oeb.polish.split import do_split
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, unicode_type, range
from css_selectors import Select, SelectorError
XPath = functools.partial(_XPath, namespaces=NAMESPACES)
@@ -243,7 +243,7 @@ class FlowSplitter(object):
self.trees = [orig_tree]
while ordered_ids:
- pb_id, (pattern, before) = ordered_ids.iteritems().next()
+ pb_id, (pattern, before) = next(iteritems(ordered_ids))
del ordered_ids[pb_id]
for i in range(len(self.trees)-1, -1, -1):
tree = self.trees[i]
diff --git a/src/calibre/ebooks/oeb/transforms/structure.py b/src/calibre/ebooks/oeb/transforms/structure.py
index 7d11f887b1..31c95c8aa1 100644
--- a/src/calibre/ebooks/oeb/transforms/structure.py
+++ b/src/calibre/ebooks/oeb/transforms/structure.py
@@ -13,7 +13,7 @@ from collections import OrderedDict, Counter
from calibre.ebooks.oeb.base import XPNSMAP, TOC, XHTML, xml2text, barename
from calibre.ebooks import ConversionError
-from polyglot.builtins import unicode_type
+from polyglot.builtins import itervalues, unicode_type
from polyglot.urllib import urlparse
@@ -85,8 +85,8 @@ class DetectStructure(object):
for item in oeb.spine:
for elem in pb_xpath(item.data):
try:
- prev = elem.itersiblings(tag=etree.Element,
- preceding=True).next()
+ prev = next(elem.itersiblings(tag=etree.Element,
+ preceding=True))
if (barename(elem.tag) in {'h1', 'h2'} and barename(
prev.tag) in {'h1', 'h2'} and (not prev.tail or
not prev.tail.split())):
@@ -271,8 +271,8 @@ class DetectStructure(object):
return []
for document in self.oeb.spine:
- previous_level1 = list(added.itervalues())[-1] if added else None
- previous_level2 = list(added2.itervalues())[-1] if added2 else None
+ previous_level1 = list(itervalues(added))[-1] if added else None
+ previous_level2 = list(itervalues(added2))[-1] if added2 else None
level1_toc, level1_title = self.get_toc_parts_for_xpath(self.opts.level1_toc)
for elem in find_matches(level1_toc, document.data):
diff --git a/src/calibre/ebooks/oeb/transforms/subset.py b/src/calibre/ebooks/oeb/transforms/subset.py
index 91bb5dde52..4e116ab4d4 100644
--- a/src/calibre/ebooks/oeb/transforms/subset.py
+++ b/src/calibre/ebooks/oeb/transforms/subset.py
@@ -11,7 +11,7 @@ from collections import defaultdict
from calibre.ebooks.oeb.base import urlnormalize
from calibre.utils.fonts.sfnt.subset import subset, NoGlyphs, UnsupportedFont
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, itervalues, unicode_type, range
from tinycss.fonts3 import parse_font_family
@@ -152,7 +152,7 @@ class SubsetFonts(object):
else:
fonts[item.href] = font
- for font in fonts.itervalues():
+ for font in itervalues(fonts):
if not font['chars']:
self.log('The font %s is unused. Removing it.'%font['src'])
remove(font)
@@ -171,8 +171,8 @@ class SubsetFonts(object):
totals[1] += sz
else:
font['item'].data = raw
- nlen = sum(new_stats.itervalues())
- olen = sum(old_stats.itervalues())
+ nlen = sum(itervalues(new_stats))
+ olen = sum(itervalues(old_stats))
self.log('Decreased the font %s to %.1f%% of its original size'%
(font['src'], nlen/olen *100))
totals[0] += nlen
@@ -208,7 +208,7 @@ class SubsetFonts(object):
if rule.type != rule.STYLE_RULE:
continue
props = {k:v for k,v in
- get_font_properties(rule).iteritems() if v}
+ iteritems(get_font_properties(rule)) if v}
if not props:
continue
for sel in rule.selectorList:
diff --git a/src/calibre/ebooks/pdf/reflow.py b/src/calibre/ebooks/pdf/reflow.py
index bc9dd27c9e..0016dc5400 100644
--- a/src/calibre/ebooks/pdf/reflow.py
+++ b/src/calibre/ebooks/pdf/reflow.py
@@ -40,7 +40,7 @@ class Image(Element):
def __init__(self, img, opts, log, idc):
Element.__init__(self)
self.opts, self.log = opts, log
- self.id = idc.next()
+ self.id = next(idc)
self.top, self.left, self.width, self.height, self.iwidth, self.iheight = \
map(float, map(img.get, ('top', 'left', 'rwidth', 'rheight', 'iwidth',
'iheight')))
@@ -61,7 +61,7 @@ class Text(Element):
def __init__(self, text, font_map, opts, log, idc):
Element.__init__(self)
- self.id = idc.next()
+ self.id = next(idc)
self.opts, self.log = opts, log
self.font_map = font_map
self.top, self.left, self.width, self.height = map(float, map(text.get,
diff --git a/src/calibre/ebooks/pdf/render/common.py b/src/calibre/ebooks/pdf/render/common.py
index 25313a8bc4..8c89f2589c 100644
--- a/src/calibre/ebooks/pdf/render/common.py
+++ b/src/calibre/ebooks/pdf/render/common.py
@@ -14,7 +14,7 @@ from binascii import hexlify
from calibre.constants import plugins, ispy3
from calibre.utils.logging import default_log
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, iterkeys, unicode_type
pdf_float = plugins['speedup'][0].pdf_float
@@ -146,7 +146,7 @@ class Dictionary(dict):
def pdf_serialize(self, stream):
stream.write(b'<<' + EOL)
- sorted_keys = sorted(self.iterkeys(),
+ sorted_keys = sorted(iterkeys(self),
key=lambda x:({'Type':'1', 'Subtype':'2'}.get(
x, x)+x))
for k in sorted_keys:
@@ -161,7 +161,7 @@ class InlineDictionary(Dictionary):
def pdf_serialize(self, stream):
stream.write(b'<< ')
- for k, v in self.iteritems():
+ for k, v in iteritems(self):
serialize(Name(k), stream)
stream.write(b' ')
serialize(v, stream)
diff --git a/src/calibre/ebooks/pdf/render/fonts.py b/src/calibre/ebooks/pdf/render/fonts.py
index 9fd6ba925a..aca2292c77 100644
--- a/src/calibre/ebooks/pdf/render/fonts.py
+++ b/src/calibre/ebooks/pdf/render/fonts.py
@@ -11,7 +11,7 @@ import re
from itertools import groupby
from operator import itemgetter
from collections import Counter, OrderedDict
-from polyglot.builtins import map, zip
+from polyglot.builtins import iteritems, iterkeys, map, zip
from calibre import as_unicode
from calibre.ebooks.pdf.render.common import (Array, String, Stream,
@@ -106,7 +106,7 @@ class CMap(Stream):
maps.append(current_map)
mapping = []
for m in maps:
- meat = '\n'.join('%s %s'%(k, v) for k, v in m.iteritems())
+ meat = '\n'.join('%s %s'%(k, v) for k, v in iteritems(m))
mapping.append('%d beginbfchar\n%s\nendbfchar'%(len(m), meat))
try:
name = name.encode('ascii').decode('ascii')
@@ -197,14 +197,14 @@ class Font(object):
widths = {g:self.metrics.pdf_scale(w) for g, w in zip(glyphs,
self.metrics.glyph_widths(glyphs))}
counter = Counter()
- for g, w in widths.iteritems():
+ for g, w in iteritems(widths):
counter[w] += 1
most_common = counter.most_common(1)[0][0]
self.descendant_font['DW'] = most_common
- widths = {g:w for g, w in widths.iteritems() if w != most_common}
+ widths = {g:w for g, w in iteritems(widths) if w != most_common}
groups = Array()
- for k, g in groupby(enumerate(widths.iterkeys()), lambda i_x:i_x[0]-i_x[1]):
+ for k, g in groupby(enumerate(iterkeys(widths)), lambda i_x:i_x[0]-i_x[1]):
group = list(map(itemgetter(1), g))
gwidths = [widths[g] for g in group]
if len(set(gwidths)) == 1 and len(group) > 1:
diff --git a/src/calibre/ebooks/pdf/render/from_html.py b/src/calibre/ebooks/pdf/render/from_html.py
index 0325a8db63..53c1341cb4 100644
--- a/src/calibre/ebooks/pdf/render/from_html.py
+++ b/src/calibre/ebooks/pdf/render/from_html.py
@@ -8,7 +8,6 @@ __copyright__ = '2012, Kovid Goyal '
__docformat__ = 'restructuredtext en'
import json, os, numbers
-from polyglot.builtins import map
from math import floor
from collections import defaultdict
@@ -25,7 +24,7 @@ from calibre.ebooks.pdf.render.common import (inch, cm, mm, pica, cicero,
from calibre.ebooks.pdf.render.engine import PdfDevice
from calibre.ptempfile import PersistentTemporaryFile
from calibre.utils.resources import load_hyphenator_dicts
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, itervalues, map, unicode_type
def get_page_size(opts, for_comic=False): # {{{
@@ -418,7 +417,7 @@ class PDFWriter(QObject):
except Exception:
doc_margins = None
if doc_margins and isinstance(doc_margins, dict):
- doc_margins = {k:float(v) for k, v in doc_margins.iteritems() if isinstance(v, numbers.Number) and k in {'right', 'top', 'left', 'bottom'}}
+ doc_margins = {k:float(v) for k, v in iteritems(doc_margins) if isinstance(v, numbers.Number) and k in {'right', 'top', 'left', 'bottom'}}
if doc_margins:
margin_top = margin_bottom = 0
page_margins = self.convert_page_margins(doc_margins)
@@ -439,7 +438,7 @@ class PDFWriter(QObject):
if not isinstance(amap, dict):
amap = {'links':[], 'anchors':{}} # Some javascript error occurred
- for val in amap['anchors'].itervalues():
+ for val in itervalues(amap['anchors']):
if isinstance(val, dict) and 'column' in val:
val['column'] = int(val['column'])
for href, val in amap['links']:
diff --git a/src/calibre/ebooks/pdf/render/links.py b/src/calibre/ebooks/pdf/render/links.py
index bc3751de65..d5fd908552 100644
--- a/src/calibre/ebooks/pdf/render/links.py
+++ b/src/calibre/ebooks/pdf/render/links.py
@@ -10,6 +10,7 @@ __docformat__ = 'restructuredtext en'
import os
from calibre.ebooks.pdf.render.common import Array, Name, Dictionary, String, UTF16String, current_log
+from polyglot.builtins import iteritems
from polyglot.urllib import unquote, urlparse
@@ -45,7 +46,7 @@ class Links(object):
path = os.path.normcase(os.path.abspath(base_path))
self.anchors[path] = a = {}
a[None] = Destination(start_page, self.start, self.pdf.get_pageref)
- for anchor, pos in anchors.iteritems():
+ for anchor, pos in iteritems(anchors):
a[anchor] = Destination(start_page, pos, self.pdf.get_pageref)
for link in links:
href, page, rect = link
diff --git a/src/calibre/ebooks/readability/htmls.py b/src/calibre/ebooks/readability/htmls.py
index 66a858326d..692f26c2ca 100644
--- a/src/calibre/ebooks/readability/htmls.py
+++ b/src/calibre/ebooks/readability/htmls.py
@@ -5,7 +5,7 @@ import lxml.html
from calibre.ebooks.readability.cleaners import normalize_spaces, clean_attributes
from calibre.ebooks.chardet import xml_to_unicode
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
def build_doc(page):
@@ -29,7 +29,7 @@ def normalize_entities(cur_title):
u'\u00BB': '"',
u'"': '"',
}
- for c, r in entities.iteritems():
+ for c, r in iteritems(entities):
if c in cur_title:
cur_title = cur_title.replace(c, r)
diff --git a/src/calibre/ebooks/rtf2xml/add_brackets.py b/src/calibre/ebooks/rtf2xml/add_brackets.py
index c3f42d30d2..0af94f6d35 100755
--- a/src/calibre/ebooks/rtf2xml/add_brackets.py
+++ b/src/calibre/ebooks/rtf2xml/add_brackets.py
@@ -15,6 +15,7 @@ import sys, os
from calibre.ebooks.rtf2xml import copy, check_brackets
from calibre.ptempfile import better_mktemp
+from polyglot.builtins import iteritems
class AddBrackets:
@@ -161,7 +162,7 @@ class AddBrackets:
self.__open_bracket = False
inline_string = ''.join(['%s%s \n%s\n'
@@ -121,7 +121,7 @@ def create_markdown_object(extensions):
if hasattr(module, 'makeExtension'):
return module.makeExtension(**configs)
for name, x in vars(module).items():
- if type(x) is type and issubclass(x, Extension) and x is not Extension:
+ if isinstance(x, type) and issubclass(x, Extension) and x is not Extension:
return x(**configs)
raise ImportError('No extension class in {}'.format(ext_name))
@@ -147,7 +147,7 @@ def convert_markdown_with_metadata(txt, title='', extensions=DEFAULT_MD_EXTENSIO
html = md.convert(txt)
mi = Metadata(title or _('Unknown'))
m = md.Meta
- for k, v in {'date':'pubdate', 'summary':'comments'}.iteritems():
+ for k, v in iteritems({'date':'pubdate', 'summary':'comments'}):
if v not in m and k in m:
m[v] = m.pop(k)
for k in 'title authors series tags pubdate comments publisher rating'.split():
diff --git a/src/calibre/ebooks/unihandecode/pykakasi/j2h.py b/src/calibre/ebooks/unihandecode/pykakasi/j2h.py
index d3f23f31a0..ddf0f23860 100644
--- a/src/calibre/ebooks/unihandecode/pykakasi/j2h.py
+++ b/src/calibre/ebooks/unihandecode/pykakasi/j2h.py
@@ -21,9 +21,11 @@
# *
# */
-from calibre.ebooks.unihandecode.pykakasi.jisyo import jisyo
import re
+from calibre.ebooks.unihandecode.pykakasi.jisyo import jisyo
+from polyglot.builtins import iteritems
+
class J2H (object):
@@ -65,7 +67,7 @@ class J2H (object):
table = self.kanwa.load_jisyo(text[0])
if table is None:
return ("", 0)
- for (k,v) in table.iteritems():
+ for (k,v) in iteritems(table):
length = len(k)
if len(text) >= length:
if text.startswith(k):
diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py
index 800c6df572..c6cfbea7eb 100644
--- a/src/calibre/gui2/__init__.py
+++ b/src/calibre/gui2/__init__.py
@@ -34,7 +34,8 @@ from calibre.utils.config import Config, ConfigProxy, JSONConfig, dynamic
from calibre.utils.date import UNDEFINED_DATE
from calibre.utils.file_type_icons import EXT_MAP
from calibre.utils.localization import get_lang
-from polyglot.builtins import unicode_type, string_or_bytes, range
+from polyglot.builtins import (iteritems, itervalues, unicode_type,
+ string_or_bytes, range)
from polyglot import queue
try:
@@ -569,7 +570,7 @@ class FileIconProvider(QFileIconProvider):
upath, bpath = I('mimetypes'), I('mimetypes', allow_user_override=False)
if upath != bpath:
# User has chosen to override mimetype icons
- path_map = {v:I('mimetypes/%s.png' % v) for v in set(self.ICONS.itervalues())}
+ path_map = {v:I('mimetypes/%s.png' % v) for v in set(itervalues(self.ICONS))}
icons = self.ICONS.copy()
for uicon in glob.glob(os.path.join(upath, '*.png')):
ukey = os.path.basename(uicon).rpartition('.')[0].lower()
@@ -577,18 +578,18 @@ class FileIconProvider(QFileIconProvider):
path_map[ukey] = uicon
icons[ukey] = ukey
else:
- path_map = {v:os.path.join(bpath, v + '.png') for v in set(self.ICONS.itervalues())}
+ path_map = {v:os.path.join(bpath, v + '.png') for v in set(itervalues(self.ICONS))}
icons = self.ICONS
- self.icons = {k:path_map[v] for k, v in icons.iteritems()}
+ self.icons = {k:path_map[v] for k, v in iteritems(icons)}
self.icons['calibre'] = I('lt.png', allow_user_override=False)
for i in ('dir', 'default', 'zero'):
self.icons[i] = QIcon(self.icons[i])
def key_from_ext(self, ext):
- key = ext if ext in self.icons.keys() else 'default'
+ key = ext if ext in list(self.icons.keys()) else 'default'
if key == 'default' and ext.count('.') > 0:
ext = ext.rpartition('.')[2]
- key = ext if ext in self.icons.keys() else 'default'
+ key = ext if ext in list(self.icons.keys()) else 'default'
return key
def cached_icon(self, key):
@@ -970,7 +971,7 @@ class Application(QApplication):
def load_calibre_style(self):
icon_map = self.__icon_map_memory_ = {}
pcache = {}
- for k, v in {
+ for k, v in iteritems({
'DialogYesButton': u'ok.png',
'DialogNoButton': u'window-close.png',
'DialogCloseButton': u'window-close.png',
@@ -987,7 +988,7 @@ class Application(QApplication):
'MessageBoxQuestion': u'dialog_question.png',
'BrowserReload': u'view-refresh.png',
'LineEditClearButton': u'clear_left.png',
- }.iteritems():
+ }):
if v not in pcache:
p = I(v)
if isinstance(p, bytes):
@@ -1099,7 +1100,7 @@ def sanitize_env_vars():
originals = {x:os.environ.get(x, '') for x in env_vars}
changed = {x:False for x in env_vars}
- for var, suffix in env_vars.iteritems():
+ for var, suffix in iteritems(env_vars):
paths = [x for x in originals[var].split(os.pathsep) if x]
npaths = [] if suffix is None else [x for x in paths if x != (sys.frozen_path + suffix)]
if len(npaths) < len(paths):
@@ -1112,7 +1113,7 @@ def sanitize_env_vars():
try:
yield
finally:
- for var, orig in originals.iteritems():
+ for var, orig in iteritems(originals):
if changed[var]:
if orig:
os.environ[var] = orig
@@ -1321,7 +1322,7 @@ if is_running_from_develop:
def event_type_name(ev_or_etype):
from PyQt5.QtCore import QEvent
etype = ev_or_etype.type() if isinstance(ev_or_etype, QEvent) else ev_or_etype
- for name, num in vars(QEvent).iteritems():
+ for name, num in iteritems(vars(QEvent)):
if num == etype:
return name
return 'UnknownEventType'
diff --git a/src/calibre/gui2/actions/__init__.py b/src/calibre/gui2/actions/__init__.py
index 30f85adef6..92c59c3444 100644
--- a/src/calibre/gui2/actions/__init__.py
+++ b/src/calibre/gui2/actions/__init__.py
@@ -278,7 +278,7 @@ class InterfaceAction(QObject):
For example to load an image::
pixmap = QPixmap()
- pixmap.loadFromData(self.load_resources(['images/icon.png']).itervalues().next())
+ next(pixmap.loadFromData(self.load_resources(['images/icon.png']).itervalues()))
icon = QIcon(pixmap)
:param names: List of paths to resources in the ZIP file using / as separator
diff --git a/src/calibre/gui2/actions/add.py b/src/calibre/gui2/actions/add.py
index 9b8575bd63..b44458a2f9 100644
--- a/src/calibre/gui2/actions/add.py
+++ b/src/calibre/gui2/actions/add.py
@@ -25,7 +25,7 @@ from calibre.gui2.actions import InterfaceAction
from calibre.gui2 import question_dialog
from calibre.ebooks.metadata import MetaInformation
from calibre.ptempfile import PersistentTemporaryFile
-from polyglot.builtins import string_or_bytes, range
+from polyglot.builtins import iteritems, string_or_bytes, range
def get_filters():
@@ -188,7 +188,7 @@ class AddAction(InterfaceAction):
fmt_map = {os.path.splitext(fpath)[1][1:].upper():fpath for fpath in paths}
for id_ in ids:
- for fmt, fpath in fmt_map.iteritems():
+ for fmt, fpath in iteritems(fmt_map):
if fmt:
db.add_format_with_hooks(id_, fmt, fpath, index_is_id=True,
notify=True)
diff --git a/src/calibre/gui2/actions/annotate.py b/src/calibre/gui2/actions/annotate.py
index b0d00e91c6..5be9babace 100644
--- a/src/calibre/gui2/actions/annotate.py
+++ b/src/calibre/gui2/actions/annotate.py
@@ -12,7 +12,7 @@ from calibre.gui2 import error_dialog
from calibre.gui2.actions import InterfaceAction
from calibre.devices.usbms.device import Device
from calibre.gui2.dialogs.progress import ProgressDialog
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, range
class Updater(QThread): # {{{
@@ -55,7 +55,7 @@ class Updater(QThread): # {{{
self.errors[id_] = traceback.format_exc()
self.update_progress.emit(i)
self.update_done.emit()
- self.done_callback(self.annotation_map.keys(), self.errors)
+ self.done_callback(list(self.annotation_map.keys()), self.errors)
# }}}
@@ -152,7 +152,7 @@ class FetchAnnotationsAction(InterfaceAction):
if errors:
db = self.gui.library_view.model().db
entries = []
- for id_, tb in errors.iteritems():
+ for id_, tb in iteritems(errors):
title = id_
if isinstance(id_, type(1)):
title = db.title(id_, index_is_id=True)
diff --git a/src/calibre/gui2/actions/author_mapper.py b/src/calibre/gui2/actions/author_mapper.py
index 5bbd41cd47..881699246c 100644
--- a/src/calibre/gui2/actions/author_mapper.py
+++ b/src/calibre/gui2/actions/author_mapper.py
@@ -4,11 +4,10 @@
from __future__ import (unicode_literals, division, absolute_import,
print_function)
-from polyglot.builtins import map
from calibre.gui2 import gprefs
from calibre.gui2.actions import InterfaceAction
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, map, range
class AuthorMapAction(InterfaceAction):
@@ -54,7 +53,7 @@ class AuthorMapAction(InterfaceAction):
author_map = db.all_field_for('authors', book_ids)
changed_author_map = {}
changed_author_sort_map = {}
- for book_id, authors in author_map.iteritems():
+ for book_id, authors in iteritems(author_map):
authors = list(authors)
new_authors = map_authors(authors, rules)
if authors != new_authors:
diff --git a/src/calibre/gui2/actions/choose_library.py b/src/calibre/gui2/actions/choose_library.py
index eb77c77610..19ccb10311 100644
--- a/src/calibre/gui2/actions/choose_library.py
+++ b/src/calibre/gui2/actions/choose_library.py
@@ -20,7 +20,7 @@ from calibre.utils.icu import sort_key
from calibre.gui2 import (gprefs, warning_dialog, Dispatcher, error_dialog,
question_dialog, info_dialog, open_local_file, choose_dir)
from calibre.gui2.actions import InterfaceAction
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iterkeys, unicode_type, range
def db_class():
@@ -40,7 +40,7 @@ class LibraryUsageStats(object): # {{{
# Rename the current library. Renaming of other libraries is
# handled by the switch function
q = os.path.basename(lp)
- for loc in list(self.stats.iterkeys()):
+ for loc in list(iterkeys(self.stats)):
bn = posixpath.basename(loc)
if bn.lower() == q.lower():
self.rename(loc, lp)
diff --git a/src/calibre/gui2/actions/copy_to_library.py b/src/calibre/gui2/actions/copy_to_library.py
index d9cb155ca1..fa4a2635fa 100644
--- a/src/calibre/gui2/actions/copy_to_library.py
+++ b/src/calibre/gui2/actions/copy_to_library.py
@@ -26,7 +26,7 @@ from calibre.gui2.widgets2 import Dialog
from calibre.utils.config import prefs
from calibre.utils.icu import sort_key, numeric_sort_key
from calibre.db.copy_to_library import copy_one_book
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, itervalues, unicode_type
def ask_about_cc_mismatch(gui, db, newdb, missing_cols, incompatible_cols): # {{{
@@ -279,7 +279,7 @@ class DuplicatesQuestion(QDialog): # {{{
self.setWindowTitle(_('Duplicate books'))
self.books = QListWidget(self)
self.items = []
- for book_id, (title, authors) in duplicates.iteritems():
+ for book_id, (title, authors) in iteritems(duplicates):
i = QListWidgetItem(_('{0} by {1}').format(title, ' & '.join(authors[:3])), self.books)
i.setData(Qt.UserRole, book_id)
i.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
@@ -492,7 +492,7 @@ class CopyToLibraryAction(InterfaceAction):
self.gui.status_bar.show_message(donemsg.format(num=len(self.worker.processed), loc=loc), 2000)
if self.worker.auto_merged_ids:
- books = '\n'.join(self.worker.auto_merged_ids.itervalues())
+ books = '\n'.join(itervalues(self.worker.auto_merged_ids))
info_dialog(self.gui, _('Auto merged'),
_('Some books were automatically merged into existing '
'records in the target library. Click "Show '
diff --git a/src/calibre/gui2/actions/edit_metadata.py b/src/calibre/gui2/actions/edit_metadata.py
index 2d8ef8e9a1..90d84e7d47 100644
--- a/src/calibre/gui2/actions/edit_metadata.py
+++ b/src/calibre/gui2/actions/edit_metadata.py
@@ -26,7 +26,7 @@ from calibre.db.errors import NoSuchFormat
from calibre.library.comments import merge_comments
from calibre.ebooks.metadata.sources.prefs import msprefs
from calibre.gui2.actions.show_quickview import get_quickview_action_plugin
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
class EditMetadataAction(InterfaceAction):
@@ -320,7 +320,7 @@ class EditMetadataAction(InterfaceAction):
failed_ids |= d.rejected_ids
restrict_to_failed = True
nid_map = {}
- for book_id, (changed, mi) in d.accepted.iteritems():
+ for book_id, (changed, mi) in iteritems(d.accepted):
if mi is None: # discarded
continue
if changed:
@@ -498,7 +498,7 @@ class EditMetadataAction(InterfaceAction):
'merge_too_many_books', self.gui)
def books_dropped(self, merge_map):
- for dest_id, src_ids in merge_map.iteritems():
+ for dest_id, src_ids in iteritems(merge_map):
if not self.confirm_large_merge(len(src_ids) + 1):
continue
from calibre.gui2.dialogs.confirm_merge import merge_drop
@@ -726,7 +726,7 @@ class EditMetadataAction(InterfaceAction):
if d.result() == d.Accepted:
to_rename = d.to_rename # dict of new text to old ids
to_delete = d.to_delete # list of ids
- for old_id, new_name in to_rename.iteritems():
+ for old_id, new_name in iteritems(to_rename):
model.rename_collection(old_id, new_name=unicode_type(new_name))
for item in to_delete:
model.delete_collection_using_id(item)
@@ -754,7 +754,7 @@ class EditMetadataAction(InterfaceAction):
'''
if title is None:
title = _('Applying changed metadata')
- self.apply_id_map = list(id_map.iteritems())
+ self.apply_id_map = list(iteritems(id_map))
self.apply_current_idx = 0
self.apply_failures = []
self.applied_ids = set()
diff --git a/src/calibre/gui2/actions/polish.py b/src/calibre/gui2/actions/polish.py
index 292dcf33d1..37e8dfd487 100644
--- a/src/calibre/gui2/actions/polish.py
+++ b/src/calibre/gui2/actions/polish.py
@@ -10,7 +10,7 @@ __docformat__ = 'restructuredtext en'
import os, weakref, shutil, textwrap
from collections import OrderedDict
from functools import partial
-from polyglot.builtins import map, unicode_type
+from polyglot.builtins import iteritems, itervalues, map, unicode_type
from PyQt5.Qt import (QDialog, QGridLayout, QIcon, QCheckBox, QLabel, QFrame,
QApplication, QDialogButtonBox, Qt, QSize, QSpacerItem,
@@ -92,7 +92,7 @@ class Polish(QDialog): # {{{
('upgrade_book', _('&Upgrade book internals')),
])
prefs = gprefs.get('polishing_settings', {})
- for name, text in self.all_actions.iteritems():
+ for name, text in iteritems(self.all_actions):
count += 1
x = QCheckBox(text, self)
x.setChecked(prefs.get(name, False))
@@ -241,7 +241,7 @@ class Polish(QDialog): # {{{
self.tdir = PersistentTemporaryDirectory('_queue_polish')
self.jobs = []
if len(self.book_id_map) <= 5:
- for i, (book_id, formats) in enumerate(self.book_id_map.iteritems()):
+ for i, (book_id, formats) in enumerate(iteritems(self.book_id_map)):
self.do_book(i+1, book_id, formats)
else:
self.queue = [(i+1, id_) for i, id_ in enumerate(self.book_id_map)]
@@ -452,7 +452,7 @@ class PolishAction(InterfaceAction):
db = self.gui.library_view.model().db
ans = (db.id(r) for r in rows)
ans = self.get_supported_books(ans)
- for fmts in ans.itervalues():
+ for fmts in itervalues(ans):
for x in fmts:
if x.startswith('ORIGINAL_'):
from calibre.gui2.dialogs.confirm_delete import confirm
@@ -481,7 +481,7 @@ class PolishAction(InterfaceAction):
' formats. Convert to one of those formats before polishing.')
%_(' or ').join(sorted(SUPPORTED)), show=True)
ans = OrderedDict(ans)
- for fmts in ans.itervalues():
+ for fmts in itervalues(ans):
for x in SUPPORTED:
if ('ORIGINAL_'+x) in fmts:
fmts.discard(x)
diff --git a/src/calibre/gui2/actions/save_to_disk.py b/src/calibre/gui2/actions/save_to_disk.py
index 6e1943ec16..0a41ed191b 100644
--- a/src/calibre/gui2/actions/save_to_disk.py
+++ b/src/calibre/gui2/actions/save_to_disk.py
@@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en'
import os, numbers
from functools import partial
-from polyglot.builtins import map
+from polyglot.builtins itervalues, import map
from calibre.utils.config import prefs
@@ -123,7 +123,7 @@ class SaveToDiskAction(InterfaceAction):
def save_library_format_by_ids(self, book_ids, fmt, single_dir=True):
if isinstance(book_ids, numbers.Integral):
book_ids = [book_ids]
- rows = list(self.gui.library_view.ids_to_rows(book_ids).itervalues())
+ rows = list(itervalues(self.gui.library_view.ids_to_rows(book_ids)))
rows = [self.gui.library_view.model().index(r, 0) for r in rows]
self.save_to_disk(True, single_dir=single_dir, single_format=fmt,
rows=rows, write_opf=False, save_cover=False)
diff --git a/src/calibre/gui2/actions/sort.py b/src/calibre/gui2/actions/sort.py
index 8d0159d40f..85336cdabd 100644
--- a/src/calibre/gui2/actions/sort.py
+++ b/src/calibre/gui2/actions/sort.py
@@ -10,6 +10,7 @@ from PyQt5.Qt import QToolButton, QAction, pyqtSignal, QIcon
from calibre.gui2.actions import InterfaceAction
from calibre.utils.icu import sort_key
+from polyglot.builtins import iteritems
class SortAction(QAction):
@@ -61,7 +62,7 @@ class SortByAction(InterfaceAction):
except TypeError:
sort_col, order = 'date', True
fm = db.field_metadata
- name_map = {v:k for k, v in fm.ui_sortable_field_keys().iteritems()}
+ name_map = {v:k for k, v in iteritems(fm.ui_sortable_field_keys())}
for name in sorted(name_map, key=sort_key):
key = name_map[name]
if key == 'ondevice' and self.gui.device_connected is None:
diff --git a/src/calibre/gui2/actions/tag_mapper.py b/src/calibre/gui2/actions/tag_mapper.py
index 9830903c09..5b4547192b 100644
--- a/src/calibre/gui2/actions/tag_mapper.py
+++ b/src/calibre/gui2/actions/tag_mapper.py
@@ -4,7 +4,7 @@
from __future__ import (unicode_literals, division, absolute_import,
print_function)
-from polyglot.builtins import map, range
+from polyglot.builtins import iteritems, map, range
from calibre.gui2 import gprefs
from calibre.gui2.actions import InterfaceAction
@@ -51,7 +51,7 @@ class TagMapAction(InterfaceAction):
db = self.gui.current_db.new_api
tag_map = db.all_field_for('tags', book_ids)
changed_tag_map = {}
- for book_id, tags in tag_map.iteritems():
+ for book_id, tags in iteritems(tag_map):
tags = list(tags)
new_tags = map_tags(tags, rules)
if tags != new_tags:
diff --git a/src/calibre/gui2/actions/toc_edit.py b/src/calibre/gui2/actions/toc_edit.py
index 518e98007a..25923733a6 100644
--- a/src/calibre/gui2/actions/toc_edit.py
+++ b/src/calibre/gui2/actions/toc_edit.py
@@ -14,7 +14,7 @@ from PyQt5.Qt import (QTimer, QDialog, QGridLayout, QCheckBox, QLabel,
from calibre.gui2 import error_dialog, gprefs
from calibre.gui2.actions import InterfaceAction
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
SUPPORTED = {'EPUB', 'AZW3'}
@@ -130,7 +130,7 @@ class ToCEditAction(InterfaceAction):
return self.get_supported_books(ans)
def do_edit(self, book_id_map):
- for book_id, fmts in book_id_map.iteritems():
+ for book_id, fmts in iteritems(book_id_map):
if len(fmts) > 1:
d = ChooseFormat(fmts, self.gui)
if d.exec_() != d.Accepted:
diff --git a/src/calibre/gui2/add.py b/src/calibre/gui2/add.py
index 7aa6130644..0429fb0cbb 100644
--- a/src/calibre/gui2/add.py
+++ b/src/calibre/gui2/add.py
@@ -10,7 +10,7 @@ import shutil, os, weakref, traceback, tempfile, time
from threading import Thread
from collections import OrderedDict
from io import BytesIO
-from polyglot.builtins import map, unicode_type, string_or_bytes
+from polyglot.builtins import iteritems, map, unicode_type, string_or_bytes
from PyQt5.Qt import QObject, Qt, pyqtSignal
@@ -435,7 +435,7 @@ class Adder(QObject):
def add_formats(self, book_id, paths, mi, replace=True, is_an_add=False):
fmap = {p.rpartition(os.path.extsep)[-1].lower():p for p in paths}
fmt_map = {}
- for fmt, path in fmap.iteritems():
+ for fmt, path in iteritems(fmap):
# The onimport plugins have already been run by the read metadata
# worker
if self.ignore_opf and fmt.lower() == 'opf':
diff --git a/src/calibre/gui2/bars.py b/src/calibre/gui2/bars.py
index f861c71525..82cb93c5b0 100644
--- a/src/calibre/gui2/bars.py
+++ b/src/calibre/gui2/bars.py
@@ -19,7 +19,7 @@ except ImportError:
from calibre.constants import isosx
from calibre.gui2 import gprefs, native_menubar_defaults, config
from calibre.gui2.throbber import ThrobbingButton
-from polyglot.builtins import unicode_type
+from polyglot.builtins import itervalues, unicode_type
class RevealBar(QWidget): # {{{
@@ -238,7 +238,7 @@ class ToolBar(QToolBar): # {{{
def check_iactions_for_drag(self, event, md, func):
if self.added_actions:
pos = event.pos()
- for iac in self.gui.iactions.itervalues():
+ for iac in itervalues(self.gui.iactions):
if iac.accepts_drops:
aa = iac.qaction
w = self.widgetForAction(aa)
diff --git a/src/calibre/gui2/convert/look_and_feel.py b/src/calibre/gui2/convert/look_and_feel.py
index 3ab986b828..15470e3839 100644
--- a/src/calibre/gui2/convert/look_and_feel.py
+++ b/src/calibre/gui2/convert/look_and_feel.py
@@ -13,7 +13,7 @@ from PyQt5.Qt import Qt
from calibre.gui2.convert.look_and_feel_ui import Ui_Form
from calibre.gui2.convert import Widget
from calibre.ebooks.conversion.config import OPTIONS
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
class LookAndFeelWidget(Widget, Ui_Form):
@@ -59,7 +59,7 @@ class LookAndFeelWidget(Widget, Ui_Form):
return ans
if g is self.opt_filter_css:
ans = set()
- for key, item in self.FILTER_CSS.iteritems():
+ for key, item in iteritems(self.FILTER_CSS):
w = getattr(self, 'filter_css_%s'%key)
if w.isChecked():
ans = ans.union(item)
@@ -86,7 +86,7 @@ class LookAndFeelWidget(Widget, Ui_Form):
if not val:
val = ''
items = frozenset([x.strip().lower() for x in val.split(',')])
- for key, vals in self.FILTER_CSS.iteritems():
+ for key, vals in iteritems(self.FILTER_CSS):
w = getattr(self, 'filter_css_%s'%key)
if not vals - items:
items = items - vals
diff --git a/src/calibre/gui2/convert/txt_input.py b/src/calibre/gui2/convert/txt_input.py
index fff09f18fe..dc66e16278 100644
--- a/src/calibre/gui2/convert/txt_input.py
+++ b/src/calibre/gui2/convert/txt_input.py
@@ -10,7 +10,7 @@ from calibre.gui2.convert.txt_input_ui import Ui_Form
from calibre.gui2.convert import Widget
from calibre.ebooks.conversion.plugins.txt_input import MD_EXTENSIONS
from calibre.ebooks.conversion.config import OPTIONS
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, itervalues, unicode_type
class PluginWidget(Widget, Ui_Form):
@@ -28,7 +28,7 @@ class PluginWidget(Widget, Ui_Form):
for x in get_option('formatting_type').option.choices:
self.opt_formatting_type.addItem(x)
self.md_map = {}
- for name, text in MD_EXTENSIONS.iteritems():
+ for name, text in iteritems(MD_EXTENSIONS):
i = QListWidgetItem('%s - %s' % (name, text), self.opt_markdown_extensions)
i.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
i.setData(Qt.UserRole, name)
@@ -38,7 +38,7 @@ class PluginWidget(Widget, Ui_Form):
def set_value_handler(self, g, val):
if g is self.opt_markdown_extensions:
- for i in self.md_map.itervalues():
+ for i in itervalues(self.md_map):
i.setCheckState(Qt.Unchecked)
for x in val.split(','):
x = x.strip()
@@ -49,7 +49,7 @@ class PluginWidget(Widget, Ui_Form):
def get_value_handler(self, g):
if g is not self.opt_markdown_extensions:
return Widget.get_value_handler(self, g)
- return ', '.join(unicode_type(i.data(Qt.UserRole) or '') for i in self.md_map.itervalues() if i.checkState())
+ return ', '.join(unicode_type(i.data(Qt.UserRole) or '') for i in itervalues(self.md_map) if i.checkState())
def connect_gui_obj_handler(self, g, f):
if g is not self.opt_markdown_extensions:
diff --git a/src/calibre/gui2/covers.py b/src/calibre/gui2/covers.py
index f5d4e574dc..d6103c6072 100644
--- a/src/calibre/gui2/covers.py
+++ b/src/calibre/gui2/covers.py
@@ -19,6 +19,7 @@ from calibre.gui2 import gprefs, error_dialog
from calibre.gui2.font_family_chooser import FontFamilyChooser
from calibre.utils.date import now
from calibre.utils.icu import sort_key
+from polyglot.builtins import iteritems, itervalues
class Preview(QLabel):
@@ -305,12 +306,12 @@ class CoverSettingsWidget(QWidget):
if not self.for_global_prefs and lu in self.colors_map and self.colors_map[lu].checkState() == Qt.Checked:
self.colors_map[lu].setSelected(True)
else:
- for name, li in self.colors_map.iteritems():
+ for name, li in iteritems(self.colors_map):
if li.checkState() == Qt.Checked:
li.setSelected(True)
break
else:
- next(self.colors_map.itervalues()).setSelected(True)
+ next(itervalues(self.colors_map)).setSelected(True)
disabled = set(prefs['disabled_styles'])
self.styles_list.clear()
@@ -323,42 +324,42 @@ class CoverSettingsWidget(QWidget):
if not self.for_global_prefs and lu in self.style_map and self.style_map[lu].checkState() == Qt.Checked:
self.style_map[lu].setSelected(True)
else:
- for name, li in self.style_map.iteritems():
+ for name, li in iteritems(self.style_map):
if li.checkState() == Qt.Checked:
li.setSelected(True)
break
else:
- next(self.style_map.itervalues()).setSelected(True)
+ next(itervalues(self.style_map)).setSelected(True)
@property
def current_colors(self):
- for name, li in self.colors_map.iteritems():
+ for name, li in iteritems(self.colors_map):
if li.isSelected():
return name
@property
def disabled_colors(self):
- for name, li in self.colors_map.iteritems():
+ for name, li in iteritems(self.colors_map):
if li.checkState() == Qt.Unchecked:
yield name
@property
def custom_colors(self):
ans = {}
- for name, li in self.colors_map.iteritems():
+ for name, li in iteritems(self.colors_map):
if name.startswith('#'):
ans[name] = li.data(Qt.UserRole)
return ans
@property
def current_style(self):
- for name, li in self.style_map.iteritems():
+ for name, li in iteritems(self.style_map):
if li.isSelected():
return name
@property
def disabled_styles(self):
- for name, li in self.style_map.iteritems():
+ for name, li in iteritems(self.style_map):
if li.checkState() == Qt.Unchecked:
yield name
@@ -386,7 +387,7 @@ class CoverSettingsWidget(QWidget):
self.colors_list.insertItem(0, li)
cm = OrderedDict()
cm[name] = li
- for k, v in self.colors_map.iteritems():
+ for k, v in iteritems(self.colors_map):
cm[k] = v
self.colors_map = cm
li.setSelected(True)
@@ -502,7 +503,7 @@ class CoverSettingsWidget(QWidget):
def save_as_prefs(self):
with self.original_prefs:
- for k, v in self.current_prefs.iteritems():
+ for k, v in iteritems(self.current_prefs):
self.original_prefs[k] = v
diff --git a/src/calibre/gui2/css_transform_rules.py b/src/calibre/gui2/css_transform_rules.py
index 361552e1e5..fefb04ba43 100644
--- a/src/calibre/gui2/css_transform_rules.py
+++ b/src/calibre/gui2/css_transform_rules.py
@@ -19,7 +19,7 @@ from calibre.gui2.tag_mapper import (
from calibre.gui2.widgets2 import Dialog
from calibre.utils.config import JSONConfig
from calibre.utils.localization import localize_user_manual_link
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
class RuleEdit(QWidget): # {{{
@@ -50,7 +50,7 @@ class RuleEdit(QWidget): # {{{
'For instance use margin-top, not margin.'))
elif clause == '{match_type}':
self.match_type = w = QComboBox(self)
- for action, text in MATCH_TYPE_MAP.iteritems():
+ for action, text in iteritems(MATCH_TYPE_MAP):
w.addItem(text, action)
w.currentIndexChanged.connect(self.update_state)
elif clause == '{query}':
@@ -70,7 +70,7 @@ class RuleEdit(QWidget): # {{{
for clause in parts:
if clause == '{action}':
self.action = w = QComboBox(self)
- for action, text in ACTION_MAP.iteritems():
+ for action, text in iteritems(ACTION_MAP):
w.addItem(text, action)
w.currentIndexChanged.connect(self.update_state)
elif clause == '{action_data}':
diff --git a/src/calibre/gui2/custom_column_widgets.py b/src/calibre/gui2/custom_column_widgets.py
index 1c73867eae..723580ba89 100644
--- a/src/calibre/gui2/custom_column_widgets.py
+++ b/src/calibre/gui2/custom_column_widgets.py
@@ -837,7 +837,7 @@ class BulkBase(Base):
break
ans = None
if len(values) == 1:
- ans = iter(values).next()
+ ans = next(iter(values))
if isinstance(ans, frozenset):
ans = list(ans)
return ans
diff --git a/src/calibre/gui2/dbus_export/menu.py b/src/calibre/gui2/dbus_export/menu.py
index 571fe48193..749a31bc37 100644
--- a/src/calibre/gui2/dbus_export/menu.py
+++ b/src/calibre/gui2/dbus_export/menu.py
@@ -16,6 +16,7 @@ from PyQt5.Qt import (
from calibre.utils.dbus_service import Object, BusName, method as dbus_method, dbus_property, signal as dbus_signal
from calibre.gui2.dbus_export.utils import (
setup_for_cli_run, swap_mnemonic_char, key_sequence_to_dbus_shortcut, icon_to_dbus_menu_icon)
+from polyglot.builtins import iteritems
null = object()
@@ -124,7 +125,7 @@ class DBusMenu(QObject):
return {}
ans = self._action_properties.get(action_id, PropDict())
if restrict_to:
- ans = PropDict({k:v for k, v in ans.iteritems() if k in restrict_to})
+ ans = PropDict({k:v for k, v in iteritems(ans) if k in restrict_to})
return ans
def publish_new_menu(self, qmenu=None):
@@ -195,7 +196,7 @@ class DBusMenu(QObject):
removed = set(old_props) - set(new_props)
if removed:
removed_props.append((ac_id, dbus.Array(removed, signature='as')))
- updated = PropDict({k:v for k, v in new_props.iteritems() if v != old_props.get(k, null)})
+ updated = PropDict({k:v for k, v in iteritems(new_props) if v != old_props.get(k, null)})
if updated:
updated_props.append((ac_id, updated))
self.action_changes = set()
diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py
index 7414e4102f..dcc8b1a6fc 100644
--- a/src/calibre/gui2/device.py
+++ b/src/calibre/gui2/device.py
@@ -411,7 +411,7 @@ class DeviceManager(Thread): # {{{
do_sleep = True
while True:
- job = self.next()
+ job = next(self)
if job is not None:
do_sleep = False
self.current_job = job
@@ -1494,8 +1494,8 @@ class DeviceMixin(object): # {{{
bad, good, gf, names, remove_ids = [], [], [], [], []
for f in _files:
- mi = imetadata.next()
- id = ids.next()
+ mi = next(imetadata)
+ id = next(ids)
if f is None:
bad.append(mi.title)
else:
diff --git a/src/calibre/gui2/device_drivers/mtp_config.py b/src/calibre/gui2/device_drivers/mtp_config.py
index ef3607fd1c..37a904402c 100644
--- a/src/calibre/gui2/device_drivers/mtp_config.py
+++ b/src/calibre/gui2/device_drivers/mtp_config.py
@@ -20,7 +20,7 @@ from calibre.gui2 import error_dialog
from calibre.gui2.dialogs.template_dialog import TemplateDialog
from calibre.utils.date import parse_date
from calibre.gui2.device_drivers.mtp_folder_browser import Browser, IgnoredFolders
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, unicode_type, range
class FormatsConfig(QWidget): # {{{
@@ -177,7 +177,7 @@ class IgnoredDevices(QWidget): # {{{
l.addWidget(f)
devs = [(snum, (x[0], parse_date(x[1]))) for snum, x in
- devs.iteritems()]
+ iteritems(devs)]
for dev, x in sorted(devs, key=lambda x:x[1][1], reverse=True):
name = x[0]
name = '%s [%s]'%(name, dev)
diff --git a/src/calibre/gui2/dialogs/custom_recipes.py b/src/calibre/gui2/dialogs/custom_recipes.py
index 8c0b5dea1f..7b33412c5c 100644
--- a/src/calibre/gui2/dialogs/custom_recipes.py
+++ b/src/calibre/gui2/dialogs/custom_recipes.py
@@ -21,7 +21,7 @@ from calibre.gui2.tweak_book.editor.text import TextEdit
from calibre.utils.icu import sort_key
from calibre.web.feeds.recipes.collection import get_builtin_recipe_collection, get_builtin_recipe_by_id
from calibre.utils.localization import localize_user_manual_link
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, unicode_type, range
def is_basic_recipe(src):
@@ -70,7 +70,7 @@ class CustomRecipeModel(QAbstractListModel): # {{{
def replace_many_by_title(self, scriptmap):
script_urn_map = {}
- for title, script in scriptmap.iteritems():
+ for title, script in iteritems(scriptmap):
urn = None
for x in self.recipe_model.custom_recipe_collection:
if x.get('title', False) == title:
@@ -650,7 +650,7 @@ class CustomRecipes(Dialog):
if replace_recipes:
self.recipe_list.replace_many_by_title(replace_recipes)
if failed_recipes:
- det_msg = '\n'.join('%s\n%s\n' % (title, tb) for title, tb in failed_recipes.iteritems())
+ det_msg = '\n'.join('%s\n%s\n' % (title, tb) for title, tb in iteritems(failed_recipes))
error_dialog(self, _('Failed to create recipes'), _(
'Failed to create some recipes, click "Show details" for details'), show=True,
det_msg=det_msg)
diff --git a/src/calibre/gui2/dialogs/metadata_bulk.py b/src/calibre/gui2/dialogs/metadata_bulk.py
index 612c0148a1..8c53ff7c0c 100644
--- a/src/calibre/gui2/dialogs/metadata_bulk.py
+++ b/src/calibre/gui2/dialogs/metadata_bulk.py
@@ -32,7 +32,7 @@ from calibre.utils.date import qt_to_dt, internal_iso_format_string
from calibre.utils.icu import capitalize, sort_key
from calibre.utils.titlecase import titlecase
from calibre.gui2.widgets import LineEditECM
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, itervalues, unicode_type
Settings = namedtuple('Settings',
'remove_all remove add au aus do_aus rating pub do_series do_autonumber '
@@ -241,8 +241,8 @@ class MyBlockingBusy(QDialog): # {{{
def new_title(authors):
ans = authors_to_string(authors)
return change_title_casing(ans) if args.do_title_case else ans
- new_title_map = {bid:new_title(authors) for bid, authors in authors_map.iteritems()}
- new_authors_map = {bid:string_to_authors(title) for bid, title in title_map.iteritems()}
+ new_title_map = {bid:new_title(authors) for bid, authors in iteritems(authors_map)}
+ new_authors_map = {bid:string_to_authors(title) for bid, title in iteritems(title_map)}
self.progress_update.emit(1)
cache.set_field('authors', new_authors_map)
cache.set_field('title', new_title_map)
@@ -252,7 +252,7 @@ class MyBlockingBusy(QDialog): # {{{
if args.do_title_case and not args.do_swap_ta:
self.progress_next_step_range.emit(0)
title_map = cache.all_field_for('title', self.ids)
- cache.set_field('title', {bid:change_title_casing(title) for bid, title in title_map.iteritems()})
+ cache.set_field('title', {bid:change_title_casing(title) for bid, title in iteritems(title_map)})
self.progress_finished_cur_step.emit()
if args.do_title_sort:
@@ -392,7 +392,7 @@ class MyBlockingBusy(QDialog): # {{{
def next_series_num(bid, i):
if args.do_series_restart:
return sval + (i * args.series_increment)
- next_num = _get_next_series_num_for_list(sorted(sval.itervalues()), unwrap=False)
+ next_num = _get_next_series_num_for_list(sorted(itervalues(sval)), unwrap=False)
sval[bid] = next_num
return next_num
@@ -443,7 +443,7 @@ class MyBlockingBusy(QDialog): # {{{
if self.sr_calls:
self.progress_next_step_range.emit(len(self.sr_calls))
self.progress_update.emit(0)
- for field, book_id_val_map in self.sr_calls.iteritems():
+ for field, book_id_val_map in iteritems(self.sr_calls):
self.refresh_books.update(self.db.new_api.set_field(field, book_id_val_map))
self.progress_update.emit(1)
self.progress_finished_cur_step.emit()
@@ -781,7 +781,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog):
if id_type:
val = [val.get(id_type, '')]
else:
- val = [u'%s:%s'%(t[0], t[1]) for t in val.iteritems()]
+ val = [u'%s:%s'%(t[0], t[1]) for t in iteritems(val)]
if val is None:
val = [] if fm['is_multiple'] else ['']
elif not fm['is_multiple']:
@@ -959,7 +959,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog):
dest_val = [dest_val.get(dst_id_type, '')]
else:
# convert the csp dict into a list
- dest_val = [u'%s:%s'%(t[0], t[1]) for t in dest_val.iteritems()]
+ dest_val = [u'%s:%s'%(t[0], t[1]) for t in iteritems(dest_val)]
if dest_val is None:
dest_val = []
elif not isinstance(dest_val, list):
@@ -1269,7 +1269,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog):
self.query_field.blockSignals(False)
self.query_field.setCurrentIndex(0)
- if item_name in self.queries.keys():
+ if item_name in list(self.queries.keys()):
del(self.queries[item_name])
self.queries.commit()
@@ -1291,7 +1291,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog):
_("You must provide a name."), show=True)
new = True
name = unicode_type(name)
- if name in self.queries.keys():
+ if name in list(self.queries.keys()):
if not question_dialog(self, _("Save search/replace"),
_("That saved search/replace already exists and will be overwritten. "
"Are you sure?")):
diff --git a/src/calibre/gui2/dialogs/opml.py b/src/calibre/gui2/dialogs/opml.py
index 7f7efc8a22..2b6bde5f3f 100644
--- a/src/calibre/gui2/dialogs/opml.py
+++ b/src/calibre/gui2/dialogs/opml.py
@@ -17,7 +17,7 @@ from lxml import etree
from calibre.gui2 import choose_files, error_dialog
from calibre.utils.icu import sort_key
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iterkeys, unicode_type
Group = namedtuple('Group', 'title feeds')
@@ -49,7 +49,7 @@ def import_opml(raw, preserve_groups=True):
break
groups[parent].append((title, url))
- for title in sorted(groups.iterkeys(), key=sort_key):
+ for title in sorted(iterkeys(groups), key=sort_key):
yield Group(title, uniq(groups[title], kmap=itemgetter(1)))
diff --git a/src/calibre/gui2/dialogs/plugin_updater.py b/src/calibre/gui2/dialogs/plugin_updater.py
index 34616b56c8..cfcddde0e1 100644
--- a/src/calibre/gui2/dialogs/plugin_updater.py
+++ b/src/calibre/gui2/dialogs/plugin_updater.py
@@ -24,7 +24,7 @@ from calibre.gui2 import error_dialog, question_dialog, info_dialog, open_url, g
from calibre.gui2.preferences.plugins import ConfigWidget
from calibre.utils.date import UNDEFINED_DATE, format_date
from calibre.utils.https import get_https_resource_securely
-from polyglot.builtins import unicode_type
+from polyglot.builtins import itervalues, unicode_type
SERVER = 'https://code.calibre-ebook.com/plugins/'
INDEX_URL = '%splugins.json.bz2' % SERVER
@@ -72,7 +72,7 @@ def read_available_plugins(raise_error=False):
raise
traceback.print_exc()
return
- for plugin in raw.itervalues():
+ for plugin in itervalues(raw):
try:
display_plugin = DisplayPlugin(plugin)
get_installed_plugin_status(display_plugin)
diff --git a/src/calibre/gui2/dialogs/scheduler.py b/src/calibre/gui2/dialogs/scheduler.py
index 27be20cb99..67a835a1fc 100644
--- a/src/calibre/gui2/dialogs/scheduler.py
+++ b/src/calibre/gui2/dialogs/scheduler.py
@@ -26,7 +26,7 @@ from calibre.utils.date import utcnow
from calibre.utils.network import internet_connected
from calibre import force_unicode
from calibre.utils.localization import get_lang, canonicalize_lang
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, unicode_type, range
def convert_day_time_schedule(val):
@@ -314,7 +314,7 @@ class SchedulerDialog(QDialog):
g.addWidget(spw, 2, 0, 1, 2)
self.rla = la = QLabel(_("For the scheduling to work, you must leave calibre running."))
vt.addWidget(la)
- for b, c in self.SCHEDULE_TYPES.iteritems():
+ for b, c in iteritems(self.SCHEDULE_TYPES):
b = getattr(self, b)
b.toggled.connect(self.schedule_type_selected)
b.setToolTip(textwrap.dedent(c.HELP))
diff --git a/src/calibre/gui2/dialogs/search.py b/src/calibre/gui2/dialogs/search.py
index 1bc27dfb21..0a3ebd278a 100644
--- a/src/calibre/gui2/dialogs/search.py
+++ b/src/calibre/gui2/dialogs/search.py
@@ -19,7 +19,7 @@ from calibre.utils.icu import sort_key
from calibre.utils.config import tweaks
from calibre.utils.date import now
from calibre.utils.localization import localize_user_manual_link
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, unicode_type, range
box_values = {}
last_matchkind = CONTAINS_MATCH
@@ -174,7 +174,7 @@ def create_date_tab(self, db):
w.h1 = h = QHBoxLayout()
l.addLayout(h)
self.date_field = df = add(_("&Search the"), QComboBox(w))
- vals = [((v['search_terms'] or [k])[0], v['name'] or k) for k, v in db.field_metadata.iteritems() if v.get('datatype', None) == 'datetime']
+ vals = [((v['search_terms'] or [k])[0], v['name'] or k) for k, v in iteritems(db.field_metadata) if v.get('datatype', None) == 'datetime']
for k, v in sorted(vals, key=lambda k_v: sort_key(k_v[1])):
df.addItem(v, k)
h.addWidget(df)
diff --git a/src/calibre/gui2/dialogs/smartdevice.py b/src/calibre/gui2/dialogs/smartdevice.py
index 57b5ad55c3..324f9af2fe 100644
--- a/src/calibre/gui2/dialogs/smartdevice.py
+++ b/src/calibre/gui2/dialogs/smartdevice.py
@@ -10,7 +10,7 @@ from PyQt5.Qt import (QDialog, QLineEdit, Qt)
from calibre.gui2 import error_dialog
from calibre.gui2.dialogs.smartdevice_ui import Ui_Dialog
from calibre.utils.mdns import get_all_ips
-from polyglot.builtins import unicode_type
+from polyglot.builtins import itervalues, unicode_type
def _cmp_ipaddr(l, r):
@@ -30,7 +30,7 @@ def _cmp_ipaddr(l, r):
def get_all_ip_addresses():
ipaddrs = list()
- for iface in get_all_ips().itervalues():
+ for iface in itervalues(get_all_ips()):
for addrs in iface:
if 'broadcast' in addrs and addrs['addr'] != '127.0.0.1':
ipaddrs.append(addrs['addr'])
diff --git a/src/calibre/gui2/dialogs/tag_categories.py b/src/calibre/gui2/dialogs/tag_categories.py
index 783a513bec..52756a5a8a 100644
--- a/src/calibre/gui2/dialogs/tag_categories.py
+++ b/src/calibre/gui2/dialogs/tag_categories.py
@@ -10,7 +10,7 @@ from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.gui2 import error_dialog
from calibre.constants import islinux
from calibre.utils.icu import sort_key, strcmp
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
class Item(object):
@@ -69,7 +69,7 @@ class TagCategories(QDialog, Ui_TagCategories):
]
category_names = ['', _('Authors'), ngettext('Series', 'Series', 2), _('Publishers'), _('Tags')]
- for key,cc in self.db.custom_field_metadata().iteritems():
+ for key,cc in iteritems(self.db.custom_field_metadata()):
if cc['datatype'] in ['text', 'series', 'enumeration']:
self.category_labels.append(key)
self.category_icons.append(cc_icon)
diff --git a/src/calibre/gui2/email.py b/src/calibre/gui2/email.py
index f24f131923..3fcfc9696a 100644
--- a/src/calibre/gui2/email.py
+++ b/src/calibre/gui2/email.py
@@ -28,7 +28,7 @@ from calibre.library.save_to_disk import get_components
from calibre.utils.config import tweaks, prefs
from calibre.utils.icu import primary_sort_key
from calibre.gui2.threaded_jobs import ThreadedJob
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, itervalues, unicode_type
class Worker(Thread):
@@ -321,7 +321,7 @@ class EmailMixin(object): # {{{
for to, fmts, subject in recipients:
rfmts = set(fmts)
- ok_ids = {book_id for book_id, bfmts in db_fmt_map.iteritems() if bfmts.intersection(rfmts)}
+ ok_ids = {book_id for book_id, bfmts in iteritems(db_fmt_map) if bfmts.intersection(rfmts)}
convert_ids = ids - ok_ids
self.send_by_mail(to, fmts, delete_from_library, subject=subject, send_ids=ok_ids, do_auto_convert=False)
if not rfmts.intersection(ofmts):
@@ -336,20 +336,20 @@ class EmailMixin(object): # {{{
auto_convert_map[outfmt].append((to, subject, ok_ids))
if auto_convert_map:
- titles = {book_id for x in auto_convert_map.itervalues() for data in x for book_id in data[2]}
+ titles = {book_id for x in itervalues(auto_convert_map) for data in x for book_id in data[2]}
titles = {db.title(book_id, index_is_id=True) for book_id in titles}
if self.auto_convert_question(
_('Auto convert the following books before sending via email?'), list(titles)):
- for ofmt, data in auto_convert_map.iteritems():
+ for ofmt, data in iteritems(auto_convert_map):
ids = {bid for x in data for bid in x[2]}
data = [(to, subject) for to, subject, x in data]
self.iactions['Convert Books'].auto_convert_multiple_mail(ids, data, ofmt, delete_from_library)
if bad_recipients:
det_msg = []
- titles = {book_id for x in bad_recipients.itervalues() for book_id in x[0]}
+ titles = {book_id for x in itervalues(bad_recipients) for book_id in x[0]}
titles = {book_id:db.title(book_id, index_is_id=True) for book_id in titles}
- for to, (ids, nooutput) in bad_recipients.iteritems():
+ for to, (ids, nooutput) in iteritems(bad_recipients):
msg = _('This recipient has no valid formats defined') if nooutput else \
_('These books have no suitable input formats for conversion')
det_msg.append('%s - %s' % (to, msg))
@@ -506,4 +506,4 @@ class EmailMixin(object): # {{{
if __name__ == '__main__':
from PyQt5.Qt import QApplication
app = QApplication([]) # noqa
- print (select_recipients())
+ print(select_recipients())
diff --git a/src/calibre/gui2/gestures.py b/src/calibre/gui2/gestures.py
index 81afadbbd8..b841e19c98 100644
--- a/src/calibre/gui2/gestures.py
+++ b/src/calibre/gui2/gestures.py
@@ -12,6 +12,7 @@ from PyQt5.Qt import (
from calibre.constants import iswindows
from calibre.utils.monotonic import monotonic
+from polyglot.builtins import itervalues
touch_supported = False
if iswindows and sys.getwindowsversion()[:2] >= (6, 2): # At least windows 7
@@ -91,14 +92,14 @@ class State(QObject):
else:
self.check_for_holds()
if Flick in self.possible_gestures:
- tp = next(self.touch_points.itervalues())
+ tp = next(itervalues(self.touch_points))
self.flicking.emit(tp, False)
def check_for_holds(self):
if not {TapAndHold} & self.possible_gestures:
return
now = monotonic()
- tp = next(self.touch_points.itervalues())
+ tp = next(itervalues(self.touch_points))
if now - tp.time_of_last_move < HOLD_THRESHOLD:
return
if self.hold_started:
@@ -116,20 +117,20 @@ class State(QObject):
def finalize(self):
if Tap in self.possible_gestures:
- tp = next(self.touch_points.itervalues())
+ tp = next(itervalues(self.touch_points))
if tp.total_movement <= TAP_THRESHOLD:
self.tapped.emit(tp)
return
if Flick in self.possible_gestures:
- tp = next(self.touch_points.itervalues())
+ tp = next(itervalues(self.touch_points))
self.flicking.emit(tp, True)
if not self.hold_started:
return
if TapAndHold in self.possible_gestures:
- tp = next(self.touch_points.itervalues())
+ tp = next(itervalues(self.touch_points))
self.tap_hold_finished.emit(tp)
return
diff --git a/src/calibre/gui2/icon_theme.py b/src/calibre/gui2/icon_theme.py
index 495a5c2969..d8d6b839bc 100644
--- a/src/calibre/gui2/icon_theme.py
+++ b/src/calibre/gui2/icon_theme.py
@@ -9,12 +9,9 @@ __copyright__ = '2015, Kovid Goyal '
import os, errno, json, importlib, math, httplib, bz2, shutil, sys
from itertools import count
from io import BytesIO
-from polyglot.builtins import map
from threading import Thread, Event
from multiprocessing.pool import ThreadPool
-from polyglot.builtins import reraise, range
-
from PyQt5.Qt import (
QImageReader, QFormLayout, QVBoxLayout, QSplitter, QGroupBox, QListWidget,
QLineEdit, QSpinBox, QTextEdit, QSize, QListWidgetItem, QIcon, QImage,
@@ -39,6 +36,7 @@ from calibre.utils.zipfile import ZipFile, ZIP_STORED
from calibre.utils.filenames import atomic_rename
from lzma.xz import compress, decompress
from polyglot.queue import Queue, Empty
+from polyglot.builtins import iteritems, iterkeys, map, range, reraise
IMAGE_EXTENSIONS = {'png', 'jpg', 'jpeg'}
THEME_COVER = 'icon-theme-cover.jpg'
@@ -191,7 +189,7 @@ def create_cover(report, icons=(), cols=5, size=120, padding=16):
def verify_theme(report):
must_use_qt()
report.bad = bad = {}
- for name, path in report.name_map.iteritems():
+ for name, path in iteritems(report.name_map):
reader = QImageReader(os.path.join(report.path, path))
img = reader.read()
if img.isNull():
@@ -364,7 +362,7 @@ def create_themeball(report, progress=None, abort=None):
except Exception:
return sys.exc_info()
- errors = tuple(filter(None, pool.map(optimize, tuple(report.name_map.iterkeys()))))
+ errors = tuple(filter(None, pool.map(optimize, tuple(iterkeys(report.name_map)))))
pool.close(), pool.join()
if abort is not None and abort.is_set():
return
diff --git a/src/calibre/gui2/keyboard.py b/src/calibre/gui2/keyboard.py
index 5d1254bc0e..f1ce68232f 100644
--- a/src/calibre/gui2/keyboard.py
+++ b/src/calibre/gui2/keyboard.py
@@ -26,7 +26,7 @@ from calibre.utils.icu import sort_key, lower
from calibre.gui2 import error_dialog, info_dialog
from calibre.utils.search_query_parser import SearchQueryParser, ParseException
from calibre.gui2.search_box import SearchBox2
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, itervalues, unicode_type, range
ROOT = QModelIndex()
@@ -60,7 +60,7 @@ def finalize(shortcuts, custom_keys_map={}): # {{{
correctly for each shortcut.
'''
seen, keys_map = {}, {}
- for unique_name, shortcut in shortcuts.iteritems():
+ for unique_name, shortcut in iteritems(shortcuts):
custom_keys = custom_keys_map.get(unique_name, None)
if custom_keys is None:
candidates = shortcut['default_keys']
@@ -142,15 +142,15 @@ class Manager(QObject): # {{{
done unregistering.
'''
self.shortcuts.pop(unique_name, None)
- for group in self.groups.itervalues():
+ for group in itervalues(self.groups):
try:
group.remove(unique_name)
except ValueError:
pass
def finalize(self):
- custom_keys_map = {un:tuple(keys) for un, keys in self.config.get(
- 'map', {}).iteritems()}
+ custom_keys_map = {un:tuple(keys) for un, keys in iteritems(self.config.get(
+ 'map', {}))}
self.keys_map = finalize(self.shortcuts, custom_keys_map=custom_keys_map)
def replace_action(self, unique_name, new_action):
@@ -198,16 +198,16 @@ class ConfigModel(SearchQueryParser, QAbstractItemModel):
self.keyboard = keyboard
groups = sorted(keyboard.groups, key=sort_key)
shortcut_map = {k:v.copy() for k, v in
- self.keyboard.shortcuts.iteritems()}
- for un, s in shortcut_map.iteritems():
+ iteritems(self.keyboard.shortcuts)}
+ for un, s in iteritems(shortcut_map):
s['keys'] = tuple(self.keyboard.keys_map.get(un, ()))
s['unique_name'] = un
- s['group'] = [g for g, names in self.keyboard.groups.iteritems() if un in
+ s['group'] = [g for g, names in iteritems(self.keyboard.groups) if un in
names][0]
group_map = {group:sorted(names, key=lambda x:
sort_key(shortcut_map[x]['name'])) for group, names in
- self.keyboard.groups.iteritems()}
+ iteritems(self.keyboard.groups)}
self.data = [Node(group_map, shortcut_map, group) for group in groups]
diff --git a/src/calibre/gui2/languages.py b/src/calibre/gui2/languages.py
index 1f7ce4f0fd..70c4302a9d 100644
--- a/src/calibre/gui2/languages.py
+++ b/src/calibre/gui2/languages.py
@@ -11,7 +11,7 @@ from calibre.gui2 import gui_prefs
from calibre.gui2.complete2 import EditWithComplete
from calibre.utils.localization import lang_map_for_ui
from calibre.utils.icu import sort_key, lower
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, itervalues, unicode_type
class LanguagesEdit(EditWithComplete):
@@ -24,15 +24,15 @@ class LanguagesEdit(EditWithComplete):
self.setSizeAdjustPolicy(self.AdjustToMinimumContentsLengthWithIcon)
self.setMinimumContentsLength(20)
self._lang_map = lang_map_for_ui()
- self.names_with_commas = [x for x in self._lang_map.itervalues() if ',' in x]
+ self.names_with_commas = [x for x in itervalues(self._lang_map) if ',' in x]
self.comma_map = {k:k.replace(',', '|') for k in self.names_with_commas}
- self.comma_rmap = {v:k for k, v in self.comma_map.iteritems()}
- self._rmap = {lower(v):k for k,v in self._lang_map.iteritems()}
+ self.comma_rmap = {v:k for k, v in iteritems(self.comma_map)}
+ self._rmap = {lower(v):k for k,v in iteritems(self._lang_map)}
self.init_langs(db)
self.item_selected.connect(self.update_recently_used)
def init_langs(self, db):
- self.update_items_cache(self._lang_map.itervalues())
+ self.update_items_cache(itervalues(self._lang_map))
def refresh_recently_used(self):
recently_used = self.prefs.get('recently_used_languages') or ()
@@ -55,7 +55,7 @@ class LanguagesEdit(EditWithComplete):
@property
def vals(self):
raw = unicode_type(self.lineEdit().text())
- for k, v in self.comma_map.iteritems():
+ for k, v in iteritems(self.comma_map):
raw = raw.replace(k, v)
parts = [x.strip() for x in raw.split(',')]
return [self.comma_rmap.get(x, x) for x in parts]
diff --git a/src/calibre/gui2/library/alternate_views.py b/src/calibre/gui2/library/alternate_views.py
index bab59f60d1..ff46e97ba8 100644
--- a/src/calibre/gui2/library/alternate_views.py
+++ b/src/calibre/gui2/library/alternate_views.py
@@ -29,7 +29,7 @@ from calibre.gui2 import gprefs, config, rating_font, empty_index
from calibre.gui2.gestures import GestureManager
from calibre.gui2.library.caches import CoverCache, ThumbnailCache
from calibre.utils.config import prefs, tweaks
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import itervalues, unicode_type, range
from polyglot.queue import LifoQueue
CM_TO_INCH = 0.393701
@@ -327,7 +327,7 @@ class AlternateViews(object):
view.setFocus(Qt.OtherFocusReason)
def set_database(self, db, stage=0):
- for view in self.views.itervalues():
+ for view in itervalues(self.views):
if view is not self.main_view:
view.set_database(db, stage=stage)
@@ -356,7 +356,7 @@ class AlternateViews(object):
self.current_view.select_rows(rows)
def set_context_menu(self, menu):
- for view in self.views.itervalues():
+ for view in itervalues(self.views):
if view is not self.main_view:
view.set_context_menu(menu)
@@ -957,7 +957,7 @@ class GridView(QListView):
# rendered, but this is better than a deadlock
join_with_timeout(self.delegate.render_queue)
except RuntimeError:
- print ('Cover rendering thread is stuck!')
+ print('Cover rendering thread is stuck!')
finally:
self.ignore_render_requests.clear()
else:
diff --git a/src/calibre/gui2/library/caches.py b/src/calibre/gui2/library/caches.py
index 6f5034ef95..dd0b925003 100644
--- a/src/calibre/gui2/library/caches.py
+++ b/src/calibre/gui2/library/caches.py
@@ -12,6 +12,7 @@ from collections import OrderedDict
from PyQt5.Qt import QImage, QPixmap
from calibre.db.utils import ThumbnailCache as TC
+from polyglot.builtins import interkeys, itervalues
class ThumbnailCache(TC):
@@ -45,7 +46,7 @@ class CoverCache(dict):
def _pop(self, book_id):
val = self.items.pop(book_id, None)
- if type(val) is QPixmap and current_thread() is not self.gui_thread:
+ if isinstance(val, QPixmap) and current_thread() is not self.gui_thread:
self.pixmap_staging.append(val)
def __getitem__(self, key):
@@ -54,7 +55,7 @@ class CoverCache(dict):
self.clear_staging()
ans = self.items.pop(key, False) # pop() so that item is moved to the top
if ans is not False:
- if type(ans) is QImage:
+ if isinstance(ans, QImage):
# Convert to QPixmap, since rendering QPixmap is much
# faster
ans = QPixmap.fromImage(ans)
@@ -67,12 +68,12 @@ class CoverCache(dict):
self._pop(key) # pop() so that item is moved to the top
self.items[key] = val
if len(self.items) > self.limit:
- del self.items[next(self.items.iterkeys())]
+ del self.items[next(iterkeys(self.items))]
def clear(self):
with self.lock:
if current_thread() is not self.gui_thread:
- pixmaps = (x for x in self.items.itervalues() if type(x) is QPixmap)
+ pixmaps = (x for x in itervalues(self.items) if isinstance(x, QPixmap))
self.pixmap_staging.extend(pixmaps)
self.items.clear()
@@ -84,8 +85,6 @@ class CoverCache(dict):
self.limit = limit
if len(self.items) > self.limit:
extra = len(self.items) - self.limit
- remove = tuple(self.iterkeys())[:extra]
+ remove = tuple(iterkeys(self))[:extra]
for k in remove:
self._pop(k)
-
-
diff --git a/src/calibre/gui2/library/models.py b/src/calibre/gui2/library/models.py
index f203a3de30..b36f91798c 100644
--- a/src/calibre/gui2/library/models.py
+++ b/src/calibre/gui2/library/models.py
@@ -30,7 +30,7 @@ from calibre.constants import filesystem_encoding, DEBUG, config_dir
from calibre.gui2.library import DEFAULT_SORT
from calibre.utils.localization import calibre_langcode_to_name
from calibre.library.coloring import color_row_key
-from polyglot.builtins import unicode_type, string_or_bytes, range
+from polyglot.builtins import iteritems, itervalues, unicode_type, string_or_bytes, range
Counts = namedtuple('Counts', 'library_total total current')
@@ -307,7 +307,7 @@ class BooksModel(QAbstractTableModel): # {{{
if db:
style_map = {'bold': self.bold_font, 'bi': self.bi_font, 'italic': self.italic_font}
- self.styled_columns = {k: style_map.get(v, None) for k, v in db.new_api.pref('styled_columns', {}).iteritems()}
+ self.styled_columns = {k: style_map.get(v, None) for k, v in iteritems(db.new_api.pref('styled_columns', {}))}
self.alignment_map = {}
self.ids_to_highlight_set = set()
self.current_highlighted_idx = None
@@ -509,7 +509,7 @@ class BooksModel(QAbstractTableModel): # {{{
self._sort(label, order, reset)
def sort_by_named_field(self, field, order, reset=True):
- if field in self.db.field_metadata.keys():
+ if field in list(self.db.field_metadata.keys()):
self._sort(field, order, reset)
def _sort(self, label, order, reset):
@@ -879,7 +879,7 @@ class BooksModel(QAbstractTableModel): # {{{
ans += '.5'
return _('%s stars') % ans
return f
- for f, allow_half in rating_fields.iteritems():
+ for f, allow_half in iteritems(rating_fields):
tc[f] = stars_tooltip(self.dc[f], allow_half)
# build a index column to data converter map, to remove the string lookup in the data loop
self.column_to_dc_map = [self.dc[col] for col in self.column_map]
@@ -1400,7 +1400,7 @@ class DeviceBooksModel(BooksModel): # {{{
return False
path = getattr(item, 'path', None)
- for items in self.marked_for_deletion.itervalues():
+ for items in itervalues(self.marked_for_deletion):
for x in items:
if x is item or (path and path == getattr(x, 'path', None)):
return True
diff --git a/src/calibre/gui2/library/views.py b/src/calibre/gui2/library/views.py
index 57c31b6c4d..a49f7c778f 100644
--- a/src/calibre/gui2/library/views.py
+++ b/src/calibre/gui2/library/views.py
@@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en'
import itertools, operator
from functools import partial
-from polyglot.builtins import map, unicode_type, range
+from polyglot.builtins import iteritems, map, unicode_type, range
from collections import OrderedDict
from PyQt5.Qt import (
@@ -194,7 +194,7 @@ class PreserveViewState(object): # {{{
'vscroll', 'hscroll')}
def fset(self, state):
- for k, v in state.iteritems():
+ for k, v in iteritems(state):
setattr(self, k, v)
self.__exit__()
return property(fget=fget, fset=fset)
@@ -465,7 +465,7 @@ class BooksView(QTableView): # {{{
ans.addSeparator()
if hidden_cols:
m = ans.addMenu(_('Show column'))
- hcols = [(hcol, unicode_type(self.model().headerData(hidx, Qt.Horizontal, Qt.DisplayRole) or '')) for hcol, hidx in hidden_cols.iteritems()]
+ hcols = [(hcol, unicode_type(self.model().headerData(hidx, Qt.Horizontal, Qt.DisplayRole) or '')) for hcol, hidx in iteritems(hidden_cols)]
hcols.sort(key=lambda x: primary_sort_key(x[1]))
for hcol, hname in hcols:
m.addAction(hname, partial(handler, action='show', column=hcol))
@@ -576,7 +576,7 @@ class BooksView(QTableView): # {{{
return
for n,d in reversed(fields):
- if n in self._model.db.field_metadata.keys():
+ if n in list(self._model.db.field_metadata.keys()):
sh.insert(0, (n, d))
sh = self.cleanup_sort_history(sh, ignore_column_map=True)
self._model.sort_history = [tuple(x) for x in sh]
diff --git a/src/calibre/gui2/lrf_renderer/document.py b/src/calibre/gui2/lrf_renderer/document.py
index 6611eb3bc3..644f4d9e17 100644
--- a/src/calibre/gui2/lrf_renderer/document.py
+++ b/src/calibre/gui2/lrf_renderer/document.py
@@ -521,10 +521,9 @@ class Document(QGraphicsScene):
self.next_match()
def next_match(self):
- page_num = self.last_search.next()[0]
+ page_num = next(self.last_search)[0]
if self.current_page == page_num:
self.update()
else:
self.add_to_history()
self.show_page(page_num)
-
diff --git a/src/calibre/gui2/lrf_renderer/text.py b/src/calibre/gui2/lrf_renderer/text.py
index d86a5e92b2..a8c59c7561 100644
--- a/src/calibre/gui2/lrf_renderer/text.py
+++ b/src/calibre/gui2/lrf_renderer/text.py
@@ -532,12 +532,12 @@ class Line(QGraphicsItem):
matches = []
try:
while True:
- word = words.next()
+ word = next(words)
word.highlight = False
if tokens[0] in unicode_type(word.string).lower():
matches.append(word)
for c in range(1, len(tokens)):
- word = words.next()
+ word = next(words)
print(tokens[c], word.string)
if tokens[c] not in unicode_type(word.string):
return None
diff --git a/src/calibre/gui2/metadata/basic_widgets.py b/src/calibre/gui2/metadata/basic_widgets.py
index 3dac5c5893..1bf2148fd1 100644
--- a/src/calibre/gui2/metadata/basic_widgets.py
+++ b/src/calibre/gui2/metadata/basic_widgets.py
@@ -41,7 +41,7 @@ from calibre.ptempfile import PersistentTemporaryFile, SpooledTemporaryFile
from calibre.gui2.languages import LanguagesEdit as LE
from calibre.db import SPOOL_SIZE
from calibre.ebooks.oeb.polish.main import SUPPORTED as EDIT_SUPPORTED
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, unicode_type, range
OK_COLOR = 'rgba(0, 255, 0, 12%)'
ERR_COLOR = 'rgba(255, 0, 0, 12%)'
@@ -1594,7 +1594,7 @@ class IdentifiersEdit(QLineEdit, ToMetadataMixin):
v = check_isbn(k)
if v is not None:
val[k] = v
- ids = sorted(val.iteritems(), key=keygen)
+ ids = sorted(iteritems(val), key=keygen)
txt = ', '.join(['%s:%s'%(k.lower(), vl) for k, vl in ids])
# Use selectAll + insert instead of setText so that undo works
self.selectAll(), self.insert(txt.strip())
diff --git a/src/calibre/gui2/metadata/bulk_download.py b/src/calibre/gui2/metadata/bulk_download.py
index e92a59b063..e2b4de5154 100644
--- a/src/calibre/gui2/metadata/bulk_download.py
+++ b/src/calibre/gui2/metadata/bulk_download.py
@@ -18,6 +18,7 @@ from calibre.ebooks.metadata.opf2 import metadata_to_opf
from calibre.utils.ipc.simple_worker import fork_job, WorkerError
from calibre.ptempfile import (PersistentTemporaryDirectory,
PersistentTemporaryFile)
+from polyglot.builtins import iteritems
# Start download {{{
@@ -244,7 +245,7 @@ def download(all_ids, tf, db, do_identify, covers, ensure_fields,
title_map[i] = metadata[i].title
lm_map[i] = metadata[i].last_modified
metadata = {i:metadata_to_opf(mi, default_lang='und') for i, mi in
- metadata.iteritems()}
+ iteritems(metadata)}
try:
ret = fork_job('calibre.ebooks.metadata.sources.worker', 'main',
(do_identify, covers, metadata, ensure_fields, tdir),
diff --git a/src/calibre/gui2/metadata/config.py b/src/calibre/gui2/metadata/config.py
index 1f5ae83243..fa72f7892d 100644
--- a/src/calibre/gui2/metadata/config.py
+++ b/src/calibre/gui2/metadata/config.py
@@ -14,7 +14,7 @@ from PyQt5.Qt import (QWidget, QGridLayout, QGroupBox, QListView, Qt, QSpinBox,
from calibre.gui2.preferences.metadata_sources import FieldsModel as FM
from calibre.utils.icu import sort_key
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
class FieldsModel(FM): # {{{
@@ -48,7 +48,7 @@ class FieldsModel(FM): # {{{
def commit(self):
ignored_fields = {x for x in self.prefs['ignore_fields'] if x not in
self.overrides}
- changed = {k for k, v in self.overrides.iteritems() if v ==
+ changed = {k for k, v in iteritems(self.overrides) if v ==
Qt.Unchecked}
self.prefs['ignore_fields'] = list(ignored_fields.union(changed))
@@ -101,7 +101,7 @@ class ConfigWidget(QWidget):
widget.setChecked(bool(val))
elif opt.type == 'choices':
widget = QComboBox(self)
- items = list(opt.choices.iteritems())
+ items = list(iteritems(opt.choices))
items.sort(key=lambda k_v: sort_key(k_v[1]))
for key, label in items:
widget.addItem(label, (key))
diff --git a/src/calibre/gui2/metadata/diff.py b/src/calibre/gui2/metadata/diff.py
index 286feaa2fd..9f5b1fe9b6 100644
--- a/src/calibre/gui2/metadata/diff.py
+++ b/src/calibre/gui2/metadata/diff.py
@@ -9,7 +9,7 @@ __copyright__ = '2013, Kovid Goyal '
import os, weakref
from collections import OrderedDict, namedtuple
from functools import partial
-from polyglot.builtins import zip, unicode_type, range
+from polyglot.builtins import iteritems, itervalues, zip, unicode_type, range
from PyQt5.Qt import (
QDialog, QWidget, QGridLayout, QLabel, QToolButton, QIcon,
@@ -245,10 +245,10 @@ class IdentifiersEdit(LineEdit):
def as_dict(self):
def fget(self):
parts = (x.strip() for x in self.current_val.split(',') if x.strip())
- return {k:v for k, v in {x.partition(':')[0].strip():x.partition(':')[-1].strip() for x in parts}.iteritems() if k and v}
+ return {k:v for k, v in iteritems({x.partition(':')[0].strip():x.partition(':')[-1].strip() for x in parts}) if k and v}
def fset(self, val):
- val = ('%s:%s' % (k, v) for k, v in val.iteritems())
+ val = ('%s:%s' % (k, v) for k, v in iteritems(val))
self.setText(', '.join(val))
self.setCursorPosition(0)
return property(fget=fget, fset=fset)
@@ -519,14 +519,14 @@ class CompareSingle(QWidget):
def __call__(self, oldmi, newmi):
self.current_mi = newmi
self.initial_vals = {}
- for field, widgets in self.widgets.iteritems():
+ for field, widgets in iteritems(self.widgets):
widgets.old.from_mi(oldmi)
widgets.new.from_mi(newmi)
self.initial_vals[field] = widgets.new.current_val
def apply_changes(self):
changed = False
- for field, widgets in self.widgets.iteritems():
+ for field, widgets in iteritems(self.widgets):
val = widgets.new.current_val
if val != self.initial_vals[field]:
widgets.new.to_mi(self.current_mi)
@@ -701,6 +701,6 @@ if __name__ == '__main__':
get_metadata = lambda x:map(gm, ids[x])
d = CompareMany(list(range(len(ids))), get_metadata, db.field_metadata, db=db)
if d.exec_() == d.Accepted:
- for changed, mi in d.accepted.itervalues():
+ for changed, mi in itervalues(d.accepted):
if changed and mi is not None:
print(mi)
diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py
index d1c4131302..b06fe83e41 100644
--- a/src/calibre/gui2/metadata/single.py
+++ b/src/calibre/gui2/metadata/single.py
@@ -31,6 +31,7 @@ from calibre.ebooks.metadata.book.base import Metadata
from calibre.utils.localization import canonicalize_lang
from calibre.utils.date import local_tz
from calibre.library.comments import merge_comments as merge_two_comments
+from polyglot.builtins import iteritems
BASE_TITLE = _('Edit Metadata')
fetched_fields = ('title', 'title_sort', 'authors', 'author_sort', 'series',
@@ -555,7 +556,7 @@ class MetadataSingleDialogBase(QDialog):
if self.metadata_before_fetch is None:
return error_dialog(self, _('No downloaded metadata'), _(
'There is no downloaded metadata to undo'), show=True)
- for field, val in self.metadata_before_fetch.iteritems():
+ for field, val in iteritems(self.metadata_before_fetch):
getattr(self, field).current_val = val
self.metadata_before_fetch = None
@@ -710,7 +711,7 @@ class MetadataSingleDialogBase(QDialog):
self.button_box.button(self.button_box.Ok).setDefault(True)
self.button_box.button(self.button_box.Ok).setFocus(Qt.OtherFocusReason)
self(self.db.id(self.row_list[self.current_row]))
- for w, state in self.comments_edit_state_at_apply.iteritems():
+ for w, state in iteritems(self.comments_edit_state_at_apply):
if state == 'code':
w.tab = 'code'
diff --git a/src/calibre/gui2/metadata/single_download.py b/src/calibre/gui2/metadata/single_download.py
index fe51133577..5d73912cd0 100644
--- a/src/calibre/gui2/metadata/single_download.py
+++ b/src/calibre/gui2/metadata/single_download.py
@@ -39,7 +39,7 @@ from calibre import force_unicode
from calibre.utils.config import tweaks
from calibre.utils.ipc.simple_worker import fork_job, WorkerError
from calibre.ptempfile import TemporaryDirectory
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, itervalues, unicode_type, range
from polyglot.queue import Queue, Empty
# }}}
@@ -509,7 +509,7 @@ class IdentifyWidget(QWidget): # {{{
parts.append('authors:'+authors_to_string(authors))
simple_desc += _('Authors: %s ') % authors_to_string(authors)
if identifiers:
- x = ', '.join('%s:%s'%(k, v) for k, v in identifiers.iteritems())
+ x = ', '.join('%s:%s'%(k, v) for k, v in iteritems(identifiers))
parts.append(x)
if 'isbn' in identifiers:
simple_desc += 'ISBN: %s' % identifiers['isbn']
@@ -689,7 +689,7 @@ class CoversModel(QAbstractListModel): # {{{
def plugin_for_index(self, index):
row = index.row() if hasattr(index, 'row') else index
- for k, v in self.plugin_map.iteritems():
+ for k, v in iteritems(self.plugin_map):
if row in v:
return k
@@ -750,7 +750,7 @@ class CoversModel(QAbstractListModel): # {{{
if pmap.isNull():
return
self.beginInsertRows(QModelIndex(), last_row, last_row)
- for rows in self.plugin_map.itervalues():
+ for rows in itervalues(self.plugin_map):
for i in range(len(rows)):
if rows[i] >= last_row:
rows[i] += 1
@@ -760,7 +760,7 @@ class CoversModel(QAbstractListModel): # {{{
else:
# single cover plugin
idx = None
- for plugin, rows in self.plugin_map.iteritems():
+ for plugin, rows in iteritems(self.plugin_map):
if plugin.name == plugin_name:
idx = rows[0]
break
diff --git a/src/calibre/gui2/open_with.py b/src/calibre/gui2/open_with.py
index 725b7af0c6..9b47f6a619 100644
--- a/src/calibre/gui2/open_with.py
+++ b/src/calibre/gui2/open_with.py
@@ -22,7 +22,7 @@ from calibre.gui2.widgets2 import Dialog
from calibre.gui2.progress_indicator import ProgressIndicator
from calibre.utils.config import JSONConfig
from calibre.utils.icu import numeric_sort_key as sort_key
-from polyglot.builtins import string_or_bytes, range
+from polyglot.builtins import iteritems, string_or_bytes, range
ENTRY_ROLE = Qt.UserRole
@@ -431,12 +431,12 @@ def register_keyboard_shortcuts(gui=None, finalize=False):
gui = get_gui()
if gui is None:
return
- for unique_name, action in registered_shortcuts.iteritems():
+ for unique_name, action in iteritems(registered_shortcuts):
gui.keyboard.unregister_shortcut(unique_name)
gui.removeAction(action)
registered_shortcuts.clear()
- for filetype, applications in oprefs['entries'].iteritems():
+ for filetype, applications in iteritems(oprefs['entries']):
for application in applications:
text = entry_to_icon_text(application, only_text=True)
t = _('cover image') if filetype.upper() == 'COVER_IMAGE' else filetype.upper()
diff --git a/src/calibre/gui2/preferences/behavior.py b/src/calibre/gui2/preferences/behavior.py
index b9a1fcfd47..5acc1ffd2b 100644
--- a/src/calibre/gui2/preferences/behavior.py
+++ b/src/calibre/gui2/preferences/behavior.py
@@ -18,7 +18,7 @@ from calibre.ebooks import BOOK_EXTENSIONS
from calibre.ebooks.oeb.iterator import is_supported
from calibre.constants import iswindows
from calibre.utils.icu import sort_key
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iterkeys, unicode_type
class OutputFormatSetting(Setting):
@@ -50,7 +50,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
choices = [(x.upper(), x) for x in output_formats]
r('output_format', prefs, choices=choices, setting=OutputFormatSetting)
- restrictions = sorted(db.prefs['virtual_libraries'].iterkeys(), key=sort_key)
+ restrictions = sorted(iterkeys(db.prefs['virtual_libraries']), key=sort_key)
choices = [('', '')] + [(x, x) for x in restrictions]
# check that the virtual library still exists
vls = db.prefs['virtual_lib_on_startup']
diff --git a/src/calibre/gui2/preferences/coloring.py b/src/calibre/gui2/preferences/coloring.py
index ee14634c1b..16ed941465 100644
--- a/src/calibre/gui2/preferences/coloring.py
+++ b/src/calibre/gui2/preferences/coloring.py
@@ -26,7 +26,7 @@ from calibre.library.coloring import (Rule, conditionable_columns,
displayable_columns, rule_from_template, color_row_key)
from calibre.utils.localization import lang_map
from calibre.utils.icu import lower
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
all_columns_string = _('All columns')
@@ -172,7 +172,7 @@ class ConditionEditor(QWidget): # {{{
def current_val(self):
ans = unicode_type(self.value_box.text()).strip()
if self.current_col == 'languages':
- rmap = {lower(v):k for k, v in lang_map().iteritems()}
+ rmap = {lower(v):k for k, v in iteritems(lang_map())}
ans = rmap.get(lower(ans), ans)
return ans
@@ -1130,8 +1130,8 @@ if __name__ == '__main__':
kind, col, r = d.rule
print('Column to be colored:', col)
- print ('Template:')
- print (r.template)
+ print('Template:')
+ print(r.template)
else:
d = EditRules()
d.resize(QSize(800, 600))
diff --git a/src/calibre/gui2/preferences/create_custom_column.py b/src/calibre/gui2/preferences/create_custom_column.py
index a67fe945e7..2fc4100cbc 100644
--- a/src/calibre/gui2/preferences/create_custom_column.py
+++ b/src/calibre/gui2/preferences/create_custom_column.py
@@ -16,7 +16,7 @@ from PyQt5.Qt import (
)
from calibre.gui2 import error_dialog
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
class CreateCustomColumn(QDialog):
@@ -86,7 +86,7 @@ class CreateCustomColumn(QDialog):
'is_multiple':True
},
)))
- column_types_map = {k['datatype']:idx for idx, k in column_types.iteritems()}
+ column_types_map = {k['datatype']:idx for idx, k in iteritems(column_types)}
def __init__(self, parent, current_row, current_key, standard_colheads, standard_colnames):
QDialog.__init__(self, parent)
diff --git a/src/calibre/gui2/preferences/ignored_devices.py b/src/calibre/gui2/preferences/ignored_devices.py
index b0ecce5bcd..1e5ecb5d24 100644
--- a/src/calibre/gui2/preferences/ignored_devices.py
+++ b/src/calibre/gui2/preferences/ignored_devices.py
@@ -12,7 +12,7 @@ from PyQt5.Qt import (QLabel, QVBoxLayout, QListWidget, QListWidgetItem, Qt,
from calibre.customize.ui import enable_plugin
from calibre.gui2.preferences import ConfigWidgetBase, test_widget
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, range
class ConfigWidget(ConfigWidgetBase):
@@ -55,7 +55,7 @@ class ConfigWidget(ConfigWidgetBase):
self.devices.blockSignals(True)
self.devices.clear()
for dev in self.gui.device_manager.devices:
- for d, name in dev.get_user_blacklisted_devices().iteritems():
+ for d, name in iteritems(dev.get_user_blacklisted_devices()):
item = QListWidgetItem('%s [%s]'%(name, d), self.devices)
item.setData(Qt.UserRole, (dev, d))
item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsUserCheckable|Qt.ItemIsSelectable)
@@ -87,7 +87,7 @@ class ConfigWidget(ConfigWidgetBase):
if e.checkState() == Qt.Checked:
devs[dev].append(uid)
- for dev, bl in devs.iteritems():
+ for dev, bl in iteritems(devs):
dev.set_user_blacklisted_devices(bl)
for i in range(self.device_plugins.count()):
diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py
index 0ba64accf0..0fb52d9a97 100644
--- a/src/calibre/gui2/preferences/look_feel.py
+++ b/src/calibre/gui2/preferences/look_feel.py
@@ -36,7 +36,7 @@ from calibre.gui2.preferences.coloring import EditRules
from calibre.gui2.library.alternate_views import auto_height, CM_TO_INCH
from calibre.gui2.widgets2 import Dialog
from calibre.gui2.actions.show_quickview import get_quickview_action_plugin
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
class BusyCursor(object):
@@ -159,7 +159,7 @@ class IdLinksEditor(Dialog):
la.setWordWrap(True)
l.addWidget(la)
items = []
- for k, lx in msprefs['id_link_rules'].iteritems():
+ for k, lx in iteritems(msprefs['id_link_rules']):
for n, t in lx:
items.append((k, n, t))
items.sort(key=lambda x:sort_key(x[1]))
diff --git a/src/calibre/gui2/preferences/metadata_sources.py b/src/calibre/gui2/preferences/metadata_sources.py
index a9ea411bcd..c6eb579ee8 100644
--- a/src/calibre/gui2/preferences/metadata_sources.py
+++ b/src/calibre/gui2/preferences/metadata_sources.py
@@ -18,6 +18,7 @@ from calibre.ebooks.metadata.sources.prefs import msprefs
from calibre.customize.ui import (all_metadata_plugins, is_disabled,
enable_plugin, disable_plugin, default_disabled_plugins)
from calibre.gui2 import error_dialog, question_dialog
+from polyglot.builtins import iteritems
class SourcesModel(QAbstractTableModel): # {{{
@@ -117,7 +118,7 @@ class SourcesModel(QAbstractTableModel): # {{{
return Qt.ItemIsEditable | ans
def commit(self):
- for plugin, val in self.enabled_overrides.iteritems():
+ for plugin, val in iteritems(self.enabled_overrides):
if val == Qt.Checked:
enable_plugin(plugin)
elif val == Qt.Unchecked:
@@ -125,7 +126,7 @@ class SourcesModel(QAbstractTableModel): # {{{
if self.cover_overrides:
cp = msprefs['cover_priorities']
- for plugin, val in self.cover_overrides.iteritems():
+ for plugin, val in iteritems(self.cover_overrides):
if val == 1:
cp.pop(plugin.name, None)
else:
@@ -235,7 +236,7 @@ class FieldsModel(QAbstractListModel): # {{{
def commit(self):
ignored_fields = {x for x in msprefs['ignore_fields'] if x not in
self.overrides}
- changed = {k for k, v in self.overrides.iteritems() if v ==
+ changed = {k for k, v in iteritems(self.overrides) if v ==
Qt.Unchecked}
msprefs['ignore_fields'] = list(ignored_fields.union(changed))
@@ -251,7 +252,7 @@ class FieldsModel(QAbstractListModel): # {{{
def commit_user_defaults(self):
default_ignored_fields = {x for x in msprefs['user_default_ignore_fields'] if x not in
self.overrides}
- changed = {k for k, v in self.overrides.iteritems() if v ==
+ changed = {k for k, v in iteritems(self.overrides) if v ==
Qt.Unchecked}
msprefs['user_default_ignore_fields'] = list(default_ignored_fields.union(changed))
diff --git a/src/calibre/gui2/preferences/misc.py b/src/calibre/gui2/preferences/misc.py
index e6f891d75d..e7dbd1867f 100644
--- a/src/calibre/gui2/preferences/misc.py
+++ b/src/calibre/gui2/preferences/misc.py
@@ -11,6 +11,7 @@ from calibre.gui2.preferences import ConfigWidgetBase, test_widget, Setting
from calibre.gui2.preferences.misc_ui import Ui_Form
from calibre.gui2 import (config, open_local_file, gprefs)
from calibre import get_proxies
+from polyglot.builtins import iteritems
class WorkersSetting(Setting):
@@ -45,7 +46,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
txt = _('No proxies used')
if proxies:
lines = [' %s: %s'%(t, p) for t, p in
- proxies.iteritems()]
+ iteritems(proxies)]
txt = _('Using proxies:') + ''.join(lines)
self.proxies.setText(txt)
@@ -67,8 +68,8 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
from calibre.utils.config import config_dir
open_local_file(config_dir)
+
if __name__ == '__main__':
from PyQt5.Qt import QApplication
app = QApplication([])
test_widget('Advanced', 'Misc')
-
diff --git a/src/calibre/gui2/preferences/plugins.py b/src/calibre/gui2/preferences/plugins.py
index 704cbc39c6..a683eccf4d 100644
--- a/src/calibre/gui2/preferences/plugins.py
+++ b/src/calibre/gui2/preferences/plugins.py
@@ -22,7 +22,7 @@ from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.utils.search_query_parser import SearchQueryParser
from calibre.utils.icu import lower
from calibre.constants import iswindows
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, itervalues, unicode_type
class AdaptSQP(SearchQueryParser):
@@ -438,12 +438,12 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
if previously_installed:
return
# If already installed in a GUI container, do nothing
- for action_names in installed_actions.itervalues():
+ for action_names in itervalues(installed_actions):
if plugin_action.name in action_names:
return
allowed_locations = [(key, text) for key, text in
- all_locations.iteritems() if key
+ iteritems(all_locations) if key
not in plugin_action.dont_add_to]
if not allowed_locations:
return # This plugin doesn't want to live in the GUI
diff --git a/src/calibre/gui2/preferences/search.py b/src/calibre/gui2/preferences/search.py
index 7384075e02..e919ece61a 100644
--- a/src/calibre/gui2/preferences/search.py
+++ b/src/calibre/gui2/preferences/search.py
@@ -14,7 +14,7 @@ from calibre.gui2 import config, error_dialog, gprefs
from calibre.utils.config import prefs
from calibre.utils.icu import sort_key
from calibre.library.caches import set_use_primary_find_in_search
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
class ConfigWidget(ConfigWidgetBase, Ui_Form):
@@ -64,7 +64,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
"a particular item, or to have hierarchical categories (categories "
"that contain categories)."))
self.gst = db.prefs.get('grouped_search_terms', {}).copy()
- self.orig_gst_keys = self.gst.keys()
+ self.orig_gst_keys = list(self.gst.keys())
fl = []
for f in db.all_field_keys():
@@ -249,7 +249,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
gui.search.do_search()
def clear_histories(self, *args):
- for key, val in config.defaults.iteritems():
+ for key, val in iteritems(config.defaults):
if key.endswith('_search_history') and isinstance(val, list):
config[key] = []
self.gui.search.clear_history()
diff --git a/src/calibre/gui2/preferences/template_functions.py b/src/calibre/gui2/preferences/template_functions.py
index e89afe0066..b8e0d49441 100644
--- a/src/calibre/gui2/preferences/template_functions.py
+++ b/src/calibre/gui2/preferences/template_functions.py
@@ -16,7 +16,7 @@ from calibre.gui2.widgets import PythonHighlighter
from calibre.utils.formatter_functions import (formatter_functions,
compile_user_function, compile_user_template_functions,
load_user_template_functions)
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
class ConfigWidget(ConfigWidgetBase, Ui_Form):
@@ -223,7 +223,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
def commit(self):
# formatter_functions().reset_to_builtins()
pref_value = []
- for name, cls in self.funcs.iteritems():
+ for name, cls in iteritems(self.funcs):
if name not in self.builtins:
pref_value.append((cls.name, cls.doc, cls.arg_count, cls.program_text))
self.db.new_api.set_pref('user_template_functions', pref_value)
diff --git a/src/calibre/gui2/preferences/tweaks.py b/src/calibre/gui2/preferences/tweaks.py
index ecff365aaa..bec93d7226 100644
--- a/src/calibre/gui2/preferences/tweaks.py
+++ b/src/calibre/gui2/preferences/tweaks.py
@@ -19,7 +19,7 @@ from calibre import isbytestring
from calibre.utils.icu import lower
from calibre.utils.search_query_parser import (ParseException,
SearchQueryParser)
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, iterkeys, unicode_type, range
from PyQt5.Qt import (
QAbstractListModel, Qt, QStyledItemDelegate, QStyle, QStyleOptionViewItem,
@@ -96,7 +96,7 @@ class Tweak(object): # {{{
for line in self.doc.splitlines():
if line:
ans.append('# ' + line)
- for key, val in self.default_values.iteritems():
+ for key, val in iteritems(self.default_values):
val = self.custom_values.get(key, val)
ans.append('%s = %r'%(key, val))
ans = '\n'.join(ans)
@@ -110,7 +110,7 @@ class Tweak(object): # {{{
@property
def is_customized(self):
- for x, val in self.default_values.iteritems():
+ for x, val in iteritems(self.default_values):
if self.custom_values.get(x, val) != val:
return True
return False
@@ -118,7 +118,7 @@ class Tweak(object): # {{{
@property
def edit_text(self):
ans = ['# %s'%self.name]
- for x, val in self.default_values.iteritems():
+ for x, val in iteritems(self.default_values):
val = self.custom_values.get(x, val)
ans.append('%s = %r'%(x, val))
return '\n\n'.join(ans)
@@ -161,7 +161,7 @@ class Tweaks(QAbstractListModel, AdaptSQP): # {{{
if tweak.is_customized:
tt = '
'+_('This tweak has been customized')
tt += '
'
- for varn, val in tweak.custom_values.iteritems():
+ for varn, val in iteritems(tweak.custom_values):
tt += '%s = %r\n\n'%(varn, val)
return textwrap.fill(tt)
if role == Qt.UserRole:
@@ -188,8 +188,8 @@ class Tweaks(QAbstractListModel, AdaptSQP): # {{{
pos += 1
self.tweaks.sort()
- default_keys = set(dl.iterkeys())
- custom_keys = set(l.iterkeys())
+ default_keys = set(iterkeys(dl))
+ custom_keys = set(iterkeys(l))
self.plugin_tweaks = {}
for key in custom_keys - default_keys:
@@ -264,14 +264,14 @@ class Tweaks(QAbstractListModel, AdaptSQP): # {{{
if self.plugin_tweaks:
ans.extend(['', '',
'# The following are tweaks for installed plugins', ''])
- for key, val in self.plugin_tweaks.iteritems():
+ for key, val in iteritems(self.plugin_tweaks):
ans.extend(['%s = %r'%(key, val), '', ''])
return '\n'.join(ans)
@property
def plugin_tweaks_string(self):
ans = []
- for key, val in self.plugin_tweaks.iteritems():
+ for key, val in iteritems(self.plugin_tweaks):
ans.extend(['%s = %r'%(key, val), '', ''])
ans = '\n'.join(ans)
if isbytestring(ans):
diff --git a/src/calibre/gui2/save.py b/src/calibre/gui2/save.py
index d7a1553496..777e351a6d 100644
--- a/src/calibre/gui2/save.py
+++ b/src/calibre/gui2/save.py
@@ -24,7 +24,7 @@ from calibre.gui2.dialogs.progress import ProgressDialog
from calibre.utils.formatter_functions import load_user_template_functions
from calibre.utils.ipc.pool import Pool, Failure
from calibre.library.save_to_disk import sanitize_args, get_path_components, find_plugboard, plugboard_save_to_disk_value
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, itervalues, unicode_type
from polyglot.queue import Empty
BookId = namedtuple('BookId', 'title authors')
@@ -33,11 +33,11 @@ BookId = namedtuple('BookId', 'title authors')
def ensure_unique_components(data): # {{{
cmap = defaultdict(set)
bid_map = {}
- for book_id, (mi, components, fmts) in data.iteritems():
+ for book_id, (mi, components, fmts) in iteritems(data):
cmap[tuple(components)].add(book_id)
bid_map[book_id] = components
- for book_ids in cmap.itervalues():
+ for book_ids in itervalues(cmap):
if len(book_ids) > 1:
for i, book_id in enumerate(sorted(book_ids)[1:]):
suffix = ' (%d)' % (i + 1)
@@ -151,7 +151,7 @@ class Saver(QObject):
self.pd.max = len(self.collected_data)
self.pd.value = 0
if self.opts.update_metadata:
- all_fmts = {fmt for data in self.collected_data.itervalues() for fmt in data[2]}
+ all_fmts = {fmt for data in itervalues(self.collected_data) for fmt in data[2]}
plugboards_cache = {fmt:find_plugboard(plugboard_save_to_disk_value, fmt, self.plugboards) for fmt in all_fmts}
self.pool = Pool(name='SaveToDisk') if self.pool is None else self.pool
try:
@@ -334,7 +334,7 @@ class Saver(QObject):
text = force_unicode(text)
return '\xa0\xa0\xa0\xa0' + '\n\xa0\xa0\xa0\xa0'.join(text.splitlines())
- for book_id, errors in self.errors.iteritems():
+ for book_id, errors in iteritems(self.errors):
types = {t for t, data in errors}
title, authors = self.book_id_data(book_id).title, authors_to_string(self.book_id_data(book_id).authors[:1])
if report:
@@ -362,7 +362,7 @@ class Saver(QObject):
def report(self):
if not self.errors:
return
- err_types = {e[0] for errors in self.errors.itervalues() for e in errors}
+ err_types = {e[0] for errors in itervalues(self.errors) for e in errors}
if err_types == {'metadata'}:
msg = _('Failed to update metadata in some books, click "Show details" for more information')
d = warning_dialog
diff --git a/src/calibre/gui2/search_restriction_mixin.py b/src/calibre/gui2/search_restriction_mixin.py
index cfb6d57409..43763975f2 100644
--- a/src/calibre/gui2/search_restriction_mixin.py
+++ b/src/calibre/gui2/search_restriction_mixin.py
@@ -255,7 +255,7 @@ class CreateVirtualLibrary(QDialog): # {{{
search = ['%s:"=%s"'%(prefix, x.replace('"', '\\"')) for x in d.names]
if search:
if not self.editing:
- self.vl_name.lineEdit().setText(d.names.next())
+ self.vl_name.lineEdit().setText(next(d.names))
self.vl_name.lineEdit().setCursorPosition(0)
self.vl_text.setText(d.match_type.join(search))
self.vl_text.setCursorPosition(0)
diff --git a/src/calibre/gui2/tag_browser/model.py b/src/calibre/gui2/tag_browser/model.py
index 75ea12470e..83997a4122 100644
--- a/src/calibre/gui2/tag_browser/model.py
+++ b/src/calibre/gui2/tag_browser/model.py
@@ -2,7 +2,6 @@
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import (unicode_literals, division, absolute_import,
print_function)
-from polyglot.builtins import map, unicode_type
__license__ = 'GPL v3'
__copyright__ = '2011, Kovid Goyal '
@@ -23,8 +22,8 @@ from calibre.utils.icu import sort_key, lower, strcmp, collation_order, primary_
from calibre.library.field_metadata import category_icon_map
from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.utils.formatter import EvalFormatter
-from polyglot.builtins import range
from calibre.utils.serialize import json_dumps, json_loads
+from polyglot.builtins import iteritems, itervalues, map, range, unicode_type
TAG_SEARCH_STATES = {'clear': 0, 'mark_plus': 1, 'mark_plusplus': 2,
@@ -307,7 +306,7 @@ class TagsModel(QAbstractItemModel): # {{{
self.node_map = {}
self.category_nodes = []
self.category_custom_icons = {}
- for k, v in self.prefs['tags_browser_category_icons'].iteritems():
+ for k, v in iteritems(self.prefs['tags_browser_category_icons']):
icon = QIcon(os.path.join(config_dir, 'tb_icons', v))
if len(icon.availableSizes()) > 0:
self.category_custom_icons[k] = icon
@@ -375,7 +374,7 @@ class TagsModel(QAbstractItemModel): # {{{
def rebuild_node_tree(self, state_map={}):
if self._build_in_progress:
- print ('Tag browser build already in progress')
+ print('Tag browser build already in progress')
traceback.print_stack()
return
# traceback.print_stack()
@@ -387,7 +386,7 @@ class TagsModel(QAbstractItemModel): # {{{
self._build_in_progress = False
def _run_rebuild(self, state_map={}):
- for node in self.node_map.itervalues():
+ for node in itervalues(self.node_map):
node.break_cycles()
del node # Clear reference to node in the current frame
self.node_map.clear()
@@ -475,7 +474,7 @@ class TagsModel(QAbstractItemModel): # {{{
intermediate_nodes = {}
if data is None:
- print ('_create_node_tree: no data!')
+ print('_create_node_tree: no data!')
traceback.print_stack()
return
@@ -1012,7 +1011,7 @@ class TagsModel(QAbstractItemModel): # {{{
if not isinstance(order, dict):
raise TypeError()
except:
- print ('Tweak tag_browser_category_order is not valid. Ignored')
+ print('Tweak tag_browser_category_order is not valid. Ignored')
order = {'*': 100}
defvalue = order.get('*', 100)
self.row_map = sorted(self.categories, key=lambda x: order.get(x, defvalue))
@@ -1032,7 +1031,7 @@ class TagsModel(QAbstractItemModel): # {{{
Here to trap usages of refresh in the old architecture. Can eventually
be removed.
'''
- print ('TagsModel: refresh called!')
+ print('TagsModel: refresh called!')
traceback.print_stack()
return False
@@ -1102,7 +1101,7 @@ class TagsModel(QAbstractItemModel): # {{{
self.use_position_based_index_on_next_recount = True
return True
- for c in sorted(user_cats.keys(), key=sort_key):
+ for c in sorted(list(user_cats.keys()), key=sort_key):
if icu_lower(c).startswith(ckey_lower):
if len(c) == len(ckey):
if strcmp(ckey, nkey) != 0 and \
diff --git a/src/calibre/gui2/tag_mapper.py b/src/calibre/gui2/tag_mapper.py
index 45af4b1211..fc05cc6468 100644
--- a/src/calibre/gui2/tag_mapper.py
+++ b/src/calibre/gui2/tag_mapper.py
@@ -20,7 +20,7 @@ from calibre.gui2.ui import get_gui
from calibre.gui2.widgets2 import Dialog
from calibre.utils.config import JSONConfig
from calibre.utils.localization import localize_user_manual_link
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, unicode_type, range
tag_maps = JSONConfig('tag-map-rules')
@@ -85,14 +85,14 @@ class RuleEdit(QWidget):
l.addLayout(h)
self.action = a = QComboBox(self)
h.addWidget(a)
- for action, text in self.ACTION_MAP.iteritems():
+ for action, text in iteritems(self.ACTION_MAP):
a.addItem(text, action)
a.currentIndexChanged.connect(self.update_state)
self.la1 = la = QLabel('\xa0' + self.SUBJECT + '\xa0')
h.addWidget(la)
self.match_type = q = QComboBox(self)
h.addWidget(q)
- for action, text in self.MATCH_TYPE_MAP.iteritems():
+ for action, text in iteritems(self.MATCH_TYPE_MAP):
q.addItem(text, action)
q.currentIndexChanged.connect(self.update_state)
self.la2 = la = QLabel(':\xa0')
@@ -452,13 +452,13 @@ class SaveLoadMixin(object):
def build_load_menu(self):
self.load_menu.clear()
if len(self.PREFS_OBJECT):
- for name, rules in self.PREFS_OBJECT.iteritems():
+ for name, rules in iteritems(self.PREFS_OBJECT):
ac = self.load_menu.addAction(name)
ac.setObjectName(name)
connect_lambda(ac.triggered, self, lambda self: self.load_ruleset(self.sender().objectName()))
self.load_menu.addSeparator()
m = self.load_menu.addMenu(_('Delete saved rulesets'))
- for name, rules in self.PREFS_OBJECT.iteritems():
+ for name, rules in iteritems(self.PREFS_OBJECT):
ac = m.addAction(name)
ac.setObjectName(name)
connect_lambda(ac.triggered, self, lambda self: self.delete_ruleset(self.sender().objectName()))
diff --git a/src/calibre/gui2/toc/main.py b/src/calibre/gui2/toc/main.py
index ba23176964..a4e8cf7be1 100644
--- a/src/calibre/gui2/toc/main.py
+++ b/src/calibre/gui2/toc/main.py
@@ -10,7 +10,7 @@ __docformat__ = 'restructuredtext en'
import sys, os, textwrap
from threading import Thread
from functools import partial
-from polyglot.builtins import map, unicode_type, range
+from polyglot.builtins import iteritems, map, unicode_type, range
from PyQt5.Qt import (QPushButton, QFrame, QMenu, QInputDialog, QCheckBox,
QDialog, QVBoxLayout, QDialogButtonBox, QSize, QStackedWidget, QWidget,
@@ -469,7 +469,7 @@ class TreeWidget(QTreeWidget): # {{{
# For order to be be preserved when moving by drag and drop, we
# have to ensure that selectedIndexes returns an ordered list of
# indexes.
- sort_map = {self.indexFromItem(item):i for i, item in enumerate(self.iteritems())}
+ sort_map = {self.indexFromItem(item):i for i, item in enumerate(iteritems(self))}
ans = sorted(ans, key=lambda x:sort_map.get(x, -1))
return ans
@@ -615,7 +615,7 @@ class TreeWidget(QTreeWidget): # {{{
def bulk_rename(self):
from calibre.gui2.tweak_book.file_list import get_bulk_rename_settings
- sort_map = {item:i for i, item in enumerate(self.iteritems())}
+ sort_map = {item:i for i, item in enumerate(iteritems(self))}
items = sorted(self.selectedItems(), key=lambda x:sort_map.get(x, -1))
settings = get_bulk_rename_settings(self, len(items), prefix=_('Chapter '), msg=_(
'All selected items will be renamed to the form prefix-number'), sanitize=lambda x:x, leading_zeros=False)
@@ -784,7 +784,7 @@ class TOCView(QWidget): # {{{
found = True
while found:
found = False
- for item in self.iteritems():
+ for item in iteritems(self):
if item.childCount() > 0:
self._flatten_item(item)
found = True
diff --git a/src/calibre/gui2/tweak_book/__init__.py b/src/calibre/gui2/tweak_book/__init__.py
index d203a7576a..b09a2c1b12 100644
--- a/src/calibre/gui2/tweak_book/__init__.py
+++ b/src/calibre/gui2/tweak_book/__init__.py
@@ -7,7 +7,7 @@ __license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal '
import string
-from polyglot.builtins import map
+from polyglot.builtins import iteritems, map
from calibre.utils.config import JSONConfig
from calibre.spell.dictionary import Dictionaries, parse_lang_code
@@ -118,7 +118,7 @@ dictionaries = Dictionaries()
def editor_name(editor):
- for n, ed in editors.iteritems():
+ for n, ed in iteritems(editors):
if ed is editor:
return n
diff --git a/src/calibre/gui2/tweak_book/boss.py b/src/calibre/gui2/tweak_book/boss.py
index e179135a4f..27dc8af7aa 100644
--- a/src/calibre/gui2/tweak_book/boss.py
+++ b/src/calibre/gui2/tweak_book/boss.py
@@ -69,7 +69,7 @@ from calibre.utils.config import JSONConfig
from calibre.utils.icu import numeric_sort_key
from calibre.utils.imghdr import identify
from calibre.utils.tdir_in_cache import tdir_in_cache
-from polyglot.builtins import iteritems, string_or_bytes
+from polyglot.builtins import iteritems, itervalues, string_or_bytes
from polyglot.urllib import urlparse
_diff_dialogs = []
@@ -185,11 +185,11 @@ class Boss(QObject):
dictionaries.initialize(force=True) # Reread user dictionaries
if p.toolbars_changed:
self.gui.populate_toolbars()
- for ed in editors.itervalues():
+ for ed in itervalues(editors):
if hasattr(ed, 'populate_toolbars'):
ed.populate_toolbars()
if orig_size != tprefs['toolbar_icon_size']:
- for ed in editors.itervalues():
+ for ed in itervalues(editors):
if hasattr(ed, 'bars'):
for bar in ed.bars:
bar.setIconSize(QSize(tprefs['toolbar_icon_size'], tprefs['toolbar_icon_size']))
@@ -199,12 +199,12 @@ class Boss(QObject):
self.gui.apply_settings()
self.refresh_file_list()
if ret == p.Accepted or p.dictionaries_changed:
- for ed in editors.itervalues():
+ for ed in itervalues(editors):
ed.apply_settings(dictionaries_changed=p.dictionaries_changed)
if orig_spell != tprefs['inline_spell_check']:
from calibre.gui2.tweak_book.editor.syntax.html import refresh_spell_check_status
refresh_spell_check_status()
- for ed in editors.itervalues():
+ for ed in itervalues(editors):
try:
ed.editor.highlighter.rehighlight()
except AttributeError:
@@ -387,7 +387,7 @@ class Boss(QObject):
def update_editors_from_container(self, container=None, names=None):
c = container or current_container()
- for name, ed in tuple(editors.iteritems()):
+ for name, ed in tuple(iteritems(editors)):
if c.has_name(name):
if names is None or name in names:
ed.replace_data(c.raw_data(name))
@@ -505,7 +505,7 @@ class Boss(QObject):
if files:
folder_map = get_recommended_folders(current_container(), files)
files = {x:('/'.join((folder, os.path.basename(x))) if folder else os.path.basename(x))
- for x, folder in folder_map.iteritems()}
+ for x, folder in iteritems(folder_map)}
self.add_savepoint(_('Before Add files'))
c = current_container()
for path in sorted(files, key=numeric_sort_key):
@@ -712,7 +712,7 @@ class Boss(QObject):
det_msg=job.traceback, show=True)
self.gui.file_list.build(current_container())
self.set_modified()
- for oldname, newname in name_map.iteritems():
+ for oldname, newname in iteritems(name_map):
if oldname in editors:
editors[newname] = ed = editors.pop(oldname)
ed.change_document_name(newname)
@@ -721,7 +721,7 @@ class Boss(QObject):
self.gui.preview.current_name = newname
self.apply_container_update_to_gui()
if from_filelist:
- self.gui.file_list.select_names(frozenset(name_map.itervalues()), current_name=name_map.get(from_filelist))
+ self.gui.file_list.select_names(frozenset(itervalues(name_map)), current_name=name_map.get(from_filelist))
self.gui.file_list.file_list.setFocus(Qt.PopupFocusReason)
# }}}
@@ -1052,7 +1052,7 @@ class Boss(QObject):
def word_ignored(self, word, locale):
if tprefs['inline_spell_check']:
- for ed in editors.itervalues():
+ for ed in itervalues(editors):
try:
ed.editor.recheck_word(word, locale)
except AttributeError:
@@ -1115,7 +1115,7 @@ class Boss(QObject):
actions on the current container '''
changed = False
with BusyCursor():
- for name, ed in editors.iteritems():
+ for name, ed in iteritems(editors):
if not ed.is_synced_to_container:
self.commit_editor_to_container(name)
ed.is_synced_to_container = True
@@ -1125,7 +1125,7 @@ class Boss(QObject):
def save_book(self):
' Save the book. Saving is performed in the background '
c = current_container()
- for name, ed in editors.iteritems():
+ for name, ed in iteritems(editors):
if ed.is_modified or not ed.is_synced_to_container:
self.commit_editor_to_container(name, c)
ed.is_modified = False
@@ -1169,7 +1169,7 @@ class Boss(QObject):
path += '.' + ext.lower()
tdir = self.mkdtemp(prefix='save-copy-')
container = clone_container(c, tdir)
- for name, ed in editors.iteritems():
+ for name, ed in iteritems(editors):
if ed.is_modified or not ed.is_synced_to_container:
self.commit_editor_to_container(name, container)
@@ -1361,7 +1361,7 @@ class Boss(QObject):
name:container.get_file_path_for_processing(name, allow_modification=False)
for name in names
}
- md.setUrls(list(map(QUrl.fromLocalFile, url_map.values())))
+ md.setUrls(list(map(QUrl.fromLocalFile, list(url_map.values()))))
import json
md.setData(FILE_COPY_MIME, json.dumps({
name: (url_map[name], container.mime_map.get(name)) for name in names
@@ -1564,7 +1564,7 @@ class Boss(QObject):
if not self.ensure_book(_('No book is currently open. You must first open a book to edit.')):
return
c = current_container()
- files = [name for name, mime in c.mime_map.iteritems() if c.exists(name) and syntax_from_mime(name, mime) is not None]
+ files = [name for name, mime in iteritems(c.mime_map) if c.exists(name) and syntax_from_mime(name, mime) is not None]
d = QuickOpen(files, parent=self.gui)
if d.exec_() == d.Accepted and d.selected_result is not None:
self.edit_file_requested(d.selected_result, None, c.mime_map[d.selected_result])
@@ -1597,7 +1597,7 @@ class Boss(QObject):
def editor_data_changed(self, editor):
self.gui.preview.start_refresh_timer()
- for name, ed in editors.iteritems():
+ for name, ed in iteritems(editors):
if ed is editor:
self.gui.toc_view.start_refresh_timer(name)
break
@@ -1776,7 +1776,7 @@ class Boss(QObject):
order = [k for k in order[extra:] if k in mem]
mem = {k:mem[k] for k in order}
mem[c.path_to_ebook] = {
- 'editors':{name:ed.current_editing_state for name, ed in editors.iteritems()},
+ 'editors':{name:ed.current_editing_state for name, ed in iteritems(editors)},
'currently_editing':self.currently_editing,
'tab_order':self.gui.central.tab_order,
}
diff --git a/src/calibre/gui2/tweak_book/check_links.py b/src/calibre/gui2/tweak_book/check_links.py
index 481f2244e3..7b51f1aa6b 100644
--- a/src/calibre/gui2/tweak_book/check_links.py
+++ b/src/calibre/gui2/tweak_book/check_links.py
@@ -16,6 +16,7 @@ from calibre.gui2 import error_dialog
from calibre.gui2.tweak_book import current_container, editors, set_current_container, tprefs
from calibre.gui2.tweak_book.boss import get_boss
from calibre.gui2.tweak_book.widgets import Dialog
+from polyglot.builtins import iteritems
def get_data(name):
@@ -149,7 +150,7 @@ class CheckExternalLinks(Dialog):
for name, href in {(l[0], l[1]) for l in err[0]}:
nmap[name].add(href)
- for name, hrefs in nmap.iteritems():
+ for name, hrefs in iteritems(nmap):
raw = oraw = get_data(name)
for href in hrefs:
raw = raw.replace(href, newurl)
diff --git a/src/calibre/gui2/tweak_book/completion/basic.py b/src/calibre/gui2/tweak_book/completion/basic.py
index 4a46dd9774..2fb008ead7 100644
--- a/src/calibre/gui2/tweak_book/completion/basic.py
+++ b/src/calibre/gui2/tweak_book/completion/basic.py
@@ -21,7 +21,7 @@ from calibre.gui2.tweak_book.completion.utils import control, data, DataError
from calibre.utils.ipc import eintr_retry_call
from calibre.utils.matcher import Matcher
from calibre.utils.icu import numeric_sort_key
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, itervalues, unicode_type
Request = namedtuple('Request', 'id type data query')
@@ -80,23 +80,23 @@ class Name(unicode_type):
def complete_names(names_data, data_conn):
if not names_cache:
mime_map, spine_names = get_data(data_conn, 'names_data')
- names_cache[None] = all_names = frozenset(Name(name, mt, spine_names) for name, mt in mime_map.iteritems())
+ names_cache[None] = all_names = frozenset(Name(name, mt, spine_names) for name, mt in iteritems(mime_map))
names_cache['text_link'] = frozenset(n for n in all_names if n.in_spine)
names_cache['stylesheet'] = frozenset(n for n in all_names if n.mime_type in OEB_STYLES)
names_cache['image'] = frozenset(n for n in all_names if n.mime_type.startswith('image/'))
names_cache['font'] = frozenset(n for n in all_names if n.mime_type in OEB_FONTS)
names_cache['css_resource'] = names_cache['image'] | names_cache['font']
names_cache['descriptions'] = d = {}
- for x, desc in {'text_link':_('Text'), 'stylesheet':_('Stylesheet'), 'image':_('Image'), 'font':_('Font')}.iteritems():
+ for x, desc in iteritems({'text_link':_('Text'), 'stylesheet':_('Stylesheet'), 'image':_('Image'), 'font':_('Font')}):
for n in names_cache[x]:
d[n] = desc
names_type, base, root = names_data
quote = (lambda x:x) if base.lower().endswith('.css') else prepare_string_for_xml
names = names_cache.get(names_type, names_cache[None])
nmap = {name:name_to_href(name, root, base, quote) for name in names}
- items = tuple(sorted(frozenset(nmap.itervalues()), key=numeric_sort_key))
+ items = tuple(sorted(frozenset(itervalues(nmap)), key=numeric_sort_key))
d = names_cache['descriptions'].get
- descriptions = {href:d(name) for name, href in nmap.iteritems()}
+ descriptions = {href:d(name) for name, href in iteritems(nmap)}
return items, descriptions, {}
@@ -184,5 +184,5 @@ class HandleDataRequest(QObject):
handle_data_request = HandleDataRequest()
-control_funcs = {name:func for name, func in globals().iteritems() if getattr(func, 'function_type', None) == 'control'}
-data_funcs = {name:func for name, func in globals().iteritems() if getattr(func, 'function_type', None) == 'data'}
+control_funcs = {name:func for name, func in iteritems(globals()) if getattr(func, 'function_type', None) == 'control'}
+data_funcs = {name:func for name, func in iteritems(globals()) if getattr(func, 'function_type', None) == 'data'}
diff --git a/src/calibre/gui2/tweak_book/completion/popup.py b/src/calibre/gui2/tweak_book/completion/popup.py
index e58a192ec4..c94fcc2469 100644
--- a/src/calibre/gui2/tweak_book/completion/popup.py
+++ b/src/calibre/gui2/tweak_book/completion/popup.py
@@ -16,6 +16,7 @@ from calibre import prints, prepare_string_for_xml
from calibre.gui2 import error_dialog
from calibre.gui2.tweak_book.widgets import make_highlighted_text
from calibre.utils.icu import string_length
+from polyglot.builtins import iteritems
class ChoosePopupWidget(QWidget):
@@ -246,7 +247,7 @@ class CompletionPopup(ChoosePopupWidget):
def set_items(self, items, descriptions=None, query=None):
self.current_query = query
- ChoosePopupWidget.set_items(self, tuple(items.iteritems()), descriptions=descriptions)
+ ChoosePopupWidget.set_items(self, tuple(iteritems(items)), descriptions=descriptions)
def choose_next_result(self, previous=False):
ChoosePopupWidget.choose_next_result(self, previous=previous)
diff --git a/src/calibre/gui2/tweak_book/diff/highlight.py b/src/calibre/gui2/tweak_book/diff/highlight.py
index 401ed0379b..38519bed97 100644
--- a/src/calibre/gui2/tweak_book/diff/highlight.py
+++ b/src/calibre/gui2/tweak_book/diff/highlight.py
@@ -14,7 +14,7 @@ from calibre.gui2.tweak_book import tprefs
from calibre.gui2.tweak_book.editor.text import get_highlighter as calibre_highlighter, SyntaxHighlighter
from calibre.gui2.tweak_book.editor.themes import get_theme, highlight_to_char_format
from calibre.gui2.tweak_book.editor.syntax.utils import format_for_pygments_token, NULL_FMT
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, range
class QtHighlighter(QTextDocument):
@@ -84,7 +84,7 @@ class PygmentsHighlighter(object):
def __init__(self, text, lexer):
theme, cache = get_theme(tprefs['editor_theme']), {}
- theme = {k:highlight_to_char_format(v) for k, v in theme.iteritems()}
+ theme = {k:highlight_to_char_format(v) for k, v in iteritems(theme)}
theme[None] = NULL_FMT
def fmt(token):
diff --git a/src/calibre/gui2/tweak_book/diff/main.py b/src/calibre/gui2/tweak_book/diff/main.py
index 6b01d12d90..0b41d6beb3 100644
--- a/src/calibre/gui2/tweak_book/diff/main.py
+++ b/src/calibre/gui2/tweak_book/diff/main.py
@@ -24,7 +24,7 @@ from calibre.gui2.tweak_book.widgets import Dialog
from calibre.gui2.widgets2 import HistoryLineEdit2
from calibre.utils.filenames import samefile
from calibre.utils.icu import numeric_sort_key
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
class BusyWidget(QWidget): # {{{
@@ -80,11 +80,11 @@ def changed_files(list_of_names1, list_of_names2, get_data1, get_data2):
removals = list_of_names1 - common_names
adds = set(list_of_names2 - common_names)
adata, rdata = {a:get_data2(a) for a in adds}, {r:get_data1(r) for r in removals}
- ahash = {a:hash(d) for a, d in adata.iteritems()}
- rhash = {r:hash(d) for r, d in rdata.iteritems()}
+ ahash = {a:hash(d) for a, d in iteritems(adata)}
+ rhash = {r:hash(d) for r, d in iteritems(rdata)}
renamed_names, removed_names, added_names = {}, set(), set()
- for name, rh in rhash.iteritems():
- for n, ah in ahash.iteritems():
+ for name, rh in iteritems(rhash):
+ for n, ah in iteritems(ahash):
if ah == rh:
renamed_names[name] = n
adds.discard(n)
@@ -139,7 +139,7 @@ def string_diff(left, right, left_syntax=None, right_syntax=None, left_name='lef
def file_diff(left, right):
(raw1, syntax1), (raw2, syntax2) = map(get_decoded_raw, (left, right))
- if type(raw1) is not type(raw2):
+ if not isinstance(raw1, type(raw2)):
raw1, raw2 = open(left, 'rb').read(), open(right, 'rb').read()
cache = Cache()
cache.set_left(left, raw1), cache.set_right(right, raw2)
@@ -420,7 +420,7 @@ class Diff(Dialog):
kwargs = lambda name: {'context':self.context, 'beautify':self.beautify, 'syntax':syntax_map.get(name, None)}
if isinstance(changed_names, dict):
- for name, other_name in sorted(changed_names.iteritems(), key=lambda x:numeric_sort_key(x[0])):
+ for name, other_name in sorted(iteritems(changed_names), key=lambda x:numeric_sort_key(x[0])):
args = (name, other_name, cache.left(name), cache.right(other_name))
add(args, kwargs(name))
else:
@@ -436,7 +436,7 @@ class Diff(Dialog):
args = (name, _('[%s was removed]') % name, cache.left(name), None)
add(args, kwargs(name))
- for name, new_name in sorted(renamed_names.iteritems(), key=lambda x:numeric_sort_key(x[0])):
+ for name, new_name in sorted(iteritems(renamed_names), key=lambda x:numeric_sort_key(x[0])):
args = (name, new_name, None, None)
add(args, kwargs(name))
diff --git a/src/calibre/gui2/tweak_book/diff/view.py b/src/calibre/gui2/tweak_book/diff/view.py
index 24c31a517e..e2fcd9841a 100644
--- a/src/calibre/gui2/tweak_book/diff/view.py
+++ b/src/calibre/gui2/tweak_book/diff/view.py
@@ -12,7 +12,7 @@ from math import ceil
from functools import partial
from collections import namedtuple, OrderedDict
from difflib import SequenceMatcher
-from polyglot.builtins import unicode_type, zip, range
+from polyglot.builtins import iteritems, unicode_type, zip, range
import regex
from PyQt5.Qt import (
@@ -652,12 +652,12 @@ class DiffSplit(QSplitter): # {{{
return x if x <= top else x + delta
lnm = LineNumberMap()
lnm.max_width = v.line_number_map.max_width
- for x, val in v.line_number_map.iteritems():
+ for x, val in iteritems(v.line_number_map):
dict.__setitem__(lnm, mapnum(x), val)
v.line_number_map = lnm
v.changes = [(mapnum(t), mapnum(b), k) for t, b, k in v.changes]
v.headers = [(mapnum(x), name) for x, name in v.headers]
- v.images = OrderedDict((mapnum(x), v) for x, v in v.images.iteritems())
+ v.images = OrderedDict((mapnum(x), v) for x, v in iteritems(v.images))
v.viewport().update()
def get_lines_for_image(self, img, view):
diff --git a/src/calibre/gui2/tweak_book/download.py b/src/calibre/gui2/tweak_book/download.py
index 9f0cb4b2c7..2b017ce152 100644
--- a/src/calibre/gui2/tweak_book/download.py
+++ b/src/calibre/gui2/tweak_book/download.py
@@ -15,7 +15,7 @@ from calibre.gui2.tweak_book import current_container
from calibre.gui2.tweak_book.widgets import Dialog
from calibre.gui2.progress_indicator import WaitStack
from calibre.ebooks.oeb.polish.download import get_external_resources, download_external_resources, replace_resources
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, range
class ChooseResources(QWidget):
@@ -50,7 +50,7 @@ class ChooseResources(QWidget):
self.items.clear()
self.original_resources = resources
dc = 0
- for url, matches in resources.iteritems():
+ for url, matches in iteritems(resources):
text = url
num = len(matches)
if text.startswith('data:'):
@@ -180,7 +180,7 @@ class DownloadResources(Dialog):
else:
replacements, failures = ret
if failures:
- tb = ['{}\n\t{}\n'.format(url, err) for url, err in failures.iteritems()]
+ tb = ['{}\n\t{}\n'.format(url, err) for url, err in iteritems(failures)]
if not replacements:
error_dialog(self, _('Download failed'), _(
'Failed to download external resources, click "Show Details" for more information.'),
diff --git a/src/calibre/gui2/tweak_book/editor/image.py b/src/calibre/gui2/tweak_book/editor/image.py
index cb9bbf71e3..2c1b72aa5c 100644
--- a/src/calibre/gui2/tweak_book/editor/image.py
+++ b/src/calibre/gui2/tweak_book/editor/image.py
@@ -15,6 +15,7 @@ from PyQt5.Qt import (
from calibre.gui2 import error_dialog
from calibre.gui2.tweak_book import actions, tprefs, editors
from calibre.gui2.tweak_book.editor.canvas import Canvas
+from polyglot.builtins import itervalues
class ResizeDialog(QDialog): # {{{
@@ -300,7 +301,7 @@ class Editor(QMainWindow):
def toolbar_floated(self, floating):
if not floating:
self.save_state()
- for ed in editors.itervalues():
+ for ed in itervalues(editors):
if ed is not self:
ed.restore_state()
diff --git a/src/calibre/gui2/tweak_book/editor/snippets.py b/src/calibre/gui2/tweak_book/editor/snippets.py
index 3c2e3b46d8..23512db75b 100644
--- a/src/calibre/gui2/tweak_book/editor/snippets.py
+++ b/src/calibre/gui2/tweak_book/editor/snippets.py
@@ -24,7 +24,7 @@ from calibre.gui2.tweak_book.widgets import Dialog, PlainTextEdit
from calibre.utils.config import JSONConfig
from calibre.utils.icu import string_length as strlen
from calibre.utils.localization import localize_user_manual_link
-from polyglot.builtins import codepoint_to_chr, unicode_type, range
+from polyglot.builtins import codepoint_to_chr, iteritems, itervalues, unicode_type, range
string_length = lambda x: strlen(unicode_type(x)) # Needed on narrow python builds, as subclasses of unicode dont work
KEY = Qt.Key_J
@@ -98,7 +98,7 @@ def escape_funcs():
escapem = {('\\' + x):codepoint_to_chr(i+1) for i, x in enumerate('\\${}')}
escape_pat = re.compile('|'.join(map(re.escape, escapem)))
escape = lambda x: escape_pat.sub(lambda m: escapem[m.group()], x.replace(r'\\', '\x01'))
- unescapem = {v:k[1] for k, v in escapem.iteritems()}
+ unescapem = {v:k[1] for k, v in iteritems(escapem)}
unescape_pat = re.compile('|'.join(unescapem))
unescape = lambda x:unescape_pat.sub(lambda m:unescapem[m.group()], x)
return escape, unescape
@@ -177,7 +177,7 @@ def snippets(refresh=False):
if snip['trigger'] and isinstance(snip['trigger'], type('')):
key = snip_key(snip['trigger'], *snip['syntaxes'])
_snippets[key] = {'template':snip['template'], 'description':snip['description']}
- _snippets = sorted(_snippets.iteritems(), key=(lambda key_snip:string_length(key_snip[0].trigger)), reverse=True)
+ _snippets = sorted(iteritems(_snippets), key=(lambda key_snip:string_length(key_snip[0].trigger)), reverse=True)
return _snippets
# Editor integration {{{
@@ -352,7 +352,7 @@ def expand_template(editor, trigger, template):
left = right - string_length(trigger)
text, tab_stops = parse_template(template)
c.setPosition(left), c.setPosition(right, c.KeepAnchor), c.insertText(text)
- editor_tab_stops = [EditorTabStop(left, ts, editor) for ts in tab_stops.itervalues()]
+ editor_tab_stops = [EditorTabStop(left, ts, editor) for ts in itervalues(tab_stops)]
tl = Template(editor_tab_stops)
if tl.has_tab_stops:
@@ -699,7 +699,7 @@ class UserSnippets(Dialog):
def change_builtin(self):
d = QDialog(self)
lw = QListWidget(d)
- for (trigger, syntaxes), snip in builtin_snippets.iteritems():
+ for (trigger, syntaxes), snip in iteritems(builtin_snippets):
snip = copy.deepcopy(snip)
snip['trigger'], snip['syntaxes'] = trigger, syntaxes
i = QListWidgetItem(self.snip_to_text(snip), lw)
diff --git a/src/calibre/gui2/tweak_book/editor/syntax/base.py b/src/calibre/gui2/tweak_book/editor/syntax/base.py
index 6618805549..c89ec23928 100644
--- a/src/calibre/gui2/tweak_book/editor/syntax/base.py
+++ b/src/calibre/gui2/tweak_book/editor/syntax/base.py
@@ -14,7 +14,7 @@ from PyQt5.Qt import QTextCursor, QTextBlockUserData, QTextLayout, QTimer
from ..themes import highlight_to_char_format
from calibre.gui2.tweak_book.widgets import BusyCursor
from calibre.utils.icu import utf16_length
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
is_wide_build = sys.maxunicode >= 0x10ffff
@@ -86,7 +86,7 @@ class SyntaxHighlighter(object):
return bool(self.requests)
def apply_theme(self, theme):
- self.theme = {k:highlight_to_char_format(v) for k, v in theme.iteritems()}
+ self.theme = {k:highlight_to_char_format(v) for k, v in iteritems(theme)}
self.create_formats()
self.rehighlight()
diff --git a/src/calibre/gui2/tweak_book/editor/syntax/css.py b/src/calibre/gui2/tweak_book/editor/syntax/css.py
index be68dae79a..ba67904dd3 100644
--- a/src/calibre/gui2/tweak_book/editor/syntax/css.py
+++ b/src/calibre/gui2/tweak_book/editor/syntax/css.py
@@ -13,6 +13,7 @@ from PyQt5.Qt import QTextBlockUserData
from calibre.gui2.tweak_book import verify_link
from calibre.gui2.tweak_book.editor import syntax_text_char_format, LINK_PROPERTY, CSS_PROPERTY
from calibre.gui2.tweak_book.editor.syntax.base import SyntaxHighlighter
+from polyglot.builtins import iteritems
space_pat = re.compile(r'[ \n\t\r\f]+')
cdo_pat = re.compile(r'/\*')
@@ -268,6 +269,7 @@ def in_string(state, text, i, formats, user_data):
state.parse = (NORMAL if state.blocks < 1 else IN_CONTENT)
return [(pos - i + len(q), formats['string'])]
+
state_map = {
NORMAL:normal,
IN_COMMENT_NORMAL: comment,
@@ -294,10 +296,10 @@ def create_formats(highlighter):
'pseudo_selector': theme['Special'],
'tag': theme['Identifier'],
}
- for name, msg in {
+ for name, msg in iteritems({
'unknown-normal': _('Invalid text'),
'unterminated-string': _('Unterminated string'),
- }.iteritems():
+ }):
f = formats[name] = syntax_text_char_format(formats['error'])
f.setToolTip(msg)
formats['link'] = syntax_text_char_format(theme['Link'])
@@ -340,4 +342,3 @@ li[rel="mewl"], p.mewl {
}
''', path_is_raw=True, syntax='css')
-
diff --git a/src/calibre/gui2/tweak_book/editor/syntax/html.py b/src/calibre/gui2/tweak_book/editor/syntax/html.py
index e0296dd5e3..7aba9d4be5 100644
--- a/src/calibre/gui2/tweak_book/editor/syntax/html.py
+++ b/src/calibre/gui2/tweak_book/editor/syntax/html.py
@@ -22,6 +22,7 @@ from calibre.gui2.tweak_book.editor import (
from calibre.gui2.tweak_book.editor.syntax.base import SyntaxHighlighter, run_loop
from calibre.gui2.tweak_book.editor.syntax.css import (
create_formats as create_css_formats, state_map as css_state_map, CSSState, CSSUserData)
+from polyglot.builtins import iteritems
cdata_tags = frozenset(['title', 'textarea', 'style', 'script', 'xmp', 'iframe', 'noembed', 'noframes', 'noscript'])
normal_pat = re.compile(r'[^<>&]+')
@@ -544,7 +545,7 @@ def create_formats(highlighter, add_css=True):
'nbsp': t['SpecialCharacter'],
'spell': t['SpellError'],
}
- for name, msg in {
+ for name, msg in iteritems({
'<': _('An unescaped < is not allowed. Replace it with <'),
'&': _('An unescaped ampersand is not allowed. Replace it with &'),
'>': _('An unescaped > is not allowed. Replace it with >'),
@@ -553,7 +554,7 @@ def create_formats(highlighter, add_css=True):
'bad-closing': _('A closing tag must contain only the tag name and nothing else'),
'no-attr-value': _('Expecting an attribute value'),
'only-prefix': _('A tag name cannot end with a colon'),
- }.iteritems():
+ }):
f = formats[name] = syntax_text_char_format(formats['error'])
f.setToolTip(msg)
f = formats['title'] = syntax_text_char_format()
diff --git a/src/calibre/gui2/tweak_book/editor/themes.py b/src/calibre/gui2/tweak_book/editor/themes.py
index 8e76121182..758c931d6f 100644
--- a/src/calibre/gui2/tweak_book/editor/themes.py
+++ b/src/calibre/gui2/tweak_book/editor/themes.py
@@ -18,7 +18,7 @@ from calibre.gui2 import error_dialog
from calibre.gui2.tweak_book import tprefs
from calibre.gui2.tweak_book.editor import syntax_text_char_format
from calibre.gui2.tweak_book.widgets import Dialog
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, iterkeys, unicode_type, range
underline_styles = {'single', 'dash', 'dot', 'dash_dot', 'dash_dot_dot', 'wave', 'spell'}
@@ -32,13 +32,14 @@ def default_theme():
_default_theme = 'wombat-dark' if isdark else 'pyte-light'
return _default_theme
+
# The solarized themes {{{
SLDX = {'base03':'1c1c1c', 'base02':'262626', 'base01':'585858', 'base00':'626262', 'base0':'808080', 'base1':'8a8a8a', 'base2':'e4e4e4', 'base3':'ffffd7', 'yellow':'af8700', 'orange':'d75f00', 'red':'d70000', 'magenta':'af005f', 'violet':'5f5faf', 'blue':'0087ff', 'cyan':'00afaf', 'green':'5f8700'} # noqa
SLD = {'base03':'002b36', 'base02':'073642', 'base01':'586e75', 'base00':'657b83', 'base0':'839496', 'base1':'93a1a1', 'base2':'eee8d5', 'base3':'fdf6e3', 'yellow':'b58900', 'orange':'cb4b16', 'red':'dc322f', 'magenta':'d33682', 'violet':'6c71c4', 'blue':'268bd2', 'cyan':'2aa198', 'green':'859900'} # noqa
m = {'base%d'%n:'base%02d'%n for n in range(1, 4)}
m.update({'base%02d'%n:'base%d'%n for n in range(1, 4)})
-SLL = {m.get(k, k) : v for k, v in SLD.iteritems()}
-SLLX = {m.get(k, k) : v for k, v in SLDX.iteritems()}
+SLL = {m.get(k, k) : v for k, v in iteritems(SLD)}
+SLLX = {m.get(k, k) : v for k, v in iteritems(SLDX)}
SOLARIZED = \
'''
CursorLine bg={base02}
@@ -238,7 +239,7 @@ def read_theme(raw):
return ans
-THEMES = {k:read_theme(raw) for k, raw in THEMES.iteritems()}
+THEMES = {k:read_theme(raw) for k, raw in iteritems(THEMES)}
def u(x):
@@ -260,7 +261,7 @@ def to_highlight(data):
def read_custom_theme(data):
dt = THEMES[default_theme()].copy()
- dt.update({k:to_highlight(v) for k, v in data.iteritems()})
+ dt.update({k:to_highlight(v) for k, v in iteritems(data)})
return dt
@@ -309,11 +310,11 @@ def theme_format(theme, name):
def custom_theme_names():
- return tuple(tprefs['custom_themes'].iterkeys())
+ return tuple(iterkeys(tprefs['custom_themes']))
def builtin_theme_names():
- return tuple(THEMES.iterkeys())
+ return tuple(iterkeys(THEMES))
def all_theme_names():
@@ -611,13 +612,13 @@ class ThemeEditor(Dialog):
def update_theme(self, name):
data = tprefs['custom_themes'][name]
- extra = set(data.iterkeys()) - set(THEMES[default_theme()].iterkeys())
- missing = set(THEMES[default_theme()].iterkeys()) - set(data.iterkeys())
+ extra = set(iterkeys(data)) - set(iterkeys(THEMES[default_theme()]))
+ missing = set(iterkeys(THEMES[default_theme()])) - set(iterkeys(data))
for k in extra:
data.pop(k)
for k in missing:
data[k] = dict(THEMES[default_theme()][k]._asdict())
- for nk, nv in data[k].iteritems():
+ for nk, nv in iteritems(data[k]):
if isinstance(nv, QBrush):
data[k][nk] = unicode_type(nv.color().name())
if extra or missing:
@@ -663,8 +664,8 @@ class ThemeEditor(Dialog):
name = '*' + d.theme_name
base = unicode_type(d.base.currentText())
theme = {}
- for key, val in THEMES[base].iteritems():
- theme[key] = {k:col_to_string(v.color()) if isinstance(v, QBrush) else v for k, v in val._asdict().iteritems()}
+ for key, val in iteritems(THEMES[base]):
+ theme[key] = {k:col_to_string(v.color()) if isinstance(v, QBrush) else v for k, v in iteritems(val._asdict())}
tprefs['custom_themes'][name] = theme
tprefs['custom_themes'] = tprefs['custom_themes']
t = self.theme
diff --git a/src/calibre/gui2/tweak_book/editor/widget.py b/src/calibre/gui2/tweak_book/editor/widget.py
index b1aa5cb5c7..6b31933c5f 100644
--- a/src/calibre/gui2/tweak_book/editor/widget.py
+++ b/src/calibre/gui2/tweak_book/editor/widget.py
@@ -24,7 +24,7 @@ from calibre.gui2.tweak_book.editor import SPELL_PROPERTY, LINK_PROPERTY, TAG_NA
from calibre.gui2.tweak_book.editor.help import help_url
from calibre.gui2.tweak_book.editor.text import TextEdit
from calibre.utils.icu import utf16_length
-from polyglot.builtins import unicode_type, string_or_bytes
+from polyglot.builtins import itervalues, unicode_type, string_or_bytes
def create_icon(text, palette=None, sz=None, divider=2, fill='white'):
@@ -346,7 +346,7 @@ class Editor(QMainWindow):
def toolbar_floated(self, floating):
if not floating:
self.save_state()
- for ed in editors.itervalues():
+ for ed in itervalues(editors):
if ed is not self:
ed.restore_state()
diff --git a/src/calibre/gui2/tweak_book/file_list.py b/src/calibre/gui2/tweak_book/file_list.py
index 9acbe741e9..674d37ceab 100644
--- a/src/calibre/gui2/tweak_book/file_list.py
+++ b/src/calibre/gui2/tweak_book/file_list.py
@@ -39,7 +39,7 @@ from calibre.gui2.tweak_book import (
from calibre.gui2.tweak_book.editor import syntax_from_mime
from calibre.gui2.tweak_book.templates import template_for
from calibre.utils.icu import numeric_sort_key
-from polyglot.builtins import iteritems, unicode_type, range
+from polyglot.builtins import iteritems, itervalues, unicode_type, range
try:
from PyQt5 import sip
@@ -264,29 +264,29 @@ class FileList(QTreeWidget):
def get_state(self):
s = {'pos':self.verticalScrollBar().value()}
- s['expanded'] = {c for c, item in self.categories.iteritems() if item.isExpanded()}
+ s['expanded'] = {c for c, item in iteritems(self.categories) if item.isExpanded()}
s['selected'] = {unicode_type(i.data(0, NAME_ROLE) or '') for i in self.selectedItems()}
return s
def set_state(self, state):
- for category, item in self.categories.iteritems():
+ for category, item in iteritems(self.categories):
item.setExpanded(category in state['expanded'])
self.verticalScrollBar().setValue(state['pos'])
- for parent in self.categories.itervalues():
+ for parent in itervalues(self.categories):
for c in (parent.child(i) for i in range(parent.childCount())):
name = unicode_type(c.data(0, NAME_ROLE) or '')
if name in state['selected']:
c.setSelected(True)
def item_from_name(self, name):
- for parent in self.categories.itervalues():
+ for parent in itervalues(self.categories):
for c in (parent.child(i) for i in range(parent.childCount())):
q = unicode_type(c.data(0, NAME_ROLE) or '')
if q == name:
return c
def select_name(self, name, set_as_current_index=False):
- for parent in self.categories.itervalues():
+ for parent in itervalues(self.categories):
for c in (parent.child(i) for i in range(parent.childCount())):
q = unicode_type(c.data(0, NAME_ROLE) or '')
c.setSelected(q == name)
@@ -296,7 +296,7 @@ class FileList(QTreeWidget):
self.setCurrentItem(c)
def select_names(self, names, current_name=None):
- for parent in self.categories.itervalues():
+ for parent in itervalues(self.categories):
for c in (parent.child(i) for i in range(parent.childCount())):
q = unicode_type(c.data(0, NAME_ROLE) or '')
c.setSelected(q in names)
@@ -355,7 +355,7 @@ class FileList(QTreeWidget):
cover_page_name = get_cover_page_name(container)
cover_image_name = get_raster_cover_name(container)
manifested_names = set()
- for names in container.manifest_type_map.itervalues():
+ for names in itervalues(container.manifest_type_map):
manifested_names |= set(names)
def get_category(name, mt):
@@ -481,7 +481,7 @@ class FileList(QTreeWidget):
continue
processed[name] = create_item(name)
- for name, c in self.categories.iteritems():
+ for name, c in iteritems(self.categories):
c.setExpanded(True)
if name != 'text':
c.sortChildren(1, Qt.AscendingOrder)
@@ -496,7 +496,7 @@ class FileList(QTreeWidget):
def show_context_menu(self, point):
item = self.itemAt(point)
- if item is None or item in set(self.categories.itervalues()):
+ if item is None or item in set(itervalues(self.categories)):
return
m = QMenu(self)
sel = self.selectedItems()
@@ -542,7 +542,7 @@ class FileList(QTreeWidget):
for item in sel:
selected_map[unicode_type(item.data(0, CATEGORY_ROLE) or '')].append(unicode_type(item.data(0, NAME_ROLE) or ''))
- for items in selected_map.itervalues():
+ for items in itervalues(selected_map):
items.sort(key=self.index_of_name)
if selected_map['text']:
@@ -557,7 +557,7 @@ class FileList(QTreeWidget):
m.popup(self.mapToGlobal(point))
def index_of_name(self, name):
- for category, parent in self.categories.iteritems():
+ for category, parent in iteritems(self.categories):
for i in range(parent.childCount()):
item = parent.child(i)
if unicode_type(item.data(0, NAME_ROLE) or '') == name:
@@ -682,7 +682,7 @@ class FileList(QTreeWidget):
for i, (name, remove) in enumerate(spine_removals):
if remove:
removals.append(self.categories['text'].child(i))
- for category, parent in self.categories.iteritems():
+ for category, parent in iteritems(self.categories):
if category != 'text':
for i in range(parent.childCount()):
child = parent.child(i)
@@ -770,7 +770,7 @@ class FileList(QTreeWidget):
@property
def all_files(self):
- return (category.child(i) for category in self.categories.itervalues() for i in range(category.childCount()))
+ return (category.child(i) for category in itervalues(self.categories) for i in range(category.childCount()))
@property
def searchable_names(self):
@@ -1012,7 +1012,7 @@ class FileListWidget(QWidget):
self.file_list = FileList(self)
self.layout().addWidget(self.file_list)
self.layout().setContentsMargins(0, 0, 0, 0)
- self.forwarded_signals = {k for k, o in vars(self.file_list.__class__).iteritems() if isinstance(o, pyqtSignal) and '_' in k and not hasattr(self, k)}
+ self.forwarded_signals = {k for k, o in iteritems(vars(self.file_list.__class__)) if isinstance(o, pyqtSignal) and '_' in k and not hasattr(self, k)}
for x in ('delete_done', 'select_name', 'select_names', 'request_edit', 'mark_name_as_current', 'clear_currently_edited_name'):
setattr(self, x, getattr(self.file_list, x))
self.setFocusProxy(self.file_list)
diff --git a/src/calibre/gui2/tweak_book/function_replace.py b/src/calibre/gui2/tweak_book/function_replace.py
index c588f63a77..039f80df6d 100644
--- a/src/calibre/gui2/tweak_book/function_replace.py
+++ b/src/calibre/gui2/tweak_book/function_replace.py
@@ -23,7 +23,7 @@ from calibre.utils.config import JSONConfig
from calibre.utils.icu import capitalize, upper, lower, swapcase
from calibre.utils.titlecase import titlecase
from calibre.utils.localization import localize_user_manual_link
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
user_functions = JSONConfig('editor-search-replace-functions')
@@ -69,7 +69,7 @@ class Function(object):
self.boss = get_boss()
self.data = {}
self.debug_buf = StringIO()
- self.functions = {name:func.mod for name, func in functions().iteritems() if func.mod is not None}
+ self.functions = {name:func.mod for name, func in iteritems(functions()) if func.mod is not None}
def __hash__(self):
return hash(self.name)
@@ -138,7 +138,7 @@ class DebugOutput(Dialog):
def builtin_functions():
- for name, obj in globals().iteritems():
+ for name, obj in iteritems(globals()):
if name.startswith('replace_') and callable(obj) and hasattr(obj, 'imports'):
yield obj
@@ -152,7 +152,7 @@ def functions(refresh=False):
ans = _functions = {}
for func in builtin_functions():
ans[func.name] = Function(func.name, func=func)
- for name, source in user_functions.iteritems():
+ for name, source in iteritems(user_functions):
try:
f = Function(name, source=source)
except Exception:
diff --git a/src/calibre/gui2/tweak_book/manage_fonts.py b/src/calibre/gui2/tweak_book/manage_fonts.py
index 3be05b2f4c..bc1d0c06f3 100644
--- a/src/calibre/gui2/tweak_book/manage_fonts.py
+++ b/src/calibre/gui2/tweak_book/manage_fonts.py
@@ -22,7 +22,7 @@ from calibre.gui2.tweak_book.widgets import Dialog, BusyCursor
from calibre.utils.icu import primary_sort_key as sort_key
from calibre.utils.fonts.scanner import font_scanner, NoFonts
from calibre.utils.fonts.metadata import FontMetadata, UnsupportedFont
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, iterkeys, unicode_type
def show_font_face_rule_for_font_file(file_data, added_name, parent=None):
@@ -103,7 +103,7 @@ class AllFonts(QAbstractTableModel):
def do_sort(self):
reverse = not self.sorted_on[1]
- self.items = sorted(self.font_data.iterkeys(), key=sort_key, reverse=reverse)
+ self.items = sorted(iterkeys(self.font_data), key=sort_key, reverse=reverse)
if self.sorted_on[0] != 'name':
self.items.sort(key=self.font_data.get, reverse=reverse)
@@ -315,7 +315,7 @@ class ManageFonts(Dialog):
fonts = self.get_selected_data()
if not fonts:
return
- d = ChangeFontFamily(', '.join(fonts), {f for f, embedded in self.model.font_data.iteritems() if embedded}, self)
+ d = ChangeFontFamily(', '.join(fonts), {f for f, embedded in iteritems(self.model.font_data) if embedded}, self)
if d.exec_() != d.Accepted:
return
changed = False
diff --git a/src/calibre/gui2/tweak_book/plugin.py b/src/calibre/gui2/tweak_book/plugin.py
index e06f862625..78100c83c8 100644
--- a/src/calibre/gui2/tweak_book/plugin.py
+++ b/src/calibre/gui2/tweak_book/plugin.py
@@ -14,7 +14,7 @@ from calibre import prints
from calibre.customize.ui import all_edit_book_tool_plugins
from calibre.gui2.tweak_book import tprefs, current_container
from calibre.gui2.tweak_book.boss import get_boss
-from polyglot.builtins import unicode_type
+from polyglot.builtins import itervalues, unicode_type
class Tool(object):
@@ -120,7 +120,7 @@ def load_plugin_tools(plugin):
import traceback
traceback.print_exc()
else:
- for x in vars(main).itervalues():
+ for x in itervalues(vars(main)):
if isinstance(x, type) and x is not Tool and issubclass(x, Tool):
ans = x()
ans.plugin = plugin
diff --git a/src/calibre/gui2/tweak_book/preferences.py b/src/calibre/gui2/tweak_book/preferences.py
index 9ee6fe3cc5..5ee795480e 100644
--- a/src/calibre/gui2/tweak_book/preferences.py
+++ b/src/calibre/gui2/tweak_book/preferences.py
@@ -9,7 +9,8 @@ __copyright__ = '2013, Kovid Goyal '
import numbers
from operator import attrgetter, methodcaller
from collections import namedtuple
-from polyglot.builtins import map, unicode_type, range
+from polyglot.builtins import (
+ iteritems, iterkeys, itervalues, map, unicode_type, range)
from itertools import product
from copy import copy, deepcopy
@@ -72,7 +73,7 @@ class BasicSettings(QWidget): # {{{
prefs = prefs or tprefs
widget = QComboBox(self)
widget.currentIndexChanged[int].connect(self.emit_changed)
- for key, human in sorted(choices.iteritems(), key=lambda key_human: key_human[1] or key_human[0]):
+ for key, human in sorted(iteritems(choices), key=lambda key_human: key_human[1] or key_human[0]):
widget.addItem(human or key, key)
def getter(w):
@@ -134,7 +135,7 @@ class BasicSettings(QWidget): # {{{
prefs[name] = cv
def restore_defaults(self):
- for setting in self.settings.itervalues():
+ for setting in itervalues(self.settings):
setting.setter(setting.widget, self.default_value(setting.name))
def initial_value(self, name):
@@ -263,7 +264,7 @@ class EditorSettings(BasicSettings):
s = self.settings['editor_theme']
current_val = s.getter(s.widget)
s.widget.clear()
- for key, human in sorted(choices.iteritems(), key=lambda key_human1: key_human1[1] or key_human1[0]):
+ for key, human in sorted(iteritems(choices), key=lambda key_human1: key_human1[1] or key_human1[0]):
s.widget.addItem(human or key, key)
s.setter(s.widget, current_val)
if d.theme_name:
@@ -489,7 +490,7 @@ class ToolbarSettings(QWidget):
ans.setToolTip(ac.toolTip())
return ans
- for key, ac in sorted(all_items.iteritems(), key=lambda k_ac: unicode_type(k_ac[1].text())):
+ for key, ac in sorted(iteritems(all_items), key=lambda k_ac: unicode_type(k_ac[1].text())):
if key not in applied:
to_item(key, ac, self.available)
if name == 'global_book_toolbar' and 'donate' not in applied:
@@ -593,7 +594,7 @@ class TemplatesDialog(Dialog): # {{{
self.l = l = QVBoxLayout(self)
self.syntaxes = s = QComboBox(self)
- s.addItems(sorted(DEFAULT_TEMPLATES.iterkeys()))
+ s.addItems(sorted(iterkeys(DEFAULT_TEMPLATES)))
s.setCurrentIndex(s.findText('html'))
h = QHBoxLayout()
l.addLayout(h)
diff --git a/src/calibre/gui2/tweak_book/reports.py b/src/calibre/gui2/tweak_book/reports.py
index 443420872f..ee424b82cf 100644
--- a/src/calibre/gui2/tweak_book/reports.py
+++ b/src/calibre/gui2/tweak_book/reports.py
@@ -8,7 +8,7 @@ __copyright__ = '2015, Kovid Goyal '
import time, textwrap, os
from threading import Thread
-from polyglot.builtins import map, range
+from polyglot.builtins import iteritems, map, range
from operator import itemgetter
from functools import partial
from collections import defaultdict
@@ -1338,7 +1338,7 @@ class ReportsWidget(QWidget):
self.stack.widget(i)(data)
if DEBUG:
category = self.reports.item(i).data(Qt.DisplayRole)
- print ('Widget time for %12s: %.2fs seconds' % (category, time.time() - st))
+ print('Widget time for %12s: %.2fs seconds' % (category, time.time() - st))
def save(self):
save_state('splitter-state', bytearray(self.splitter.saveState()))
@@ -1439,8 +1439,8 @@ class Reports(Dialog):
' information.'), det_msg=data, show=True)
data, timing = data
if DEBUG:
- for x, t in sorted(timing.iteritems(), key=itemgetter(1)):
- print ('Time for %6s data: %.3f seconds' % (x, t))
+ for x, t in sorted(iteritems(timing), key=itemgetter(1)):
+ print('Time for %6s data: %.3f seconds' % (x, t))
self.reports(data)
def accept(self):
diff --git a/src/calibre/gui2/tweak_book/search.py b/src/calibre/gui2/tweak_book/search.py
index eb7432aa94..abe2535916 100644
--- a/src/calibre/gui2/tweak_book/search.py
+++ b/src/calibre/gui2/tweak_book/search.py
@@ -34,7 +34,7 @@ from calibre.gui2.tweak_book.widgets import BusyCursor
from calibre.gui2.widgets2 import FlowLayout, HistoryComboBox
from calibre.utils.icu import primary_contains
from calibre.ebooks.conversion.search_replace import REGEX_FLAGS, compile_regular_expression
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, iterkeys, unicode_type, range
# The search panel {{{
@@ -160,7 +160,7 @@ class WhereBox(QComboBox):
return wm[self.currentIndex()]
def fset(self, val):
- self.setCurrentIndex({v:k for k, v in wm.iteritems()}[val])
+ self.setCurrentIndex({v:k for k, v in iteritems(wm)}[val])
return property(fget=fget, fset=fset)
def showPopup(self):
@@ -569,8 +569,7 @@ class SearchesModel(QAbstractListModel):
def dropMimeData(self, data, action, row, column, parent):
if parent.isValid() or action != Qt.MoveAction or not data.hasFormat('x-calibre/searches-rows') or not self.filtered_searches:
return False
- rows = map(int, bytes(bytearray(data.data('x-calibre/searches-rows'))).decode('ascii').split(','))
- rows.sort()
+ rows = sorted(map(int, bytes(bytearray(data.data('x-calibre/searches-rows'))).decode('ascii').split(',')))
moved_searches = [self.searches[self.filtered_searches[r]] for r in rows]
moved_searches_q = {id(s) for s in moved_searches}
insert_at = max(0, min(row, len(self.filtered_searches)))
@@ -1221,7 +1220,7 @@ class SavedSearches(QWidget):
return err()
searches = []
for item in obj['searches']:
- if not isinstance(item, dict) or not set(item.iterkeys()).issuperset(needed_keys):
+ if not isinstance(item, dict) or not set(iterkeys(item)).issuperset(needed_keys):
return err
searches.append({k:item[k] for k in needed_keys})
@@ -1422,7 +1421,7 @@ def run_search(
return True
if wrap and not files and editor.find(p, wrap=True, marked=marked, save_match='gui'):
return True
- for fname, syntax in files.iteritems():
+ for fname, syntax in iteritems(files):
ed = editors.get(fname, None)
if ed is not None:
if not wrap and ed is editor:
diff --git a/src/calibre/gui2/tweak_book/spell.py b/src/calibre/gui2/tweak_book/spell.py
index 3fe4e0522a..130f2deac9 100644
--- a/src/calibre/gui2/tweak_book/spell.py
+++ b/src/calibre/gui2/tweak_book/spell.py
@@ -37,7 +37,7 @@ from calibre.spell.import_from import import_from_oxt
from calibre.spell.break_iterator import split_into_words
from calibre.utils.localization import calibre_langcode_to_name, get_language, get_lang, canonicalize_lang
from calibre.utils.icu import sort_key, primary_sort_key, primary_contains, contains
-from polyglot.builtins import unicode_type, range
+from polyglot.builtins import iteritems, unicode_type, range
LANG = 0
COUNTRY = 1
@@ -707,7 +707,7 @@ class WordsModel(QAbstractTableModel):
self.endResetModel()
def update_counts(self, emit_signal=True):
- self.counts = (len([None for w, recognized in self.spell_map.iteritems() if not recognized]), len(self.words))
+ self.counts = (len([None for w, recognized in iteritems(self.spell_map) if not recognized]), len(self.words))
if emit_signal:
self.counts_changed.emit()
@@ -1342,7 +1342,7 @@ def find_next(word, locations, current_editor, current_editor_name,
if current_editor_name not in files:
current_editor_name = None
- locations = [(fname, {l.original_word for l in _locations}, False) for fname, _locations in files.iteritems()]
+ locations = [(fname, {l.original_word for l in _locations}, False) for fname, _locations in iteritems(files)]
else:
# Re-order the list of locations to search so that we search in the
# current editor first
diff --git a/src/calibre/gui2/tweak_book/templates.py b/src/calibre/gui2/tweak_book/templates.py
index 5c845ab282..762d9904ad 100644
--- a/src/calibre/gui2/tweak_book/templates.py
+++ b/src/calibre/gui2/tweak_book/templates.py
@@ -8,6 +8,7 @@ __copyright__ = '2013, Kovid Goyal '
from calibre import prepare_string_for_xml
from calibre.gui2.tweak_book import current_container, tprefs
+from polyglot.builtins import iteritems
DEFAULT_TEMPLATES = {
'html':
@@ -46,4 +47,4 @@ def template_for(syntax):
'AUTHOR': ' & '.join(mi.authors),
}
return raw_template_for(syntax).format(
- **{k:prepare_string_for_xml(v, True) for k, v in data.iteritems()})
+ **{k:prepare_string_for_xml(v, True) for k, v in iteritems(data)})
diff --git a/src/calibre/gui2/tweak_book/text_search.py b/src/calibre/gui2/tweak_book/text_search.py
index 48ad66aea2..eed04a90d0 100644
--- a/src/calibre/gui2/tweak_book/text_search.py
+++ b/src/calibre/gui2/tweak_book/text_search.py
@@ -17,7 +17,7 @@ from calibre.gui2.tweak_book import tprefs, editors, current_container
from calibre.gui2.tweak_book.search import get_search_regex, InvalidRegex, initialize_search_request
from calibre.gui2.tweak_book.widgets import BusyCursor
from calibre.gui2.widgets2 import HistoryComboBox
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
# UI {{{
@@ -79,7 +79,7 @@ class WhereBox(QComboBox):
return wm[self.currentIndex()]
def fset(self, val):
- self.setCurrentIndex({v:k for k, v in wm.iteritems()}[val])
+ self.setCurrentIndex({v:k for k, v in iteritems(wm)}[val])
return property(fget=fget, fset=fset)
def showPopup(self):
@@ -174,7 +174,7 @@ def run_text_search(search, current_editor, current_editor_name, searchable_name
return True
if not files and editor.find_text(pat, wrap=True):
return True
- for fname, syntax in files.iteritems():
+ for fname, syntax in iteritems(files):
ed = editors.get(fname, None)
if ed is not None:
if ed.find_text(pat, complete=True):
diff --git a/src/calibre/gui2/tweak_book/ui.py b/src/calibre/gui2/tweak_book/ui.py
index fbd7e11b93..f328c0f54f 100644
--- a/src/calibre/gui2/tweak_book/ui.py
+++ b/src/calibre/gui2/tweak_book/ui.py
@@ -9,7 +9,7 @@ __copyright__ = '2013, Kovid Goyal '
import os
from functools import partial
from itertools import product
-from polyglot.builtins import map, unicode_type, range
+from polyglot.builtins import iteritems, itervalues, map, unicode_type, range
from PyQt5.Qt import (
QDockWidget, Qt, QLabel, QIcon, QAction, QApplication, QWidget, QEvent,
@@ -107,7 +107,7 @@ class Central(QStackedWidget): # {{{
@property
def tab_order(self):
ans = []
- rmap = {v:k for k, v in editors.iteritems()}
+ rmap = {v:k for k, v in iteritems(editors)}
for i in range(self.editor_tabs.count()):
name = rmap.get(self.editor_tabs.widget(i))
if name is not None:
@@ -166,7 +166,7 @@ class Central(QStackedWidget): # {{{
def save_state(self):
tprefs.set('search-panel-visible', self.search_panel.isVisible())
self.search_panel.save_state()
- for ed in editors.itervalues():
+ for ed in itervalues(editors):
ed.save_state()
if self.current_editor is not None:
self.current_editor.save_state() # Ensure the current editor saves it state last
diff --git a/src/calibre/gui2/tweak_book/widgets.py b/src/calibre/gui2/tweak_book/widgets.py
index cb93518123..835b038d4b 100644
--- a/src/calibre/gui2/tweak_book/widgets.py
+++ b/src/calibre/gui2/tweak_book/widgets.py
@@ -27,7 +27,7 @@ from calibre.gui2.widgets2 import Dialog as BaseDialog, HistoryComboBox
from calibre.utils.icu import primary_sort_key, sort_key, primary_contains, numeric_sort_key
from calibre.utils.matcher import get_char, Matcher
from calibre.gui2.complete2 import EditWithComplete
-from polyglot.builtins import unicode_type, zip
+from polyglot.builtins import iteritems, unicode_type, zip
ROOT = QModelIndex()
PARAGRAPH_SEPARATOR = '\u2029'
@@ -347,7 +347,7 @@ class Results(QWidget):
[(p.setTextFormat(Qt.RichText), p.setTextOption(self.text_option)) for p in prefixes]
self.maxwidth = max([x.size().width() for x in prefixes])
self.results = tuple((prefix, self.make_text(text, positions), text)
- for prefix, (text, positions) in zip(prefixes, results.iteritems()))
+ for prefix, (text, positions) in zip(prefixes, iteritems(results)))
else:
self.results = ()
self.current_result = -1
@@ -551,7 +551,7 @@ class NamesModel(QAbstractListModel):
if not query:
self.items = tuple((text, None) for text in self.names)
else:
- self.items = tuple(self.matcher(query).iteritems())
+ self.items = tuple(iteritems(self.matcher(query)))
self.endResetModel()
self.filtered.emit(not bool(query))
@@ -820,7 +820,7 @@ class InsertSemantics(Dialog):
'text': _('First "real" page of content'),
}
t = _
- all_types = [(k, (('%s (%s)' % (t(v), type_map_help[k])) if k in type_map_help else t(v))) for k, v in self.known_type_map.iteritems()]
+ all_types = [(k, (('%s (%s)' % (t(v), type_map_help[k])) if k in type_map_help else t(v))) for k, v in iteritems(self.known_type_map)]
all_types.sort(key=lambda x: sort_key(x[1]))
self.all_types = OrderedDict(all_types)
@@ -830,7 +830,7 @@ class InsertSemantics(Dialog):
self.tl = tl = QFormLayout()
self.semantic_type = QComboBox(self)
- for key, val in self.all_types.iteritems():
+ for key, val in iteritems(self.all_types):
self.semantic_type.addItem(val, key)
tl.addRow(_('Type of &semantics:'), self.semantic_type)
self.target = t = QLineEdit(self)
@@ -946,13 +946,13 @@ class InsertSemantics(Dialog):
@property
def changed_type_map(self):
- return {k:v for k, v in self.final_type_map.iteritems() if v != self.original_type_map.get(k, None)}
+ return {k:v for k, v in iteritems(self.final_type_map) if v != self.original_type_map.get(k, None)}
def apply_changes(self, container):
from calibre.ebooks.oeb.polish.opf import set_guide_item, get_book_language
from calibre.translations.dynamic import translate
lang = get_book_language(container)
- for item_type, (name, frag) in self.changed_type_map.iteritems():
+ for item_type, (name, frag) in iteritems(self.changed_type_map):
title = self.known_type_map[item_type]
if lang:
title = translate(lang, title)
@@ -1093,7 +1093,7 @@ class AddCover(Dialog):
@property
def image_names(self):
img_types = {guess_type('a.'+x) for x in ('png', 'jpeg', 'gif')}
- for name, mt in self.container.mime_map.iteritems():
+ for name, mt in iteritems(self.container.mime_map):
if mt.lower() in img_types:
yield name
diff --git a/src/calibre/gui2/viewer/config.py b/src/calibre/gui2/viewer/config.py
index cc5e71c188..2eae758e1d 100644
--- a/src/calibre/gui2/viewer/config.py
+++ b/src/calibre/gui2/viewer/config.py
@@ -22,7 +22,7 @@ from calibre.gui2 import min_available_height, error_dialog
from calibre.gui2.languages import LanguagesEdit
from calibre.gui2.shortcuts import ShortcutConfig
from calibre.gui2.viewer.config_ui import Ui_Dialog
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, iterkeys, unicode_type
def config(defaults=None):
@@ -213,7 +213,7 @@ class ConfigDialog(QDialog, Ui_Dialog):
for x in ('load', 'delete'):
m = getattr(self, '%s_theme_button'%x).menu()
m.clear()
- for x in self.themes.iterkeys():
+ for x in iterkeys(self.themes):
title = x[len('theme_'):]
ac = m.addAction(title)
ac.theme_id = x
@@ -243,7 +243,7 @@ class ConfigDialog(QDialog, Ui_Dialog):
def fset(self, wl):
self.dictionary_list.clear()
- for langcode, url in sorted(wl.iteritems(), key=lambda lc_url:sort_key(calibre_langcode_to_name(lc_url[0]))):
+ for langcode, url in sorted(iteritems(wl), key=lambda lc_url:sort_key(calibre_langcode_to_name(lc_url[0]))):
i = QListWidgetItem('%s: %s' % (calibre_langcode_to_name(langcode), url), self.dictionary_list)
i.setData(Qt.UserRole, (langcode, url))
return property(fget=fget, fset=fset)
diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py
index 857e1be147..9430df1d7a 100644
--- a/src/calibre/gui2/viewer/documentview.py
+++ b/src/calibre/gui2/viewer/documentview.py
@@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en'
import math, json
from base64 import b64encode
from functools import partial
-from polyglot.builtins import map, unicode_type, string_or_bytes
+from polyglot.builtins import iteritems, map, unicode_type, string_or_bytes
from PyQt5.Qt import (
QSize, QSizePolicy, QUrl, Qt, QPainter, QPalette, QBrush,
@@ -259,7 +259,7 @@ class Document(QWebPage): # {{{
if not isinstance(self.anchor_positions, dict):
# Some weird javascript error happened
self.anchor_positions = {}
- return {k:tuple(v) for k, v in self.anchor_positions.iteritems()}
+ return {k:tuple(v) for k, v in iteritems(self.anchor_positions)}
def switch_to_paged_mode(self, onresize=False, last_loaded_path=None):
if onresize and not self.loaded_javascript:
diff --git a/src/calibre/gui2/viewer/gestures.py b/src/calibre/gui2/viewer/gestures.py
index b99d870baf..027090e9ce 100644
--- a/src/calibre/gui2/viewer/gestures.py
+++ b/src/calibre/gui2/viewer/gestures.py
@@ -13,6 +13,7 @@ from PyQt5.Qt import (
QContextMenuEvent, QDialog, QDialogButtonBox, QLabel, QVBoxLayout)
from calibre.constants import iswindows
+from polyglot.builtins import itervalues
touch_supported = False
if iswindows and sys.getwindowsversion()[:2] >= (6, 2): # At least windows 7
@@ -182,14 +183,14 @@ class State(QObject):
else:
self.check_for_holds()
if {Swipe, SwipeAndHold} & self.possible_gestures:
- tp = next(self.touch_points.itervalues())
+ tp = next(itervalues(self.touch_points))
self.swiping.emit(*tp.swipe_live)
def check_for_holds(self):
if not {SwipeAndHold, TapAndHold} & self.possible_gestures:
return
now = time.time()
- tp = next(self.touch_points.itervalues())
+ tp = next(itervalues(self.touch_points))
if now - tp.time_of_last_move < HOLD_THRESHOLD:
return
if self.hold_started:
@@ -216,20 +217,20 @@ class State(QObject):
def finalize(self):
if Tap in self.possible_gestures:
- tp = next(self.touch_points.itervalues())
+ tp = next(itervalues(self.touch_points))
if tp.total_movement <= TAP_THRESHOLD:
self.tapped.emit(tp)
return
if Swipe in self.possible_gestures:
- tp = next(self.touch_points.itervalues())
+ tp = next(itervalues(self.touch_points))
st = tp.swipe_type
if st is not None:
self.swiped.emit(st)
return
if Pinch in self.possible_gestures:
- points = tuple(self.touch_points.itervalues())
+ points = tuple(itervalues(self.touch_points))
if len(points) == 2:
pinch_dir = get_pinch(*points)
if pinch_dir is not None:
@@ -239,7 +240,7 @@ class State(QObject):
return
if TapAndHold in self.possible_gestures:
- tp = next(self.touch_points.itervalues())
+ tp = next(itervalues(self.touch_points))
self.tap_hold_finished.emit(tp)
return
diff --git a/src/calibre/gui2/viewer/javascript.py b/src/calibre/gui2/viewer/javascript.py
index 1bc617d8b9..3348227460 100644
--- a/src/calibre/gui2/viewer/javascript.py
+++ b/src/calibre/gui2/viewer/javascript.py
@@ -11,11 +11,12 @@ import os
import calibre
from calibre.utils.resources import compiled_coffeescript, load_hyphenator_dicts
+from polyglot.builtins import iteritems
class JavaScriptLoader(object):
- JS = {x:('viewer/%s.js'%x if y is None else y) for x, y in {
+ JS = {x:('viewer/%s.js'%x if y is None else y) for x, y in iteritems({
'bookmarks':None,
'referencing':None,
@@ -25,7 +26,7 @@ class JavaScriptLoader(object):
'hyphenator':'viewer/hyphenate/Hyphenator.js',
'images':None
- }.iteritems()}
+ })}
CS = {
'cfi':'ebooks.oeb.display.cfi',
@@ -49,7 +50,7 @@ class JavaScriptLoader(object):
compile_coffeescript
except:
self._dynamic_coffeescript = False
- print ('WARNING: Failed to load serve_coffee, not compiling '
+ print('WARNING: Failed to load serve_coffee, not compiling '
'coffeescript dynamically.')
self._cache = {}
diff --git a/src/calibre/gui2/viewer/toc.py b/src/calibre/gui2/viewer/toc.py
index 5202a27a7f..a993bda91b 100644
--- a/src/calibre/gui2/viewer/toc.py
+++ b/src/calibre/gui2/viewer/toc.py
@@ -19,6 +19,7 @@ from calibre.ebooks.metadata.toc import TOC as MTOC
from calibre.gui2 import error_dialog
from calibre.gui2.search_box import SearchBox2
from calibre.utils.icu import primary_contains
+from polyglot.builtins import iteritems
class Delegate(QStyledItemDelegate):
@@ -211,7 +212,7 @@ class TOCItem(QStandardItem):
# to count a partial line as being visible.
# We only care about y position
- anchor_map = {k:v[1] for k, v in anchor_map.iteritems()}
+ anchor_map = {k:v[1] for k, v in iteritems(anchor_map)}
if spine_index >= self.starts_at and spine_index <= self.ends_at:
# The position at which this anchor is present in the document
@@ -358,10 +359,10 @@ class TOC(QStandardItemModel):
if in_paged_mode:
start = viewport_rect[0]
- anchor_map = {k:v[0] for k, v in anchor_map.iteritems()}
+ anchor_map = {k:v[0] for k, v in iteritems(anchor_map)}
else:
start = viewport_rect[1]
- anchor_map = {k:v[1] for k, v in anchor_map.iteritems()}
+ anchor_map = {k:v[1] for k, v in iteritems(anchor_map)}
for item in items:
if found:
diff --git a/src/calibre/gui2/wizard/__init__.py b/src/calibre/gui2/wizard/__init__.py
index 93b0d9ba1b..ec61d6c0fe 100644
--- a/src/calibre/gui2/wizard/__init__.py
+++ b/src/calibre/gui2/wizard/__init__.py
@@ -25,7 +25,7 @@ from calibre.utils.localization import localize_user_manual_link
from calibre.utils.config import dynamic, prefs
from calibre.gui2 import choose_dir, error_dialog
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
if iswindows:
winutil = plugins['winutil'][0]
@@ -492,7 +492,7 @@ class KindlePage(QWizardPage, KindleUI):
opts = smtp_prefs().parse()
accs = []
has_default = False
- for x, ac in opts.accounts.iteritems():
+ for x, ac in iteritems(opts.accounts):
default = ac[2]
if x.strip().endswith('@kindle.com'):
accs.append((x, default))
@@ -871,7 +871,7 @@ class Wizard(QWizard):
self.resize(600, 520)
def set_button_texts(self):
- for but, text in self.BUTTON_TEXTS.iteritems():
+ for but, text in iteritems(self.BUTTON_TEXTS):
self.setButtonText(getattr(self, but+'Button'), _(text))
def retranslate(self):
diff --git a/src/calibre/library/caches.py b/src/calibre/library/caches.py
index 16eb2698ce..c8fdfbf5c9 100644
--- a/src/calibre/library/caches.py
+++ b/src/calibre/library/caches.py
@@ -20,7 +20,8 @@ from calibre.db.search import CONTAINS_MATCH, EQUALS_MATCH, REGEXP_MATCH, _match
from calibre.ebooks.metadata import title_sort, author_to_author_sort
from calibre.ebooks.metadata.opf2 import metadata_to_opf
from calibre import prints, force_unicode
-from polyglot.builtins import map, unicode_type, string_or_bytes, zip
+from polyglot.builtins import (iteritems, iterkeys, itervalues, map,
+ unicode_type, string_or_bytes, zip)
class MetadataBackup(Thread): # {{{
@@ -774,7 +775,7 @@ class ResultCache(SearchQueryParser): # {{{
q = canonicalize_lang(query)
if q is None:
lm = lang_map()
- rm = {v.lower():k for k,v in lm.iteritems()}
+ rm = {v.lower():k for k,v in iteritems(lm)}
q = rm.get(query, query)
else:
q = query
@@ -917,15 +918,15 @@ class ResultCache(SearchQueryParser): # {{{
self.marked_ids_dict = dict.fromkeys(id_dict, u'true')
else:
# Ensure that all the items in the dict are text
- self.marked_ids_dict = dict(zip(id_dict.iterkeys(), map(unicode_type,
- id_dict.itervalues())))
+ self.marked_ids_dict = dict(zip(iterkeys(id_dict), map(unicode_type,
+ itervalues(id_dict))))
# Set the values in the cache
marked_col = self.FIELD_MAP['marked']
for r in self.iterall():
r[marked_col] = None
- for id_, val in self.marked_ids_dict.iteritems():
+ for id_, val in iteritems(self.marked_ids_dict):
try:
self._data[id_][marked_col] = val
except:
@@ -1052,7 +1053,7 @@ class ResultCache(SearchQueryParser): # {{{
item.extend((None, None))
marked_col = self.FIELD_MAP['marked']
- for id_,val in self.marked_ids_dict.iteritems():
+ for id_,val in iteritems(self.marked_ids_dict):
try:
self._data[id_][marked_col] = val
except:
diff --git a/src/calibre/library/catalogs/epub_mobi_builder.py b/src/calibre/library/catalogs/epub_mobi_builder.py
index 83736fb65a..686345f767 100644
--- a/src/calibre/library/catalogs/epub_mobi_builder.py
+++ b/src/calibre/library/catalogs/epub_mobi_builder.py
@@ -4616,7 +4616,9 @@ class CatalogBuilder(object):
"""
templates = {}
- execfile(P('catalog/section_list_templates.py'), templates)
+ ef = P('catalog/section_list_templates.py')
+ with open(ef, 'rb')) as f:
+ exec(compile(f.read(), ef, 'exec'), templates)
for name, template in templates.iteritems():
if name.startswith('by_') and name.endswith('_template'):
setattr(self, name, force_unicode(template, 'utf-8'))
diff --git a/src/calibre/library/check_library.py b/src/calibre/library/check_library.py
index 20ef7a4862..0b958c73d4 100644
--- a/src/calibre/library/check_library.py
+++ b/src/calibre/library/check_library.py
@@ -10,6 +10,7 @@ import re, os, traceback, fnmatch
from calibre import isbytestring
from calibre.constants import filesystem_encoding
from calibre.ebooks import BOOK_EXTENSIONS
+from polyglot.builtins import iteritems
EBOOK_EXTENSIONS = frozenset(BOOK_EXTENSIONS)
NORMALS = frozenset(['metadata.opf', 'cover.jpg'])
@@ -219,14 +220,14 @@ class CheckLibrary(object):
missing = book_formats_lc - formats_lc
# Check: any books that aren't formats or normally there?
- for lcfn,ccfn in lc_map(filenames, unknowns).iteritems():
+ for lcfn,ccfn in iteritems(lc_map(filenames, unknowns)):
if lcfn in missing: # An unknown format correctly registered
continue
self.extra_files.append((title_dir, os.path.join(db_path, ccfn),
book_id))
# Check: any book formats that should be there?
- for lcfn,ccfn in lc_map(book_formats, missing).iteritems():
+ for lcfn,ccfn in iteritems(lc_map(book_formats, missing)):
if lcfn in unknowns: # An unknown format correctly registered
continue
self.missing_formats.append((title_dir,
diff --git a/src/calibre/library/database.py b/src/calibre/library/database.py
index 8c78324215..b303833439 100644
--- a/src/calibre/library/database.py
+++ b/src/calibre/library/database.py
@@ -1337,10 +1337,10 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE;
formats, metadata, uris = iter(formats), iter(metadata), iter(uris)
duplicates = []
for path in paths:
- mi = metadata.next()
- format = formats.next()
+ mi = next(metadata)
+ format = next(formats)
try:
- uri = uris.next()
+ uri = next(uris)
except StopIteration:
uri = None
if not add_duplicates and self.has_book(mi):
diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py
index 239f72871f..80f11ea65e 100644
--- a/src/calibre/library/database2.py
+++ b/src/calibre/library/database2.py
@@ -47,7 +47,7 @@ from calibre.db.lazy import FormatMetadata, FormatsList
from calibre.db.categories import Tag, CATEGORY_SORTS
from calibre.utils.localization import (canonicalize_lang,
calibre_langcode_to_name)
-from polyglot.builtins import unicode_type, string_or_bytes
+from polyglot.builtins import iteritems, iterkeys, unicode_type, string_or_bytes
copyfile = os.link if hasattr(os, 'link') else shutil.copyfile
SPOOL_SIZE = 30*1024*1024
@@ -405,17 +405,17 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
'(SELECT MAX(uncompressed_size) FROM data WHERE book=books.id) size',
('rating', 'ratings', 'rating', 'ratings.rating'),
('tags', 'tags', 'tag', 'group_concat(name)'),
- '(SELECT text FROM comments WHERE book=books.id) comments',
+ '(SELECT text FROM comments WHERE book=books.id) comments',
('series', 'series', 'series', 'name'),
('publisher', 'publishers', 'publisher', 'name'),
- 'series_index',
- 'sort',
- 'author_sort',
- '(SELECT group_concat(format) FROM data WHERE data.book=books.id) formats',
- 'path',
- 'pubdate',
- 'uuid',
- 'has_cover',
+ 'series_index',
+ 'sort',
+ 'author_sort',
+ '(SELECT group_concat(format) FROM data WHERE data.book=books.id) formats',
+ 'path',
+ 'pubdate',
+ 'uuid',
+ 'has_cover',
('au_map', 'authors', 'author',
'aum_sortconcat(link.id, authors.name, authors.sort, authors.link)'),
'last_modified',
@@ -442,7 +442,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
'formats':13, 'path':14, 'pubdate':15, 'uuid':16, 'cover':17,
'au_map':18, 'last_modified':19, 'identifiers':20, 'languages':21}
- for k,v in self.FIELD_MAP.iteritems():
+ for k,v in iteritems(self.FIELD_MAP):
self.field_metadata.set_field_record_index(k, v, prefer_custom=False)
base = max(self.FIELD_MAP.values())
@@ -931,7 +931,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
# The random stuff is here to prevent a single book from
# blocking progress if its metadata cannot be written for some
# reason.
- id_ = self.dirtied_cache.keys()[random.randint(0, l-1)]
+ id_ = list(self.dirtied_cache.keys())[random.randint(0, l-1)]
sequence = self.dirtied_cache[id_]
return (id_, sequence)
return (None, None)
@@ -1259,7 +1259,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
def format_files(self, index, index_is_id=False):
id = index if index_is_id else self.id(index)
- return [(v, k) for k, v in self.format_filename_cache[id].iteritems()]
+ return [(v, k) for k, v in iteritems(self.format_filename_cache[id])]
def formats(self, index, index_is_id=False, verify_formats=True):
''' Return available formats as a comma separated list or None if there are no available formats '''
@@ -1798,7 +1798,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
# First, build the maps. We need a category->items map and an
# item -> (item_id, sort_val) map to use in the books loop
- for category in tb_cats.iterkeys():
+ for category in iterkeys(tb_cats):
cat = tb_cats[category]
if not cat['is_category'] or cat['kind'] in ['user', 'search'] \
or category in ['news', 'formats'] or cat.get('is_csp',
@@ -1854,7 +1854,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
md.append((category, cat['rec_index'],
cat['is_multiple'].get('cache_to_list', None), False))
- for category in tb_cats.iterkeys():
+ for category in iterkeys(tb_cats):
cat = tb_cats[category]
if cat['datatype'] == 'composite' and \
cat['display'].get('make_category', False):
@@ -1959,7 +1959,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
# and building the Tag instances.
categories = {}
tag_class = Tag
- for category in tb_cats.iterkeys():
+ for category in iterkeys(tb_cats):
if category not in tcategories:
continue
cat = tb_cats[category]
@@ -2119,7 +2119,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
continue
user_categories[c] = []
for sc in gst[c]:
- if sc in categories.keys():
+ if sc in list(categories.keys()):
for t in categories[sc]:
user_categories[c].append([t.name, sc, 0])
@@ -2367,13 +2367,13 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
self.set_identifiers(id, mi_idents, notify=False, commit=False)
elif mi_idents:
identifiers = self.get_identifiers(id, index_is_id=True)
- for key, val in mi_idents.iteritems():
+ for key, val in iteritems(mi_idents):
if val and val.strip(): # Don't delete an existing identifier
identifiers[icu_lower(key)] = val
self.set_identifiers(id, identifiers, notify=False, commit=False)
user_mi = mi.get_all_user_metadata(make_copy=False)
- for key in user_mi.iterkeys():
+ for key in iterkeys(user_mi):
if key in self.field_metadata and \
user_mi[key]['datatype'] == self.field_metadata[key]['datatype'] and \
(user_mi[key]['datatype'] != 'text' or
@@ -3321,7 +3321,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
'INSERT OR REPLACE INTO identifiers (book, type, val) VALUES (?, ?, ?)', (id_, typ, val))
if changed:
raw = ','.join(['%s:%s'%(k, v) for k, v in
- identifiers.iteritems()])
+ iteritems(identifiers)])
self.data.set(id_, self.FIELD_MAP['identifiers'], raw,
row_is_id=True)
if commit:
@@ -3333,16 +3333,16 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
cleaned = {}
if not identifiers:
identifiers = {}
- for typ, val in identifiers.iteritems():
+ for typ, val in iteritems(identifiers):
typ, val = self._clean_identifier(typ, val)
if val:
cleaned[typ] = val
self.conn.execute('DELETE FROM identifiers WHERE book=?', (id_,))
self.conn.executemany(
'INSERT INTO identifiers (book, type, val) VALUES (?, ?, ?)',
- [(id_, k, v) for k, v in cleaned.iteritems()])
+ [(id_, k, v) for k, v in iteritems(cleaned)])
raw = ','.join(['%s:%s'%(k, v) for k, v in
- cleaned.iteritems()])
+ iteritems(cleaned)])
self.data.set(id_, self.FIELD_MAP['identifiers'], raw,
row_is_id=True)
if commit:
@@ -3498,9 +3498,9 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
ids = []
postimport = []
for path in paths:
- mi = metadata.next()
+ mi = next(metadata)
self._add_newbook_tag(mi)
- format = formats.next()
+ format = next(formats)
if not add_duplicates and self.has_book(mi):
duplicates.append((path, format, mi))
continue
@@ -3683,7 +3683,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
self.conn.executemany(
'INSERT OR REPLACE INTO books_plugin_data (book, name, val) VALUES (?, ?, ?)',
[(book_id, name, json.dumps(val, default=to_json))
- for book_id, val in vals.iteritems()])
+ for book_id, val in iteritems(vals)])
self.commit()
def get_custom_book_data(self, book_id, name, default=None):
diff --git a/src/calibre/library/field_metadata.py b/src/calibre/library/field_metadata.py
index 2569b56523..9abdd6d853 100644
--- a/src/calibre/library/field_metadata.py
+++ b/src/calibre/library/field_metadata.py
@@ -7,6 +7,7 @@ import traceback
from collections import OrderedDict
from calibre.utils.config_base import tweaks
+from polyglot.builtins import iteritems, iterkeys, itervalues
category_icon_map = {
'authors' : 'user_profile.png',
@@ -428,7 +429,7 @@ class FieldMetadata(object):
return key in self
def keys(self):
- return self._tb_cats.keys()
+ return list(self._tb_cats.keys())
def __eq__(self, other):
if not isinstance(other, FieldMetadata):
@@ -484,21 +485,21 @@ class FieldMetadata(object):
yield key
def itervalues(self):
- return self._tb_cats.itervalues()
+ return itervalues(self._tb_cats)
def values(self):
- return self._tb_cats.values()
+ return list(self._tb_cats.values())
def iteritems(self):
for key in self._tb_cats:
yield (key, self._tb_cats[key])
def custom_iteritems(self):
- for key, meta in self._tb_custom_fields.iteritems():
+ for key, meta in iteritems(self._tb_custom_fields):
yield (key, meta)
def items(self):
- return list(self.iteritems())
+ return list(iteritems(self))
def is_custom_field(self, key):
return key.startswith(self.custom_field_prefix)
@@ -508,7 +509,7 @@ class FieldMetadata(object):
return self.is_custom_field(key) or key.startswith('@')
def ignorable_field_keys(self):
- return [k for k in self._tb_cats.iterkeys() if self.is_ignorable_field(k)]
+ return [k for k in iterkeys(self._tb_cats) if self.is_ignorable_field(k)]
def is_series_index(self, key):
try:
@@ -681,8 +682,8 @@ def fm_as_dict(self):
'custom_fields': self._tb_custom_fields,
'search_term_map': self._search_term_map,
'custom_label_to_key_map': self.custom_label_to_key_map,
- 'user_categories': {k:v for k, v in self._tb_cats.iteritems() if v['kind'] == 'user'},
- 'search_categories': {k:v for k, v in self._tb_cats.iteritems() if v['kind'] == 'search'},
+ 'user_categories': {k:v for k, v in iteritems(self._tb_cats) if v['kind'] == 'user'},
+ 'search_categories': {k:v for k, v in iteritems(self._tb_cats) if v['kind'] == 'search'},
}
@@ -692,6 +693,6 @@ def fm_from_dict(src):
ans._search_term_map = src['search_term_map']
ans.custom_label_to_key_map = src['custom_label_to_key_map']
for q in ('custom_fields', 'user_categories', 'search_categories'):
- for k, v in src[q].iteritems():
+ for k, v in iteritems(src[q]):
ans._tb_cats[k] = v
return ans
diff --git a/src/calibre/library/prefs.py b/src/calibre/library/prefs.py
index d5e7398ffa..3c41a4d78f 100644
--- a/src/calibre/library/prefs.py
+++ b/src/calibre/library/prefs.py
@@ -10,7 +10,7 @@ import json, os
from calibre.constants import preferred_encoding
from calibre.utils.config import to_json, from_json
from calibre import prints
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
class DBPrefs(dict):
@@ -98,7 +98,7 @@ class DBPrefs(dict):
return d
cls.clear()
cls.db.conn.execute('DELETE FROM preferences')
- for k,v in d.iteritems():
+ for k,v in iteritems(d):
raw = cls.to_raw(v)
cls.db.conn.execute(
'INSERT INTO preferences (key,val) VALUES (?,?)', (k, raw))
diff --git a/src/calibre/library/restore.py b/src/calibre/library/restore.py
index b22ec16253..4a2f428f60 100644
--- a/src/calibre/library/restore.py
+++ b/src/calibre/library/restore.py
@@ -16,6 +16,8 @@ from calibre.library.prefs import DBPrefs
from calibre.constants import filesystem_encoding
from calibre.utils.date import utcfromtimestamp
from calibre import isbytestring
+from polyglot.builtins import iteritems, iterkeys
+i
NON_EBOOK_EXTENSIONS = frozenset([
'jpg', 'jpeg', 'gif', 'png', 'bmp',
@@ -196,7 +198,7 @@ class Restore(Thread):
self.mismatched_dirs.append(dirpath)
alm = mi.get('author_link_map', {})
- for author, link in alm.iteritems():
+ for author, link in iteritems(alm):
existing_link, timestamp = self.authors_links.get(author, (None, None))
if existing_link is None or existing_link != link and timestamp < mi.timestamp:
self.authors_links[author] = (link, mi.timestamp)
@@ -247,7 +249,7 @@ class Restore(Thread):
self.failed_restores.append((book, traceback.format_exc()))
self.progress_callback(book['mi'].title, i+1)
- for author in self.authors_links.iterkeys():
+ for author in iterkeys(self.authors_links):
link, ign = self.authors_links[author]
db.conn.execute('UPDATE authors SET link=? WHERE name=?',
(link, author.replace(',', '|')))
@@ -278,4 +280,3 @@ class Restore(Thread):
os.remove(save_path)
os.rename(dbpath, save_path)
shutil.copyfile(ndbpath, dbpath)
-
diff --git a/src/calibre/library/schema_upgrades.py b/src/calibre/library/schema_upgrades.py
index a0ff54c302..8b4b6e6c83 100644
--- a/src/calibre/library/schema_upgrades.py
+++ b/src/calibre/library/schema_upgrades.py
@@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en'
import os
from calibre.utils.date import isoformat, DEFAULT_DATE
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iterkeys, itervalues, unicode_type
class SchemaUpgrade(object):
@@ -293,7 +293,7 @@ class SchemaUpgrade(object):
'''.format(tn=table_name, cn=column_name, vcn=view_column_name))
self.conn.executescript(script)
- for field in self.field_metadata.itervalues():
+ for field in itervalues(self.field_metadata):
if field['is_category'] and not field['is_custom'] and 'link_column' in field:
table = self.conn.get(
'SELECT name FROM sqlite_master WHERE type="table" AND name=?',
@@ -369,7 +369,7 @@ class SchemaUpgrade(object):
'''.format(lt=link_table_name, table=table_name)
self.conn.executescript(script)
- for field in self.field_metadata.itervalues():
+ for field in itervalues(self.field_metadata):
if field['is_category'] and not field['is_custom'] and 'link_column' in field:
table = self.conn.get(
'SELECT name FROM sqlite_master WHERE type="table" AND name=?',
@@ -590,7 +590,7 @@ class SchemaUpgrade(object):
custom_recipe_filename
bdir = os.path.dirname(custom_recipes.file_path)
for id_, title, script in recipes:
- existing = frozenset(map(int, custom_recipes.iterkeys()))
+ existing = frozenset(map(int, iterkeys(custom_recipes)))
if id_ in existing:
id_ = max(existing) + 1000
id_ = str(id_)
diff --git a/src/calibre/linux.py b/src/calibre/linux.py
index 194059540b..8700c0ec08 100644
--- a/src/calibre/linux.py
+++ b/src/calibre/linux.py
@@ -13,6 +13,7 @@ from calibre.constants import islinux, isbsd
from calibre.customize.ui import all_input_formats
from calibre.ptempfile import TemporaryDirectory
from calibre import CurrentDir
+from polyglot.builtins import iteritems
entry_points = {
@@ -70,7 +71,7 @@ class PreserveMIMEDefaults(object):
self.initial_values[x] = None
def __exit__(self, *args):
- for path, val in self.initial_values.iteritems():
+ for path, val in iteritems(self.initial_values):
if val is None:
try:
os.remove(path)
@@ -416,13 +417,13 @@ _ebook_edit() {
f.write('\n_calibredb_cmds() {\n local commands; commands=(\n')
f.write(' {-h,--help}":Show help"\n')
f.write(' "--version:Show version"\n')
- for command, desc in descs.iteritems():
+ for command, desc in iteritems(descs):
f.write(' "%s:%s"\n'%(
command, desc.replace(':', '\\:').replace('"', '\'')))
f.write(' )\n _describe -t commands "calibredb command" commands \n}\n')
subcommands = []
- for command, parser in parsers.iteritems():
+ for command, parser in iteritems(parsers):
exts = []
if command == 'catalog':
exts = [x.lower() for x in available_catalog_formats()]
@@ -477,7 +478,7 @@ _ebook_edit() {
self.do_calibredb(f)
self.do_ebook_edit(f)
f.write('case $service in\n')
- for c, txt in self.commands.iteritems():
+ for c, txt in iteritems(self.commands):
if isinstance(txt, type(u'')):
txt = txt.encode('utf-8')
if isinstance(c, type(u'')):
@@ -651,7 +652,7 @@ class PostInstall:
print('\n'+'_'*20, 'WARNING','_'*20)
prints(*args, **kwargs)
print('_'*50)
- print ('\n')
+ print('\n')
self.warnings.append((args, kwargs))
sys.stdout.flush()
@@ -1101,7 +1102,7 @@ def write_appdata(key, entry, base, translators):
description = E.description()
for para in entry['description']:
description.append(E.p(para))
- for lang, t in translators.iteritems():
+ for lang, t in iteritems(translators):
tp = t.ugettext(para)
if tp != para:
description.append(E.p(tp))
@@ -1118,7 +1119,7 @@ def write_appdata(key, entry, base, translators):
screenshots,
type='desktop'
)
- for lang, t in translators.iteritems():
+ for lang, t in iteritems(translators):
tp = t.ugettext(entry['summary'])
if tp != entry['summary']:
root.append(E.summary(tp))
diff --git a/src/calibre/spell/dictionary.py b/src/calibre/spell/dictionary.py
index a49ee8a04c..598c6e302d 100644
--- a/src/calibre/spell/dictionary.py
+++ b/src/calibre/spell/dictionary.py
@@ -18,7 +18,7 @@ from calibre.spell import parse_lang_code
from calibre.utils.config import JSONConfig
from calibre.utils.icu import capitalize
from calibre.utils.localization import get_lang, get_system_locale
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, itervalues, unicode_type
Dictionary = namedtuple('Dictionary', 'primary_locale locales dicpath affpath builtin name id')
LoadedDictionary = namedtuple('Dictionary', 'primary_locale locales obj builtin name id')
@@ -102,7 +102,7 @@ def best_locale_for_language(langcode):
def preferred_dictionary(locale):
- return {parse_lang_code(k):v for k, v in dprefs['preferred_dictionaries'].iteritems()}.get(locale, None)
+ return {parse_lang_code(k):v for k, v in iteritems(dprefs['preferred_dictionaries'])}.get(locale, None)
def remove_dictionary(dictionary):
@@ -110,7 +110,7 @@ def remove_dictionary(dictionary):
raise ValueError('Cannot remove builtin dictionaries')
base = os.path.dirname(dictionary.dicpath)
shutil.rmtree(base)
- dprefs['preferred_dictionaries'] = {k:v for k, v in dprefs['preferred_dictionaries'].iteritems() if v != dictionary.id}
+ dprefs['preferred_dictionaries'] = {k:v for k, v in iteritems(dprefs['preferred_dictionaries']) if v != dictionary.id}
def rename_dictionary(dictionary, name):
@@ -255,13 +255,13 @@ class Dictionaries(object):
dprefs['user_dictionaries'] = [d.serialize() for d in self.all_user_dictionaries]
def add_user_words(self, words, langcode):
- for d in self.dictionaries.itervalues():
+ for d in itervalues(self.dictionaries):
if d and getattr(d.primary_locale, 'langcode', None) == langcode:
for word in words:
d.obj.add(word)
def remove_user_words(self, words, langcode):
- for d in self.dictionaries.itervalues():
+ for d in itervalues(self.dictionaries):
if d and d.primary_locale.langcode == langcode:
for word in words:
d.obj.remove(word)
@@ -313,7 +313,7 @@ class Dictionaries(object):
if changed:
for key in words:
self.word_cache.pop(key, None)
- for langcode, words in removals.iteritems():
+ for langcode, words in iteritems(removals):
self.remove_user_words(words, langcode)
self.save_user_dictionaries()
return changed
diff --git a/src/calibre/spell/import_from.py b/src/calibre/spell/import_from.py
index e2763eb04e..1d29fdca80 100644
--- a/src/calibre/spell/import_from.py
+++ b/src/calibre/spell/import_from.py
@@ -12,6 +12,7 @@ from lxml import etree
from calibre.constants import config_dir
from calibre.utils.zipfile import ZipFile
+from polyglot.builtins import iteritems
NS_MAP = {
'oor': "http://openoffice.org/2001/registry",
@@ -68,7 +69,7 @@ def import_from_libreoffice_source_tree(source_path):
base = P('dictionaries', allow_user_override=False)
want_locales = set(BUILTIN_LOCALES)
- for (dic, aff), locales in dictionaries.iteritems():
+ for (dic, aff), locales in iteritems(dictionaries):
c = set(locales) & want_locales
if c:
locale = tuple(c)[0]
@@ -126,7 +127,7 @@ def import_from_oxt(source_path, name, dest_dir=None, prefix='dic-'):
root = etree.fromstring(zf.open('META-INF/manifest.xml').read())
xcu = XPath('//manifest:file-entry[@manifest:media-type="application/vnd.sun.star.configuration-data"]')(root)[0].get(
'{%s}full-path' % NS_MAP['manifest'])
- for (dic, aff), locales in parse_xcu(zf.open(xcu).read(), origin='').iteritems():
+ for (dic, aff), locales in iteritems(parse_xcu(zf.open(xcu).read(), origin='')):
dic, aff = dic.lstrip('/'), aff.lstrip('/')
d = tempfile.mkdtemp(prefix=prefix, dir=dest_dir)
locales = uniq([x for x in map(fill_country_code, locales) if parse_lang_code(x).countrycode])
@@ -143,5 +144,6 @@ def import_from_oxt(source_path, name, dest_dir=None, prefix='dic-'):
num += 1
return num
+
if __name__ == '__main__':
import_from_libreoffice_source_tree(sys.argv[-1])
diff --git a/src/calibre/srv/ajax.py b/src/calibre/srv/ajax.py
index ccd8319eaf..dd577408f5 100644
--- a/src/calibre/srv/ajax.py
+++ b/src/calibre/srv/ajax.py
@@ -7,7 +7,7 @@ __license__ = 'GPL v3'
__copyright__ = '2015, Kovid Goyal '
from functools import partial
-from polyglot.builtins import unicode_type, zip, string_or_bytes
+from polyglot.builtins import iteritems, iterkeys, itervalues, unicode_type, zip, string_or_bytes
from itertools import cycle
from calibre import force_unicode
@@ -77,13 +77,13 @@ def book_to_json(ctx, rd, db, book_id,
if not device_compatible:
mi.format_metadata = {k.lower():dict(v) for k, v in
- mi.format_metadata.iteritems()}
- for v in mi.format_metadata.itervalues():
+ iteritems(mi.format_metadata)}
+ for v in itervalues(mi.format_metadata):
mtime = v.get('mtime', None)
if mtime is not None:
v['mtime'] = isoformat(mtime, as_utc=True)
data['format_metadata'] = mi.format_metadata
- fmts = set(x.lower() for x in mi.format_metadata.iterkeys())
+ fmts = set(x.lower() for x in iterkeys(mi.format_metadata))
pf = prefs['output_format'].lower()
other_fmts = list(fmts)
try:
@@ -280,7 +280,7 @@ def categories(ctx, rd, library_id):
ans[url] = (display_name, icon)
ans = [{'url':k, 'name':v[0], 'icon':v[1], 'is_category':True}
- for k, v in ans.iteritems()]
+ for k, v in iteritems(ans)]
ans.sort(key=lambda x: sort_key(x['name']))
for name, url, icon in [
(_('All books'), 'allbooks', 'book.png'),
diff --git a/src/calibre/srv/auto_reload.py b/src/calibre/srv/auto_reload.py
index e986846cac..7051a540d8 100644
--- a/src/calibre/srv/auto_reload.py
+++ b/src/calibre/srv/auto_reload.py
@@ -17,6 +17,7 @@ from calibre.srv.standalone import create_option_parser
from calibre.srv.utils import create_sock_pair
from calibre.srv.web_socket import DummyHandler
from calibre.utils.monotonic import monotonic
+from polyglot.builtins import iterkeys, itervalues
from polyglot.queue import Queue, Empty
MAX_RETRIES = 10
@@ -75,7 +76,7 @@ if islinux:
def loop(self):
while True:
- r = select.select([self.srv_sock] + list(self.fd_map.iterkeys()), [], [])[0]
+ r = select.select([self.srv_sock] + list(iterkeys(self.fd_map)), [], [])[0]
modified = set()
for fd in r:
if fd is self.srv_sock:
@@ -345,14 +346,14 @@ class ReloadHandler(DummyHandler):
def notify_reload(self):
with self.conn_lock:
- for connref in self.connections.itervalues():
+ for connref in itervalues(self.connections):
conn = connref()
if conn is not None and conn.ready:
conn.send_websocket_message('reload')
def ping(self):
with self.conn_lock:
- for connref in self.connections.itervalues():
+ for connref in itervalues(self.connections):
conn = connref()
if conn is not None and conn.ready:
conn.send_websocket_message('ping')
diff --git a/src/calibre/srv/cdb.py b/src/calibre/srv/cdb.py
index 7f2cf13d0a..7ed12d5d7d 100644
--- a/src/calibre/srv/cdb.py
+++ b/src/calibre/srv/cdb.py
@@ -19,6 +19,7 @@ from calibre.srv.routes import endpoint, json, msgpack_or_json
from calibre.srv.utils import get_db, get_library_data
from calibre.utils.imghdr import what
from calibre.utils.serialize import MSGPACK_MIME, json_loads, msgpack_loads
+from polyglot.builtins import iteritems
receive_data_methods = {'GET', 'POST'}
@@ -170,7 +171,7 @@ def cdb_set_fields(ctx, rd, book_id, library_id):
raise HTTPBadRequest('Cover data must be either JPEG or PNG')
dirtied |= db.set_cover({book_id: cdata})
- for field, value in changes.iteritems():
+ for field, value in iteritems(changes):
dirtied |= db.set_field(field, {book_id: value})
ctx.notify_changes(db.backend.library_path, metadata(dirtied))
all_ids = dirtied if all_dirtied else (dirtied & loaded_book_ids)
diff --git a/src/calibre/srv/code.py b/src/calibre/srv/code.py
index 806577d525..99b7d160d6 100644
--- a/src/calibre/srv/code.py
+++ b/src/calibre/srv/code.py
@@ -29,6 +29,7 @@ from calibre.utils.icu import sort_key, numeric_sort_key
from calibre.utils.localization import get_lang, lang_map_for_ui, localize_website_link
from calibre.utils.search_query_parser import ParseException
from calibre.utils.serialize import json_dumps
+from polyglot.builtins import iteritems, itervalues
POSTABLE = frozenset({'GET', 'POST', 'HEAD'})
@@ -195,7 +196,7 @@ def get_library_init_data(ctx, rd, db, num, sorts, orders, vl):
sf.pop('ondevice', None)
ans['sortable_fields'] = sorted(
((sanitize_sort_field_name(db.field_metadata, k), v)
- for k, v in sf.iteritems()),
+ for k, v in iteritems(sf)),
key=lambda field_name: sort_key(field_name[1])
)
ans['field_metadata'] = db.field_metadata.all_metadata()
@@ -396,7 +397,7 @@ def tag_browser(ctx, rd):
def all_lang_names():
ans = getattr(all_lang_names, 'ans', None)
if ans is None:
- ans = all_lang_names.ans = tuple(sorted(lang_map_for_ui().itervalues(), key=numeric_sort_key))
+ ans = all_lang_names.ans = tuple(sorted(itervalues(lang_map_for_ui()), key=numeric_sort_key))
return ans
diff --git a/src/calibre/srv/convert.py b/src/calibre/srv/convert.py
index 2246b5576e..811c8232de 100644
--- a/src/calibre/srv/convert.py
+++ b/src/calibre/srv/convert.py
@@ -17,6 +17,7 @@ from calibre.srv.routes import endpoint, json
from calibre.srv.utils import get_library_data
from calibre.utils.monotonic import monotonic
from calibre.utils.shared_file import share_open
+from polyglot.builtins import iteritems
receive_data_methods = {'GET', 'POST'}
conversion_jobs = {}
@@ -61,8 +62,7 @@ class JobStatus(object):
def expire_old_jobs():
now = monotonic()
with cache_lock:
- remove = [job_id for job_id, job_status in conversion_jobs.iteritems(
- ) if now - job_status.last_check_at >= 360]
+ remove = [job_id for job_id, job_status in iteritems(conversion_jobs) if now - job_status.last_check_at >= 360]
for job_id in remove:
job_status = conversion_jobs.pop(job_id)
job_status.cleanup()
@@ -140,7 +140,7 @@ def queue_job(ctx, rd, library_id, db, fmt, book_id, conversion_data):
recs.update(conversion_data['options'])
recs['gui_preferred_input_format'] = conversion_data['input_fmt'].lower()
save_specifics(db, book_id, recs)
- recs = [(k, v, OptionRecommendation.HIGH) for k, v in recs.iteritems()]
+ recs = [(k, v, OptionRecommendation.HIGH) for k, v in iteritems(recs)]
job_id = ctx.start_job(
'Convert book %s (%s)' % (book_id, fmt), 'calibre.srv.convert',
@@ -234,7 +234,7 @@ def get_conversion_options(input_fmt, output_fmt, book_id, db):
ans['defaults'].update(defaults)
ans['help'] = plumber.get_all_help()
- for group_name, option_names in OPTIONS['pipe'].iteritems():
+ for group_name, option_names in iteritems(OPTIONS['pipe']):
merge_group(group_name, option_names)
group_name, option_names = options_for_input_fmt(input_fmt)
diff --git a/src/calibre/srv/handler.py b/src/calibre/srv/handler.py
index dcce493d47..d4ec69c111 100644
--- a/src/calibre/srv/handler.py
+++ b/src/calibre/srv/handler.py
@@ -15,6 +15,7 @@ from calibre.srv.routes import Router
from calibre.srv.users import UserManager
from calibre.utils.date import utcnow
from calibre.utils.search_query_parser import ParseException
+from polyglot.builtins import iterkeys, itervalues
class Context(object):
@@ -66,7 +67,7 @@ class Context(object):
allowed_libraries = self.library_broker.allowed_libraries(lf)
if not allowed_libraries:
raise HTTPForbidden('The user {} is not allowed to access any libraries on this server'.format(request_data.username))
- library_id = library_id or next(allowed_libraries.iterkeys())
+ library_id = library_id or next(iterkeys(allowed_libraries))
if library_id in allowed_libraries:
return self.library_broker.get(library_id)
raise HTTPForbidden('The user {} is not allowed to access the library {}'.format(request_data.username, library_id))
@@ -78,7 +79,7 @@ class Context(object):
allowed_libraries = self.library_broker.allowed_libraries(lf)
if not allowed_libraries:
raise HTTPForbidden('The user {} is not allowed to access any libraries on this server'.format(request_data.username))
- return dict(allowed_libraries), next(allowed_libraries.iterkeys())
+ return dict(allowed_libraries), next(iterkeys(allowed_libraries))
def restriction_for(self, request_data, db):
return self.user_manager.library_restriction(request_data.username, path_for_db(db))
@@ -198,7 +199,7 @@ class Handler(object):
self.router = Router(ctx=ctx, url_prefix=opts.url_prefix, auth_controller=self.auth_controller)
for module in SRV_MODULES:
module = import_module('calibre.srv.' + module)
- self.router.load_routes(vars(module).itervalues())
+ self.router.load_routes(itervalues(vars(module)))
self.router.finalize()
self.router.ctx.url_for = self.router.url_for
self.dispatch = self.router.dispatch
diff --git a/src/calibre/srv/http_response.py b/src/calibre/srv/http_response.py
index 4873182849..b64db6dab6 100644
--- a/src/calibre/srv/http_response.py
+++ b/src/calibre/srv/http_response.py
@@ -13,7 +13,7 @@ from itertools import chain, repeat
from operator import itemgetter
from functools import wraps
-from polyglot.builtins import reraise, map, is_py3
+from polyglot.builtins import iteritems, itervalues, reraise, map, is_py3
from calibre import guess_type, force_unicode
from calibre.constants import __version__, plugins
@@ -419,7 +419,7 @@ class HTTPConnection(HTTPRequest):
if self.close_after_response and self.response_protocol is HTTP11:
buf.append("Connection: close")
if extra_headers is not None:
- for h, v in extra_headers.iteritems():
+ for h, v in iteritems(extra_headers):
buf.append('%s: %s' % (h, v))
buf.append('')
buf = [(x + '\r\n').encode('ascii') for x in buf]
@@ -510,9 +510,9 @@ class HTTPConnection(HTTPRequest):
outheaders.set('Content-Type', ct + '; charset=UTF-8', replace_all=True)
buf = [HTTP11 + (' %d ' % data.status_code) + httplib.responses[data.status_code]]
- for header, value in sorted(outheaders.iteritems(), key=itemgetter(0)):
+ for header, value in sorted(iteritems(outheaders), key=itemgetter(0)):
buf.append('%s: %s' % (header, value))
- for morsel in data.outcookie.itervalues():
+ for morsel in itervalues(data.outcookie):
morsel['version'] = '1'
x = morsel.output()
if isinstance(x, bytes):
diff --git a/src/calibre/srv/jobs.py b/src/calibre/srv/jobs.py
index d529ba3f6c..8385f715dd 100644
--- a/src/calibre/srv/jobs.py
+++ b/src/calibre/srv/jobs.py
@@ -14,6 +14,7 @@ from calibre import detect_ncpus, force_unicode
from calibre.utils.monotonic import monotonic
from calibre.utils.ipc.simple_worker import fork_job, WorkerError
from polyglot.queue import Queue, Empty
+from polyglot.builtins import iteritems, itervalues
StartEvent = namedtuple('StartEvent', 'job_id name module function args kwargs callback data')
DoneEvent = namedtuple('DoneEvent', 'job_id')
@@ -145,12 +146,12 @@ class JobsManager(object):
def shutdown(self, timeout=5.0):
with self.lock:
self.shutting_down = True
- for job in self.jobs.itervalues():
+ for job in itervalues(self.jobs):
job.abort_event.set()
self.events.put(False)
def wait_for_shutdown(self, wait_till):
- for job in self.jobs.itervalues():
+ for job in itervalues(self.jobs):
delta = wait_till - monotonic()
if delta > 0:
job.join(delta)
@@ -194,7 +195,7 @@ class JobsManager(object):
with self.lock:
mb = None
now = monotonic()
- for job in self.jobs.itervalues():
+ for job in itervalues(self.jobs):
if not job.done and not job.abort_event.is_set():
delta = self.max_job_time - (now - job.start_time)
if delta <= 0:
@@ -209,7 +210,7 @@ class JobsManager(object):
def abort_hanging_jobs(self):
now = monotonic()
found = False
- for job in self.jobs.itervalues():
+ for job in itervalues(self.jobs):
if not job.done and not job.abort_event.is_set():
delta = self.max_job_time - (now - job.start_time)
if delta <= 0:
@@ -238,7 +239,7 @@ class JobsManager(object):
with self.lock:
remove = []
now = monotonic()
- for job_id, job in self.finished_jobs.iteritems():
+ for job_id, job in iteritems(self.finished_jobs):
if now - job.end_time > 3600:
remove.append(job_id)
for job_id in remove:
diff --git a/src/calibre/srv/legacy.py b/src/calibre/srv/legacy.py
index 4d9cb81be9..197d56ac18 100644
--- a/src/calibre/srv/legacy.py
+++ b/src/calibre/srv/legacy.py
@@ -19,7 +19,7 @@ from calibre.srv.routes import endpoint
from calibre.srv.utils import get_library_data, http_date
from calibre.utils.cleantext import clean_xml_chars
from calibre.utils.date import dt_as_local, is_date_undefined, timestampfromdt
-from polyglot.builtins import string_or_bytes
+from polyglot.builtins import iteritems, string_or_bytes
from polyglot.urllib import urlencode
# /mobile {{{
@@ -33,7 +33,7 @@ def clean(x):
def E(tag, *children, **attribs):
children = list(map(clean, children))
- attribs = {k.rstrip('_').replace('_', '-'):clean(v) for k, v in attribs.iteritems()}
+ attribs = {k.rstrip('_').replace('_', '-'):clean(v) for k, v in iteritems(attribs)}
return getattr(E_, tag)(*children, **attribs)
@@ -125,7 +125,7 @@ def build_navigation(start, num, total, url_base): # {{{
def build_choose_library(ctx, library_map):
select = E.select(name='library_id')
- for library_id, library_name in library_map.iteritems():
+ for library_id, library_name in iteritems(library_map):
select.append(E.option(library_name, value=library_id))
return E.div(
E.form(
@@ -247,7 +247,7 @@ def mobile(ctx, rd):
order = 'ascending' if ascending else 'descending'
q = {b'search':search.encode('utf-8'), b'order':bytes(order), b'sort':sort_by.encode('utf-8'), b'num':bytes(num), 'library_id':library_id}
url_base = ctx.url_for('/mobile') + '?' + urlencode(q)
- lm = {k:v for k, v in library_map.iteritems() if k != library_id}
+ lm = {k:v for k, v in iteritems(library_map) if k != library_id}
return build_index(rd, books, num, search, sort_by, order, start, total, url_base, db.field_metadata, ctx, lm, library_id)
# }}}
diff --git a/src/calibre/srv/library_broker.py b/src/calibre/srv/library_broker.py
index 24f5e5938b..6d02eb062e 100644
--- a/src/calibre/srv/library_broker.py
+++ b/src/calibre/srv/library_broker.py
@@ -13,6 +13,7 @@ from calibre.db.cache import Cache
from calibre.db.legacy import LibraryDatabase, create_backend, set_global_state
from calibre.utils.filenames import samefile as _samefile
from calibre.utils.monotonic import monotonic
+from polyglot.builtins import iteritems, iterkeys, itervalues
def canonicalize_path(p):
@@ -114,13 +115,13 @@ class LibraryBroker(object):
def close(self):
with self:
- for db in self.loaded_dbs.itervalues():
+ for db in itervalues(self.loaded_dbs):
getattr(db, 'close', lambda: None)()
self.lmap, self.loaded_dbs = OrderedDict(), {}
@property
def default_library(self):
- return next(self.lmap.iterkeys())
+ return next(iterkeys(self.lmap))
@property
def library_map(self):
@@ -130,9 +131,9 @@ class LibraryBroker(object):
def allowed_libraries(self, filter_func):
with self:
allowed_names = filter_func(
- basename(l) for l in self.lmap.itervalues())
+ basename(l) for l in itervalues(self.lmap))
return OrderedDict(((lid, self.library_map[lid])
- for lid, path in self.lmap.iteritems()
+ for lid, path in iteritems(self.lmap)
if basename(path) in allowed_names))
def __enter__(self):
@@ -179,7 +180,7 @@ class GuiLibraryBroker(LibraryBroker):
def get_library(self, original_library_path):
library_path = canonicalize_path(original_library_path)
with self:
- for library_id, path in self.lmap.iteritems():
+ for library_id, path in iteritems(self.lmap):
if samefile(library_path, path):
db = self.loaded_dbs.get(library_id)
if db is None:
@@ -201,7 +202,7 @@ class GuiLibraryBroker(LibraryBroker):
def prepare_for_gui_library_change(self, newloc):
# Must be called with lock held
- for library_id, path in self.lmap.iteritems():
+ for library_id, path in iteritems(self.lmap):
db = self.loaded_dbs.get(library_id)
if db is not None and samefile(newloc, path):
if library_id == self.gui_library_id:
@@ -215,7 +216,7 @@ class GuiLibraryBroker(LibraryBroker):
# Must be called with lock held
original_path = path_for_db(db)
newloc = canonicalize_path(original_path)
- for library_id, path in self.lmap.iteritems():
+ for library_id, path in iteritems(self.lmap):
if samefile(newloc, path):
self.loaded_dbs[library_id] = db
self.gui_library_id = library_id
@@ -256,7 +257,7 @@ class GuiLibraryBroker(LibraryBroker):
def unload_library(self, library_path):
with self:
path = canonicalize_path(library_path)
- for library_id, q in self.lmap.iteritems():
+ for library_id, q in iteritems(self.lmap):
if samefile(path, q):
break
else:
@@ -269,7 +270,7 @@ class GuiLibraryBroker(LibraryBroker):
def remove_library(self, path):
with self:
path = canonicalize_path(path)
- for library_id, q in self.lmap.iteritems():
+ for library_id, q in iteritems(self.lmap):
if samefile(path, q):
break
else:
diff --git a/src/calibre/srv/loop.py b/src/calibre/srv/loop.py
index 180603c42a..3c84587d64 100644
--- a/src/calibre/srv/loop.py
+++ b/src/calibre/srv/loop.py
@@ -24,7 +24,7 @@ from calibre.utils.socket_inheritance import set_socket_inherit
from calibre.utils.logging import ThreadSafeLog
from calibre.utils.monotonic import monotonic
from calibre.utils.mdns import get_external_ip
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, range
from polyglot.queue import Empty, Full
READ, WRITE, RDWR, WAIT = 'READ', 'WRITE', 'RDWR', 'WAIT'
@@ -505,7 +505,7 @@ class ServerLoop(object):
now = monotonic()
read_needed, write_needed, readable, remove, close_needed = [], [], [], [], []
has_ssl = self.ssl_context is not None
- for s, conn in self.connection_map.iteritems():
+ for s, conn in iteritems(self.connection_map):
if now - conn.last_activity > self.opts.timeout:
if conn.handle_timeout():
conn.last_activity = now
@@ -551,7 +551,7 @@ class ServerLoop(object):
# e.args[0]
if getattr(e, 'errno', e.args[0]) in socket_errors_eintr:
return
- for s, conn in tuple(self.connection_map.iteritems()):
+ for s, conn in tuple(iteritems(self.connection_map)):
try:
select.select([s], [], [], 0)
except (select.error, socket.error) as e:
@@ -681,7 +681,7 @@ class ServerLoop(object):
self.socket = None
except socket.error:
pass
- for s, conn in tuple(self.connection_map.iteritems()):
+ for s, conn in tuple(iteritems(self.connection_map)):
self.close(s, conn)
wait_till = monotonic() + self.opts.shutdown_timeout
for pool in (self.plugin_pool, self.pool):
diff --git a/src/calibre/srv/manage_users_cli.py b/src/calibre/srv/manage_users_cli.py
index 70ee4aada0..916e6d7358 100644
--- a/src/calibre/srv/manage_users_cli.py
+++ b/src/calibre/srv/manage_users_cli.py
@@ -9,6 +9,7 @@ from functools import partial
from calibre import prints
from calibre.constants import preferred_encoding
+from polyglot.builtins import iteritems
# Manage users CLI {{{
@@ -137,7 +138,7 @@ def manage_users_cli(path=None):
prints(
_('{} has the following additional per-library restrictions:')
.format(username))
- for k, v in r['library_restrictions'].iteritems():
+ for k, v in iteritems(r['library_restrictions']):
prints(k + ':', v)
else:
prints(_('{} has no additional per-library restrictions').format(username))
diff --git a/src/calibre/srv/metadata.py b/src/calibre/srv/metadata.py
index 0a41c41161..2e28cf7786 100644
--- a/src/calibre/srv/metadata.py
+++ b/src/calibre/srv/metadata.py
@@ -22,7 +22,7 @@ from calibre.utils.icu import collation_order
from calibre.utils.localization import calibre_langcode_to_name
from calibre.library.comments import comments_to_html, markdown
from calibre.library.field_metadata import category_icon_map
-from polyglot.builtins import range
+from polyglot.builtins import iteritems, itervalues, range
from polyglot.urllib import quote
IGNORED_FIELDS = frozenset('cover ondevice path marked au_map size'.split())
@@ -183,11 +183,11 @@ def icon_map():
from calibre.gui2 import gprefs
_icon_map = category_icon_map.copy()
custom_icons = gprefs.get('tags_browser_category_icons', {})
- for k, v in custom_icons.iteritems():
+ for k, v in iteritems(custom_icons):
if os.access(os.path.join(config_dir, 'tb_icons', v), os.R_OK):
_icon_map[k] = '_' + quote(v)
_icon_map['file_type_icons'] = {
- k:'mimetypes/%s.png' % v for k, v in EXT_MAP.iteritems()
+ k:'mimetypes/%s.png' % v for k, v in iteritems(EXT_MAP)
}
return _icon_map
@@ -512,7 +512,7 @@ def fillout_tree(root, items, node_id_map, category_nodes, category_data, field_
count += 1
item['avg_rating'] = float(total)/count if count else 0
- for item_id, item in tag_map.itervalues():
+ for item_id, item in itervalues(tag_map):
id_len = len(item.pop('id_set', ()))
if id_len:
item['count'] = id_len
diff --git a/src/calibre/srv/opds.py b/src/calibre/srv/opds.py
index 4319eecd5d..d62112ec22 100644
--- a/src/calibre/srv/opds.py
+++ b/src/calibre/srv/opds.py
@@ -26,7 +26,7 @@ from calibre import force_unicode
from calibre.srv.errors import HTTPNotFound, HTTPInternalServerError
from calibre.srv.routes import endpoint
from calibre.srv.utils import get_library_data, http_date, Offsets
-from polyglot.builtins import unicode_type
+from polyglot.builtins import iteritems, unicode_type
from polyglot.urllib import urlencode
@@ -301,7 +301,7 @@ class TopLevel(Feed): # {{{
categories]
for x in subcatalogs:
self.root.append(x)
- for library_id, library_name in sorted(request_context.library_map.iteritems(), key=lambda item: sort_key(item[1])):
+ for library_id, library_name in sorted(iteritems(request_context.library_map), key=lambda item: sort_key(item[1])):
id_ = 'calibre-library:' + library_id
self.root.append(E.entry(
TITLE(_('Library:') + ' ' + library_name),
diff --git a/src/calibre/srv/opts.py b/src/calibre/srv/opts.py
index 75d14ab56e..48177b72d6 100644
--- a/src/calibre/srv/opts.py
+++ b/src/calibre/srv/opts.py
@@ -13,7 +13,7 @@ from functools import partial
from calibre.constants import config_dir
from calibre.utils.lock import ExclusiveFile
-from polyglot.builtins import is_py3
+from polyglot.builtins import itervalues, is_py3
if is_py3:
from itertools import zip_longest
else:
@@ -215,7 +215,7 @@ class Options(object):
__slots__ = tuple(name for name in options)
def __init__(self, **kwargs):
- for opt in options.itervalues():
+ for opt in itervalues(options):
setattr(self, opt.name, kwargs.get(opt.name, opt.default))
@@ -242,7 +242,7 @@ def boolean_option(add_option, opt):
def opts_to_parser(usage):
from calibre.utils.config import OptionParser
parser = OptionParser(usage)
- for opt in options.itervalues():
+ for opt in itervalues(options):
add_option = partial(parser.add_option, dest=opt.name, help=opt_to_cli_help(opt), default=opt.default)
if opt.default is True or opt.default is False:
boolean_option(add_option, opt)
diff --git a/src/calibre/srv/render_book.py b/src/calibre/srv/render_book.py
index 9f03211a92..8f9a5cd7f6 100644
--- a/src/calibre/srv/render_book.py
+++ b/src/calibre/srv/render_book.py
@@ -9,7 +9,6 @@ from base64 import standard_b64encode, standard_b64decode
from collections import defaultdict, OrderedDict
from itertools import count
from functools import partial
-from polyglot.builtins import map, unicode_type
from css_parser import replaceUrls
from css_parser.css import CSSRule
@@ -28,6 +27,7 @@ from calibre.ebooks.oeb.polish.toc import get_toc, get_landmarks
from calibre.ebooks.oeb.polish.utils import guess_type
from calibre.utils.short_uuid import uuid4
from calibre.utils.logging import default_log
+from polyglot.builtins import iteritems, iterkeys, map, unicode_type
from polyglot.urllib import quote, urlparse
RENDER_VERSION = 1
@@ -179,7 +179,7 @@ class Container(ContainerBase):
# browser has no good way to distinguish between zero byte files and
# load failures.
excluded_names = {
- name for name, mt in self.mime_map.iteritems() if
+ name for name, mt in iteritems(self.mime_map) if
name == self.opf_name or mt == guess_type('a.ncx') or name.startswith('META-INF/') or
name == 'mimetype' or not self.has_name_and_is_not_empty(name)}
raster_cover_name, titlepage_name = self.create_cover_page(input_fmt.lower())
@@ -276,7 +276,7 @@ class Container(ContainerBase):
# Firefox flakes out sometimes when dynamically creating