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