Commit 4b736917 authored by Jason Madden's avatar Jason Madden

Update tblib implementation. Fixes #954

parent 8ed03d70
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
``getaddrinfo`` when ``connect`` is called. Reported in :issue:`944` ``getaddrinfo`` when ``connect`` is called. Reported in :issue:`944`
by Bernie Hackett. by Bernie Hackett.
- Replace ``optparse`` module with ``argparse``. See :issue:`947`. - Replace ``optparse`` module with ``argparse``. See :issue:`947`.
- Update to an unreleased version of ``tblib`` to fix :issue:`954`,
reported by ml31415.
1.2.1 (2017-01-12) 1.2.1 (2017-01-12)
================== ==================
......
...@@ -158,21 +158,38 @@ class Frame(object): ...@@ -158,21 +158,38 @@ class Frame(object):
class Traceback(object): class Traceback(object):
tb_next = None
def __init__(self, tb): def __init__(self, tb):
self.tb_frame = Frame(tb.tb_frame) self.tb_frame = Frame(tb.tb_frame)
# noinspection SpellCheckingInspection # noinspection SpellCheckingInspection
self.tb_lineno = int(tb.tb_lineno) self.tb_lineno = int(tb.tb_lineno)
if tb.tb_next is None:
self.tb_next = None # Build in place to avoid exceeding the recursion limit
else: tb = tb.tb_next
self.tb_next = Traceback(tb.tb_next) prev_traceback = self
cls = type(self)
while tb is not None:
traceback = object.__new__(cls)
traceback.tb_frame = Frame(tb.tb_frame)
traceback.tb_lineno = int(tb.tb_lineno)
prev_traceback.tb_next = traceback
prev_traceback = traceback
tb = tb.tb_next
def as_traceback(self): def as_traceback(self):
if tproxy: if tproxy:
return tproxy(TracebackType, self.__tproxy_handler) return tproxy(TracebackType, self.__tproxy_handler)
elif tb_set_next: if not tb_set_next:
f_code = self.tb_frame.f_code raise RuntimeError("Cannot re-create traceback !")
code = compile('\n' * (self.tb_lineno - 1) + 'raise __traceback_maker', self.tb_frame.f_code.co_filename, 'exec')
current = self
top_tb = None
tb = None
while current:
f_code = current.tb_frame.f_code
code = compile('\n' * (current.tb_lineno - 1) + 'raise __traceback_maker', current.tb_frame.f_code.co_filename, 'exec')
if PY3: if PY3:
code = CodeType( code = CodeType(
0, code.co_kwonlyargcount, 0, code.co_kwonlyargcount,
...@@ -192,18 +209,23 @@ class Traceback(object): ...@@ -192,18 +209,23 @@ class Traceback(object):
# noinspection PyBroadException # noinspection PyBroadException
try: try:
exec(code, self.tb_frame.f_globals, {}) exec(code, current.tb_frame.f_globals, {})
except: except:
tb = sys.exc_info()[2].tb_next next_tb = sys.exc_info()[2].tb_next
tb_set_next(tb, self.tb_next and self.tb_next.as_traceback()) if top_tb is None:
try: top_tb = next_tb
return tb if tb is not None:
finally: tb_set_next(tb, next_tb)
# gevent: don't leak the traceback objects, this tb = next_tb
# makes our leaktests fail del next_tb
del tb
else: current = current.tb_next
raise RuntimeError("Cannot re-create traceback !") try:
return top_tb
finally:
del top_tb
del tb
# noinspection SpellCheckingInspection # noinspection SpellCheckingInspection
def __tproxy_handler(self, operation, *args, **kwargs): def __tproxy_handler(self, operation, *args, **kwargs):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment