b.cleanup : module documentation

Part of bzrlib

Helpers for managing cleanup functions and the errors they might raise.

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.
def _log_cleanup_error(exc):
Undocumented
def _run_cleanup(func, *args, **kwargs):
Run func(*args, **kwargs), logging but not propagating any error it
raises.

:returns: True if func raised no errors, else False.
def _run_cleanups(funcs):
Run a series of cleanup functions.
def _do_with_cleanups(cleanup_funcs, func, *args, **kwargs):
Run 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)
It avoids several problems with using try/finally directly:
  • an exception from func will not be obscured by a subsequent exception from a cleanup.
  • an exception from a cleanup will not prevent other cleanups from running (but the first exception encountered is still the one propagated).

Unike _run_cleanup, _do_with_cleanups can propagate an exception from a cleanup, but only if there is no exception from func.

API Documentation for Bazaar, generated by pydoctor at 2022-06-16 00:25:16.