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 b049d77  Move the outcome types to the storage types module
b049d77 is described below

commit b049d771cfea8b09461699474f97c0f5b5707499
Author: Sean B. Palmer <[email protected]>
AuthorDate: Mon Jul 21 10:51:12 2025 +0100

    Move the outcome types to the storage types module
---
 atr/blueprints/admin/admin.py |   2 +-
 atr/blueprints/api/api.py     |  12 +--
 atr/routes/keys.py            |  10 +--
 atr/storage/__init__.py       | 179 +-------------------------------------
 atr/storage/types.py          | 196 ++++++++++++++++++++++++++++++++++++++----
 atr/storage/writers/keys.py   |  47 +++++-----
 6 files changed, 216 insertions(+), 230 deletions(-)

diff --git a/atr/blueprints/admin/admin.py b/atr/blueprints/admin/admin.py
index e017000..1e9b57b 100644
--- a/atr/blueprints/admin/admin.py
+++ b/atr/blueprints/admin/admin.py
@@ -661,7 +661,7 @@ async def admin_test() -> quart.wrappers.response.Response:
     async with storage.write(asf_uid) as write:
         wacm = write.as_committee_member("tooling").writer_or_raise()
         start = time.perf_counter_ns()
-        outcomes: types.KeyOutcomes = await 
wacm.keys.ensure_stored(keys_file_text)
+        outcomes: types.Outcomes[types.Key] = await 
wacm.keys.ensure_stored(keys_file_text)
         end = time.perf_counter_ns()
         logging.info(f"Upload of {outcomes.result_count} keys took {end - 
start} ns")
     for ocr in outcomes.results():
diff --git a/atr/blueprints/api/api.py b/atr/blueprints/api/api.py
index 4a6e743..43712ba 100644
--- a/atr/blueprints/api/api.py
+++ b/atr/blueprints/api/api.py
@@ -305,12 +305,14 @@ async def keys_add(data: models.api.KeysAddArgs) -> 
DictResponse:
 
     async with storage.write(asf_uid) as write:
         wafm = write.as_foundation_member().writer_or_raise()
-        ocr: types.KeyOutcome = await wafm.keys.ensure_stored_one(data.key)
+        ocr: types.Outcome[types.Key] = await 
wafm.keys.ensure_stored_one(data.key)
         key = ocr.result_or_raise()
 
         for selected_committee_name in selected_committee_names:
             wacm = 
