Skip to content
Snippets Groups Projects
Commit d6d07de5 authored by Piotr Maślanka's avatar Piotr Maślanka
Browse files

2.26.5

parent 43f58382
No related branches found
Tags 2.26.5
No related merge requests found
Pipeline #64232 passed with stages
in 2 minutes and 3 seconds
# v2.26.5
* added `get_current_traceback` and fixed `RunActionAfterGeneratorCompletes` and `run_when_iterator_completes` default
exception handling plus better docs
# v2.26.4 # v2.26.4
* `run_when_iterator_completes` and `RunActionAfterGeneratorCompletes` will now support exceptions * `run_when_iterator_completes` and `RunActionAfterGeneratorCompletes` will now support exceptions
......
...@@ -57,10 +57,12 @@ Alternatively, you can pass a `<frame>` object to Traceback, in order to seriali ...@@ -57,10 +57,12 @@ Alternatively, you can pass a `<frame>` object to Traceback, in order to seriali
.. autoclass:: satella.instrumentation.GenerationPolicy .. autoclass:: satella.instrumentation.GenerationPolicy
:members: :members:
There's a helper function as well There's some helper function as well
.. autofunction:: satella.instrumentation.frame_from_traceback .. autofunction:: satella.instrumentation.frame_from_traceback
.. autofunction:: satella.instrumentation.get_current_traceback
Dumping all stack frames Dumping all stack frames
------------------------ ------------------------
......
__version__ = '2.26.4' __version__ = '2.26.5'
...@@ -20,7 +20,6 @@ class RunActionAfterGeneratorCompletes(tp.Generator, metaclass=ABCMeta): ...@@ -20,7 +20,6 @@ class RunActionAfterGeneratorCompletes(tp.Generator, metaclass=ABCMeta):
:param generator: generator to watch for :param generator: generator to watch for
:param args: arguments to invoke action_to_run with :param args: arguments to invoke action_to_run with
:param call_despite_closed: :meth:`action_to_run` will be called even if the generator is closed :param call_despite_closed: :meth:`action_to_run` will be called even if the generator is closed
:param call_on_exception: callable/1 with exception instance if generator somehow fails
:param kwargs: keyword arguments to invoke action_to_run with :param kwargs: keyword arguments to invoke action_to_run with
""" """
self.closed = False self.closed = False
...@@ -73,7 +72,11 @@ class RunActionAfterGeneratorCompletes(tp.Generator, metaclass=ABCMeta): ...@@ -73,7 +72,11 @@ class RunActionAfterGeneratorCompletes(tp.Generator, metaclass=ABCMeta):
"""This will run when this generator completes. Override it.""" """This will run when this generator completes. Override it."""
def call_on_exception(self, exc: Exception): def call_on_exception(self, exc: Exception):
"""This will run when this generator throws any exception. Override it.""" """
This will run when this generator throws any exception inside it's __next__() or send(). You can reraise
it (which is the default behavior if you do not override this).
"""
raise exc
def run_when_generator_completes(gen: tp.Generator, call_on_done: tp.Callable, def run_when_generator_completes(gen: tp.Generator, call_on_done: tp.Callable,
......
...@@ -138,19 +138,24 @@ class hint_with_length: ...@@ -138,19 +138,24 @@ class hint_with_length:
return self.length return self.length
def run_when_iterator_completes(iterator: tp.Iterator, func_to_run: tp.Callable, do_exception=lambda e: None, def run_when_iterator_completes(iterator: tp.Iterator, func_to_run: tp.Callable, do_exception=None,
*args, **kwargs): *args, **kwargs):
""" """
Schedule a function to be called when an iterator completes. Schedule a function to be called when an iterator completes.
:param iterator: iterator to use :param iterator: iterator to use
:param func_to_run: function to run afterwards :param func_to_run: function to run afterwards, but only if there were no exceptions or they were swallowed by
:param do_exception: a callable to call with the exception instance if generator fails at some point do_exception.
:param do_exception: a callable to call with the exception instance if generator fails at some point. Note that
if this doesn't re-raise the exception, it will be swallowed. Default behaviour is just to
re-raise it.
:param args: arguments to pass to the function :param args: arguments to pass to the function
:param kwargs: keyword arguments to pass to the function :param kwargs: keyword arguments to pass to the function
""" """
try: try:
yield from iterator yield from iterator
except Exception as e: except Exception as e:
if do_exception is None:
raise
do_exception(e) do_exception(e)
func_to_run(*args, **kwargs) func_to_run(*args, **kwargs)
from .dump_frames_on import install_dump_frames_on, dump_frames_on from .dump_frames_on import install_dump_frames_on, dump_frames_on
from .trace_back import Traceback, GenerationPolicy, StackFrame, StoredVariableValue, \ from .trace_back import Traceback, GenerationPolicy, StackFrame, StoredVariableValue, \
frame_from_traceback frame_from_traceback, get_current_traceback
__all__ = ['install_dump_frames_on', 'Traceback', 'GenerationPolicy', 'StoredVariableValue', __all__ = ['install_dump_frames_on', 'Traceback', 'GenerationPolicy', 'StoredVariableValue',
'StackFrame', 'frame_from_traceback', 'dump_frames_on'] 'StackFrame', 'frame_from_traceback', 'dump_frames_on', 'get_current_traceback']
from .classes import GenerationPolicy, StackFrame, StoredVariableValue from .classes import GenerationPolicy, StackFrame, StoredVariableValue
from .trace_back import Traceback, frame_from_traceback from .trace_back import Traceback, frame_from_traceback, get_current_traceback
__all__ = ['GenerationPolicy', 'StoredVariableValue', 'StackFrame', 'Traceback', __all__ = ['GenerationPolicy', 'StoredVariableValue', 'StackFrame', 'Traceback',
'frame_from_traceback'] 'frame_from_traceback', 'get_current_traceback']
...@@ -148,3 +148,10 @@ class Traceback(JSONAble): ...@@ -148,3 +148,10 @@ class Traceback(JSONAble):
except BaseException as e: except BaseException as e:
output.write( output.write(
u'*** %s: repr unavailable (due to locally raised %s)\n' % (name, repr(e))) u'*** %s: repr unavailable (due to locally raised %s)\n' % (name, repr(e)))
def get_current_traceback() -> str:
"""
A shorthand form for :code:`Traceback().pretty_format()`.
"""
return Traceback().pretty_format()
...@@ -3,10 +3,17 @@ import pickle ...@@ -3,10 +3,17 @@ import pickle
import sys import sys
import unittest import unittest
from satella.instrumentation import Traceback from satella.instrumentation import Traceback, get_current_traceback
class TestTraceback(unittest.TestCase): class TestTraceback(unittest.TestCase):
def test_get_current_traceback(self):
try:
a = 1 / 0
except ZeroDivisionError:
tb = get_current_traceback()
self.assertIn('ZeroDivisionError', tb)
def test_no_exc(self): def test_no_exc(self):
tb = Traceback() tb = Traceback()
byte = io.BytesIO() byte = io.BytesIO()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment