воскресенье, 13 января 2013 г.

Re-raise exceptions in Python in compatible (2to3) way

Good practice is to keep original traceback (stack-trace) when you re-raise modified exception. In Python 2 it's simple:
        try:
            return buggy()
        except Exception as x:
            cls,obj,tb = sys.exc_info()
            # modify obj OR create new the same class (cls), like here
            raise cls, SOME_ARGS, tb
In Python 3 it's simple too, but now there is a special BaseException method for this and new syntax, so:
        try:
            return buggy()
        except Exception as x:
            cls,obj,tb = sys.exc_info()
            # modify obj OR create new the same class (cls), like here
            raise cls(SOME_ARGS).with_traceback(tb)
Now to make common code compatible with Python 2 and 3 we SHOULD save it in DIFFERENT files, to avoid syntax errors when Python compile it to byte-code. For example, let's save it to 'comp2.py' and 'comp3.py'. And lets represent it as function... with signature reraise(exclass, msg, traceb). In 'comp2.py':
def reraise(exc, msg, tb):
    raise exc, msg, tb

and similar in 'comp3.py' but with with_traceback() usage. Now use it:
import sys
_PY23 = 3 if sys.version_info.major > 2 else 2
if _PY23 == 2:
    from comp2 import *
elif _PY23 == 3:
    from comp3 import *
That is it :)

Комментариев нет:

Отправить комментарий

Thanks for your posting!