write.as_committee_member(selected_committee_name).writer_or_raise()
-            outcome: types.LinkedCommitteeOutcome = await 
wacm.keys.associate_fingerprint(key.key_model.fingerprint)
+            outcome: types.Outcome[types.LinkedCommittee] = await 
wacm.keys.associate_fingerprint(
+                key.key_model.fingerprint
+            )
             outcome.result_or_raise()
 
     return models.api.KeysAddResults(
@@ -382,20 +384,20 @@ async def keys_upload(data: models.api.KeysUploadArgs) -> 
DictResponse:
     selected_committee_name = data.committee
     async with storage.write(asf_uid) as write:
         wacm = 
write.as_committee_member(selected_committee_name).writer_or_raise()
-        outcomes: types.KeyOutcomes = await 
wacm.keys.ensure_associated(filetext)
+        outcomes: types.Outcomes[types.Key] = await 
wacm.keys.ensure_associated(filetext)
 
         # TODO: It would be nice to serialise the actual outcomes
         api_outcomes = []
         for outcome in outcomes.outcomes():
             api_outcome: models.api.KeysUploadOutcome | None = None
             match outcome:
-                case storage.OutcomeResult() as ocr:
+                case types.OutcomeResult() as ocr:
                     result: types.Key = ocr.result_or_raise()
                     api_outcome = models.api.KeysUploadResult(
                         status="success",
                         key=result.key_model,
                     )
-                case storage.OutcomeException() as oce:
+                case types.OutcomeException() as oce:
                     # TODO: This branch means we must improve the return type
                     match oce.exception_or_none():
                         case types.PublicKeyError() as pke:
diff --git a/atr/routes/keys.py b/atr/routes/keys.py
index 6d52b70..93ad707 100644
--- a/atr/routes/keys.py
+++ b/atr/routes/keys.py
@@ -170,12 +170,12 @@ async def add(session: routes.CommitterSession) -> str:
 
             async with storage.write(asf_uid) as write:
                 wafm = write.as_foundation_member().writer_or_raise()
-                ocr: types.KeyOutcome = await 
wafm.keys.ensure_stored_one(key_text)
+                ocr: types.Outcome[types.Key] = await 
wafm.keys.ensure_stored_one(key_text)
                 key = ocr.result_or_raise()
 
                 for selected_committee_name in selected_committee_names:
                     wacm = 
write.as_committee_member(selected_committee_name).writer_or_raise()
-                    outcome: types.LinkedCommitteeOutcome = await 
wacm.keys.associate_fingerprint(
+                    outcome: types.Outcome[types.LinkedCommittee] = await 
wacm.keys.associate_fingerprint(
                         key.key_model.fingerprint
                     )
                     outcome.result_or_raise()
@@ -535,7 +535,7 @@ async def upload(session: routes.CommitterSession) -> str:
         )
 
     form = await UploadKeyForm.create_form()
-    results: types.KeyOutcomes | None = None
+    results: types.Outcomes[types.Key] | None = None
 
     async def render(
         error: str | None = None,
@@ -743,10 +743,10 @@ async def _upload_keys(
     asf_uid: str,
     filetext: str,
     selected_committee: str,
-) -> types.KeyOutcomes:
+) -> types.Outcomes[types.Key]:
     async with storage.write(asf_uid) as write:
         wacm = write.as_committee_member(selected_committee).writer_or_raise()
-        outcomes: types.KeyOutcomes = await 
wacm.keys.ensure_associated(filetext)
+        outcomes: types.Outcomes[types.Key] = await 
wacm.keys.ensure_associated(filetext)
     return outcomes
 
 
diff --git a/atr/storage/__init__.py b/atr/storage/__init__.py
index 4c7c704..ab2da74 100644
--- a/atr/storage/__init__.py
+++ b/atr/storage/__init__.py
@@ -18,10 +18,10 @@
 from __future__ import annotations
 
 import contextlib
-from typing import TYPE_CHECKING, Final, NoReturn, TypeVar
+from typing import TYPE_CHECKING, Final, TypeVar
 
 if TYPE_CHECKING:
-    from collections.abc import AsyncGenerator, Callable, Sequence
+    from collections.abc import AsyncGenerator
 
 import atr.db as db
 import atr.storage.writers as writers
@@ -222,181 +222,6 @@ class Write:
         return AccessOutcomeWrite(wafm)
 
 
-# Outcome
-
-E = TypeVar("E", bound=Exception)
-T = TypeVar("T", bound=object)
-
-
-class OutcomeCore[T]:
-    @property
-    def ok(self) -> bool:
-        raise NotImplementedError("ok is not implemented")
-
-    @property
-    def name(self) -> str | None:
-        raise NotImplementedError("name is not implemented")
-
-    def result_or_none(self) -> T | None:
-        raise NotImplementedError("result_or_none is not implemented")
-
-    def result_or_raise(self, exception_class: type[E] | None = None) -> T:
-        raise NotImplementedError("result_or_raise is not implemented")
-
-    def exception_or_none(self) -> Exception | None:
-        raise NotImplementedError("exception_or_none is not implemented")
-
-    def exception_type_or_none(self) -> type[Exception] | None:
-        raise NotImplementedError("exception_type_or_none is not implemented")
-
-
-class OutcomeResult[T](OutcomeCore[T]):
-    __result: T
-
-    def __init__(self, result: T, name: str | None = None):
-        self.__result = result
-        self.__name = name
-
-    @property
-    def ok(self) -> bool:
-        return True
-
-    @property
-    def name(self) -> str | None:
-        return self.__name
-
-    def result_or_none(self) -> T | None:
-        return self.__result
-
-    def result_or_raise(self, exception_class: type[Exception] | None = None) 
-> T:
-        return self.__result
-
-    def exception_or_none(self) -> Exception | None:
-        return None
-
-    def exception_type_or_none(self) -> type[Exception] | None:
-        return None
-
-
-class OutcomeException[T, E: Exception](OutcomeCore[T]):
-    __exception: E
-
-    def __init__(self, exception: E, name: str | None = None):
-        self.__exception = exception
-        self.__name = name
-
-    @property
-    def ok(self) -> bool:
-        return False
-
-    @property
-    def name(self) -> str | None:
-        return self.__name
-
-    def result_or_none(self) -> T | None:
-        return None
-
-    def result_or_raise(self, exception_class: type[Exception] | None = None) 
-> NoReturn:
-        if exception_class is not None:
-            raise exception_class(str(self.__exception)) from self.__exception
-        raise self.__exception
-
-    def exception_or_none(self) -> Exception | None:
-        return self.__exception
-
-    def exception_type_or_none(self) -> type[Exception] | None:
-        return type(self.__exception)
-
-
-class Outcomes[T]:
-    __outcomes: list[OutcomeResult[T] | OutcomeException[T, Exception]]
-
-    def __init__(self, *outcomes: OutcomeResult[T] | OutcomeException[T, 
Exception]):
-        self.__outcomes = list(outcomes)
-
-    @property
-    def any_ok(self) -> bool:
-        return any(outcome.ok for outcome in self.__outcomes)
-
-    @property
-    def all_ok(self) -> bool:
-        return all(outcome.ok for outcome in self.__outcomes)
-
-    def append(self, result_or_error: T | Exception, name: str | None = None) 
-> None:
-        if isinstance(result_or_error, Exception):
-            self.__outcomes.append(OutcomeException(result_or_error, name))
-        else:
-            self.__outcomes.append(OutcomeResult(result_or_error, name))
-
-    @property
-    def exception_count(self) -> int:
-        return sum(1 for outcome in self.__outcomes if isinstance(outcome, 
OutcomeException))
-
-    def exceptions(self) -> list[Exception]:
-        exceptions_list = []
-        for outcome in self.__outcomes:
-            if isinstance(outcome, OutcomeException):
-                exception_or_none = outcome.exception_or_none()
-                if exception_or_none is not None:
-                    exceptions_list.append(exception_or_none)
-        return exceptions_list
-
-    def extend(self, result_or_error_list: Sequence[T | Exception]) -> None:
-        for result_or_error in result_or_error_list:
-            self.append(result_or_error)
-
-    def named_results(self) -> dict[str, T]:
-        named = {}
-        for outcome in self.__outcomes:
-            if (outcome.name is not None) and outcome.ok:
-                named[outcome.name] = outcome.result_or_raise()
-        return named
-
-    def names(self) -> list[str | None]:
-        return [outcome.name for outcome in self.__outcomes if (outcome.name 
is not None)]
-
-    # def replace(self, a: T, b: T) -> None:
-    #     for i, outcome in enumerate(self.__outcomes):
-    #         if isinstance(outcome, OutcomeResult):
-    #             if outcome.result_or_raise() == a:
-    #                 self.__outcomes[i] = OutcomeResult(b, outcome.name)
-
-    def results_or_raise(self, exception_class: type[Exception] | None = None) 
-> list[T]:
-        return [outcome.result_or_raise(exception_class) for outcome in 
self.__outcomes]
-
-    def results(self) -> list[T]:
-        return [outcome.result_or_raise() for outcome in self.__outcomes if 
outcome.ok]
-
-    @property
-    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]]:
-        return self.__outcomes
-
-    def result_predicate_count(self, predicate: Callable[[T], bool]) -> int:
-        return sum(
-            1
-            for outcome in self.__outcomes
-            if isinstance(outcome, OutcomeResult) and 
predicate(outcome.result_or_raise())
-        )
-
-    def update_results(self, 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)
-                else:
-                    self.__outcomes[i] = OutcomeResult(result, outcome.name)
-
-
-# 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()])
-
-
 # Context managers
 
 
