This is an automated email from the ASF dual-hosted git repository.

sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-release.git


The following commit(s) were added to refs/heads/main by this push:
     new 4975c6f  Add an exception type parameter to outcomes
4975c6f is described below

commit 4975c6ff87d3fedd0e7ef374989b5e5de0b7c296
Author: Sean B. Palmer <[email protected]>
AuthorDate: Tue Jul 22 15:42:02 2025 +0100

    Add an exception type parameter to outcomes
---
 atr/storage/types.py        | 51 +++++++++++++++++++++++++++------------------
 atr/storage/writers/keys.py | 12 +++++------
 2 files changed, 37 insertions(+), 26 deletions(-)

diff --git a/atr/storage/types.py b/atr/storage/types.py
index 56d60d1..c4a7be3 100644
--- a/atr/storage/types.py
+++ b/atr/storage/types.py
@@ -112,10 +112,10 @@ class OutcomeException[T, E: Exception = 
Exception](OutcomeCore[T]):
 type Outcome[T, E: Exception = Exception] = OutcomeResult[T] | 
OutcomeException[T, E]
 
 
-class Outcomes[T]:
-    __outcomes: list[OutcomeResult[T] | OutcomeException[T, Exception]]
+class Outcomes[T, E: Exception = Exception]:
+    __outcomes: list[Outcome[T, E]]
 
-    def __init__(self, *outcomes: OutcomeResult[T] | OutcomeException[T, 
Exception]):
+    def __init__(self, *outcomes: Outcome[T, E]):
         self.__outcomes = list(outcomes)
 
     @property
@@ -126,12 +126,20 @@ class Outcomes[T]:
     def all_ok(self) -> bool:
         return all(outcome.ok for outcome in self.__outcomes)
 
-    def append(self, outcome: OutcomeResult[T] | OutcomeException[T, 
Exception]) -> None:
+    def append(self, outcome: Outcome[T, E]) -> None:
         self.__outcomes.append(outcome)
 
-    def append_roe(self, roe: T | Exception, name: str | None = None) -> None:
-        if isinstance(roe, Exception):
-            self.__outcomes.append(OutcomeException[T, Exception](roe, name))
+    def append_exception(self, exception: E, name: str | None = None) -> None:
+        self.__outcomes.append(OutcomeException[T, E](exception, name))
+
+    def append_result(self, result: T, name: str | None = None) -> None:
+        self.__outcomes.append(OutcomeResult[T](result, name))
+
+    def append_roe(self, exception_type: type[E], roe: T | E, name: str | None 
= None) -> None:
+        if isinstance(roe, exception_type):
+            self.__outcomes.append(OutcomeException[T, E](roe, name))
+        elif isinstance(roe, Exception):
+            self.__outcomes.append(OutcomeException[T, 
E](exception_type(str(roe)), name))
         else:
             self.__outcomes.append(OutcomeResult[T](roe, name))
 
@@ -139,7 +147,7 @@ class Outcomes[T]:
     def exception_count(self) -> int:
         return sum(1 for outcome in self.__outcomes if isinstance(outcome, 
OutcomeException))
 
-    def exceptions(self) -> list[Exception]:
+    def exceptions(self) -> list[E]:
         exceptions_list = []
         for outcome in self.__outcomes:
             if isinstance(outcome, OutcomeException):
@@ -148,9 +156,17 @@ class Outcomes[T]:
                     exceptions_list.append(exception_or_none)
         return exceptions_list
 
-    def extend(self, roes: Sequence[T | Exception]) -> None:
+    def extend_exceptions(self, exceptions: Sequence[E]) -> None:
+        for exception in exceptions:
+            self.append_exception(exception)
+
+    def extend_results(self, results: Sequence[T]) -> None:
+        for result in results:
+            self.append_result(result)
+
+    def extend_roes(self, exception_type: type[E], roes: Sequence[T | E]) -> 
None:
         for roe in roes:
-            self.append_roe(roe)
+            self.append_roe(exception_type, roe)
 
     def named_results(self) -> dict[str, T]:
         named = {}
