From 9dd8580f105f3999e2f5f4283d2033a74051dbc6 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 12 Nov 2014 23:45:05 +0100 Subject: Revert changes related to traceback Storing a traceback object in a Future object on Python 2 may introduce reference cycles, and I need to spend more time to check all cases. I prefer to defer these enhancemnets to release first current changes. --- doc/changelog.rst | 4 ---- trollius/compat.py | 8 -------- trollius/futures.py | 30 +++--------------------------- trollius/tasks.py | 33 +++++++++------------------------ 4 files changed, 12 insertions(+), 63 deletions(-) diff --git a/doc/changelog.rst b/doc/changelog.rst index 407ea60..d402d60 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -27,10 +27,6 @@ Major bugfixes: Other changes: -* On Python 2, Task waiting on a future now keeps the exception traceback of - the future, instead of showing where the exception was re-raised -* On Python 2, Future.exception() now raises the traceback with the original - traceback. * Return destructor logs the source traceback in debug mode * Python issue #22448: Improve cancelled timer callback handles cleanup. Patch by Joshua Moore-Oliva. diff --git a/trollius/compat.py b/trollius/compat.py index 7947842..b93070d 100644 --- a/trollius/compat.py +++ b/trollius/compat.py @@ -51,11 +51,3 @@ def flatten_bytes(data): return data.tobytes() else: return data - -if PY3: - def reraise(tp, value, tb=None): - if value.__traceback__ is not tb: - raise value.with_traceback(tb) - raise value -else: - exec("""def reraise(tp, value, tb=None): raise tp, value, tb""") diff --git a/trollius/futures.py b/trollius/futures.py index 68beb99..780c73d 100644 --- a/trollius/futures.py +++ b/trollius/futures.py @@ -13,7 +13,6 @@ try: except ImportError: import repr as reprlib # Python 2 -from . import compat from . import events from . import executor @@ -138,10 +137,6 @@ class Future(object): _exception = None _loop = None - # Used by Python 2 to raise the exception with the original traceback - # in the exception() method - _exception_tb = None - _log_traceback = False # Used for Python >= 3.4 _tb_logger = None # Used for Python <= 3.3 @@ -278,13 +273,8 @@ class Future(object): if self._tb_logger is not None: self._tb_logger.clear() self._tb_logger = None - tb = self._exception_tb - self._exception_tb = None if self._exception is not None: - if tb is not None: - compat.reraise(type(self._exception), self._exception, tb) - else: - raise self._exception + raise self._exception return self._result def exception(self): @@ -303,7 +293,6 @@ class Future(object): if self._tb_logger is not None: self._tb_logger.clear() self._tb_logger = None - self._exception_tb = None return self._exception def add_done_callback(self, fn): @@ -351,16 +340,7 @@ class Future(object): self._state = _FINISHED self._schedule_callbacks() - def _get_exception_tb(self): - """Helper method to call _set_exception_with_tb(). - - Use it to get the traceback of a future to copy it to a new future.""" - return self._exception_tb - def set_exception(self, exception): - self._set_exception_with_tb(exception, None) - - def _set_exception_with_tb(self, exception, exc_tb): """Mark the future done and set an exception. If the future is already done when this method is called, raises @@ -371,17 +351,13 @@ class Future(object): if isinstance(exception, type): exception = exception() self._exception = exception - if exc_tb is not None: - self._exception_tb = exc_tb - elif not compat.PY3: - self._exception_tb = sys.exc_info()[2] self._state = _FINISHED self._schedule_callbacks() if _PY34: self._log_traceback = True else: self._tb_logger = _TracebackLogger(self, exception) - if compat.PY3: + if hasattr(exception, '__traceback__'): # Python 3: exception contains a link to the traceback # Arrange for the logger to be activated after all callbacks @@ -391,7 +367,7 @@ class Future(object): if self._loop.get_debug(): frame = sys._getframe(1) tb = ['Traceback (most recent call last):\n'] - tb += traceback.format_tb(self._exception_tb) + tb += traceback.format_stack(frame) tb += traceback.format_exception_only(type(exception), exception) self._tb_logger.tb = tb else: diff --git a/trollius/tasks.py b/trollius/tasks.py index 0915120..ab5c226 100644 --- a/trollius/tasks.py +++ b/trollius/tasks.py @@ -229,7 +229,7 @@ class Task(futures.Future): self._must_cancel = True return True - def _step(self, value=None, exc=None, exc_tb=None): + def _step(self, value=None, exc=None): assert not self.done(), \ '_step(): already done: {0!r}, {1!r}, {2!r}'.format(self, value, exc) if self._must_cancel: @@ -240,7 +240,6 @@ class Task(futures.Future): self._fut_waiter = None self.__class__._current_tasks[self._loop] = self - init_exc = exc # Call either coro.throw(exc) or coro.send(value). try: if exc is not None: @@ -263,10 +262,7 @@ class Task(futures.Future): except futures.CancelledError as exc: super(Task, self).cancel() # I.e., Future.cancel(self). except Exception as exc: - if exc is init_exc: - self._set_exception_with_tb(exc, exc_tb) - else: - self.set_exception(exc) + self.set_exception(exc) except BaseException as exc: self.set_exception(exc) raise @@ -312,27 +308,16 @@ class Task(futures.Future): 'Task got bad yield: {0!r}'.format(result))) finally: self.__class__._current_tasks.pop(self._loop) - - # Needed to break cycles when an exception occurs. - self = None - init_exc = None + self = None # Needed to break cycles when an exception occurs. def _wakeup(self, future): - if (future._state == futures._FINISHED - and future._exception is not None): - # Get the traceback before calling exception(), because the call - # to exception() clears the traceback - exc_tb = future._get_exception_tb() - exc = future.exception() - self._step(None, exc, exc_tb) + try: + value = future.result() + except Exception as exc: + # This may also be a cancellation. + self._step(None, exc) else: - try: - value = future.result() - except Exception as exc: - # This may also be a cancellation. - self._step(None, exc) - else: - self._step(value, None) + self._step(value, None) self = None # Needed to break cycles when an exception occurs. -- cgit v1.2.1