adjust/rewrite code to fix https://bugs.libre-soc.org/show_bug.cgi?id=706
[utils.git] / src / budget_sync / config.py
index 28b584ca33468fd449d66e6c0c5a8fe0dd14834f..16084445b398835550362888fb687984ac3a6910 100644 (file)
@@ -1,6 +1,8 @@
+from budget_sync.ordered_set import OrderedSet
+from budget_sync.util import PrettyPrinter
 import toml
 import sys
-from typing import Set, Dict, Any, Optional
+from typing import Mapping, Set, Dict, Any, Optional
 from functools import cached_property
 
 
@@ -9,24 +11,26 @@ class ConfigParseError(Exception):
 
 
 class Person:
-    aliases: Set[str]
+    aliases: OrderedSet[str]
     email: Optional[str]
 
     def __init__(self, config: "Config", identifier: str,
                  output_markdown_file: str,
-                 aliases: Optional[Set[str]] = None,
+                 aliases: Optional[OrderedSet[str]] = None,
                  email: Optional[str] = None):
         self.config = config
         self.identifier = identifier
         self.output_markdown_file = output_markdown_file
         if aliases is None:
-            aliases = set()
+            aliases = OrderedSet()
+        else:
+            assert isinstance(aliases, OrderedSet)
         self.aliases = aliases
         self.email = email
 
     @cached_property
-    def all_names(self) -> Set[str]:
-        retval = self.aliases.copy()
+    def all_names(self) -> OrderedSet[str]:
+        retval = OrderedSet(self.aliases)
         retval.add(self.identifier)
         if self.email is not None:
             retval.add(self.email)
@@ -38,6 +42,11 @@ class Person:
     def __hash__(self):
         return hash(self.identifier)
 
+    def __pretty_print__(self, pp: PrettyPrinter):
+        with pp.type_pp("Person") as tpp:
+            tpp.field("config", ...)
+            tpp.field("identifier", self.identifier)
+
     def __repr__(self):
         return (f"Person(config=..., identifier={self.identifier!r}, "
                 f"output_markdown_file={self.output_markdown_file!r}, "
@@ -111,7 +120,7 @@ class Config:
     def canonical_bug_ids(self) -> Dict[int, Milestone]:
         # also checks for any bug id clashes and raises
         # ConfigParseError if any are detected
-        retval = {}
+        retval: Dict[int, Milestone] = {}
         for milestone in self.milestones.values():
             other_milestone = retval.get(milestone.canonical_bug_id)
             if other_milestone is not None:
@@ -134,7 +143,7 @@ class Config:
         if not isinstance(value, dict):
             raise ConfigParseError(
                 f"person entry for {identifier!r} must be a table")
-        aliases = set()
+        aliases = OrderedSet()
         email = None
         output_markdown_file = None
         for k, v in value.items():
@@ -220,7 +229,7 @@ class Config:
         self.canonical_bug_ids
 
     @staticmethod
-    def _from_toml(parsed_toml: Dict[str, Any]) -> "Config":
+    def _from_toml(parsed_toml: Mapping[str, Any]) -> "Config":
         people = None
         bugzilla_url = None
         milestones = None