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 :)