diff --git a/atr/storage/types.py b/atr/storage/types.py
index 3237e74..b639474 100644
--- a/atr/storage/types.py
+++ b/atr/storage/types.py
@@ -17,11 +17,183 @@
 
 import dataclasses
 import enum
-from typing import Any
+from collections.abc import Callable, Sequence
+from typing import NoReturn, TypeVar
 
 import atr.models.schema as schema
 import atr.models.sql as sql
-import atr.storage as storage
+
+# Outcome
+
+E = TypeVar("E", bound=Exception)
+T = TypeVar("T", bound=object)
+
+
+class OutcomeCore[T]:
+    @property
+    def ok(self) -> bool:
+        raise NotImplementedError("ok is not implemented")
+
+    @property
+    def name(self) -> str | None:
+        raise NotImplementedError("name is not implemented")
+
+    def result_or_none(self) -> T | None:
+        raise NotImplementedError("result_or_none is not implemented")
+
+    def result_or_raise(self, exception_class: type[E] | None = None) -> T:
+        raise NotImplementedError("result_or_raise is not implemented")
+
+    def exception_or_none(self) -> Exception | None:
+        raise NotImplementedError("exception_or_none is not implemented")
+
+    def exception_type_or_none(self) -> type[Exception] | None:
+        raise NotImplementedError("exception_type_or_none is not implemented")
+
+
+class OutcomeResult[T](OutcomeCore[T]):
+    __result: T
+
+    def __init__(self, result: T, name: str | None = None):
+        self.__result = result
+        self.__name = name
+
+    @property
+    def ok(self) -> bool:
+        return True
+
+    @property
+    def name(self) -> str | None:
+        return self.__name
+
+    def result_or_none(self) -> T | None:
+        return self.__result
+
+    def result_or_raise(self, exception_class: type[Exception] | None = None) 
-> T:
+        return self.__result
+
+    def exception_or_none(self) -> Exception | None:
+        return None
+
+    def exception_type_or_none(self) -> type[Exception] | None:
+        return None
+
+
+class OutcomeException[T, E: Exception](OutcomeCore[T]):
+    __exception: E
+
+    def __init__(self, exception: E, name: str | None = None):
+        self.__exception = exception
+        self.__name = name
+
+    @property
+    def ok(self) -> bool:
+        return False
+
+    @property
+    def name(self) -> str | None:
+        return self.__name
+
+    def result_or_none(self) -> T | None:
+        return None
+
+    def result_or_raise(self, exception_class: type[Exception] | None = None) 
-> NoReturn:
+        if exception_class is not None:
+            raise exception_class(str(self.__exception)) from self.__exception
+        raise self.__exception
+
+    def exception_or_none(self) -> Exception | None:
+        return self.__exception
+
+    def exception_type_or_none(self) -> type[Exception] | None:
+        return type(self.__exception)
+
+
+class Outcomes[T]:
+    __outcomes: list[OutcomeResult[T] | OutcomeException[T, Exception]]
+
+    def __init__(self, *outcomes: OutcomeResult[T] | OutcomeException[T, 
Exception]):
+        self.__outcomes = list(outcomes)
+
+    @property
+    def any_ok(self) -> bool:
+        return any(outcome.ok for outcome in self.__outcomes)
+
+    @property
+    def all_ok(self) -> bool:
+        return all(outcome.ok for outcome in self.__outcomes)
+
+    def append(self, result_or_error: T | Exception, name: str | None = None) 
-> None:
+        if isinstance(result_or_error, Exception):
+            self.__outcomes.append(OutcomeException(result_or_error, name))
+        else:
+            self.__outcomes.append(OutcomeResult(result_or_error, name))
+
+    @property
+    def exception_count(self) -> int:
+        return sum(1 for outcome in self.__outcomes if isinstance(outcome, 
OutcomeException))
+
+    def exceptions(self) -> list[Exception]:
+        exceptions_list = []
+        for outcome in self.__outcomes:
+            if isinstance(outcome, OutcomeException):
+                exception_or_none = outcome.exception_or_none()
+                if exception_or_none is not None:
+                    exceptions_list.append(exception_or_none)
+        return exceptions_list
+
+    def extend(self, result_or_error_list: Sequence[T | Exception]) -> None:
+        for result_or_error in result_or_error_list:
+            self.append(result_or_error)
+
+    def named_results(self) -> dict[str, T]:
+        named = {}
+        for outcome in self.__outcomes:
+            if (outcome.name is not None) and outcome.ok:
+                named[outcome.name] = outcome.result_or_raise()
+        return named
+
+    def names(self) -> list[str | None]:
+        return [outcome.name for outcome in self.__outcomes if (outcome.name 
is not None)]
+
+    # def replace(self, a: T, b: T) -> None:
+    #     for i, outcome in enumerate(self.__outcomes):
+    #         if isinstance(outcome, OutcomeResult):
+    #             if outcome.result_or_raise() == a:
+    #                 self.__outcomes[i] = OutcomeResult(b, outcome.name)
+
+    def results_or_raise(self, exception_class: type[Exception] | None = None) 
-> list[T]:
+        return [outcome.result_or_raise(exception_class) for outcome in 
self.__outcomes]
+
+    def results(self) -> list[T]:
+        return [outcome.result_or_raise() for outcome in self.__outcomes if 
outcome.ok]
+
+    @property
+    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]]:
+        return self.__outcomes
+
+    def result_predicate_count(self, predicate: Callable[[T], bool]) -> int:
+        return sum(
+            1
+            for outcome in self.__outcomes
+            if isinstance(outcome, OutcomeResult) and 
predicate(outcome.result_or_raise())
+        )
+
+    def update_results(self, 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)
+                else:
+                    self.__outcomes[i] = OutcomeResult(result, outcome.name)
+
+
+type Outcome[T] = OutcomeResult[T] | OutcomeException[T, Exception]
 
 
 class KeyStatus(enum.Flag):
