diff --git a/src/calibre/ebooks/oeb/polish/check/images.py b/src/calibre/ebooks/oeb/polish/check/images.py index 2b7dac850a..5cadc0ad86 100644 --- a/src/calibre/ebooks/oeb/polish/check/images.py +++ b/src/calibre/ebooks/oeb/polish/check/images.py @@ -12,6 +12,7 @@ from calibre import as_unicode from calibre.ebooks.oeb.polish.check.base import BaseError, WARN from calibre.ebooks.oeb.polish.check.parsing import EmptyFile +from polyglot.builtins import error_message class InvalidImage(BaseError): @@ -59,7 +60,7 @@ def check_raster_images(name, mt, raw): try: i = Image.open(BytesIO(raw)) except Exception as e: - errors.append(InvalidImage(as_unicode(e.message), name)) + errors.append(InvalidImage(as_unicode(error_message(e)), name)) else: if i.mode == 'CMYK': errors.append(CMYKImage(_('Image is in the CMYK colorspace'), name)) diff --git a/src/calibre/ebooks/oeb/polish/check/parsing.py b/src/calibre/ebooks/oeb/polish/check/parsing.py index 1ef9fef430..130bf8751d 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.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 iteritems, unicode_type +from polyglot.builtins import iteritems, unicode_type, error_message HTML_ENTITTIES = frozenset(html5_entities) XML_ENTITIES = {'lt', 'gt', 'amp', 'apos', 'quot'} @@ -297,9 +297,9 @@ def check_xml_parsing(name, mt, raw): line, col = err.position except: line = col = None - return errors + [errcls(err.message, name, line, col)] + return errors + [errcls(error_message(err), name, line, col)] except Exception as err: - return errors + [errcls(err.message, name)] + return errors + [errcls(error_message(err), name)] if mt in OEB_DOCS: if root.nsmap.get(root.prefix, None) != XHTML_NS: diff --git a/src/calibre/gui2/dialogs/metadata_bulk.py b/src/calibre/gui2/dialogs/metadata_bulk.py index 8c53ff7c0c..6b82d69b37 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.py +++ b/src/calibre/gui2/dialogs/metadata_bulk.py @@ -32,7 +32,7 @@ from calibre.utils.icu import capitalize, sort_key from calibre.utils.titlecase import titlecase from calibre.gui2.widgets import LineEditECM -from polyglot.builtins import iteritems, itervalues, unicode_type +from polyglot.builtins import iteritems, itervalues, unicode_type, error_message Settings = namedtuple('Settings', 'remove_all remove add au aus do_aus rating pub do_series do_autonumber ' @@ -885,7 +885,7 @@ def s_r_separator_changed(self, txt): def s_r_set_colors(self): if self.s_r_error is not None: col = 'rgb(255, 0, 0, 20%)' - self.test_result.setText(self.s_r_error.message) + self.test_result.setText(error_message(self.s_r_error)) else: col = 'rgb(0, 255, 0, 20%)' self.test_result.setStyleSheet('QLineEdit { color: black; ' @@ -1155,7 +1155,7 @@ def accept(self): if self.s_r_error is not None and do_sr: error_dialog(self, _('Search/replace invalid'), - _('Search/replace is invalid: %s')%self.s_r_error.message, + _('Search/replace is invalid: %s')%error_message(self.s_r_error), show=True) return False self.changed = bool(self.ids) diff --git a/src/calibre/gui2/tweak_book/search.py b/src/calibre/gui2/tweak_book/search.py index de8397b5ca..84f859e0cf 100644 --- a/src/calibre/gui2/tweak_book/search.py +++ b/src/calibre/gui2/tweak_book/search.py @@ -34,7 +34,7 @@ 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 iteritems, unicode_type, range +from polyglot.builtins import iteritems, unicode_type, range, error_message # The search panel {{{ @@ -1279,7 +1279,7 @@ def validate_search_request(name, searchable_names, has_marked_text, state, gui_ class InvalidRegex(regex.error): def __init__(self, raw, e): - regex.error.__init__(self, e.message) + regex.error.__init__(self, error_message(e)) self.regex = raw @@ -1399,10 +1399,10 @@ def run_search( except InvalidRegex as e: return error_dialog(gui_parent, _('Invalid regex'), '
' + _( 'The regular expression you entered is invalid:
{0}With error: {1}').format(
- prepare_string_for_xml(e.regex), e.message), show=True)
+ prepare_string_for_xml(e.regex), error_message(e)), show=True)
except NoSuchFunction as e:
return error_dialog(gui_parent, _('No such function'), '' + _( - 'No replace function with the name: %s exists') % prepare_string_for_xml(e.message), show=True) + 'No replace function with the name: %s exists') % prepare_string_for_xml(error_message(e)), show=True) def no_match(): QApplication.restoreOverrideCursor() diff --git a/src/calibre/gui2/tweak_book/text_search.py b/src/calibre/gui2/tweak_book/text_search.py index eed04a90d0..23794a6577 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.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 iteritems, unicode_type +from polyglot.builtins import iteritems, unicode_type, error_message # UI {{{ @@ -166,7 +166,7 @@ def run_text_search(search, current_editor, current_editor_name, searchable_name except InvalidRegex as e: return error_dialog(gui_parent, _('Invalid regex'), '
' + _( 'The regular expression you entered is invalid:
{0}With error: {1}').format(
- prepare_string_for_xml(e.regex), e.message), show=True)
+ prepare_string_for_xml(e.regex), error_message(e)), show=True)
editor, where, files, do_all, marked = initialize_search_request(search, 'count', current_editor, current_editor_name, searchable_names)
with BusyCursor():
if editor is not None:
diff --git a/src/calibre/srv/auto_reload.py b/src/calibre/srv/auto_reload.py
index 4c0d3dbdf7..dca62448ba 100644
--- a/src/calibre/srv/auto_reload.py
+++ b/src/calibre/srv/auto_reload.py
@@ -17,7 +17,7 @@
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 itervalues
+from polyglot.builtins import itervalues, error_message
from polyglot.queue import Queue, Empty
MAX_RETRIES = 10
@@ -300,7 +300,7 @@ def restart(self, forced=False):
time.sleep(0.01)
compile_srv()
except CompileFailure as e:
- self.log.error(e.message)
+ self.log.error(error_message(e))
time.sleep(0.1 * self.retry_count)
if self.retry_count < MAX_RETRIES and self.wakeup is not None:
self.wakeup() # Force a restart
diff --git a/src/calibre/srv/http_request.py b/src/calibre/srv/http_request.py
index 02afb5252f..376139cc58 100644
--- a/src/calibre/srv/http_request.py
+++ b/src/calibre/srv/http_request.py
@@ -16,6 +16,7 @@
from calibre.srv.utils import MultiDict, HTTP1, HTTP11, Accumulator
from polyglot import http_client, reprlib
from polyglot.urllib import unquote
+from polyglot.builtins import error_message
protocol_map = {(1, 0):HTTP1, (1, 1):HTTP11}
quoted_slash = re.compile(br'%2[fF]')
@@ -281,7 +282,7 @@ def parse_request_line(self, buf, event, first=False): # {{{
try:
self.scheme, self.path, self.query = parse_uri(uri)
except HTTPSimpleResponse as e:
- return self.simple_response(e.http_code, e.message, close_after_response=False)
+ return self.simple_response(e.http_code, error_message(e), close_after_response=False)
self.header_line_too_long_error_code = http_client.REQUEST_ENTITY_TOO_LARGE
self.set_state(READ, self.parse_header_line, HTTPHeaderParser(), Accumulator())
# }}}
diff --git a/src/calibre/srv/http_response.py b/src/calibre/srv/http_response.py
index a4fcdef924..3c97610129 100644
--- a/src/calibre/srv/http_response.py
+++ b/src/calibre/srv/http_response.py
@@ -27,6 +27,7 @@
from calibre.utils.speedups import ReadOnlyFileBuffer
from calibre.utils.monotonic import monotonic
from polyglot import http_client, reprlib
+from polyglot.builtins import error_message
Range = namedtuple('Range', 'start stop size')
MULTIPART_SEPARATOR = uuid.uuid4().hex
@@ -489,7 +490,7 @@ def job_done(self, ok, result):
eh['WWW-Authenticate'] = e.authenticate
if e.log:
self.log.warn(e.log)
- return self.simple_response(e.http_code, msg=e.message or '', close_after_response=e.close_connection, extra_headers=eh)
+ return self.simple_response(e.http_code, msg=error_message(e) or '', close_after_response=e.close_connection, extra_headers=eh)
reraise(etype, e, tb)
data, output = result
diff --git a/src/calibre/srv/standalone.py b/src/calibre/srv/standalone.py
index 9f585510cc..e2fd973341 100644
--- a/src/calibre/srv/standalone.py
+++ b/src/calibre/srv/standalone.py
@@ -24,6 +24,7 @@
from calibre.utils.config import prefs
from calibre.utils.localization import localize_user_manual_link
from calibre.utils.lock import singleinstance
+from polyglot.builtins import error_message
def daemonize(): # {{{
@@ -213,7 +214,7 @@ def main(args=sys.argv):
from calibre.utils.logging import default_log
return auto_reload(default_log, listen_on=opts.listen_on)
except NoAutoReload as e:
- raise SystemExit(e.message)
+ raise SystemExit(error_message(e))
opts.auto_reload_port = int(os.environ.get('CALIBRE_AUTORELOAD_PORT', 0))
opts.allow_console_print = 'CALIBRE_ALLOW_CONSOLE_PRINT' in os.environ
if opts.log and os.path.isdir(opts.log):
diff --git a/src/calibre/utils/exim.py b/src/calibre/utils/exim.py
index 9011340f53..7cc77eaf82 100644
--- a/src/calibre/utils/exim.py
+++ b/src/calibre/utils/exim.py
@@ -12,7 +12,7 @@
from calibre.utils.config_base import prefs, StringConfig, create_global_prefs
from calibre.utils.config import JSONConfig
from calibre.utils.filenames import samefile
-from polyglot.builtins import iteritems, raw_input
+from polyglot.builtins import iteritems, raw_input, error_message
from polyglot.binary import as_hex_unicode
@@ -439,7 +439,7 @@ def run_importer():
try:
importer = Importer(export_dir)
except ValueError as err:
- raise SystemExit(err.message)
+ raise SystemExit(error_message(err))
import_dir = input_unicode('Enter path to an empty folder (all libraries will be created inside this folder): ').rstrip('\r')
if not os.path.exists(import_dir):
diff --git a/src/calibre/utils/formatter.py b/src/calibre/utils/formatter.py
index 5581d1eb16..e0ccd216d5 100644
--- a/src/calibre/utils/formatter.py
+++ b/src/calibre/utils/formatter.py
@@ -13,7 +13,7 @@
from calibre import prints
from calibre.constants import DEBUG
from calibre.utils.formatter_functions import formatter_functions
-from polyglot.builtins import unicode_type
+from polyglot.builtins import unicode_type, error_message
class _Parser(object):
@@ -379,7 +379,7 @@ def safe_format(self, fmt, kwargs, error_value, book,
traceback.print_exc()
if column_name:
prints('Error evaluating column named:', column_name)
- ans = error_value + ' ' + e.message
+ ans = error_value + ' ' + error_message(e)
return ans
diff --git a/src/calibre/utils/rapydscript.py b/src/calibre/utils/rapydscript.py
index fb8da3a8e0..4c73700ab8 100644
--- a/src/calibre/utils/rapydscript.py
+++ b/src/calibre/utils/rapydscript.py
@@ -22,7 +22,7 @@
from calibre.utils.terminal import ANSIStream
from duktape import Context, JSError, to_python
from lzma.xz import compress, decompress
-from polyglot.builtins import itervalues, range, exec_path, raw_input
+from polyglot.builtins import itervalues, range, exec_path, raw_input, error_message
from polyglot.queue import Empty, Queue
COMPILER_PATH = 'rapydscript/compiler.js.xz'
@@ -372,7 +372,7 @@ def prompt(lw):
self.from_repl.put(val[0])
except Exception as e:
if isinstance(e, JSError):
- print(e.stack or e.message, file=sys.stderr)
+ print(e.stack or error_message(e), file=sys.stderr)
else:
import traceback
traceback.print_exc()
@@ -448,9 +448,9 @@ def main(args=sys.argv):
data = compile_pyj(sys.stdin.read().decode(enc), libdir=libdir, private_scope=not args.no_private_scope, omit_baselib=args.omit_baselib)
print(data.encode(enc))
except JSError as e:
- raise SystemExit(e.message)
+ raise SystemExit(error_message(e))
except CompileFailure as e:
- raise SystemExit(e.message)
+ raise SystemExit(error_message(e))
def entry():
diff --git a/src/calibre/utils/serve_coffee.py b/src/calibre/utils/serve_coffee.py
index fc8bddb036..114aa7b1a2 100644
--- a/src/calibre/utils/serve_coffee.py
+++ b/src/calibre/utils/serve_coffee.py
@@ -17,6 +17,7 @@
from polyglot import socketserver
from polyglot.http_server import HTTPServer, SimpleHTTPRequestHandler
+from polyglot.builtins import error_message
# Compiler {{{
@@ -39,7 +40,7 @@ def compile_coffeescript(raw, filename=None):
try:
ans = compiler().eval('CoffeeScript.compile(src)')
except JSError as e:
- return u'', (e.message,)
+ return u'', (error_message(e),)
return ans, ()
# }}}
diff --git a/src/css_selectors/parser.py b/src/css_selectors/parser.py
index 1a90bb335d..d9575eef3c 100644
--- a/src/css_selectors/parser.py
+++ b/src/css_selectors/parser.py
@@ -375,8 +375,6 @@ def parse(css):
# message = "%s at %s -> %r" % (
# e, stream.used, stream.peek())
# e.msg = message
-# if sys.version_info < (2,6):
-# e.message = message
# e.args = tuple([message])
# raise
diff --git a/src/duktape/__init__.py b/src/duktape/__init__.py
index f4f7032444..e7dd525c96 100644
--- a/src/duktape/__init__.py
+++ b/src/duktape/__init__.py
@@ -17,6 +17,7 @@
from calibre.constants import iswindows
from calibre.utils.filenames import atomic_rename
+from polyglot.builtins import error_message
Context_, undefined = dukpy.Context, dukpy.undefined
@@ -122,7 +123,7 @@ def readfile(path, enc='utf-8'):
except UnicodeDecodeError as e:
return None, '', 'Failed to decode the file: %s with specified encoding: %s' % (path, enc)
except EnvironmentError as e:
- return [None, errno.errorcode[e.errno], 'Failed to read from file: %s with error: %s' % (path, e.message or e)]
+ return [None, errno.errorcode[e.errno], 'Failed to read from file: %s with error: %s' % (path, error_message(e) or e)]
def atomic_write(name, raw):
@@ -143,7 +144,7 @@ def writefile(path, data, enc='utf-8'):
except UnicodeEncodeError as e:
return ['', 'Failed to encode the data for file: %s with specified encoding: %s' % (path, enc)]
except EnvironmentError as e:
- return [errno.errorcode[e.errno], 'Failed to write to file: %s with error: %s' % (path, e.message or e)]
+ return [errno.errorcode[e.errno], 'Failed to write to file: %s with error: %s' % (path, error_message(e) or e)]
return [None, None]
@@ -217,7 +218,7 @@ def __init__(self, ex):
def as_dict(self):
return {
'name':self.name or undefined,
- 'message': self.js_message or self.message,
+ 'message': self.js_message or error_message(self),
'fileName': self.fileName or undefined,
'lineNumber': self.lineNumber or undefined,
'stack': self.stack or undefined
diff --git a/src/lzma/xz.py b/src/lzma/xz.py
index 5237db1de1..94cb12665c 100644
--- a/src/lzma/xz.py
+++ b/src/lzma/xz.py
@@ -15,6 +15,7 @@
from calibre.ptempfile import SpooledTemporaryFile
from lzma.errors import NotXZ, InvalidXZ, lzma
+from polyglot.builtins import error_message
HEADER_MAGIC = b'\xfd7zXZ\0'
FOOTER_MAGIC = b'YZ'
@@ -190,7 +191,7 @@ def write(raw):
lzma.decompress2(f.read, f.seek, write, self.props, self.bufsize)
except lzma.error as e:
raise InvalidXZ(
- 'Failed to decode LZMA2 block with error code: %s' % e.message
+ 'Failed to decode LZMA2 block with error code: %s' % error_message(e)
)
self.crc.finish()
diff --git a/src/polyglot/builtins.py b/src/polyglot/builtins.py
index da0a0cb857..d70a207da8 100644
--- a/src/polyglot/builtins.py
+++ b/src/polyglot/builtins.py
@@ -38,6 +38,12 @@ def reraise(tp, value, tb=None):
long_type = int
raw_input = input
+ def error_message(exc):
+ args = getattr(exc, 'args', None)
+ if args and isinstance(args[0], unicode_type):
+ return args[0]
+ return unicode_type(exc)
+
def iteritems(d):
return iter(d.items())
@@ -83,6 +89,12 @@ def int_to_byte(x):
cmp = builtins.cmp
int_to_byte = chr
+ def error_message(exc):
+ ans = exc.message
+ if isinstance(ans, bytes):
+ ans = ans.decode('utf-8', 'replace')
+ return ans
+
def iteritems(d):
return d.iteritems()
diff --git a/src/tinycss/media3.py b/src/tinycss/media3.py
index 5d91c9f080..e75ec0b315 100644
--- a/src/tinycss/media3.py
+++ b/src/tinycss/media3.py
@@ -8,6 +8,8 @@
from tinycss.css21 import CSS21Parser
from tinycss.parsing import remove_whitespace, split_on_comma, ParseError
+from polyglot.builtins import error_message
+
class MediaQuery(object):
@@ -27,12 +29,14 @@ def __eq__(self, other):
self.negated == getattr(other, 'negated', None) and \
self.expressions == getattr(other, 'expressions', None)
+
class MalformedExpression(Exception):
def __init__(self, tok, msg):
Exception.__init__(self, msg)
self.tok = tok
+
class CSSMedia3Parser(CSS21Parser):
''' Parse media queries as defined by the CSS 3 media module '''
@@ -96,9 +100,8 @@ def parse_media(self, tokens, errors):
expressions.append((media_feature, expr))
except MalformedExpression as err:
- errors.extend(ParseError(err.tok, err.message))
+ errors.extend(ParseError(err.tok, error_message(err)))
media_type, negated, expressions = 'all', True, ()
queries.append(MediaQuery(media_type or 'all', expressions=tuple(expressions), negated=negated))
return queries
-