Mercurial > public > mercurial-scm > hg
comparison mercurial/util.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 | 02a745c20121 |
children | 05264fc9d8d6 |
comparison
equal
deleted
inserted
replaced
33792:5904511fc9f8 | 33793:bbbbd3c30bfc |
---|---|
13 hide platform-specific details from the core. | 13 hide platform-specific details from the core. |
14 """ | 14 """ |
15 | 15 |
16 from __future__ import absolute_import | 16 from __future__ import absolute_import |
17 | 17 |
18 import abc | |
18 import bz2 | 19 import bz2 |
19 import calendar | 20 import calendar |
20 import codecs | 21 import codecs |
21 import collections | 22 import collections |
22 import contextlib | 23 import contextlib |
589 def update(self, src): | 590 def update(self, src): |
590 if isinstance(src, dict): | 591 if isinstance(src, dict): |
591 src = src.iteritems() | 592 src = src.iteritems() |
592 for k, v in src: | 593 for k, v in src: |
593 self[k] = v | 594 self[k] = v |
595 | |
596 class transactional(object): | |
597 """Base class for making a transactional type into a context manager.""" | |
598 __metaclass__ = abc.ABCMeta | |
599 | |
600 @abc.abstractmethod | |
601 def close(self): | |
602 """Successfully closes the transaction.""" | |
603 | |
604 @abc.abstractmethod | |
605 def release(self): | |
606 """Marks the end of the transaction. | |
607 | |
608 If the transaction has not been closed, it will be aborted. | |
609 """ | |
610 | |
611 def __enter__(self): | |
612 return self | |
613 | |
614 def __exit__(self, exc_type, exc_val, exc_tb): | |
615 try: | |
616 if exc_type is None: | |
617 self.close() | |
618 finally: | |
619 self.release() | |
594 | 620 |
595 @contextlib.contextmanager | 621 @contextlib.contextmanager |
596 def acceptintervention(tr=None): | 622 def acceptintervention(tr=None): |
597 """A context manager that closes the transaction on InterventionRequired | 623 """A context manager that closes the transaction on InterventionRequired |
598 | 624 |