@@ -36,14 +208,10 @@ class Key(schema.Strict):
     key_model: sql.PublicSigningKey
 
 
-# OutcomeStr = storage.OutcomeResult[str] | storage.OutcomeException[str, 
Exception]
-
-
 @dataclasses.dataclass
 class LinkedCommittee:
     name: str
-    # TODO: Move Outcome here
-    autogenerated_keys_file: Any
+    autogenerated_keys_file: Outcome[str]
 
 
 class PublicKeyError(Exception):
@@ -63,14 +231,6 @@ class PublicKeyError(Exception):
         return self.__original_error
 
 
-type KeyOutcomeResult = storage.OutcomeResult[Key]
-type KeyOutcomeException = storage.OutcomeException[Key, Exception]
-type KeyOutcome = KeyOutcomeResult | KeyOutcomeException
-
-type KeyOutcomes = storage.Outcomes[Key]
-
-type LinkedCommitteeOutcomeResult = storage.OutcomeResult[LinkedCommittee]
-type LinkedCommitteeOutcomeException = 
storage.OutcomeException[LinkedCommittee, Exception]
-type LinkedCommitteeOutcome = LinkedCommitteeOutcomeResult | 
LinkedCommitteeOutcomeException
-
-type LinkedCommitteeOutcomes = storage.Outcomes[LinkedCommittee]
+# 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 c9acbf5..2794c94 100644
--- a/atr/storage/writers/keys.py
+++ b/atr/storage/writers/keys.py
@@ -85,7 +85,7 @@ class FoundationMember:
         self.__key_block_models_cache = {}
 
     @performance_async
