~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/cleanup.py

  • Committer: Andrew Bennetts
  • Date: 2009-12-03 02:24:54 UTC
  • mfrom: (4634.101.4 2.0)
  • mto: This revision was merged to the branch mainline in revision 4857.
  • Revision ID: andrew.bennetts@canonical.com-20091203022454-m2gyhbcdqi1t7ujz
Merge lp:bzr/2.0 into lp:bzr.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009, 2010 Canonical Ltd
 
1
# Copyright (C) 2009 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
31
31
If you want to be certain that the first, and only the first, error is raised,
32
32
then use::
33
33
 
34
 
    operation = OperationWithCleanups(do_something)
 
34
    operation = OperationWithCleanups(lambda operation: do_something())
35
35
    operation.add_cleanup(cleanup_something)
36
 
    operation.run_simple()
 
36
    operation.run()
37
37
 
38
38
This is more inconvenient (because you need to make every try block a
39
39
function), but will ensure that the first error encountered is the one raised,
41
41
details.
42
42
"""
43
43
 
44
 
from __future__ import absolute_import
45
44
 
46
45
from collections import deque
47
46
import sys
79
78
        _run_cleanup(func, *args, **kwargs)
80
79
 
81
80
 
82
 
class ObjectWithCleanups(object):
83
 
    """A mixin for objects that hold a cleanup list.
84
 
 
85
 
    Subclass or client code can call add_cleanup and then later `cleanup_now`.
86
 
    """
87
 
    def __init__(self):
88
 
        self.cleanups = deque()
89
 
 
90
 
    def add_cleanup(self, cleanup_func, *args, **kwargs):
91
 
        """Add a cleanup to run.
92
 
 
93
 
        Cleanups may be added at any time.  
94
 
        Cleanups will be executed in LIFO order.
95
 
        """
96
 
        self.cleanups.appendleft((cleanup_func, args, kwargs))
97
 
 
98
 
    def cleanup_now(self):
99
 
        _run_cleanups(self.cleanups)
100
 
        self.cleanups.clear()
101
 
 
102
 
 
103
 
class OperationWithCleanups(ObjectWithCleanups):
 
81
class OperationWithCleanups(object):
104
82
    """A way to run some code with a dynamic cleanup list.
105
83
 
106
84
    This provides a way to add cleanups while the function-with-cleanups is
113
91
 
114
92
    where `some_func` is::
115
93
 
116
 
        def some_func(operation, args, ...):
 
94
        def some_func(operation, args, ...)
117
95
            do_something()
118
96
            operation.add_cleanup(something)
119
97
            # etc
120
98
 
121
99
    Note that the first argument passed to `some_func` will be the
122
 
    OperationWithCleanups object.  To invoke `some_func` without that, use
123
 
    `run_simple` instead of `run`.
 
100
    OperationWithCleanups object.
124
101
    """
125
102
 
126
103
    def __init__(self, func):
127
 
        super(OperationWithCleanups, self).__init__()
128
104
        self.func = func
 
105
        self.cleanups = deque()
 
106
 
 
107
    def add_cleanup(self, cleanup_func, *args, **kwargs):
 
108
        """Add a cleanup to run.
 
109
 
 
110
        Cleanups may be added at any time before or during the execution of
 
111
        self.func.  Cleanups will be executed in LIFO order.
 
112
        """
 
113
        self.cleanups.appendleft((cleanup_func, args, kwargs))
129
114
 
130
115
    def run(self, *args, **kwargs):
131
116
        return _do_with_cleanups(
132
117
            self.cleanups, self.func, self, *args, **kwargs)
133
118
 
134
 
    def run_simple(self, *args, **kwargs):
135
 
        return _do_with_cleanups(
136
 
            self.cleanups, self.func, *args, **kwargs)
137
 
 
138
119
 
139
120
def _do_with_cleanups(cleanup_funcs, func, *args, **kwargs):
140
121
    """Run `func`, then call all the cleanup_funcs.
189
170
                # but don't propagate them.
190
171
                _run_cleanup(cleanup, *c_args, **kwargs)
191
172
        if exc_info is not None:
192
 
            try:
193
 
                raise exc_info[0], exc_info[1], exc_info[2]
194
 
            finally:
195
 
                del exc_info
 
173
            raise exc_info[0], exc_info[1], exc_info[2]
196
174
        # No error, so we can return the result
197
175
        return result
198
176