From: Plom Heller Date: Sat, 13 Jun 2026 16:39:49 +0000 (+0200) Subject: Simplify BrickDesign attributes linkage. X-Git-Url: https://plomlompom.com/repos/%22https:/validator.w3.org/te%22st.html?a=commitdiff_plain;h=8037a6ce2c4162fb396655f6fabed848bbb40530;p=bricksplom Simplify BrickDesign attributes linkage. --- diff --git a/bricksplom.py b/bricksplom.py index cfe67b8..eaff95c 100755 --- a/bricksplom.py +++ b/bricksplom.py @@ -2,6 +2,7 @@ 'Data structures for managing/sorting bricks of a certain kind.' from abc import ABC, abstractmethod from argparse import ArgumentError, ArgumentParser +from dataclasses import dataclass from os import environ from pathlib import Path from typing import Callable, Optional, Self @@ -227,16 +228,11 @@ class BrickColor(Textfiled, Lookupable): + self.wavelength) +@dataclass class BrickDesignData: - 'Whatever be available in BrickDesign.attrs.' - - def __init__( - self, - n_studs=-1, - description='' - ) -> None: - self.description = description - self.n_studs = n_studs + 'Lookupables for BrickDesign besides .id.' + n_studs: int = -1 + description: str = '' class BrickDesign(Textfiled, Lookupable): @@ -250,18 +246,19 @@ class BrickDesign(Textfiled, Lookupable): attrs: Optional[BrickDesignData] = None ) -> None: self.id_ = id_ - self._attrs = attrs + self.direct_attrs = attrs self.alternate_ids: set[str] = set() - @property - def attrs( - self - ) -> BrickDesignData: - 'Collect from either .alternate_to or ._attrs.' - if self.alternate_to: - return self.alternate_to.attrs - assert self._attrs - return self._attrs + def __getattribute__(self, key: str): + if key in BrickDesignData.__annotations__: + if self.direct_attrs: + attrs = self.direct_attrs + else: + assert self.alternate_to is not None + assert self.alternate_to.direct_attrs is not None + attrs = self.alternate_to.direct_attrs + return getattr(attrs, key) + return super().__getattribute__(key) @property def all_ids( @@ -278,7 +275,7 @@ class BrickDesign(Textfiled, Lookupable): q_body ) -> bool: assert q_body.isdigit() - return self.attrs.n_studs == int(q_body) + return self.n_studs == int(q_body) return super().matchers | {PARAM_Q_STUDS: q_studs} @property @@ -289,7 +286,7 @@ class BrickDesign(Textfiled, Lookupable): return super().sorters | { TOK_SORT_BOX: self._by_box_sorter('design'), TOK_SORT_STUDS: lambda _, pre_sorted: tuple( - sorted(pre_sorted, key=lambda item: item.attrs.n_studs)) + sorted(pre_sorted, key=lambda item: item.n_studs)) } @classmethod @@ -312,14 +309,15 @@ class BrickDesign(Textfiled, Lookupable): else: assert SEP_DESIGN_DESC in body metadata, desc = body.split(SEP_DESIGN_DESC, maxsplit=1) - kwargs: dict[str, str | int] = {'description': desc} + attrs = BrickDesignData(description=desc) + annos = BrickDesignData.__annotations__ for attr in metadata.split(SEP_DESIGN_ATTR): assert CHAR_ATTR_EQ in attr a_key, a_val_str = attr.split(CHAR_ATTR_EQ, maxsplit=1) + assert a_key in annos and annos[a_key] is int assert a_val_str.isdigit() - kwargs[a_key] = int(a_val_str) - collected[design_id] = cls(design_id, - BrickDesignData(**kwargs)) + setattr(attrs, a_key, int(a_val_str)) + collected[design_id] = cls(design_id, attrs) for id_, alternate_ids in alts.items(): collected[id_].alternate_ids = alternate_ids for alt_id in alternate_ids: @@ -332,9 +330,9 @@ class BrickDesign(Textfiled, Lookupable): return ( f'{self.id_indented()} ' + (f'{CHAR_DESIGN_ALT}{self.alternate_to.id_}' if self.alternate_to - else (('' if self.attrs.n_studs < 0 - else f'n_studs{CHAR_ATTR_EQ}{self.attrs.n_studs}') - + f'{SEP_DESIGN_DESC}{self.attrs.description}'))) + else (('' if self.n_studs < 0 + else f'n_studs{CHAR_ATTR_EQ}{self.n_studs}') + + f'{SEP_DESIGN_DESC}{self.description}'))) class Brick(Textfiled, WithDb, Lookupable): @@ -396,7 +394,7 @@ class Brick(Textfiled, WithDb, Lookupable): comment = f' # {self.comment}' if self.comment else '' return (f'{self.id_indented()} ' f'{BrickDesign.indent_id(self.design_id)} ' - f'{design.attrs.description} ({color}){comment}') + f'{design.description} ({color}){comment}') class BrickSet(Textfiled, WithDb, Lookupable): @@ -546,7 +544,7 @@ class BrickSet(Textfiled, WithDb, Lookupable): return ( f'{count:>2}× {Brick.indent_id(brick_id)}:' f'{BrickDesign.indent_id(design_id)} {box_listing} {color} ' - + self._db.designs[design_id].attrs.description + tail_comment) + + self._db.designs[design_id].description + tail_comment) return f'{self}{CHAR_NEWLINE}{self._format_paginated(format_line)}' @@ -596,8 +594,7 @@ class Box(WithDb, Lookupable): lines = [] for design, listings in self.designs_to_listings: lines += [ - f'=== {" / ".join(design.all_ids)}: ' - f'{design.attrs.description} ==='] + f'=== {" / ".join(design.all_ids)}: {design.description} ==='] for count, brick_id, comment in listings: color = self._db.colors[self._db.bricks[brick_id].color_id] lines += [f'{count:>2}× {Brick.indent_id(brick_id)} / {color} '