-    async def ensure_stored_one(self, key_file_text: str) -> types.KeyOutcome:
+    async def ensure_stored_one(self, key_file_text: str) -> 
types.Outcome[types.Key]:
         return await self.__ensure_one(key_file_text, associate=False)
 
     @performance
@@ -124,7 +124,7 @@ class FoundationMember:
     async def __database_add_model(
         self,
         key: types.Key,
-    ) -> storage.OutcomeResult[types.Key]:
+    ) -> types.Outcome[types.Key]:
         via = sql.validate_instrumented_attribute
 
         await self.__data.begin_immediate()
@@ -143,22 +143,22 @@ class FoundationMember:
 
         await self.__data.commit()
         # TODO: PARSED now acts as "ALREADY_ADDED"
-        return 
storage.OutcomeResult(types.Key(status=types.KeyStatus.INSERTED, 
key_model=key.key_model))
+        return types.OutcomeResult(types.Key(status=types.KeyStatus.INSERTED, 
key_model=key.key_model))
 
     @performance_async
-    async def __ensure_one(self, key_file_text: str, associate: bool = True) 
-> types.KeyOutcome:
+    async def __ensure_one(self, key_file_text: str, associate: bool = True) 
-> types.Outcome[types.Key]:
         try:
             key_blocks = util.parse_key_blocks(key_file_text)
         except Exception as e:
-            return storage.OutcomeException(e)
+            return types.OutcomeException(e)
         if len(key_blocks) != 1:
