From 3dd3790597e84186d922b798aa8bb4650513ce4b Mon Sep 17 00:00:00 2001 From: Xavier Morel <xmo@odoo.com> Date: Mon, 8 May 2017 16:15:02 +0200 Subject: [PATCH] [FIX] P3: raise exception with existing traceback In Python 2, to raise a new exception but reuse a traceback requires a special form of ``raise`` (``raise etype, evalue, tb``). In Python 3, this is now done via a ``with_traceback`` method on exception objects. However this requires a bit of trickery as the former is invalid syntax in Python 3, hence pycompat bridge created via an exec for Python 2. --- addons/google_calendar/models/google_calendar.py | 2 +- odoo/addons/base/ir/ir_http.py | 2 +- odoo/addons/base/ir/ir_qweb/ir_qweb.py | 2 +- odoo/addons/test_pylint/tests/test_pylint.py | 6 ++++++ odoo/service/server.py | 4 ++-- odoo/tools/convert.py | 6 +++++- odoo/tools/pycompat.py | 7 +++++++ odoo/tools/safe_eval.py | 8 ++++---- 8 files changed, 27 insertions(+), 10 deletions(-) diff --git a/addons/google_calendar/models/google_calendar.py b/addons/google_calendar/models/google_calendar.py index d8e136faf533..f60ce78ef3d4 100644 --- a/addons/google_calendar/models/google_calendar.py +++ b/addons/google_calendar/models/google_calendar.py @@ -802,7 +802,7 @@ class GoogleCalendar(models.AbstractModel): if actSrc == 'GG': self.create_from_google(event, my_partner_id) elif actSrc == 'OE': - raise "Should be never here, creation for OE is done before update !" + raise AssertionError("Should be never here, creation for OE is done before update !") #TODO Add to batch elif isinstance(actToDo, Update): if actSrc == 'GG': diff --git a/odoo/addons/base/ir/ir_http.py b/odoo/addons/base/ir/ir_http.py index aa23531055ee..ff4654cf6c94 100644 --- a/odoo/addons/base/ir/ir_http.py +++ b/odoo/addons/base/ir/ir_http.py @@ -356,6 +356,6 @@ def convert_exception_to(to_type, with_message=False): else: message = str(with_message) - raise to_type, message, tb + raise pycompat.reraise(to_type, to_type(message), tb) except to_type as e: return e diff --git a/odoo/addons/base/ir/ir_qweb/ir_qweb.py b/odoo/addons/base/ir/ir_qweb/ir_qweb.py index 5548fcd47d8d..19119891ec44 100644 --- a/odoo/addons/base/ir/ir_qweb/ir_qweb.py +++ b/odoo/addons/base/ir/ir_qweb/ir_qweb.py @@ -127,7 +127,7 @@ class IrQWeb(models.AbstractModel, QWeb): def _compile_directive_call_assets(self, el, options): """ This special 't-call' tag can be used in order to aggregate/minify javascript and css assets""" if len(el): - raise "t-call-assets cannot contain children nodes" + raise SyntaxError("t-call-assets cannot contain children nodes") # self._get_asset(xmlid, options, css=css, js=js, debug=values.get('debug'), async=async, values=values) return [ diff --git a/odoo/addons/test_pylint/tests/test_pylint.py b/odoo/addons/test_pylint/tests/test_pylint.py index 0def4516dc22..c2d1f2cf457d 100644 --- a/odoo/addons/test_pylint/tests/test_pylint.py +++ b/odoo/addons/test_pylint/tests/test_pylint.py @@ -42,6 +42,12 @@ class TestPyLint(TransactionCase): 'parameter-unpacking', 'metaclass-assignment', + + 'exception-message-attribute', + 'indexing-exception', + 'old-raise-syntax', + 'raising-string', + 'unpacking-in-except', ] BAD_FUNCTIONS = [ diff --git a/odoo/service/server.py b/odoo/service/server.py index fa6ed422f817..cd1ae39491f5 100644 --- a/odoo/service/server.py +++ b/odoo/service/server.py @@ -550,7 +550,7 @@ class PreforkServer(CommonServer): if e.errno not in [errno.EAGAIN]: raise except select.error as e: - if e[0] not in [errno.EINTR]: + if e.args[0] not in [errno.EINTR]: raise def start(self): @@ -660,7 +660,7 @@ class Worker(object): try: select.select([self.multi.socket], [], [], self.multi.beat) except select.error as e: - if e[0] not in [errno.EINTR]: + if e.args[0] not in [errno.EINTR]: raise def process_limit(self): diff --git a/odoo/tools/convert.py b/odoo/tools/convert.py index 76c7ec523af5..93684b3514fc 100644 --- a/odoo/tools/convert.py +++ b/odoo/tools/convert.py @@ -783,7 +783,11 @@ form: module.record_id""" % (xml_id,) except Exception as e: self.cr.rollback() exc_info = sys.exc_info() - raise ParseError, (ustr(e), etree.tostring(rec).rstrip(), rec.getroottree().docinfo.URL, rec.sourceline), exc_info[2] + pycompat.reraise( + ParseError, + ParseError(ustr(e), etree.tostring(rec).rstrip(), rec.getroottree().docinfo.URL, rec.sourceline), + exc_info[2] + ) return True def __init__(self, cr, module, idref, mode, report=None, noupdate=False, xml_filename=None): diff --git a/odoo/tools/pycompat.py b/odoo/tools/pycompat.py index 3fbb847a9fac..7ce4f45773a1 100644 --- a/odoo/tools/pycompat.py +++ b/odoo/tools/pycompat.py @@ -20,6 +20,8 @@ if PY2: cls.next = cls.__next__ del cls.__next__ return cls + + exec ('def reraise(tp, value, tb=None):\n raise tp, value, tb') else: # pylint: disable=bad-functions integer_types = (int,) @@ -34,3 +36,8 @@ else: def implements_iterator(cls): return cls + + def reraise(tp, value, tb=None): + if value.__traceback__ != tb: + raise value.with_traceback(tb) + raise value diff --git a/odoo/tools/safe_eval.py b/odoo/tools/safe_eval.py index 1897486eb82f..569df6455e2b 100644 --- a/odoo/tools/safe_eval.py +++ b/odoo/tools/safe_eval.py @@ -21,8 +21,10 @@ import functools from psycopg2 import OperationalError from types import CodeType import logging +import sys import werkzeug +from . import pycompat from .misc import ustr import odoo @@ -159,9 +161,8 @@ def test_expr(expr, allowed_codes, mode="eval"): except (SyntaxError, TypeError, ValueError): raise except Exception as e: - import sys exc_info = sys.exc_info() - raise ValueError, '"%s" while compiling\n%r' % (ustr(e), expr), exc_info[2] + pycompat.reraise(ValueError, ValueError('"%s" while compiling\n%r' % (ustr(e), expr)), exc_info[2]) assert_valid_codeobj(allowed_codes, code_obj, expr) return code_obj @@ -320,9 +321,8 @@ def safe_eval(expr, globals_dict=None, locals_dict=None, mode="eval", nocopy=Fal except odoo.exceptions.MissingError: raise except Exception as e: - import sys exc_info = sys.exc_info() - raise ValueError, '%s: "%s" while evaluating\n%r' % (ustr(type(e)), ustr(e), expr), exc_info[2] + pycompat.reraise(ValueError, ValueError('%s: "%s" while evaluating\n%r' % (ustr(type(e)), ustr(e), expr)), exc_info[2]) def test_python_expr(expr, mode="eval"): try: test_expr(expr, _SAFE_OPCODES, mode=mode) -- GitLab