]> arthur.barton.de Git - bup.git/commitdiff
compat.pending_raise: allow/ignore None ex; make rethrow optional
authorRob Browning <rlb@defaultvalue.org>
Sun, 3 Oct 2021 17:44:25 +0000 (12:44 -0500)
committerRob Browning <rlb@defaultvalue.org>
Mon, 22 Nov 2021 06:33:50 +0000 (00:33 -0600)
This supports compact __exit__ handlers, e.g.

  def __exit__(self, type, value, ...):
      with pending_raise(value, rethrow=False):
          clean_up()

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Tested-by: Rob Browning <rlb@defaultvalue.org>
lib/bup/compat.py

index 72722017addc5dd3cb52589576576b8a99a1b04b..9002025a6d49ec76cda219bc46468f10769ca905 100644 (file)
@@ -40,16 +40,18 @@ if py3:
         return ex
 
     class pending_raise:
-        """Rethrow either the provided ex, or any exception raised by the with
-        statement body.  (Supports Python 2 compatibility.)
+        """If rethrow is true, rethrow ex (if any), unless the body throws.
+
+        (Supports Python 2 compatibility.)
 
         """
-        def __init__(self, ex):
+        def __init__(self, ex, rethrow=True):
             self.ex = ex
+            self.rethrow = rethrow
         def __enter__(self):
             return None
         def __exit__(self, exc_type, exc_value, traceback):
-            if not exc_type:
+            if not exc_type and self.ex and self.rethrow:
                 raise self.ex
 
     def items(x):
@@ -126,22 +128,28 @@ else:  # Python 2
         return ex
 
     class pending_raise:
-        """Rethrow either the provided ex, or any exception raised by the with
-        statement body, after making ex the __context__ of the newer
-        exception (assuming there's no existing __context__).  Ensure
-        the exceptions have __tracebacks__.  (Supports Python 2
-        compatibility.)
+        """If rethrow is true, rethrow ex (if any), unless the body throws.
+
+        If the body does throw, make any provided ex the __context__
+        of the newer exception (assuming there's no existing
+        __context__).  Ensure the exceptions have __tracebacks__.
+        (Supports Python 2 compatibility.)
 
         """
-        def __init__(self, ex):
+        def __init__(self, ex, rethrow=True):
             self.ex = ex
+            self.rethrow = rethrow
         def __enter__(self):
-            add_ex_tb(self.ex)
+            if self.ex:
+                add_ex_tb(self.ex)
         def __exit__(self, exc_type, exc_value, traceback):
-            if not exc_type:
+            if exc_value:
+                if self.ex:
+                    add_ex_tb(exc_value)
+                    add_ex_ctx(exc_value, self.ex)
+                return
+            if self.rethrow and self.ex:
                 raise self.ex
-            add_ex_tb(exc_value)
-            add_ex_ctx(exc_value, self.ex)
 
     def dump_traceback(ex):
         stack = [ex]