kicad-sch-api 0.3.5__py3-none-any.whl → 0.4.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kicad_sch_api/__init__.py +2 -2
- kicad_sch_api/cli/__init__.py +45 -0
- kicad_sch_api/cli/base.py +302 -0
- kicad_sch_api/cli/bom.py +164 -0
- kicad_sch_api/cli/erc.py +229 -0
- kicad_sch_api/cli/export_docs.py +289 -0
- kicad_sch_api/cli/netlist.py +94 -0
- kicad_sch_api/cli/types.py +43 -0
- kicad_sch_api/collections/__init__.py +2 -2
- kicad_sch_api/collections/base.py +5 -7
- kicad_sch_api/collections/components.py +24 -12
- kicad_sch_api/collections/junctions.py +31 -43
- kicad_sch_api/collections/labels.py +19 -27
- kicad_sch_api/collections/wires.py +17 -18
- kicad_sch_api/core/collections/__init__.py +5 -0
- kicad_sch_api/core/collections/base.py +248 -0
- kicad_sch_api/core/component_bounds.py +5 -0
- kicad_sch_api/core/components.py +67 -45
- kicad_sch_api/core/config.py +85 -3
- kicad_sch_api/core/factories/__init__.py +5 -0
- kicad_sch_api/core/factories/element_factory.py +276 -0
- kicad_sch_api/core/formatter.py +3 -1
- kicad_sch_api/core/junctions.py +26 -75
- kicad_sch_api/core/labels.py +29 -53
- kicad_sch_api/core/managers/__init__.py +26 -0
- kicad_sch_api/core/managers/file_io.py +244 -0
- kicad_sch_api/core/managers/format_sync.py +501 -0
- kicad_sch_api/core/managers/graphics.py +579 -0
- kicad_sch_api/core/managers/metadata.py +269 -0
- kicad_sch_api/core/managers/sheet.py +454 -0
- kicad_sch_api/core/managers/text_elements.py +536 -0
- kicad_sch_api/core/managers/validation.py +475 -0
- kicad_sch_api/core/managers/wire.py +352 -0
- kicad_sch_api/core/nets.py +38 -43
- kicad_sch_api/core/no_connects.py +33 -55
- kicad_sch_api/core/parser.py +75 -1731
- kicad_sch_api/core/schematic.py +951 -1192
- kicad_sch_api/core/texts.py +28 -55
- kicad_sch_api/core/types.py +60 -22
- kicad_sch_api/core/wires.py +27 -75
- kicad_sch_api/geometry/font_metrics.py +3 -1
- kicad_sch_api/geometry/symbol_bbox.py +40 -21
- kicad_sch_api/interfaces/__init__.py +1 -1
- kicad_sch_api/interfaces/parser.py +1 -1
- kicad_sch_api/interfaces/repository.py +1 -1
- kicad_sch_api/interfaces/resolver.py +1 -1
- kicad_sch_api/parsers/__init__.py +2 -2
- kicad_sch_api/parsers/base.py +7 -10
- kicad_sch_api/parsers/elements/__init__.py +22 -0
- kicad_sch_api/parsers/elements/graphics_parser.py +564 -0
- kicad_sch_api/parsers/elements/label_parser.py +194 -0
- kicad_sch_api/parsers/elements/library_parser.py +165 -0
- kicad_sch_api/parsers/elements/metadata_parser.py +58 -0
- kicad_sch_api/parsers/elements/sheet_parser.py +352 -0
- kicad_sch_api/parsers/elements/symbol_parser.py +313 -0
- kicad_sch_api/parsers/elements/text_parser.py +250 -0
- kicad_sch_api/parsers/elements/wire_parser.py +242 -0
- kicad_sch_api/parsers/registry.py +4 -2
- kicad_sch_api/parsers/utils.py +80 -0
- kicad_sch_api/symbols/__init__.py +1 -1
- kicad_sch_api/symbols/cache.py +9 -12
- kicad_sch_api/symbols/resolver.py +20 -26
- kicad_sch_api/symbols/validators.py +188 -137
- kicad_sch_api/validation/__init__.py +25 -0
- kicad_sch_api/validation/erc.py +171 -0
- kicad_sch_api/validation/erc_models.py +203 -0
- kicad_sch_api/validation/pin_matrix.py +243 -0
- kicad_sch_api/validation/validators.py +391 -0
- {kicad_sch_api-0.3.5.dist-info → kicad_sch_api-0.4.1.dist-info}/METADATA +17 -9
- kicad_sch_api-0.4.1.dist-info/RECORD +87 -0
- kicad_sch_api/core/manhattan_routing.py +0 -430
- kicad_sch_api/core/simple_manhattan.py +0 -228
- kicad_sch_api/core/wire_routing.py +0 -380
- kicad_sch_api/parsers/label_parser.py +0 -254
- kicad_sch_api/parsers/symbol_parser.py +0 -227
- kicad_sch_api/parsers/wire_parser.py +0 -99
- kicad_sch_api-0.3.5.dist-info/RECORD +0 -58
- {kicad_sch_api-0.3.5.dist-info → kicad_sch_api-0.4.1.dist-info}/WHEEL +0 -0
- {kicad_sch_api-0.3.5.dist-info → kicad_sch_api-0.4.1.dist-info}/entry_points.txt +0 -0
- {kicad_sch_api-0.3.5.dist-info → kicad_sch_api-0.4.1.dist-info}/licenses/LICENSE +0 -0
- {kicad_sch_api-0.3.5.dist-info → kicad_sch_api-0.4.1.dist-info}/top_level.txt +0 -0
|
@@ -10,7 +10,8 @@ import uuid
|
|
|
10
10
|
from typing import Any, Callable, Dict, Iterator, List, Optional, Tuple, Union
|
|
11
11
|
|
|
12
12
|
from ..utils.validation import SchematicValidator, ValidationError, ValidationIssue
|
|
13
|
-
from .
|
|
13
|
+
from .collections import BaseCollection
|
|
14
|
+
from .types import NoConnect, Point
|
|
14
15
|
|
|
15
16
|
logger = logging.getLogger(__name__)
|
|
16
17
|
|
|
@@ -72,10 +73,13 @@ class NoConnectElement:
|
|
|
72
73
|
return f"<NoConnect @ {self.position}>"
|
|
73
74
|
|
|
74
75
|
|
|
75
|
-
class NoConnectCollection:
|
|
76
|
+
class NoConnectCollection(BaseCollection[NoConnectElement]):
|
|
76
77
|
"""
|
|
77
78
|
Collection class for efficient no-connect element management.
|
|
78
79
|
|
|
80
|
+
Inherits from BaseCollection for standard operations and adds no-connect-specific
|
|
81
|
+
functionality including position-based indexing.
|
|
82
|
+
|
|
79
83
|
Provides fast lookup, filtering, and bulk operations for schematic no-connect elements.
|
|
80
84
|
"""
|
|
81
85
|
|
|
@@ -86,18 +90,17 @@ class NoConnectCollection:
|
|
|
86
90
|
Args:
|
|
87
91
|
no_connects: Initial list of no-connect data
|
|
88
92
|
"""
|
|
89
|
-
|
|
90
|
-
|
|
93
|
+
# Initialize base collection
|
|
94
|
+
super().__init__([], collection_name="no_connects")
|
|
95
|
+
|
|
96
|
+
# Additional no-connect-specific index
|
|
91
97
|
self._position_index: Dict[Tuple[float, float], List[NoConnectElement]] = {}
|
|
92
|
-
self._modified = False
|
|
93
98
|
|
|
94
99
|
# Add initial no-connects
|
|
95
100
|
if no_connects:
|
|
96
101
|
for no_connect_data in no_connects:
|
|
97
102
|
self._add_to_indexes(NoConnectElement(no_connect_data, self))
|
|
98
103
|
|
|
99
|
-
logger.debug(f"NoConnectCollection initialized with {len(self._no_connects)} no-connects")
|
|
100
|
-
|
|
101
104
|
def add(
|
|
102
105
|
self,
|
|
103
106
|
position: Union[Point, Tuple[float, float]],
|
|
@@ -144,9 +147,7 @@ class NoConnectCollection:
|
|
|
144
147
|
logger.debug(f"Added no-connect: {no_connect_element}")
|
|
145
148
|
return no_connect_element
|
|
146
149
|
|
|
147
|
-
|
|
148
|
-
"""Get no-connect by UUID."""
|
|
149
|
-
return self._uuid_index.get(no_connect_uuid)
|
|
150
|
+
# get() method inherited from BaseCollection
|
|
150
151
|
|
|
151
152
|
def remove(self, no_connect_uuid: str) -> bool:
|
|
152
153
|
"""
|
|
@@ -158,18 +159,26 @@ class NoConnectCollection:
|
|
|
158
159
|
Returns:
|
|
159
160
|
True if no-connect was removed, False if not found
|
|
160
161
|
"""
|
|
161
|
-
no_connect_element = self.
|
|
162
|
+
no_connect_element = self.get(no_connect_uuid)
|
|
162
163
|
if not no_connect_element:
|
|
163
164
|
return False
|
|
164
165
|
|
|
165
|
-
# Remove from
|
|
166
|
-
|
|
167
|
-
self.
|
|
166
|
+
# Remove from position index
|
|
167
|
+
pos_key = (no_connect_element.position.x, no_connect_element.position.y)
|
|
168
|
+
if pos_key in self._position_index:
|
|
169
|
+
self._position_index[pos_key].remove(no_connect_element)
|
|
170
|
+
if not self._position_index[pos_key]:
|
|
171
|
+
del self._position_index[pos_key]
|
|
172
|
+
|
|
173
|
+
# Remove using base class method
|
|
174
|
+
super().remove(no_connect_uuid)
|
|
168
175
|
|
|
169
176
|
logger.debug(f"Removed no-connect: {no_connect_element}")
|
|
170
177
|
return True
|
|
171
178
|
|
|
172
|
-
def find_at_position(
|
|
179
|
+
def find_at_position(
|
|
180
|
+
self, position: Union[Point, Tuple[float, float]], tolerance: float = 0.1
|
|
181
|
+
) -> List[NoConnectElement]:
|
|
173
182
|
"""
|
|
174
183
|
Find no-connects at or near a position.
|
|
175
184
|
|
|
@@ -184,7 +193,7 @@ class NoConnectCollection:
|
|
|
184
193
|
position = Point(position[0], position[1])
|
|
185
194
|
|
|
186
195
|
matches = []
|
|
187
|
-
for no_connect_element in self.
|
|
196
|
+
for no_connect_element in self._items:
|
|
188
197
|
distance = no_connect_element.position.distance_to(position)
|
|
189
198
|
if distance <= tolerance:
|
|
190
199
|
matches.append(no_connect_element)
|
|
@@ -192,7 +201,7 @@ class NoConnectCollection:
|
|
|
192
201
|
|
|
193
202
|
def filter(self, predicate: Callable[[NoConnectElement], bool]) -> List[NoConnectElement]:
|
|
194
203
|
"""
|
|
195
|
-
Filter no-connects by predicate function.
|
|
204
|
+
Filter no-connects by predicate function (delegates to base class find).
|
|
196
205
|
|
|
197
206
|
Args:
|
|
198
207
|
predicate: Function that returns True for no-connects to include
|
|
@@ -200,7 +209,7 @@ class NoConnectCollection:
|
|
|
200
209
|
Returns:
|
|
201
210
|
List of no-connects matching predicate
|
|
202
211
|
"""
|
|
203
|
-
return
|
|
212
|
+
return self.find(predicate)
|
|
204
213
|
|
|
205
214
|
def bulk_update(self, criteria: Callable[[NoConnectElement], bool], updates: Dict[str, Any]):
|
|
206
215
|
"""
|
|
@@ -211,7 +220,7 @@ class NoConnectCollection:
|
|
|
211
220
|
updates: Dictionary of property updates
|
|
212
221
|
"""
|
|
213
222
|
updated_count = 0
|
|
214
|
-
for no_connect_element in self.
|
|
223
|
+
for no_connect_element in self._items:
|
|
215
224
|
if criteria(no_connect_element):
|
|
216
225
|
for prop, value in updates.items():
|
|
217
226
|
if hasattr(no_connect_element, prop):
|
|
@@ -224,15 +233,12 @@ class NoConnectCollection:
|
|
|
224
233
|
|
|
225
234
|
def clear(self):
|
|
226
235
|
"""Remove all no-connects from collection."""
|
|
227
|
-
self._no_connects.clear()
|
|
228
|
-
self._uuid_index.clear()
|
|
229
236
|
self._position_index.clear()
|
|
230
|
-
|
|
237
|
+
super().clear()
|
|
231
238
|
|
|
232
239
|
def _add_to_indexes(self, no_connect_element: NoConnectElement):
|
|
233
|
-
"""Add no-connect to internal indexes."""
|
|
234
|
-
self.
|
|
235
|
-
self._uuid_index[no_connect_element.uuid] = no_connect_element
|
|
240
|
+
"""Add no-connect to internal indexes (base + position index)."""
|
|
241
|
+
self._add_item(no_connect_element)
|
|
236
242
|
|
|
237
243
|
# Add to position index
|
|
238
244
|
pos_key = (no_connect_element.position.x, no_connect_element.position.y)
|
|
@@ -240,35 +246,7 @@ class NoConnectCollection:
|
|
|
240
246
|
self._position_index[pos_key] = []
|
|
241
247
|
self._position_index[pos_key].append(no_connect_element)
|
|
242
248
|
|
|
243
|
-
|
|
244
|
-
"""Remove no-connect from internal indexes."""
|
|
245
|
-
self._no_connects.remove(no_connect_element)
|
|
246
|
-
del self._uuid_index[no_connect_element.uuid]
|
|
247
|
-
|
|
248
|
-
# Remove from position index
|
|
249
|
-
pos_key = (no_connect_element.position.x, no_connect_element.position.y)
|
|
250
|
-
if pos_key in self._position_index:
|
|
251
|
-
self._position_index[pos_key].remove(no_connect_element)
|
|
252
|
-
if not self._position_index[pos_key]:
|
|
253
|
-
del self._position_index[pos_key]
|
|
254
|
-
|
|
255
|
-
def _mark_modified(self):
|
|
256
|
-
"""Mark collection as modified."""
|
|
257
|
-
self._modified = True
|
|
258
|
-
|
|
259
|
-
# Collection interface methods
|
|
260
|
-
def __len__(self) -> int:
|
|
261
|
-
"""Return number of no-connects."""
|
|
262
|
-
return len(self._no_connects)
|
|
263
|
-
|
|
264
|
-
def __iter__(self) -> Iterator[NoConnectElement]:
|
|
265
|
-
"""Iterate over no-connects."""
|
|
266
|
-
return iter(self._no_connects)
|
|
267
|
-
|
|
268
|
-
def __getitem__(self, index: int) -> NoConnectElement:
|
|
269
|
-
"""Get no-connect by index."""
|
|
270
|
-
return self._no_connects[index]
|
|
271
|
-
|
|
249
|
+
# Collection interface methods - __len__, __iter__, __getitem__ inherited from BaseCollection
|
|
272
250
|
def __bool__(self) -> bool:
|
|
273
251
|
"""Return True if collection has no-connects."""
|
|
274
|
-
return len(self.
|
|
252
|
+
return len(self._items) > 0
|