comparison mercurial/dirstateguard.py @ 33793:bbbbd3c30bfc

util: add base class for transactional context managers We have at least three types with a close() and a release() method where the close() method is supposed to be called on success and the release() method is supposed to be called last, whether successful or not. Two of them (transaction and dirstateguard) already have identical implementations of __enter__ and __exit__. Let's extract a base class for this, so we reuse the code and so the third type (transactionmanager) can also be used as a context manager. Differential Revision: https://phab.mercurial-scm.org/D392
author Martin von Zweigbergk <martinvonz@google.com>
date Fri, 28 Jul 2017 22:42:10 -0700
parents 609606d21765
children ad24b581e4d9
comparison
equal deleted inserted replaced
33792:5904511fc9f8 33793:bbbbd3c30bfc
9 9
10 from .i18n import _ 10 from .i18n import _
11 11
12 from . import ( 12 from . import (
13 error, 13 error,
14 util,
14 ) 15 )
15 16
16 class dirstateguard(object): 17 class dirstateguard(util.transactional):
17 '''Restore dirstate at unexpected failure. 18 '''Restore dirstate at unexpected failure.
18 19
19 At the construction, this class does: 20 At the construction, this class does:
20 21
21 - write current ``repo.dirstate`` out, and 22 - write current ``repo.dirstate`` out, and
41 # for example, releasing other resources like transaction 42 # for example, releasing other resources like transaction
42 # may raise exception before ``dirstateguard.release`` in 43 # may raise exception before ``dirstateguard.release`` in
43 # ``release(tr, ....)``. 44 # ``release(tr, ....)``.
44 self._abort() 45 self._abort()
45 46
46 def __enter__(self):
47 return self
48
49 def __exit__(self, exc_type, exc_val, exc_tb):
50 try:
51 if exc_type is None:
52 self.close()
53 finally:
54 self.release()
55
56 def close(self): 47 def close(self):
57 if not self._active: # already inactivated 48 if not self._active: # already inactivated
58 msg = (_("can't close already inactivated backup: %s") 49 msg = (_("can't close already inactivated backup: %s")
59 % self._backupname) 50 % self._backupname)
60 raise error.Abort(msg) 51 raise error.Abort(msg)