Part of bzrlib
The usual way to run cleanup code in Python is:
try: do_something() finally: cleanup_something()
However if both do_something
and cleanup_something
raise an exception
Python will forget the original exception and propagate the one from
cleanup_something. Unfortunately, this is almost always much less useful than
the original exception.
If you want to be certain that the first, and only the first, error is raised, then use:
operation = OperationWithCleanups(do_something) operation.add_cleanup(cleanup_something) operation.run_simple()
This is more inconvenient (because you need to make every try block a function), but will ensure that the first error encountered is the one raised, while also ensuring all cleanups are run. See OperationWithCleanups for more details.
Class | ObjectWithCleanups | A mixin for objects that hold a cleanup list. |
Class | OperationWithCleanups | A way to run some code with a dynamic cleanup list. |
Function | _log_cleanup_error | Undocumented |
Function | _run_cleanup | Run func(*args, **kwargs), logging but not propagating any error it |
Function | _run_cleanups | Run a series of cleanup functions. |
Function | _do_with_cleanups | Run func , then call all the cleanup_funcs. |
Run func(*args, **kwargs), logging but not propagating any error it raises. :returns: True if func raised no errors, else False.
func
, then call all the cleanup_funcs.
All the cleanup_funcs are guaranteed to be run. The first exception raised by func or any of the cleanup_funcs is the one that will be propagted by this function (subsequent errors are caught and logged).
Conceptually similar to:
try: return func(*args, **kwargs) finally: for cleanup, cargs, ckwargs in cleanup_funcs: cleanup(*cargs, **ckwargs)
Unike _run_cleanup
, _do_with_cleanups
can propagate an exception from a
cleanup, but only if there is no exception from func.