f"bug #{self.bug_id}: {self.msg}"
+class BudgetGraphUnknownAssignee(BudgetGraphParseError):
+ def __init__(self, bug_id: int, assignee: str):
+ super().__init__(bug_id)
+ self.assignee = assignee
+
+ def __str__(self):
+ return f"Bug #{self.bug_id} is assigned to an unknown person: " \
+ f"{self.assignee!r}"
+
+
class BudgetGraphLoopError(BudgetGraphBaseError):
def __init__(self, bug_ids: List[int]):
self.bug_ids = bug_ids
new_err = BudgetGraphUnknownStatus(self.bug.id, self.bug.status)
raise new_err.with_traceback(sys.exc_info()[2])
+ @cached_property
+ def assignee(self) -> Person:
+ try:
+ return self.graph.config.all_names[self.bug.assigned_to]
+ except KeyError:
+ raise BudgetGraphUnknownAssignee(self.bug.id,
+ self.bug.assigned_to) \
+ .with_traceback(sys.exc_info()[2])
+
@cached_property
def bug_url(self) -> str:
return f"{self.graph.config.bugzilla_url_stripped}/show_bug.cgi?" \
status = repr(self.status)
except BudgetGraphBaseError:
status = f"<unknown status: {self.bug.status!r}>"
+ try:
+ assignee = f"Person<{self.assignee.identifier!r}>"
+ except BudgetGraphBaseError:
+ assignee = f"<unknown assignee: {self.bug.assigned_to!r}>"
immediate_children = []
for i in self.immediate_children:
immediate_children.append(_NodeSimpleReprWrapper(i))
f"milestone={milestone}, "
f"immediate_children={immediate_children!r}, "
f"payments={payments!r}, "
- f"status={status})")
+ f"status={status}, "
+ f"assignee={assignee})")
class BudgetGraphError(BudgetGraphBaseError):
except BudgetGraphBaseError as e:
errors.append(e)
+ try:
+ # check for assignee errors
+ node.assignee
+ except BudgetGraphBaseError as e:
+ errors.append(e)
+
if node.milestone_str != root.milestone_str:
errors.append(BudgetGraphMilestoneMismatch(
node.bug.id, root.bug.id))