Mercurial > hg
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) |