From: Christian Heller Date: Thu, 29 Jan 2026 01:34:57 +0000 (+0100) Subject: Fix error calculation for lines without amount and currency, simplify code. X-Git-Url: https://plomlompom.com/repos/booking/%7B%7B%20web_path%20%7D%7D/static/%7B%7Bdb.prefix%7D%7D/condition?a=commitdiff_plain;ds=inline;p=ledgplom Fix error calculation for lines without amount and currency, simplify code. --- diff --git a/src/ledgplom/ledger.py b/src/ledgplom/ledger.py index ac6acff..7d26eae 100644 --- a/src/ledgplom/ledger.py +++ b/src/ledgplom/ledger.py @@ -1,13 +1,10 @@ 'Actual ledger classes.' # standard libs -from abc import ABC +from abc import ABC, abstractmethod from datetime import date as dt_date from decimal import Decimal, InvalidOperation as DecimalInvalidOperation from pathlib import Path -from typing import Any, Generic, Iterator, Optional, Self, TypeVar - - -_TypeDatLine = TypeVar('_TypeDatLine', bound='_DatLine') +from typing import Any, Iterator, Optional, Self _INDENT_CHARS = {' ', '\t'} @@ -204,10 +201,9 @@ class _BookingLine(_DatLine, ABC): for idx in range(maxsplit)) @property + @abstractmethod def errors(self) -> tuple[str, ...]: 'Whatever is wrong with the respective line.' - return tuple(f'{name} empty' for name in self._field_names - if not getattr(self, name)) class _IntroLine(_BookingLine): @@ -226,7 +222,8 @@ class _IntroLine(_BookingLine): @property def errors(self) -> tuple[str, ...]: - errors = list(super().errors) + errors = [f'{name} empty' for name in self._field_names + if not getattr(self, name)] if self.indent: errors += ['intro line indented'] try: @@ -263,9 +260,11 @@ class _TransferLine(_BookingLine): @property def errors(self) -> tuple[str, ...]: - errors = list(super().errors) + errors = [] # if not self.indent: # errors += ['transfer line not indented'] + if not self.account: + errors += ['account missing'] if isinstance(self.amount, str): errors += [f'improper amount value: {self.amount}'] if len(self.currency.split()) > 1: @@ -284,18 +283,18 @@ class _TransferLine(_BookingLine): return '' -class _LinesBlock(Generic[_TypeDatLine]): - _lines: list[_TypeDatLine] +class _LinesBlock: + _lines: list[_DatLine] def __init__(self) -> None: self._lines = [] @property - def lines(self) -> tuple[_TypeDatLine, ...]: + def lines(self) -> tuple[_DatLine, ...]: 'Return collected lines.' return tuple(self._lines) - def add(self, lines: tuple[_TypeDatLine, ...], at_end=True) -> None: + def add(self, lines: tuple[_DatLine, ...], at_end=True) -> None: 'Grow block downwards by this one DatLine.' if at_end: self._lines += lines @@ -303,7 +302,7 @@ class _LinesBlock(Generic[_TypeDatLine]): self._lines[0:0] = list(lines) -class _Booking(_LinesBlock[_BookingLine]): +class _Booking(_LinesBlock): @property def _sink_account(self) -> str: @@ -382,7 +381,7 @@ class _Booking(_LinesBlock[_BookingLine]): return self.intro_line.target -class _DatBlock(_LinesBlock[_DatLine]): +class _DatBlock(_LinesBlock): 'Unit of lines with optional .booking, and (possibly zero) .gap_lines.' _prev: Optional[Self] = None _next: Optional[Self] = None @@ -433,7 +432,7 @@ class _DatBlock(_LinesBlock[_DatLine]): @property def booking(self) -> Optional[_Booking]: 'Booking made from lines indented or with code.' - booking_lines = tuple(_BookingLine(line.raw) for line in self.lines + booking_lines = tuple(_DatLine(line.raw) for line in self.lines if line.indent or line.code) if not booking_lines: return None