~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/cleanup.py

  • Committer: Jelmer Vernooij
  • Date: 2011-12-19 10:58:39 UTC
  • mfrom: (6383 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6386.
  • Revision ID: jelmer@canonical.com-20111219105839-uji05ck4rkm1mj4j
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
 
17
from __future__ import absolute_import
 
18
 
17
19
"""Helpers for managing cleanup functions and the errors they might raise.
18
20
 
19
21
The usual way to run cleanup code in Python is::
78
80
        _run_cleanup(func, *args, **kwargs)
79
81
 
80
82
 
81
 
class OperationWithCleanups(object):
 
83
class ObjectWithCleanups(object):
 
84
    """A mixin for objects that hold a cleanup list.
 
85
 
 
86
    Subclass or client code can call add_cleanup and then later `cleanup_now`.
 
87
    """
 
88
    def __init__(self):
 
89
        self.cleanups = deque()
 
90
 
 
91
    def add_cleanup(self, cleanup_func, *args, **kwargs):
 
92
        """Add a cleanup to run.
 
93
 
 
94
        Cleanups may be added at any time.  
 
95
        Cleanups will be executed in LIFO order.
 
96
        """
 
97
        self.cleanups.appendleft((cleanup_func, args, kwargs))
 
98
 
 
99
    def cleanup_now(self):
 
100
        _run_cleanups(self.cleanups)
 
101
        self.cleanups.clear()
 
102
 
 
103
 
 
104
class OperationWithCleanups(ObjectWithCleanups):
82
105
    """A way to run some code with a dynamic cleanup list.
83
106
 
84
107
    This provides a way to add cleanups while the function-with-cleanups is
102
125
    """
103
126
 
104
127
    def __init__(self, func):
 
128
        super(OperationWithCleanups, self).__init__()
105
129
        self.func = func
106
 
        self.cleanups = deque()
107
 
 
108
 
    def add_cleanup(self, cleanup_func, *args, **kwargs):
109
 
        """Add a cleanup to run.
110
 
 
111
 
        Cleanups may be added at any time before or during the execution of
112
 
        self.func.  Cleanups will be executed in LIFO order.
113
 
        """
114
 
        self.cleanups.appendleft((cleanup_func, args, kwargs))
115
130
 
116
131
    def run(self, *args, **kwargs):
117
132
        return _do_with_cleanups(
121
136
        return _do_with_cleanups(
122
137
            self.cleanups, self.func, *args, **kwargs)
123
138
 
124
 
    def cleanup_now(self):
125
 
        _run_cleanups(self.cleanups)
126
 
        self.cleanups.clear()
127
 
 
128
139
 
129
140
def _do_with_cleanups(cleanup_funcs, func, *args, **kwargs):
130
141
    """Run `func`, then call all the cleanup_funcs.
179
190
                # but don't propagate them.
180
191
                _run_cleanup(cleanup, *c_args, **kwargs)
181
192
        if exc_info is not None:
182
 
            raise exc_info[0], exc_info[1], exc_info[2]
 
193
            try:
 
194
                raise exc_info[0], exc_info[1], exc_info[2]
 
195
            finally:
 
196
                del exc_info
183
197
        # No error, so we can return the result
184
198
        return result
185
199