-            return storage.OutcomeException(ValueError("Expected one key 
block, got none or multiple"))
+            return types.OutcomeException(ValueError("Expected one key block, 
got none or multiple"))
         key_block = key_blocks[0]
         try:
             ldap_data = await util.email_to_uid_map()
             key = await asyncio.to_thread(self.__block_model, key_block, 
ldap_data)
         except Exception as e:
-            return storage.OutcomeException(e)
+            return types.OutcomeException(e)
         outcome = await self.__database_add_model(key)
         return outcome
 
@@ -245,7 +245,7 @@ class CommitteeMember(CommitteeParticipant):
         self.__committee_name = committee_name
 
     @performance_async
-    async def associate_fingerprint(self, fingerprint: str) -> 
types.LinkedCommitteeOutcome:
+    async def associate_fingerprint(self, fingerprint: str) -> 
types.Outcome[types.LinkedCommittee]:
         via = sql.validate_instrumented_attribute
         link_values = [{"committee_name": self.__committee_name, 
"key_fingerprint": fingerprint}]
         try:
@@ -261,12 +261,12 @@ class CommitteeMember(CommitteeParticipant):
                 pass
             await self.__data.commit()
         except Exception as e:
-            return storage.OutcomeException(e)
+            return types.OutcomeException(e)
         try:
             autogenerated_outcome = await self.__autogenerate_keys_file()
         except Exception as e:
-            return storage.OutcomeException(e)
-        return storage.OutcomeResult(
+            return types.OutcomeException(e)
+        return types.OutcomeResult(
             types.LinkedCommittee(
                 name=self.__committee_name,
                 autogenerated_keys_file=autogenerated_outcome,
@@ -280,18 +280,17 @@ class CommitteeMember(CommitteeParticipant):
         )
 
     @performance_async
-    async def ensure_associated(self, keys_file_text: str) -> 
storage.Outcomes[types.Key]:
+    async def ensure_associated(self, keys_file_text: str) -> 
types.Outcomes[types.Key]:
         # TODO: Autogenerate KEYS file
         return await self.__ensure(keys_file_text, associate=True)
 
     @performance_async
-    async def ensure_stored(self, keys_file_text: str) -> 
storage.Outcomes[types.Key]:
+    async def ensure_stored(self, keys_file_text: str) -> 
types.Outcomes[types.Key]:
         return await self.__ensure(keys_file_text, associate=False)
 
-    # TODO: Outcome[str]
     async def __autogenerate_keys_file(
         self,
-    ) -> storage.OutcomeResult[str] | storage.OutcomeException[str, Exception]:
+    ) -> types.Outcome[str]:
         base_downloads_dir = util.get_downloads_dir()
 
         committee = await self.committee()
@@ -309,12 +308,12 @@ class CommitteeMember(CommitteeParticipant):
             await asyncio.to_thread(committee_keys_path.write_text, 
full_keys_file_content, encoding="utf-8")
         except OSError as e:
             error_msg = f"Failed to write KEYS file for committee 
{self.__committee_name}: {e}"
-            return storage.OutcomeException(storage.AccessError(error_msg))
+            return types.OutcomeException(storage.AccessError(error_msg))
         except Exception as e:
             error_msg = f"An unexpected error occurred writing KEYS for 
committee {self.__committee_name}: {e}"
             logging.exception(e)
-            return storage.OutcomeException(storage.AccessError(error_msg))
-        return storage.OutcomeResult(str(committee_keys_path))
+            return types.OutcomeException(storage.AccessError(error_msg))
+        return types.OutcomeResult(str(committee_keys_path))
 
     @performance
     def __block_models(self, key_block: str, ldap_data: dict[str, str]) -> 
list[types.Key | Exception]:
@@ -343,8 +342,8 @@ class CommitteeMember(CommitteeParticipant):
 
     @performance_async
     async def __database_add_models(
-        self, outcomes: storage.Outcomes[types.Key], associate: bool = True
-    ) -> storage.Outcomes[types.Key]:
+        self, outcomes: types.Outcomes[types.Key], associate: bool = True
+    ) -> types.Outcomes[types.Key]:
         # Try to upsert all models and link to the committee in one transaction
         try:
             outcomes = await self.__database_add_models_core(outcomes, 
associate=associate)
@@ -364,9 +363,9 @@ class CommitteeMember(CommitteeParticipant):
     @performance_async
     async def __database_add_models_core(
         self,
-        outcomes: storage.Outcomes[types.Key],
+        outcomes: types.Outcomes[types.Key],
         associate: bool = True,
-    ) -> storage.Outcomes[types.Key]:
+    ) -> types.Outcomes[types.Key]:
         via = sql.validate_instrumented_attribute
         key_list = outcomes.results()
 
@@ -425,8 +424,8 @@ class CommitteeMember(CommitteeParticipant):
         return outcomes
 
     @performance_async
-    async def __ensure(self, keys_file_text: str, associate: bool = True) -> 
storage.Outcomes[types.Key]:
-        outcomes = storage.Outcomes[types.Key]()
+    async def __ensure(self, keys_file_text: str, associate: bool = True) -> 
types.Outcomes[types.Key]:
+        outcomes = types.Outcomes[types.Key]()
         try:
             ldap_data = await util.email_to_uid_map()
             key_blocks = util.parse_key_blocks(keys_file_text)


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

Reply via email to