From: Christian Heller Date: Wed, 22 Jan 2025 12:02:33 +0000 (+0100) Subject: More warning/error/validation code refactoring. X-Git-Url: https://plomlompom.com/repos/%7B%7Bdb.prefix%7D%7D/static/%7B%7Bprefix%7D%7D/booking/condition_descriptions?a=commitdiff_plain;h=d92e8558a11b6efc4c8e6f6d49d261895d040a3f;p=plomledger More warning/error/validation code refactoring. --- diff --git a/ledger.py b/ledger.py index 5fc80a4..51c722b 100755 --- a/ledger.py +++ b/ledger.py @@ -71,7 +71,7 @@ class DatLine: @property def error(self) -> str: """Return error if registered on attempt to parse into BookingLine.""" - return self.booking_line.error if self.booking_line else '' + return '; '.join(self.booking_line.errors) if self.booking_line else '' @property def questionable(self) -> bool: @@ -96,7 +96,7 @@ class BookingLine: """Parsed code part of a DatLine belonging to a Booking.""" def __init__(self, booking: 'Booking') -> None: - self.error = '' + self.errors: list[str] = [] self.booking = booking @@ -106,15 +106,16 @@ class IntroLine(BookingLine): def __init__(self, booking: 'Booking', code: str) -> None: super().__init__(booking) if code[0].isspace(): - self.error = 'intro line indented' + self.errors += ['intro line indented'] toks = code.lstrip().split(maxsplit=1) if len(toks) != 2: - self.error = 'illegal number of tokens' + self.errors += ['illegal number of tokens'] + if len(toks) < 1: return try: dt_date.fromisoformat(toks[0]) except ValueError: - self.error = 'not starting with properly formatted legal date' + self.errors += [f'not properly formatted legal date: {toks[0]}'] class TransferLine(BookingLine): @@ -123,21 +124,20 @@ class TransferLine(BookingLine): def __init__(self, booking: 'Booking', code: str) -> None: super().__init__(booking) if not code[0].isspace(): - self.error = 'transfer line not indented' - return + self.errors += ['transfer line not indented'] toks = code.lstrip().split() self.account = toks[0] self.amount: Optional[Decimal] = None if 1 == len(toks): self.currency = '' - elif 3 == len(toks): + elif 3 <= len(toks): self.currency = toks[2] try: self.amount = Decimal(toks[1]) except DecimalInvalidOperation: - self.error = 'improper amount value' - else: - self.error = 'illegal number of tokens' + self.errors += [f'improper amount value: {toks[1]}'] + if len(toks) not in {1, 3}: + self.errors += ['illegal number of tokens'] @property def amount_short(self) -> str: @@ -155,34 +155,32 @@ class Booking: def __init__(self, id_: int, dat_lines: list[DatLine]) -> None: self.id_ = id_ - self.dat_lines = dat_lines - self.dat_lines[0].booking_line = IntroLine(self, - self.dat_lines[0].code) - for dat_line in self.dat_lines[1:]: + dat_lines[0].booking_line = IntroLine(self, dat_lines[0].code) + intro_line = dat_lines[0].booking_line + transfer_lines = [] + for dat_line in dat_lines[1:]: dat_line.booking_line = TransferLine(self, dat_line.code) + transfer_lines += [dat_line.booking_line] self.account_changes: dict[str, Wealth] = {} self.sink_account = None changes = Wealth() - for transfer_line in [dl.booking_line for dl in self.dat_lines[1:]]: - assert isinstance(transfer_line, TransferLine) + for transfer_line in [tl for tl in transfer_lines if not tl.errors]: if transfer_line.account not in self.account_changes: self.account_changes[transfer_line.account] = Wealth() if transfer_line.amount is None: if self.sink_account: - transfer_line.error = 'too many sinks' - break + transfer_line.errors += ['too many sinks'] self.sink_account = transfer_line.account continue change = Wealth({transfer_line.currency: transfer_line.amount}) self.account_changes[transfer_line.account] += change changes += change - self.questionable = False if self.sink_account: self.account_changes[self.sink_account] += changes.as_sink elif not changes.sink_empty: - assert self.dat_lines[-1].booking_line is not None - self.dat_lines[-1].booking_line.error = 'needed sink missing' - for dat_line in [dl for dl in self.dat_lines if dl.error]: + transfer_lines[-1].errors += ['needed sink missing'] + self.questionable = False + for _ in [bl for bl in [intro_line] + transfer_lines if bl.errors]: self.questionable = True break