@@ -178,7 +194,7 @@ class Outcomes[T]:
     def result_count(self) -> int:
         return sum(1 for outcome in self.__outcomes if outcome.ok)
 
-    def outcomes(self) -> list[OutcomeResult[T] | OutcomeException[T, 
Exception]]:
+    def outcomes(self) -> list[Outcome[T, E]]:
         return self.__outcomes
 
     def result_predicate_count(self, predicate: Callable[[T], bool]) -> int:
@@ -188,15 +204,15 @@ class Outcomes[T]:
             if isinstance(outcome, OutcomeResult) and 
predicate(outcome.result_or_raise())
         )
 
-    def update_results(self, f: Callable[[T], T]) -> None:
+    def update_roes(self, exception_type: type[E], f: Callable[[T], T]) -> 
None:
         for i, outcome in enumerate(self.__outcomes):
             if isinstance(outcome, OutcomeResult):
                 try:
                     result = f(outcome.result_or_raise())
-                except Exception as e:
-                    self.__outcomes[i] = OutcomeException(e, outcome.name)
+                except exception_type as e:
+                    self.__outcomes[i] = OutcomeException[T, E](e, 
outcome.name)
                 else:
-                    self.__outcomes[i] = OutcomeResult(result, outcome.name)
+                    self.__outcomes[i] = OutcomeResult[T](result, outcome.name)
 
 
 class KeyStatus(enum.Flag):
@@ -232,8 +248,3 @@ class PublicKeyError(Exception):
     @property
     def original_error(self) -> Exception:
         return self.__original_error
-
-
-# TODO: Could use + and += instead, or in addition
-def outcomes_merge[T](*outcomes: Outcomes[T]) -> Outcomes[T]:
-    return Outcomes(*[outcome for outcome in outcomes for outcome in 
outcome.outcomes()])
diff --git a/atr/storage/writers/keys.py b/atr/storage/writers/keys.py
index fe8d9d1..2ee6dfa 100644
--- a/atr/storage/writers/keys.py
+++ b/atr/storage/writers/keys.py
@@ -361,7 +361,7 @@ class CommitteeMember(CommitteeParticipant):
                 key = types.Key(status=types.KeyStatus.PARSED, 
key_model=key.key_model)
                 raise types.PublicKeyError(key, e)
 
-            outcomes.update_results(raise_post_parse_error)
+            outcomes.update_roes(Exception, raise_post_parse_error)
         return outcomes
 
     @performance_async
@@ -391,7 +391,7 @@ class CommitteeMember(CommitteeParticipant):
                 key.status = types.KeyStatus.INSERTED
             return key
 
-        outcomes.update_results(replace_with_inserted)
+        outcomes.update_roes(Exception, replace_with_inserted)
 
         persisted_fingerprints = {v["fingerprint"] for v in key_values}
         await self.__data.flush()
@@ -420,7 +420,7 @@ class CommitteeMember(CommitteeParticipant):
                             key.status = types.KeyStatus.LINKED
                 return key
 
-            outcomes.update_results(replace_with_linked)
+            outcomes.update_roes(Exception, replace_with_linked)
         else:
             logging.info("Inserted 0 key links (none to insert)")
 
@@ -434,14 +434,14 @@ class CommitteeMember(CommitteeParticipant):
             ldap_data = await util.email_to_uid_map()
             key_blocks = util.parse_key_blocks(keys_file_text)
         except Exception as e:
-            outcomes.append_roe(e)
+            outcomes.append_exception(e)
             return outcomes
         for key_block in key_blocks:
             try:
                 key_models = await asyncio.to_thread(self.__block_models, 
key_block, ldap_data)
-                outcomes.extend(key_models)
+                outcomes.extend_results(key_models)
             except Exception as e:
-                outcomes.append_roe(e)
+                outcomes.append_exception(e)
         # Try adding the keys to the database
         # If not, all keys will be replaced with a PostParseError
         outcomes = await self.__database_add_models(outcomes, 
associate=associate)


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to