kicad-sch-api 0.3.5__py3-none-any.whl → 0.4.0__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.

Potentially problematic release.


This version of kicad-sch-api might be problematic. Click here for more details.

Files changed (47) hide show
  1. kicad_sch_api/collections/__init__.py +2 -2
  2. kicad_sch_api/collections/base.py +5 -7
  3. kicad_sch_api/collections/components.py +24 -12
  4. kicad_sch_api/collections/junctions.py +31 -43
  5. kicad_sch_api/collections/labels.py +19 -27
  6. kicad_sch_api/collections/wires.py +17 -18
  7. kicad_sch_api/core/components.py +5 -0
  8. kicad_sch_api/core/formatter.py +3 -1
  9. kicad_sch_api/core/labels.py +2 -2
  10. kicad_sch_api/core/managers/__init__.py +26 -0
  11. kicad_sch_api/core/managers/file_io.py +243 -0
  12. kicad_sch_api/core/managers/format_sync.py +501 -0
  13. kicad_sch_api/core/managers/graphics.py +579 -0
  14. kicad_sch_api/core/managers/metadata.py +268 -0
  15. kicad_sch_api/core/managers/sheet.py +454 -0
  16. kicad_sch_api/core/managers/text_elements.py +536 -0
  17. kicad_sch_api/core/managers/validation.py +474 -0
  18. kicad_sch_api/core/managers/wire.py +346 -0
  19. kicad_sch_api/core/nets.py +1 -1
  20. kicad_sch_api/core/no_connects.py +5 -3
  21. kicad_sch_api/core/parser.py +75 -41
  22. kicad_sch_api/core/schematic.py +779 -1083
  23. kicad_sch_api/core/texts.py +1 -1
  24. kicad_sch_api/core/types.py +1 -4
  25. kicad_sch_api/geometry/font_metrics.py +3 -1
  26. kicad_sch_api/geometry/symbol_bbox.py +40 -21
  27. kicad_sch_api/interfaces/__init__.py +1 -1
  28. kicad_sch_api/interfaces/parser.py +1 -1
  29. kicad_sch_api/interfaces/repository.py +1 -1
  30. kicad_sch_api/interfaces/resolver.py +1 -1
  31. kicad_sch_api/parsers/__init__.py +2 -2
  32. kicad_sch_api/parsers/base.py +7 -10
  33. kicad_sch_api/parsers/label_parser.py +7 -7
  34. kicad_sch_api/parsers/registry.py +4 -2
  35. kicad_sch_api/parsers/symbol_parser.py +5 -10
  36. kicad_sch_api/parsers/wire_parser.py +2 -2
  37. kicad_sch_api/symbols/__init__.py +1 -1
  38. kicad_sch_api/symbols/cache.py +9 -12
  39. kicad_sch_api/symbols/resolver.py +20 -26
  40. kicad_sch_api/symbols/validators.py +188 -137
  41. {kicad_sch_api-0.3.5.dist-info → kicad_sch_api-0.4.0.dist-info}/METADATA +1 -1
  42. kicad_sch_api-0.4.0.dist-info/RECORD +67 -0
  43. kicad_sch_api-0.3.5.dist-info/RECORD +0 -58
  44. {kicad_sch_api-0.3.5.dist-info → kicad_sch_api-0.4.0.dist-info}/WHEEL +0 -0
  45. {kicad_sch_api-0.3.5.dist-info → kicad_sch_api-0.4.0.dist-info}/entry_points.txt +0 -0
  46. {kicad_sch_api-0.3.5.dist-info → kicad_sch_api-0.4.0.dist-info}/licenses/LICENSE +0 -0
  47. {kicad_sch_api-0.3.5.dist-info → kicad_sch_api-0.4.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,268 @@
1
+ """
2
+ Metadata Manager for KiCAD schematic configuration.
3
+
4
+ Handles schematic-level settings, properties, and configuration including
5
+ paper size, title block, version information, and instance sections.
6
+ """
7
+
8
+ import logging
9
+ from typing import Any, Dict, List, Optional
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class MetadataManager:
15
+ """
16
+ Manages schematic metadata and configuration settings.
17
+
18
+ Responsible for:
19
+ - Title block management
20
+ - Paper size and page setup
21
+ - Version and generator information
22
+ - Library and instance sections
23
+ - Schema-level properties
24
+ """
25
+
26
+ def __init__(self, schematic_data: Dict[str, Any]):
27
+ """
28
+ Initialize MetadataManager with schematic data.
29
+
30
+ Args:
31
+ schematic_data: Reference to schematic data dictionary
32
+ """
33
+ self._data = schematic_data
34
+
35
+ def set_paper_size(self, paper: str) -> None:
36
+ """
37
+ Set paper size for the schematic.
38
+
39
+ Args:
40
+ paper: Paper size (e.g., "A4", "A3", "Letter", "Legal")
41
+ """
42
+ valid_sizes = ["A4", "A3", "A2", "A1", "A0", "Letter", "Legal", "Tabloid"]
43
+
44
+ if paper not in valid_sizes:
45
+ logger.warning(f"Unusual paper size: {paper}. Valid sizes: {valid_sizes}")
46
+
47
+ self._data["paper"] = paper
48
+ logger.debug(f"Set paper size: {paper}")
49
+
50
+ def set_version_info(
51
+ self, version: Optional[int] = None, generator: Optional[str] = None
52
+ ) -> None:
53
+ """
54
+ Set KiCAD version and generator information.
55
+
56
+ Args:
57
+ version: KiCAD schema version number
58
+ generator: Generator application string
59
+ """
60
+ if version is not None:
61
+ self._data["version"] = version
62
+ logger.debug(f"Set version: {version}")
63
+
64
+ if generator is not None:
65
+ self._data["generator"] = generator
66
+ logger.debug(f"Set generator: {generator}")
67
+
68
+ def set_title_block(
69
+ self,
70
+ title: str = "",
71
+ date: str = "",
72
+ rev: str = "",
73
+ company: str = "",
74
+ comments: Optional[Dict[int, str]] = None,
75
+ ) -> None:
76
+ """
77
+ Set title block information.
78
+
79
+ Args:
80
+ title: Schematic title
81
+ date: Creation/revision date
82
+ rev: Revision number
83
+ company: Company name
84
+ comments: Numbered comments (1, 2, 3, etc.)
85
+ """
86
+ if comments is None:
87
+ comments = {}
88
+
89
+ self._data["title_block"] = {
90
+ "title": title,
91
+ "date": date,
92
+ "rev": rev,
93
+ "company": company,
94
+ "comments": comments,
95
+ }
96
+
97
+ logger.debug(f"Set title block: {title} rev {rev}")
98
+
99
+ def copy_metadata_from(self, source_data: Dict[str, Any]) -> None:
100
+ """
101
+ Copy metadata from another schematic.
102
+
103
+ Args:
104
+ source_data: Source schematic data to copy from
105
+ """
106
+ # Copy basic metadata
107
+ for key in ["paper", "version", "generator"]:
108
+ if key in source_data:
109
+ self._data[key] = source_data[key]
110
+
111
+ # Copy title block if present
112
+ if "title_block" in source_data:
113
+ self._data["title_block"] = source_data["title_block"].copy()
114
+
115
+ # Copy lib_symbols if present
116
+ if "lib_symbols" in source_data:
117
+ self._data["lib_symbols"] = source_data["lib_symbols"].copy()
118
+
119
+ logger.info("Copied metadata from source schematic")
120
+
121
+ def add_lib_symbols_section(self, lib_symbols: Dict[str, Any]) -> None:
122
+ """
123
+ Add or update lib_symbols section.
124
+
125
+ Args:
126
+ lib_symbols: Library symbols data
127
+ """
128
+ self._data["lib_symbols"] = lib_symbols
129
+ logger.debug(f"Updated lib_symbols section with {len(lib_symbols)} symbols")
130
+
131
+ def add_instances_section(self, instances: Dict[str, Any]) -> None:
132
+ """
133
+ Add or update symbol instances section.
134
+
135
+ Args:
136
+ instances: Symbol instances data
137
+ """
138
+ self._data["symbol_instances"] = instances
139
+ logger.debug("Updated symbol_instances section")
140
+
141
+ def add_sheet_instances_section(self, sheet_instances: List[Dict]) -> None:
142
+ """
143
+ Add or update sheet instances section.
144
+
145
+ Args:
146
+ sheet_instances: List of sheet instance data
147
+ """
148
+ self._data["sheet_instances"] = sheet_instances
149
+ logger.debug(f"Updated sheet_instances section with {len(sheet_instances)} instances")
150
+
151
+ def set_uuid(self, uuid_str: str) -> None:
152
+ """
153
+ Set schematic UUID.
154
+
155
+ Args:
156
+ uuid_str: UUID string for the schematic
157
+ """
158
+ self._data["uuid"] = uuid_str
159
+ logger.debug(f"Set schematic UUID: {uuid_str}")
160
+
161
+ def get_version(self) -> Optional[int]:
162
+ """Get KiCAD schema version."""
163
+ return self._data.get("version")
164
+
165
+ def get_generator(self) -> Optional[str]:
166
+ """Get generator application string."""
167
+ return self._data.get("generator")
168
+
169
+ def get_uuid(self) -> Optional[str]:
170
+ """Get schematic UUID."""
171
+ return self._data.get("uuid")
172
+
173
+ def get_paper_size(self) -> Optional[str]:
174
+ """Get paper size."""
175
+ return self._data.get("paper")
176
+
177
+ def get_title_block(self) -> Dict[str, Any]:
178
+ """
179
+ Get title block information.
180
+
181
+ Returns:
182
+ Title block data dictionary
183
+ """
184
+ return self._data.get("title_block", {})
185
+
186
+ def get_lib_symbols(self) -> Dict[str, Any]:
187
+ """
188
+ Get lib_symbols section.
189
+
190
+ Returns:
191
+ Library symbols data
192
+ """
193
+ return self._data.get("lib_symbols", {})
194
+
195
+ def get_symbol_instances(self) -> Dict[str, Any]:
196
+ """
197
+ Get symbol instances section.
198
+
199
+ Returns:
200
+ Symbol instances data
201
+ """
202
+ return self._data.get("symbol_instances", {})
203
+
204
+ def get_sheet_instances(self) -> List[Dict]:
205
+ """
206
+ Get sheet instances section.
207
+
208
+ Returns:
209
+ List of sheet instances
210
+ """
211
+ return self._data.get("sheet_instances", [])
212
+
213
+ def get_metadata_summary(self) -> Dict[str, Any]:
214
+ """
215
+ Get comprehensive metadata summary.
216
+
217
+ Returns:
218
+ Dictionary with all metadata information
219
+ """
220
+ title_block = self.get_title_block()
221
+
222
+ return {
223
+ "version": self.get_version(),
224
+ "generator": self.get_generator(),
225
+ "uuid": self.get_uuid(),
226
+ "paper": self.get_paper_size(),
227
+ "title": title_block.get("title", ""),
228
+ "revision": title_block.get("rev", ""),
229
+ "company": title_block.get("company", ""),
230
+ "date": title_block.get("date", ""),
231
+ "comments": title_block.get("comments", {}),
232
+ "lib_symbols_count": len(self.get_lib_symbols()),
233
+ "symbol_instances_count": (
234
+ len(self.get_symbol_instances())
235
+ if isinstance(self.get_symbol_instances(), list)
236
+ else 1 if self.get_symbol_instances() else 0
237
+ ),
238
+ "sheet_instances_count": len(self.get_sheet_instances()),
239
+ }
240
+
241
+ def validate_metadata(self) -> List[str]:
242
+ """
243
+ Validate metadata consistency and completeness.
244
+
245
+ Returns:
246
+ List of validation warnings/issues
247
+ """
248
+ issues = []
249
+
250
+ # Check required fields
251
+ if not self.get_version():
252
+ issues.append("Missing KiCAD version")
253
+
254
+ if not self.get_generator():
255
+ issues.append("Missing generator information")
256
+
257
+ # Check title block
258
+ title_block = self.get_title_block()
259
+ if not title_block.get("title"):
260
+ issues.append("Title block missing title")
261
+
262
+ # Check paper size
263
+ paper = self.get_paper_size()
264
+ valid_sizes = ["A4", "A3", "A2", "A1", "A0", "Letter", "Legal", "Tabloid"]
265
+ if paper and paper not in valid_sizes:
266
+ issues.append(f"Non-standard paper size: {paper}")
267
+
268
+ return issues