Skip to content

Commit 193421e

Browse files
committed
Refactor all boolean parameters parsing in from_sexpr calls
1 parent ab00808 commit 193421e

15 files changed

Lines changed: 209 additions & 213 deletions

src/kiutils/board.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
from kiutils.utils.sexpr import sexp_prettify as prettify, sexp_to_string, parse_sexp
2828
from kiutils.footprint import Footprint
2929
from kiutils.misc.config import *
30-
from kiutils.utils.parsing_utils import parse_bool, format_bool
30+
from kiutils.utils.parsing_utils import *
3131

3232
@dataclass
3333
class Board():
@@ -333,7 +333,7 @@ def _to_sexpr_raw(self):
333333

334334
# Embedded fonts
335335
if self.embedded_fonts is not None:
336-
expr.append(format_bool_raw('embedded_fonts', self.embedded_fonts, compact=False, yesno=True))
336+
expr.append(format_bool('embedded_fonts', self.embedded_fonts, compact=False, yesno=True))
337337

338338
# Embedded files
339339
if len(self.embedded_files) > 0:

src/kiutils/footprint.py

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from kiutils.utils.string_utils import *
3030
from kiutils.misc.config import *
3131
from kiutils.utils.format_utils import format_float
32-
from kiutils.utils.parsing_utils import parse_bool, format_bool, format_bool_raw
32+
from kiutils.utils.parsing_utils import *
3333

