diff --git a/jedi/_compatibility.py b/jedi/_compatibility.py index 78abf874..5f03f736 100644 --- a/jedi/_compatibility.py +++ b/jedi/_compatibility.py @@ -81,6 +81,16 @@ else: eval(compile("""def exec_function(source, global_map): exec source in global_map """, 'blub', 'exec')) +# re-raise function +if is_py3k: + def reraise(exception, traceback): + raise exception.with_traceback(traceback) +else: + eval(compile(""" +def reraise(exception, traceback): + raise exception, None, traceback +""", 'blub', 'exec')) + # StringIO (Python 2.5 has no io module), so use io only for py3k try: from StringIO import StringIO diff --git a/jedi/common.py b/jedi/common.py index 35a10f62..83337eef 100644 --- a/jedi/common.py +++ b/jedi/common.py @@ -1,8 +1,10 @@ """ A universal module with functions / classes without dependencies. """ +import sys import contextlib +import functools import tokenize -from _compatibility import next +from _compatibility import next, reraise import debug import settings @@ -33,6 +35,17 @@ class MultiLevelAttributeError(Exception): return 'Original:\n\n' + ''.join(tb) +def rethrow_uncaught(func): + @functools.wraps(func) + def wrapper(*args, **kwds): + try: + return func(*args, **kwds) + except AttributeError: + exc_info = sys.exc_info() + reraise(MultiLevelAttributeError, exc_info[2]) + return wrapper + + class PushBackIterator(object): def __init__(self, iterator): self.pushes = []