From: Plom Heller Date: Sun, 4 Oct 2026 17:29:55 +0000 (+0200) Subject: Underscore names not meant to be shared. X-Git-Url: https://plomlompom.com/repos/booking/do_day?a=commitdiff_plain;h=87c452694b95a9a82776fd8415c0aeb18e45e9aa;p=bricksplom Underscore names not meant to be shared. --- diff --git a/src/bricksplom/ldraw.py b/src/bricksplom/ldraw.py index 4fa56bc..3fb10d2 100644 --- a/src/bricksplom/ldraw.py +++ b/src/bricksplom/ldraw.py @@ -7,7 +7,7 @@ from typing import Any, Callable, NamedTuple, Optional, Self # ourselves from bricksplom.constants import CHAR_NEWLINE, NUMBER_UNSET -LDRAW_STUDS = { +_LDRAW_STUDS = { 'stud.dat', 'studa.dat', 'stud2.dat', @@ -161,7 +161,7 @@ class LdrawDb: if jdx != idx and row[jdx] != 0]: do_ignore = True break - return (int((not do_ignore) and ref in LDRAW_STUDS) or walk(), ) + return (int((not do_ignore) and ref in _LDRAW_STUDS) or walk(), ) return self._walk_tree(filename, collect=count_studs, diff --git a/src/bricksplom/misc.py b/src/bricksplom/misc.py index 0bbe80e..ff8c5b3 100644 --- a/src/bricksplom/misc.py +++ b/src/bricksplom/misc.py @@ -9,53 +9,53 @@ from typing import Any, Callable, Optional, Self from bricksplom.constants import CHAR_NEWLINE, NUMBER_UNSET from bricksplom.ldraw import LdrawDb, LdrawPathFailure, LdrawRefsTree, XYZ -CHAR_SEP_TOKEN = ' ' -CHAR_COMMENT = '#' -CHAR_DESIGN_ALT = '=' -CHAR_ATTR_EQ = '=' -CHAR_ATTR_LESS = '<' -CHAR_ATTR_MORE = '>' -CHAR_TEXTCONTAINS = ':' -SEP_DESIGN_DESC = '#' -CHAR_COLL_INDENT = ' ' +_CHAR_SEP_TOKEN = ' ' +_CHAR_COMMENT = '#' +_CHAR_DESIGN_ALT = '=' +_CHAR_ATTR_EQ = '=' +_CHAR_ATTR_LESS = '<' +_CHAR_ATTR_MORE = '>' +_CHAR_TEXTCONTAINS = ':' +_SEP_DESIGN_DESC = '#' +_CHAR_COLL_INDENT = ' ' CHAR_SEP_LDRAW_MODES = ',' -CHAR_COLL_IN = '+' -CHAR_COLL_OUT = '-' -CHAR_COLL_INACTIVE = '#' -CHAR_COLL_SEP_COLUMN = '-' -CHAR_COLL_SEP_PAGE = '=' -CHAR_COL_SOLID = '+' -CHAR_COL_TRANSPARENT = '-' -BOX_PREFIX = 'box:' +_CHAR_COLL_IN = '+' +_CHAR_COLL_OUT = '-' +_CHAR_COLL_INACTIVE = '#' +_CHAR_COLL_SEP_COLUMN = '-' +_CHAR_COLL_SEP_PAGE = '=' +_CHAR_COL_SOLID = '+' +_CHAR_COL_TRANSPARENT = '-' +_BOX_PREFIX = 'box:' ARG_QMARK = '?' -PARAM_Q_ID = f'id{CHAR_ATTR_EQ}' -MATCH_OPERATORS = { - CHAR_ATTR_EQ, - CHAR_TEXTCONTAINS, - CHAR_ATTR_LESS, - CHAR_ATTR_MORE +PARAM_Q_ID = f'id{_CHAR_ATTR_EQ}' +_MATCH_OPERATORS = { + _CHAR_ATTR_EQ, + _CHAR_TEXTCONTAINS, + _CHAR_ATTR_LESS, + _CHAR_ATTR_MORE } -TOK_SORT_BOX = 'box' -TOK_SORT_ID = 'id' - -LDRAW_MODE_FILL_N_STUDS = 'fill_n_studs' -LDRAW_MODE_FILL_PATHS = 'fill_paths' -LDRAW_MODE_FILL_SIZES = 'fill_sizes' -LDRAW_MODE_VERIFY_N_STUDS = 'verify_n_studs' -LDRAW_MODE_VERIFY_PATHS = 'verify_paths' -LDRAW_MODES = {LDRAW_MODE_FILL_N_STUDS, - LDRAW_MODE_FILL_PATHS, - LDRAW_MODE_FILL_SIZES, - LDRAW_MODE_VERIFY_N_STUDS, - LDRAW_MODE_VERIFY_PATHS} - -BrickListing = tuple[int, str, str] # count, ID, comment -PageColumn = tuple[BrickListing, ...] -Page = tuple[PageColumn, ...] - - -class Textfiled(ABC): +_TOK_SORT_BOX = 'box' +_TOK_SORT_ID = 'id' + +_LDRAW_MODE_FILL_N_STUDS = 'fill_n_studs' +_LDRAW_MODE_FILL_PATHS = 'fill_paths' +_LDRAW_MODE_FILL_SIZES = 'fill_sizes' +_LDRAW_MODE_VERIFY_N_STUDS = 'verify_n_studs' +_LDRAW_MODE_VERIFY_PATHS = 'verify_paths' +LDRAW_MODES = {_LDRAW_MODE_FILL_N_STUDS, + _LDRAW_MODE_FILL_PATHS, + _LDRAW_MODE_FILL_SIZES, + _LDRAW_MODE_VERIFY_N_STUDS, + _LDRAW_MODE_VERIFY_PATHS} + +_BrickListing = tuple[int, str, str] # count, ID, comment +_PageColumn = tuple[_BrickListing, ...] +_Page = tuple[_PageColumn, ...] + + +class _Textfiled(ABC): 'Table to be read from textfile, and compatible output in .raw().' @staticmethod @@ -67,7 +67,7 @@ class Textfiled(ABC): return tuple(line.rstrip() for line in joined_path.read_text(encoding='utf8' ).split(CHAR_NEWLINE) - if line.strip() and not line.startswith(CHAR_COMMENT)) + if line.strip() and not line.startswith(_CHAR_COMMENT)) @staticmethod def tokify( @@ -81,8 +81,8 @@ class Textfiled(ABC): if len(collected) == len_expected - 1: tok = body else: - assert CHAR_SEP_TOKEN in body, body - tok, body = body.split(CHAR_SEP_TOKEN, maxsplit=1) + assert _CHAR_SEP_TOKEN in body, body + tok, body = body.split(_CHAR_SEP_TOKEN, maxsplit=1) collected += [tok] return tuple(collected) @@ -105,7 +105,7 @@ class Textfiled(ABC): return self.raw() -class WithDb: +class _WithDb: 'Add db:Optional[BricksDB] field to __init__, setting .db.' def __init__( @@ -117,7 +117,7 @@ class WithDb: super().__init__(**kwargs) -class Lookupable: +class _Lookupable: 'Provides methods for BricksDb.lookup and .id_ padding.' _id_indent: int = 0 id_: str @@ -152,7 +152,7 @@ class Lookupable: 'most commonly relevant infos', lambda item: item.show()) } - if issubclass(cls, Textfiled): + if issubclass(cls, _Textfiled): formatters['raw'] = ( 'in source-file format', lambda item: item.raw()) @@ -164,14 +164,14 @@ class Lookupable: ) -> dict[str, tuple[str, dict[str, Callable[[Self, str], bool]]]]: 'Available lookup matchers.' return { - TOK_SORT_ID: ( + _TOK_SORT_ID: ( 'ID of individual item', - {CHAR_ATTR_EQ: ( + {_CHAR_ATTR_EQ: ( lambda item, val: item.id_ == val)} ), 'text': ( 'text contained in item description', - {CHAR_TEXTCONTAINS: ( + {_CHAR_TEXTCONTAINS: ( lambda item, val: val.upper() in item.show().upper())} ), } @@ -220,7 +220,7 @@ class Lookupable: tuple[Self, ...]]]]: 'Available sorters.' return { - TOK_SORT_ID: ( + _TOK_SORT_ID: ( 'by individual items\' IDs', lambda _, pre_sorted: tuple(sorted(pre_sorted, @@ -228,7 +228,7 @@ class Lookupable: } -class BrickColor(Textfiled, Lookupable, WithDb): +class _BrickColor(_Textfiled, _Lookupable, _WithDb): 'Color incl. solidness/transparency field.' _id_indent = 3 @@ -255,8 +255,8 @@ class BrickColor(Textfiled, Lookupable, WithDb): for id_, desc in [cls.tokify(line, 2) for line in cls.lines_of(path)]: assert id_ not in collected assert len(desc) > 1 - assert desc[0] in {CHAR_COL_SOLID, CHAR_COL_TRANSPARENT} - collected[id_] = cls(id_, desc[0] == CHAR_COL_SOLID, desc[1:], + assert desc[0] in {_CHAR_COL_SOLID, _CHAR_COL_TRANSPARENT} + collected[id_] = cls(id_, desc[0] == _CHAR_COL_SOLID, desc[1:], db=db) return collected @@ -266,13 +266,13 @@ class BrickColor(Textfiled, Lookupable, WithDb): ) -> dict[str, tuple[str, Callable[['BricksDb', tuple[Self, ...]], tuple[Self, ...]]]]: - return super().sorters() | {TOK_SORT_BOX: cls._by_box_sorter('color')} + return super().sorters() | {_TOK_SORT_BOX: cls._by_box_sorter('color')} def show( self ) -> str: def idx_in_sample_set( - pages: tuple[Page, ...] + pages: tuple[_Page, ...] ) -> str: for idx, page in enumerate(pages): for jdx, column in enumerate(page): @@ -291,13 +291,13 @@ class BrickColor(Textfiled, Lookupable, WithDb): self ) -> str: return (f'{self.id_indented()} ' - + (CHAR_COL_SOLID if self.solid else CHAR_COL_TRANSPARENT) + + (_CHAR_COL_SOLID if self.solid else _CHAR_COL_TRANSPARENT) + self.wavelength) @dataclass -class BrickDesignData: - 'Lookupables for BrickDesign besides .id.' +class _BrickDesignData: + 'Lookupables for _BrickDesign besides .id.' n_studs: int = dc_field(default=NUMBER_UNSET, metadata={ 'usage': 'number of studs'}) description: str = dc_field(default='?', metadata={ @@ -350,17 +350,17 @@ class BrickDesignData: cls, text: str ) -> Self: - 'Parse from format expected by BrickDesign.from_textfile.' - assert SEP_DESIGN_DESC in text - parts = text.split(SEP_DESIGN_DESC, maxsplit=1) + 'Parse from format expected by _BrickDesign.from_textfile.' + assert _SEP_DESIGN_DESC in text + parts = text.split(_SEP_DESIGN_DESC, maxsplit=1) attributables = cls.sortables() attrs = cls(description=parts[-1]) metadata = parts[0].rstrip() if len(parts) > 1 else '' - for attr in [a for a in metadata.split(CHAR_SEP_TOKEN) if a]: - assert CHAR_ATTR_EQ in attr, attr - a_key, a_val_str = attr.split(CHAR_ATTR_EQ, maxsplit=1) + for attr in [a for a in metadata.split(_CHAR_SEP_TOKEN) if a]: + assert _CHAR_ATTR_EQ in attr, attr + a_key, a_val_str = attr.split(_CHAR_ATTR_EQ, maxsplit=1) assert a_key in attributables - if a_val_str[:1] == CHAR_ATTR_EQ: + if a_val_str[:1] == _CHAR_ATTR_EQ: a_val_str = a_val_str[1:] attrs.secure((a_key)) if attributables[a_key] is int: @@ -375,7 +375,7 @@ class BrickDesignData: return attrs -class BrickDesign(Textfiled, WithDb, Lookupable): +class _BrickDesign(_Textfiled, _WithDb, _Lookupable): 'Shape and texture configurations with descriptions and equalities.' _id_indent = 6 alternate_to: Optional[Self] = None @@ -383,7 +383,7 @@ class BrickDesign(Textfiled, WithDb, Lookupable): def __init__( self, id_: str, - attrs: Optional[BrickDesignData] = None, + attrs: Optional[_BrickDesignData] = None, **kwargs ) -> None: self.id_ = id_ @@ -392,7 +392,7 @@ class BrickDesign(Textfiled, WithDb, Lookupable): super().__init__(**kwargs) def __getattribute__(self, key: str): - if key in BrickDesignData.__annotations__ or key == 'secured': + if key in _BrickDesignData.__annotations__ or key == 'secured': if self.direct_attrs: attrs = self.direct_attrs else: @@ -413,8 +413,8 @@ class BrickDesign(Textfiled, WithDb, Lookupable): self, attr_name: str ) -> bool: - 'Compare current attribute value to BrickDesignData default.' - return getattr(self, attr_name) == getattr(BrickDesignData, attr_name) + 'Compare current attribute value to _BrickDesignData default.' + return getattr(self, attr_name) == getattr(_BrickDesignData, attr_name) @classmethod def formatters( @@ -473,13 +473,13 @@ class BrickDesign(Textfiled, WithDb, Lookupable): ) -> float: assert q_body.isdigit() return int(q_body) - float(getattr(item, attr_name)) - return 'by ' + BrickDesignData.usage(attr_name), { - CHAR_ATTR_EQ: lambda item, v: 0 == cmp(item, v), - CHAR_ATTR_LESS: lambda item, v: 0 < cmp(item, v), - CHAR_ATTR_MORE: lambda item, v: 0 > cmp(item, v)} + return 'by ' + _BrickDesignData.usage(attr_name), { + _CHAR_ATTR_EQ: lambda item, v: 0 == cmp(item, v), + _CHAR_ATTR_LESS: lambda item, v: 0 < cmp(item, v), + _CHAR_ATTR_MORE: lambda item, v: 0 > cmp(item, v)} return super().matchers() | { f'{attr_name}': attr_matcher(attr_name) - for attr_name, attr_type in BrickDesignData.sortables().items() + for attr_name, attr_type in _BrickDesignData.sortables().items() if attr_type in {int, float}} @classmethod @@ -498,11 +498,11 @@ class BrickDesign(Textfiled, WithDb, Lookupable): ) -> tuple[Self, ...]: return tuple(sorted(pre_sorted, key=lambda item: getattr(item, attr_name))) - return 'by ' + BrickDesignData.usage(attr_name), f_sort + return 'by ' + _BrickDesignData.usage(attr_name), f_sort return super().sorters()\ - | {TOK_SORT_BOX: cls._by_box_sorter('design')}\ + | {_TOK_SORT_BOX: cls._by_box_sorter('design')}\ | {attr_name: attr_sorter(attr_name) - for attr_name in BrickDesignData.sortables().keys()} + for attr_name in _BrickDesignData.sortables().keys()} @classmethod def from_textfile( @@ -517,14 +517,14 @@ class BrickDesign(Textfiled, WithDb, Lookupable): for line in cls.lines_of(path)]: assert design_id not in collected, design_id assert len(body) > 1 - if body[0] == CHAR_DESIGN_ALT: + if body[0] == _CHAR_DESIGN_ALT: alt_id = body[1:] alts[alt_id] = alts.get(alt_id, set()) alts[alt_id].add(design_id) collected[design_id] = cls(design_id, db=db) else: collected[design_id] = cls( - design_id, db=db, attrs=BrickDesignData.from_text(body)) + design_id, db=db, attrs=_BrickDesignData.from_text(body)) for id_, alternate_ids in alts.items(): collected[id_].alternate_ids = alternate_ids for alt_id in alternate_ids: @@ -536,17 +536,17 @@ class BrickDesign(Textfiled, WithDb, Lookupable): ) -> str: raw = f'{self.id_indented()} ' if self.alternate_to: - return f'{raw}{CHAR_DESIGN_ALT}{self.alternate_to.id_}' + return f'{raw}{_CHAR_DESIGN_ALT}{self.alternate_to.id_}' attrs = [] - for attr_key in [k for k in BrickDesignData.sortables() + for attr_key in [k for k in _BrickDesignData.sortables() if k != 'description' and not self.at_default(k)]: - operator = CHAR_ATTR_EQ * (1 + int(self.secured(attr_key))) + operator = _CHAR_ATTR_EQ * (1 + int(self.secured(attr_key))) attrs += [f'{attr_key}{operator}{getattr(self, attr_key)}'] - attrs += [f'{SEP_DESIGN_DESC}{self.description}'] - return f'{raw}{CHAR_SEP_TOKEN.join(attrs)}' + attrs += [f'{_SEP_DESIGN_DESC}{self.description}'] + return f'{raw}{_CHAR_SEP_TOKEN.join(attrs)}' -class Brick(Textfiled, WithDb, Lookupable): +class _Brick(_Textfiled, _WithDb, _Lookupable): 'Individual configuration of design and color.' _id_indent = 7 @@ -569,7 +569,7 @@ class Brick(Textfiled, WithDb, Lookupable): cls ) -> dict[str, tuple[str, Callable[['BricksDb', tuple[Self, ...]], tuple[Self, ...]]]]: - return super().sorters() | {TOK_SORT_BOX: cls._by_box_sorter()} + return super().sorters() | {_TOK_SORT_BOX: cls._by_box_sorter()} @classmethod def from_textfile( @@ -582,7 +582,7 @@ class Brick(Textfiled, WithDb, Lookupable): for toks in [cls.tokify(line, 3) for line in cls.lines_of(path)]: brick_id, design_id = toks[:2] assert brick_id not in collected, brick_id - color_id, comment = (toks[-1].split(CHAR_SEP_TOKEN, maxsplit=1) + color_id, comment = (toks[-1].split(_CHAR_SEP_TOKEN, maxsplit=1) + [''])[:2] collected[brick_id] = cls(brick_id, design_id, color_id, comment, db=db) @@ -592,8 +592,8 @@ class Brick(Textfiled, WithDb, Lookupable): self ) -> str: return (f'{self.id_indented()} ' - f'{BrickDesign.indent_id(self.design_id)} ' - f'{BrickColor.indent_id(self.color_id)} {self.comment}' + f'{_BrickDesign.indent_id(self.design_id)} ' + f'{_BrickColor.indent_id(self.color_id)} {self.comment}' ).rstrip() def __str__( @@ -603,11 +603,11 @@ class Brick(Textfiled, WithDb, Lookupable): color = str(self.db.colors[self.color_id]).strip() comment = f' # {self.comment}' if self.comment else '' return (f'{self.id_indented()} ' - f'{BrickDesign.indent_id(self.design_id)} ' + f'{_BrickDesign.indent_id(self.design_id)} ' f'{design.description} ({color}){comment}') -class BrickSet(Textfiled, WithDb, Lookupable): +class BrickSet(_Textfiled, _WithDb, _Lookupable): 'Named collection of bricks in order of pages of columns of counts.' def __init__( @@ -615,7 +615,7 @@ class BrickSet(Textfiled, WithDb, Lookupable): id_: str, is_in: Optional[bool], description: str, - brick_listings: tuple[Page, ...], + brick_listings: tuple[_Page, ...], **kwargs ) -> None: self.id_ = id_ @@ -633,28 +633,28 @@ class BrickSet(Textfiled, WithDb, Lookupable): ) -> dict[str, Self]: collected: dict[str, tuple[Optional[bool], str, - list[list[list[BrickListing]]]]] + list[list[list[_BrickListing]]]]] collected = {} - i_listings: list[list[list[BrickListing]]] = [[[]]] + i_listings: list[list[list[_BrickListing]]] = [[[]]] for line in cls.lines_of(path): - if not line.startswith(CHAR_COLL_INDENT): + if not line.startswith(_CHAR_COLL_INDENT): id_, metadata = cls.tokify(line, 2) assert metadata - assert metadata[0] in {CHAR_COLL_IN, - CHAR_COLL_OUT, - CHAR_COLL_INACTIVE} - is_in = (None if metadata[0] == CHAR_COLL_INACTIVE - else metadata[0] == CHAR_COLL_IN) + assert metadata[0] in {_CHAR_COLL_IN, + _CHAR_COLL_OUT, + _CHAR_COLL_INACTIVE} + is_in = (None if metadata[0] == _CHAR_COLL_INACTIVE + else metadata[0] == _CHAR_COLL_IN) i_listings = [[[]]] collected[id_] = is_in, metadata[1:], i_listings - elif line[1:2] == CHAR_COLL_SEP_COLUMN: + elif line[1:2] == _CHAR_COLL_SEP_COLUMN: i_listings[-1] += [[]] - elif line[1:2] == CHAR_COLL_SEP_PAGE: + elif line[1:2] == _CHAR_COLL_SEP_PAGE: i_listings += [[[]]] else: count, remainder = cls.tokify(line, 2) assert count.isdigit() - id_, comment = (remainder.split(CHAR_SEP_TOKEN, maxsplit=1) + id_, comment = (remainder.split(_CHAR_SEP_TOKEN, maxsplit=1) + [''])[:2] assert len(id_) > 0 i_listings[-1][-1] += [(int(count), id_, comment)] @@ -671,8 +671,8 @@ class BrickSet(Textfiled, WithDb, Lookupable): def _is_in_str( self ) -> str: - return (CHAR_COLL_INACTIVE if self.is_in is None - else (CHAR_COLL_IN if self.is_in else CHAR_COLL_OUT)) + return (_CHAR_COLL_INACTIVE if self.is_in is None + else (_CHAR_COLL_IN if self.is_in else _CHAR_COLL_OUT)) def raw( self @@ -680,7 +680,7 @@ class BrickSet(Textfiled, WithDb, Lookupable): return (f'{self.id_indented()} ' f'{self._is_in_str}{self.description}{CHAR_NEWLINE}' + self._format_paginated(lambda count, p_id, comment: - f' {count:4} {Brick.indent_id(p_id)}' + f' {count:4} {_Brick.indent_id(p_id)}' + (f' {comment}' if comment else ''))) def __str__( @@ -703,9 +703,9 @@ class BrickSet(Textfiled, WithDb, Lookupable): lines += [format_line(count, brick_id, comment)] return CHAR_NEWLINE.join(lines) + CHAR_NEWLINE - def brick_listings_flat(self) -> tuple[BrickListing, ...]: + def brick_listings_flat(self) -> tuple[_BrickListing, ...]: 'Flattened variant of .brick_listings, no division into pages/cols.' - collected: list[BrickListing] = [] + collected: list[_BrickListing] = [] for page in self.brick_listings: for column in page: collected += list(column) @@ -720,9 +720,9 @@ class BrickSet(Textfiled, WithDb, Lookupable): design_id = brick.design_id tail_comment = f' # {comment}' if comment else '' color = str(self.db.colors[self.db.bricks[brick_id].color_id] - ).lstrip().split(CHAR_SEP_TOKEN, maxsplit=1)[1] + ).lstrip().split(_CHAR_SEP_TOKEN, maxsplit=1)[1] if to_boxes: - box: Optional[Box] = None + box: Optional[_Box] = None for i_box in self.db.boxes.values(): for idx_in_box in [ idx for idx, d_to_ls @@ -744,13 +744,13 @@ class BrickSet(Textfiled, WithDb, Lookupable): if box: break box_listing = ((box.id_indented() if box - else Box.indent_id('')) + else _Box.indent_id('')) + ':' + (f'{idx_in_box:>2}' if box else '__')) else: box_listing = '' return ( - f'{count:>2}× {Brick.indent_id(brick_id)}:' - f'{BrickDesign.indent_id(design_id)} {box_listing} {color} ' + f'{count:>2}× {_Brick.indent_id(brick_id)}:' + f'{_BrickDesign.indent_id(design_id)} {box_listing} {color} ' + self.db.designs[design_id].description + tail_comment) return f'{self}{CHAR_NEWLINE}{self._format_paginated(format_line)}' @@ -767,7 +767,7 @@ class BrickSet(Textfiled, WithDb, Lookupable): } -class Box(WithDb, Lookupable): +class _Box(_WithDb, _Lookupable): 'Order of designs.' _id_indent = 5 @@ -780,7 +780,7 @@ class Box(WithDb, Lookupable): super().__init__(**kwargs) self.id_ = id_ self._set = bricks_set - designed_listings: list[tuple[BrickDesign, list[BrickListing]]] = [] + designed_listings: list[tuple[_BrickDesign, list[_BrickListing]]] = [] for listing in self.brick_listings_flat(): design = self.db.designs[self.db.bricks[listing[1]].design_id] design = design.alternate_to or design @@ -800,7 +800,7 @@ class Box(WithDb, Lookupable): def brick_listings_flat( self - ) -> tuple[BrickListing, ...]: + ) -> tuple[_BrickListing, ...]: 'Shortcut to BrickSet method of same name.' return self._set.brick_listings_flat() @@ -813,23 +813,24 @@ class Box(WithDb, Lookupable): 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} ' - f'# {comment}'] + lines += [ + f'{count:>2}× {_Brick.indent_id(brick_id)} / {color} ' + f'# {comment}'] return CHAR_NEWLINE.join(lines) class BricksDb: 'Collection of all the tables enabling their combined processing.' - lookupables: dict[str, type[Lookupable]] = { - 'boxes': Box, - 'bricks': Brick, - 'colors': BrickColor, - 'designs': BrickDesign, + lookupables: dict[str, type[_Lookupable]] = { + 'boxes': _Box, + 'bricks': _Brick, + 'colors': _BrickColor, + 'designs': _BrickDesign, 'sets': BrickSet } - bricks: dict[str, Brick] - colors: dict[str, BrickColor] - designs: dict[str, BrickDesign] + bricks: dict[str, _Brick] + colors: dict[str, _BrickColor] + designs: dict[str, _BrickDesign] sets: dict[str, BrickSet] def __init__( @@ -841,13 +842,13 @@ class BricksDb: ) -> None: self._name_set_colors = name_set_colors for name, cls in [(name, cls) for name, cls in self.lookupables.items() - if issubclass(cls, Textfiled)]: - kwargs = {'db': self} if issubclass(cls, WithDb) else {} + if issubclass(cls, _Textfiled)]: + kwargs = {'db': self} if issubclass(cls, _WithDb) else {} setattr(self, name, cls.from_textfile((path_tables, f'{name}.txt'), **kwargs)) self.ldraw = LdrawDb(Path(path_ldraw)) self._ldraw_modes = ldraw_modes.split(CHAR_SEP_LDRAW_MODES) - if LDRAW_MODE_FILL_PATHS in self._ldraw_modes: + if _LDRAW_MODE_FILL_PATHS in self._ldraw_modes: for design in [design for design in self.designs.values() if not (design.alternate_to or design.ldraw)]: filename = f'{design.id_}.dat' @@ -861,12 +862,12 @@ class BricksDb: design.direct_attrs.ldraw = filename self._check_consistencies() for design in self._designs_ldrawed(): - if LDRAW_MODE_FILL_N_STUDS in self._ldraw_modes\ + if _LDRAW_MODE_FILL_N_STUDS in self._ldraw_modes\ and design.at_default('n_studs'): assert design.direct_attrs is not None design.direct_attrs.n_studs\ = self.ldraw.count_studs(design.ldraw) - if LDRAW_MODE_FILL_SIZES in self._ldraw_modes: + if _LDRAW_MODE_FILL_SIZES in self._ldraw_modes: xyz_calc = XYZ() for k in [k for k in ('x', 'y', 'z') if design.at_default(k)]: if set(xyz_calc) == {NUMBER_UNSET}: @@ -876,18 +877,18 @@ class BricksDb: @property def boxes( self - ) -> dict[str, Box]: - 'Parsed from BOX_PREFIX-prefixed entries in .sets.' + ) -> dict[str, _Box]: + 'Parsed from _BOX_PREFIX-prefixed entries in .sets.' collected = {} for bricks_set in [c for c in self.sets.values() - if c.id_.startswith(BOX_PREFIX)]: - box_id = bricks_set.id_[len(BOX_PREFIX):] - collected[box_id] = Box(box_id, bricks_set, db=self) + if c.id_.startswith(_BOX_PREFIX)]: + box_id = bricks_set.id_[len(_BOX_PREFIX):] + collected[box_id] = _Box(box_id, bricks_set, db=self) return collected def _designs_ldrawed( self - ) -> tuple[BrickDesign, ...]: + ) -> tuple[_BrickDesign, ...]: return tuple(design for design in self.designs.values() if (not design.alternate_to) and design.ldraw and design.ldraw != '!') @@ -934,13 +935,13 @@ class BricksDb: for design in self._designs_ldrawed(): # hunt for dangling Design.ldraw references - if LDRAW_MODE_VERIFY_PATHS in self._ldraw_modes: + if _LDRAW_MODE_VERIFY_PATHS in self._ldraw_modes: if not self.ldraw.path(design.ldraw).exists(): fails += ['unresolved ldraw reference for design of ID: ' f'{design.id_} ({design.ldraw})'] continue # compare n_studs calculations to explicit records - if LDRAW_MODE_VERIFY_N_STUDS in self._ldraw_modes\ + if _LDRAW_MODE_VERIFY_N_STUDS in self._ldraw_modes\ and design.n_studs > -1\ and not design.secured('n_studs'): studs_counted = self.ldraw.count_studs(design.ldraw) @@ -968,7 +969,7 @@ class BricksDb: for instruction in match_by: match_key = match_val = match_operator = '' for idx, c in enumerate(instruction): - if c in MATCH_OPERATORS: + if c in _MATCH_OPERATORS: match_operator = c match_val = instruction[idx+1:] break