3434
@dataclass
3535
class Attributes():
@@ -62,9 +62,9 @@ class Attributes():
6262
Available since KiCad 7"""
6363

6464
# Available since KiCad v9
65-
# TODO Update docs
6665

6766
dnp: Optional[bool] = None
67+
"""The optional ``dnp`` token indicates that the footprint will not be populated"""
6868

6969
@classmethod
7070
def from_sexpr(cls, exp: list) -> Attributes:
@@ -87,18 +87,15 @@ def from_sexpr(cls, exp: list) -> Attributes:
8787
raise Exception("Expression does not have the correct type")
8888

8989
object = cls()
90-
if len(exp) > 1:
91-
# Attributes token may be set with no other items (empty attributes)
92-
# Test case for this: test_fp_empty_attr.kicad_mod
93-
if exp[1] == 'through_hole' or exp[1] == 'smd':
94-
object.type = exp[1]
95-
9690
for item in exp[1:]:
97-
if parse_bool(item, 'board_only'): object.boardOnly = True
98-
elif parse_bool(item, 'exclude_from_pos_files'): object.excludeFromPosFiles = True
99-
elif parse_bool(item, 'exclude_from_bom'): object.excludeFromBom = True
100-
elif parse_bool(item, 'allow_missing_courtyard'): object.allowMissingCourtyard = True
101-
elif parse_bool(item, 'dnp'): object.dnp = True
91+
if is_bool_key(item, 'board_only'): object.boardOnly = parse_bool(item, 'board_only')
92+
elif is_bool_key(item, 'exclude_from_pos_files'): object.excludeFromPosFiles = parse_bool(item, 'exclude_from_pos_files')
93+
elif is_bool_key(item, 'exclude_from_bom'): object.excludeFromBom = parse_bool(item, 'exclude_from_bom')
94+
elif is_bool_key(item, 'allow_missing_courtyard'): object.allowMissingCourtyard = parse_bool(item, 'allow_missing_courtyard')
95+
elif is_bool_key(item, 'dnp'): object.dnp = parse_bool(item, 'dnp')
96+
elif item in ['through_hole', 'smd']: object.type = item
97+
else:
98+
raise ValueError(f"Unrecognized property key: {item[0]}. Full expression: {item}")
10299

103100
return object
104101

@@ -199,7 +196,7 @@ def from_sexpr(cls, exp: list) -> Model:
199196
object.path = exp[1]
200197

201198
for item in exp[2:]:
202-
if parse_bool(item, 'hide'): object.hide = True
199+
if is_bool_key(item, 'hide'): object.hide = parse_bool(item, 'hide')
203200
elif not isinstance(item, list):
204201
raise ValueError(f"Expected list property [key, value], got: {item}. Full expression: {exp}")
205202
elif item[0] == 'opacity': object.opacity = item[1]
@@ -227,7 +224,7 @@ def to_sexpr(self, indent=2, newline=True) -> str:
227224
def _to_sexpr_raw(self):
228225
expr = ['model', escape_and_quote(self.path)]
229226

230-
expr.append(format_bool_raw('hide', self.hide))
227+
expr.append(format_bool('hide', self.hide))
231228

232229
if self.opacity is not None:
233230
expr.append(['opacity', self.opacity])
@@ -554,8 +551,8 @@ def from_sexpr(cls, exp: list) -> Pad:
554551
object.shape = exp[3]
555552

556553
for item in exp[4:]:
557-
if parse_bool(item, 'locked'): object.locked = True
558-
elif parse_bool(item, 'zone_layer_connections'): object.zone_layer_connections = True
554+
if is_bool_key(item, 'locked'): object.locked = parse_bool(item, 'locked')
555+
elif is_bool_key(item, 'zone_layer_connections'): object.zone_layer_connections = parse_bool(item, 'zone_layer_connections')
559556
elif not isinstance(item, list):
560557
raise ValueError(f"Expected list property [key, value], got: {item}. Full expression: {exp}")
561558
elif item[0] == 'at': object.position = Position().from_sexpr(item)
@@ -623,7 +620,7 @@ def _to_sexpr_raw(self):
623620
self.shape
624621
]
625622

626-
expr.append(format_bool_raw('locked', self.locked))
623+
expr.append(format_bool('locked', self.locked))
627624

628625
pos = ['at', format_float(self.position.X), format_float(self.position.Y)]
629626
if self.position.angle is not None:
@@ -650,7 +647,7 @@ def _to_sexpr_raw(self):
650647
if self.roundrectRatio is not None:
651648
expr.append(['roundrect_rratio', self.roundrectRatio])
652649

653-
expr.append(format_bool_raw('zone_layer_connections', self.zone_layer_connections))
650+
expr.append(format_bool('zone_layer_connections', self.zone_layer_connections))
654651

655652
if self.chamferRatio is not None:
656653
expr.append(['chamfer_ratio', self.chamferRatio])
@@ -927,8 +924,8 @@ def from_sexpr(cls, exp: list) -> Footprint:
927924
object = cls()
928925
object.libId = exp[1]
929926
for item in exp[2:]:
930-
if parse_bool(item, 'locked'): object.locked = True
931-
elif parse_bool(item, 'placed'): object.placed = True
927+
if is_bool_key(item, 'locked'): object.locked = parse_bool(item, 'locked')
928+
elif is_bool_key(item, 'placed'): object.placed = parse_bool(item, 'placed')
932929
elif not isinstance(item, list):
933930
raise ValueError(f"Expected list property [key, value], got: {item}. Full expression: {exp}")
934931
elif item[0] == 'version': object.version = item[1]
@@ -1092,8 +1089,8 @@ def to_sexpr(self, indent=0, newline=True, layerInFirstLine=False) -> str:
10921089
def _to_sexpr_raw(self):
10931090
expr = ['footprint', escape_and_quote(self.libId)]
10941091

1095-
expr.append(format_bool_raw('locked', self.locked))
1096-
expr.append(format_bool_raw('placed', self.placed))
1092+
expr.append(format_bool('locked', self.locked))
1093+
expr.append(format_bool('placed', self.placed))
10971094

10981095
if self.version is not None:
10991096
expr.append(['version', self.version])

src/kiutils/items/brditems.py

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from kiutils.items.common import Position
2222
from kiutils.utils.string_utils import *
2323
from kiutils.utils.format_utils import format_float
24-
from kiutils.utils.parsing_utils import parse_bool, format_bool_raw
24+
from kiutils.utils.parsing_utils import *
2525
from kiutils.utils.sexpr import sexp_to_string
2626

2727
@dataclass
@@ -409,8 +409,8 @@ def from_sexpr(cls, exp: list) -> Stackup:
409409

410410
object = cls()
411411
for item in exp[1:]:
412-
if parse_bool(item, 'castellated_pads'): object.castellatedPads = True
413-
elif parse_bool(item, 'edge_plating'): object.edgePlating = True
412+
if is_bool_key(item, 'castellated_pads'): object.castellatedPads = parse_bool(item, 'castellated_pads')
413+
elif is_bool_key(item, 'edge_plating'): object.edgePlating = parse_bool(item, 'edge_plating')
414414
elif not isinstance(item, list):
415415
raise ValueError(f"Expected list property [key, value], got: {item}. Full expression: {exp}")
416416
elif item[0] == 'layer': object.layers.append(StackupLayer().from_sexpr(item))
@@ -1005,7 +1005,7 @@ def from_sexpr(cls, exp: list) -> Segment:
10051005

10061006
object = cls()
10071007
for item in exp[1:]:
1008-
if parse_bool(item, 'locked'): object.locked = True
1008+
if is_bool_key(item, 'locked'): object.locked = parse_bool(item, 'locked')
10091009
elif not isinstance(item, list):
10101010
raise ValueError(f"Expected list property [key, value], got: {item}. Full expression: {exp}")
10111011
elif item[0] == 'start': object.start = Position().from_sexpr(item)
@@ -1042,7 +1042,7 @@ def _to_sexpr_raw(self):
10421042
]
10431043

10441044
if self.locked:
1045-
expr.append(format_bool_raw("locked", self.locked))
1045+
expr.append(format_bool("locked", self.locked))
10461046

10471047
expr.extend([
10481048
['layer', escape_and_quote(self.layer)],
@@ -1098,9 +1098,9 @@ class Via():
10981098
"""The ``tstamp`` token defines the unique identifier of the via"""
10991099

11001100
# Available since KiCad v9
1101-
# TODO Update docs
11021101

11031102
zone_layer_connections: bool = False
1103+
"""The ``zone_layer_connections`` token indicates which cooper layers are connected"""
11041104

11051105
@classmethod
11061106
def from_sexpr(cls, exp: list) -> Via:
@@ -1124,12 +1124,12 @@ def from_sexpr(cls, exp: list) -> Via:
11241124

11251125
object = cls()
11261126
for item in exp[1:]:
1127-
if parse_bool(item, 'locked'): object.locked = True
1128-
elif parse_bool(item, 'remove_unused_layers'): object.removeUnusedLayers = True
1129-
elif parse_bool(item, 'keepEndLayers'): object.keepEndLayers = True
1130-
elif parse_bool(item, 'free'): object.free = True
1131-
elif parse_bool(item, 'zone_layer_connections'): object.zone_layer_connections = True
1132-
elif not isinstance(item, list) and item in ['micro','blind']: object.type = item
1127+
if is_bool_key(item, 'locked'): object.locked = parse_bool(item, 'locked')
1128+
elif is_bool_key(item, 'remove_unused_layers'): object.removeUnusedLayers = parse_bool(item, 'remove_unused_layers')
1129+
elif is_bool_key(item, 'keepEndLayers'): object.keepEndLayers = parse_bool(item, 'keepEndLayers')
1130+
elif is_bool_key(item, 'free'): object.free = parse_bool(item, 'free')
1131+
elif is_bool_key(item, 'zone_layer_connections'): object.zone_layer_connections = parse_bool(item, 'zone_layer_connections')
1132+
elif not isinstance(item, list) and item in ['micro', 'blind']: object.type = item
11331133
elif not isinstance(item, list):
11341134
raise ValueError(f"Expected list property [key, value], got: {item}. Full expression: {exp}")
11351135
elif item[0] == 'at': object.position = Position().from_sexpr(item)
@@ -1177,16 +1177,16 @@ def _to_sexpr_raw(self):
11771177
expr.append(layer_list)
11781178

11791179
if self.removeUnusedLayers:
1180-
expr.append(format_bool_raw("remove_unused_layers", self.removeUnusedLayers))
1180+
expr.append(format_bool("remove_unused_layers", self.removeUnusedLayers))
11811181

11821182
if self.keepEndLayers:
1183-
expr.append(format_bool_raw("keep_end_layers", self.keepEndLayers))
1183+
expr.append(format_bool("keep_end_layers", self.keepEndLayers))
11841184

11851185
if self.locked:
1186-
expr.append(format_bool_raw("locked", self.locked))
1186+
expr.append(format_bool("locked", self.locked))
11871187

11881188
if self.free:
1189-
expr.append(format_bool_raw("free", self.free))
1189+
expr.append(format_bool("free", self.free))
11901190

11911191
if self.zone_layer_connections:
11921192
expr.append(['zone_layer_connections'])
@@ -1255,7 +1255,7 @@ def from_sexpr(cls, exp: list) -> Arc:
12551255

12561256
object = cls()
12571257
for item in exp[1:]:
1258-
if parse_bool(item, 'locked'): object.locked = True
1258+
if is_bool_key(item, 'locked'): object.locked = parse_bool(item, 'locked')
12591259
elif not isinstance(item, list):
12601260
raise ValueError(f"Expected list property [key, value], got: {item}. Full expression: {exp}")
12611261
elif item[0] == 'start': object.start = Position().from_sexpr(item)
@@ -1288,7 +1288,7 @@ def _to_sexpr_raw(self):
12881288
expr = ['arc']
12891289

12901290
if self.locked:
1291-
expr.append(format_bool_raw("locked", self.locked))
1291+
expr.append(format_bool("locked", self.locked))
12921292

12931293
expr.extend([
12941294
['start', format_float(self.start.X), format_float(self.start.Y)],
@@ -1512,7 +1512,7 @@ def from_sexpr(cls, exp: list) -> Generated:
15121512

15131513
object = cls()
15141514
for item in exp[1:]:
1515-
if parse_bool(item, 'locked'): object.locked = True
1515+
if is_bool_key(item, 'locked'): object.locked = parse_bool(item, 'locked')
15161516
elif not isinstance(item, list):
15171517
raise ValueError(f"Expected list property [key, value], got: {item}. Full expression: {exp}")
15181518
elif item[0] == 'uuid': object.uuid = item[1]
@@ -1583,7 +1583,7 @@ def _to_sexpr_raw(self):
15831583
]
15841584

15851585
if self.locked:
1586-
expr.append(format_bool_raw("locked", self.locked))
1586+
expr.append(format_bool("locked", self.locked))
15871587

15881588
if len(self.base_line) > 0:
15891589
base_line_pts = ['pts']

src/kiutils/items/common.py

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
from kiutils.utils.string_utils import *
2727
from kiutils.utils.format_utils import format_float
28-
from kiutils.utils.parsing_utils import parse_bool, format_bool_raw
28+
from kiutils.utils.parsing_utils import *
2929
from kiutils.utils.sexpr import sexp_to_string
3030

3131
def is_url(path: str) -> bool:
@@ -75,14 +75,13 @@ def from_sexpr(cls, exp: list) -> Position:
7575
object = cls()
7676
object.X = float(exp[1])
7777
object.Y = float(exp[2])
78-
if len(exp) >= 4:
79-
# More than four components means X, Y, and either angle or unlocked are present
80-
if exp[3] != 'unlocked':
78+
if len(exp) > 3:
79+
# More than three components means X, Y, and either angle or unlocked are present
80+
if is_bool_key(exp[3], 'unlocked'):
81+
object.unlocked = parse_bool(exp[3], 'unlocked')
82+
else:
8183
object.angle = exp[3]
8284

83-
for item in exp:
84-
if parse_bool(item, 'unlocked'): object.unlocked = True
85-
8685
return object
8786

8887
def to_sexpr(self) -> str:
@@ -352,8 +351,8 @@ def from_sexpr(cls, exp: list) -> Font:
352351

353352
object = cls()
354353
for item in exp[1:]:
355-
if parse_bool(item, 'bold'): object.bold = True
356-
elif parse_bool(item, 'italic'): object.italic = True
354+
if is_bool_key(item, 'bold'): object.bold = parse_bool(item, 'bold')
355+
elif is_bool_key(item, 'italic'): object.italic = parse_bool(item, 'italic')
357356
elif not isinstance(item, list):
358357
raise ValueError(f"Expected list property [key, value], got: {item}. Full expression: {exp}")
359358
elif item[0] == 'face': object.face = item[1]
@@ -392,13 +391,13 @@ def _to_sexpr_raw(self):
392391
expr.append(['thickness', self.thickness])
393392

394393
if self.bold:
395-
expr.append(format_bool_raw('bold', self.bold))
394+
expr.append(format_bool('bold', self.bold))
396395

397396
if self.color is not None:
398397
expr.append(self.color._to_sexpr_raw())
399398

400399
if self.italic:
401-
expr.append(format_bool_raw('italic', self.italic))
400+
expr.append(format_bool('italic', self.italic))
402401

403402
if self.lineSpacing is not None:
404403
expr.append(['line_spacing', self.lineSpacing])
@@ -529,7 +528,7 @@ def from_sexpr(cls, exp: list) -> Effects:
529528

530529
object = cls()
531530
for item in exp[1:]:
532-
if parse_bool(item, 'hide'): object.hide = True
531+
if is_bool_key(item, 'hide'): object.hide = parse_bool(item, 'hide')
533532
elif not isinstance(item, list):
534533
raise ValueError(f"Expected list property [key, value], got: {item}. Full expression: {exp}")
535534
elif item[0] == 'font': object.font = Font().from_sexpr(item)
@@ -566,7 +565,7 @@ def _to_sexpr_raw(self):
566565
if self.href is not None:
567566
expr.append(['href', dequote(self.href)])
568567

569-
expr.append(format_bool_raw("hide", self.hide))
568+
expr.append(format_bool("hide", self.hide))
570569

571570
return expr
572571

@@ -667,7 +666,7 @@ def from_sexpr(cls, exp: list) -> Group:
667666
object = cls()
668667
object.name = exp[1]
669668
for item in exp[2:]:
670-
if parse_bool(item, 'locked'): object.locked = True
669+
if is_bool_key(item, 'locked'): object.locked = parse_bool(item, 'locked')
671670
elif not isinstance(item, list):
672671
raise ValueError(f"Expected list property [key, value], got: {item}. Full expression: {exp}")
673672
elif item[0] == 'id': object.id = item[1]
@@ -696,7 +695,7 @@ def _to_sexpr_raw(self):
696695
'group',
697696
escape_and_quote(self.name),
698697
['uuid', escape_and_quote(self.id)],
699-
format_bool_raw("locked", self.locked),
698+
format_bool("locked", self.locked),
700699
['members'] + [quote(member) for member in self.members],
701700
]
702701
return expr
@@ -951,8 +950,8 @@ def from_sexpr(cls, exp: list) -> Property:
951950
object.value = exp[2]
952951

953952
for item in exp[3:]:
954-
if item[0] == 'show_name': object.showName = parse_bool(item, 'show_name')
955-
elif item[0] == 'do_not_autoplace': object.do_not_autoplace = parse_bool(item, 'do_not_autoplace')
953+
if is_bool_key(item, 'show_name'): object.showName = parse_bool(item, 'show_name')
954+
elif is_bool_key(item, 'do_not_autoplace'): object.do_not_autoplace = parse_bool(item, 'do_not_autoplace')
956955
elif not isinstance(item, list):
957956
raise ValueError(f"Expected list property [key, value], got: {item}. Full expression: {exp}")
958957
elif item[0] == 'id': object.id = item[1]
@@ -994,10 +993,10 @@ def _to_sexpr_raw(self):
994993
expr.append(['id', self.id])
995994

996995
if self.showName:
997-
expr.append(format_bool_raw('show_name', self.showName))
996+
expr.append(format_bool('show_name', self.showName))
998997

999998
if self.do_not_autoplace:
1000-
expr.append(format_bool_raw('do_not_autoplace', self.do_not_autoplace, compact=True))
999+
expr.append(format_bool('do_not_autoplace', self.do_not_autoplace, compact=True))
10011000

10021001
if self.effects is not None:
10031002
expr.append(self.effects._to_sexpr_raw())

0 commit comments

Comments
 (0)