pyedb 0.52.0__py3-none-any.whl → 0.53.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 pyedb might be problematic. Click here for more details.

@@ -25,6 +25,7 @@ import os
25
25
  import re
26
26
  import subprocess
27
27
  import sys
28
+ from typing import Any, Dict, List, Optional, Union
28
29
 
29
30
  from pyedb.edb_logger import pyedb_logger
30
31
  from pyedb.generic.general_methods import ET, env_path, env_value, is_linux
@@ -257,21 +258,24 @@ class ControlProperty:
257
258
  Value of the property.
258
259
  """
259
260
 
260
- def __init__(self, property_name, value):
261
- self.name = property_name
262
- self.value = value
261
+ def __init__(self, property_name: str, value: Union[str, float, list]) -> None:
262
+ self.name: str = property_name
263
+ self.value: Union[str, float, list] = value
264
+ self.type: int = self._get_type(value)
265
+
266
+ def _get_type(self, value: Any) -> int:
263
267
  if isinstance(value, str):
264
- self.type = 1
268
+ return 1
265
269
  elif isinstance(value, list):
266
- self.type = 2
270
+ return 2
267
271
  else:
268
272
  try:
269
273
  float(value)
270
- self.type = 0
274
+ return 0
271
275
  except TypeError:
272
- pass
276
+ return -1
273
277
 
274
- def _write_xml(self, root):
278
+ def _write_xml(self, root) -> None:
275
279
  """Write the property to XML element.
276
280
 
277
281
  Parameters
@@ -301,13 +305,13 @@ class ControlFileMaterial:
301
305
  Material properties dictionary.
302
306
  """
303
307
 
304
- def __init__(self, name, properties):
305
- self.name = name
306
- self.properties = {}
307
- for name, property in properties.items():
308
- self.properties[name] = ControlProperty(name, property)
308
+ def __init__(self, name: str, properties: Dict[str, Any]) -> None:
309
+ self.name: str = name
310
+ self.properties: Dict[str, ControlProperty] = {
311
+ name: ControlProperty(name, prop) for name, prop in properties.items()
312
+ }
309
313
 
310
- def _write_xml(self, root):
314
+ def _write_xml(self, root) -> None:
311
315
  """Write material to XML element.
312
316
 
313
317
  Parameters
@@ -332,13 +336,13 @@ class ControlFileDielectric:
332
336
  Layer properties dictionary.
333
337
  """
334
338
 
335
- def __init__(self, name, properties):
336
- self.name = name
337
- self.properties = {}
339
+ def __init__(self, name: str, properties: Dict[str, Any]) -> None:
340
+ self.name: str = name
341
+ self.properties: Dict[str, Any] = {}
338
342
  for name, prop in properties.items():
339
343
  self.properties[name] = prop
340
344
 
341
- def _write_xml(self, root):
345
+ def _write_xml(self, root) -> None:
342
346
  """Write dielectric layer to XML element.
343
347
 
344
348
  Parameters
@@ -411,19 +415,19 @@ class ControlFileVia(ControlFileLayer):
411
415
  Via properties dictionary.
412
416
  """
413
417
 
414
- def __init__(self, name, properties):
415
- ControlFileLayer.__init__(self, name, properties)
416
- self.create_via_group = False
417
- self.check_containment = True
418
- self.method = "proximity"
419
- self.persistent = False
420
- self.tolerance = "1um"
421
- self.snap_via_groups = False
422
- self.snap_method = "areaFactor"
423
- self.remove_unconnected = True
424
- self.snap_tolerance = 3
425
-
426
- def _write_xml(self, root):
418
+ def __init__(self, name: str, properties: Dict[str, Any]) -> None:
419
+ super().__init__(name, properties)
420
+ self.create_via_group: bool = False
421
+ self.check_containment: bool = True
422
+ self.method: str = "proximity"
423
+ self.persistent: bool = False
424
+ self.tolerance: str = "1um"
425
+ self.snap_via_groups: bool = False
426
+ self.snap_method: str = "areaFactor"
427
+ self.remove_unconnected: bool = True
428
+ self.snap_tolerance: int = 3
429
+
430
+ def _write_xml(self, root) -> None:
427
431
  """Write via to XML element.
428
432
 
429
433
  Parameters
@@ -470,14 +474,14 @@ class ControlFileStackup:
470
474
  Length units (e.g., "mm", "um"). Default is "mm".
471
475
  """
472
476
 
473
- def __init__(self, units="mm"):
474
- self._materials = {}
475
- self._layers = []
476
- self._dielectrics = []
477
- self._vias = []
478
- self.units = units
479
- self.metal_layer_snapping_tolerance = None
480
- self.dielectrics_base_elevation = 0
477
+ def __init__(self, units: str = "mm") -> None:
478
+ self._materials: Dict[str, ControlFileMaterial] = {}
479
+ self._layers: List[ControlFileLayer] = []
480
+ self._dielectrics: List[Any] = []
481
+ self._vias: List[ControlFileVia] = []
482
+ self.units: str = units
483
+ self.metal_layer_snapping_tolerance: Optional[float] = None
484
+ self.dielectrics_base_elevation: float = 0.0
481
485
 
482
486
  @property
483
487
  def vias(self):
@@ -490,7 +494,7 @@ class ControlFileStackup:
490
494
  return self._vias
491
495
 
492
496
  @property
493
- def materials(self):
497
+ def materials(self) -> Dict[str, ControlFileMaterial]:
494
498
  """Dictionary of material objects.
495
499
 
496
500
  Returns
@@ -511,7 +515,7 @@ class ControlFileStackup:
511
515
  return self._dielectrics
512
516
 
513
517
  @property
514
- def layers(self):
518
+ def layers(self) -> List[ControlFileLayer]:
515
519
  """List of general layers.
516
520
 
517
521
  Returns
@@ -522,13 +526,13 @@ class ControlFileStackup:
522
526
 
523
527
  def add_material(
524
528
  self,
525
- material_name,
526
- permittivity=1.0,
527
- dielectric_loss_tg=0.0,
528
- permeability=1.0,
529
- conductivity=0.0,
530
- properties=None,
531
- ):
529
+ material_name: str,
530
+ permittivity: float = 1.0,
531
+ dielectric_loss_tg: float = 0.0,
532
+ permeability: float = 1.0,
533
+ conductivity: float = 0.0,
534
+ properties: Optional[Dict[str, Any]] = None,
535
+ ) -> ControlFileMaterial:
532
536
  """Add a new material.
533
537
 
534
538
  Parameters
@@ -567,16 +571,16 @@ class ControlFileStackup:
567
571
 
568
572
  def add_layer(
569
573
  self,
570
- layer_name,
571
- elevation=0.0,
572
- material="",
573
- gds_type=0,
574
- target_layer="",
575
- thickness=0.0,
576
- layer_type="conductor",
577
- solve_inside=True,
578
- properties=None,
579
- ):
574
+ layer_name: str,
575
+ elevation: float = 0.0,
576
+ material: str = "",
577
+ gds_type: int = 0,
578
+ target_layer: str = "",
579
+ thickness: float = 0.0,
580
+ layer_type: str = "conductor",
581
+ solve_inside: bool = True,
582
+ properties: Optional[Dict[str, Any]] = None,
583
+ ) -> ControlFileLayer:
580
584
  """Add a new layer.
581
585
 
582
586
  Parameters
@@ -624,14 +628,14 @@ class ControlFileStackup:
624
628
 
625
629
  def add_dielectric(
626
630
  self,
627
- layer_name,
628
- layer_index=None,
629
- material="",
630
- thickness=0.0,
631
- properties=None,
632
- base_layer=None,
633
- add_on_top=True,
634
- ):
631
+ layer_name: str,
632
+ layer_index: Optional[int] = None,
633
+ material: str = "",
634
+ thickness: float = 0.0,
635
+ properties: Optional[Dict[str, Any]] = None,
636
+ base_layer: Optional[str] = None,
637
+ add_on_top: bool = True,
638
+ ) -> ControlFileDielectric:
635
639
  """Add a new dielectric layer.
636
640
 
637
641
  Parameters
@@ -685,20 +689,20 @@ class ControlFileStackup:
685
689
 
686
690
  def add_via(
687
691
  self,
688
- layer_name,
689
- material="",
690
- gds_type=0,
691
- target_layer="",
692
- start_layer="",
693
- stop_layer="",
694
- solve_inside=True,
695
- via_group_method="proximity",
696
- via_group_tol=1e-6,
697
- via_group_persistent=True,
698
- snap_via_group_method="distance",
699
- snap_via_group_tol=10e-9,
700
- properties=None,
701
- ):
692
+ layer_name: str,
693
+ material: str = "",
694
+ gds_type: int = 0,
695
+ target_layer: str = "",
696
+ start_layer: str = "",
697
+ stop_layer: str = "",
698
+ solve_inside: bool = True,
699
+ via_group_method: str = "proximity",
700
+ via_group_tol: float = 1e-6,
701
+ via_group_persistent: bool = True,
702
+ snap_via_group_method: str = "distance",
703
+ snap_via_group_tol: float = 10e-9,
704
+ properties: Optional[Dict[str, Any]] = None,
705
+ ) -> ControlFileVia:
702
706
  """Add a new via layer.
703
707
 
704
708
  Parameters
@@ -756,7 +760,7 @@ class ControlFileStackup:
756
760
  self._vias.append(ControlFileVia(layer_name, properties))
757
761
  return self._vias[-1]
758
762
 
759
- def _write_xml(self, root):
763
+ def _write_xml(self, root: ET.Element) -> None:
760
764
  """Write stackup to XML element.
761
765
 
762
766
  Parameters
@@ -792,31 +796,37 @@ class ControlFileStackup:
792
796
  class ControlFileImportOptions:
793
797
  """Manages import options for the control file."""
794
798
 
795
- def __init__(self):
796
- self.auto_close = False
797
- self.convert_closed_wide_lines_to_polys = False
798
- self.round_to = 0
799
- self.defeature_tolerance = 0.0
800
- self.flatten = True
801
- self.enable_default_component_values = True
802
- self.import_dummy_nets = False
803
- self.gdsii_convert_polygon_to_circles = False
804
- self.import_cross_hatch_shapes_as_lines = True
805
- self.max_antipad_radius = 0.0
806
- self.extracta_use_pin_names = False
807
- self.min_bondwire_width = 0.0
808
- self.antipad_repalce_radius = 0.0
809
- self.gdsii_scaling_factor = 0.0
810
- self.delte_empty_non_laminate_signal_layers = False
811
-
812
- def _write_xml(self, root):
813
- """Write import options to XML element.
799
+ def __init__(self) -> None:
800
+ self.auto_close: bool = False
801
+ self.convert_closed_wide_lines_to_polys: bool = False
802
+ self.round_to: int = 0
803
+ self.defeature_tolerance: float = 0.0
804
+ self.flatten: bool = True
805
+ self.enable_default_component_values: bool = True
806
+ self.import_dummy_nets: bool = False
807
+ self.gdsii_convert_polygon_to_circles: bool = False
808
+ self.import_cross_hatch_shapes_as_lines: bool = True
809
+ self.max_antipad_radius: float = 0.0
810
+ self.extracta_use_pin_names: bool = False
811
+ self.min_bondwire_width: float = 0.0
812
+ self.antipad_replace_radius: float = 0.0
813
+ self.gdsii_scaling_factor: float = 0.0
814
+ self.delete_empty_non_laminate_signal_layers: bool = False
815
+
816
+ def _write_xml(self, root: ET.Element) -> bool:
817
+ """Write control file to XML element.
814
818
 
815
819
  Parameters
816
820
  ----------
817
821
  root : xml.etree.ElementTree.Element
818
822
  Parent XML element to append to.
823
+
824
+ Returns
825
+ -------
826
+ bool
827
+ True if XML content was written successfully.
819
828
  """
829
+
820
830
  content = ET.SubElement(root, "ImportOptions")
821
831
  content.set("AutoClose", str(self.auto_close).lower())
822
832
  if self.round_to != 0:
@@ -838,6 +848,7 @@ class ControlFileImportOptions:
838
848
  if self.gdsii_scaling_factor != 0.0:
839
849
  content.set("GDSIIScalingFactor", str(self.gdsii_scaling_factor))
840
850
  content.set("DeleteEmptyNonLaminateSignalLayers", str(self.delte_empty_non_laminate_signal_layers).lower())
851
+ return True
841
852
 
842
853
 
843
854
  class ControlExtent:
@@ -867,16 +878,16 @@ class ControlExtent:
867
878
 
868
879
  def __init__(
869
880
  self,
870
- type="bbox",
871
- dieltype="bbox",
872
- diel_hactor=0.25,
873
- airbox_hfactor=0.25,
874
- airbox_vr_p=0.25,
875
- airbox_vr_n=0.25,
876
- useradiation=True,
877
- honor_primitives=True,
878
- truncate_at_gnd=True,
879
- ):
881
+ type: str = "bbox",
882
+ dieltype: str = "bbox",
883
+ diel_hactor: float = 0.25,
884
+ airbox_hfactor: float = 0.25,
885
+ airbox_vr_p: float = 0.25,
886
+ airbox_vr_n: float = 0.25,
887
+ useradiation: bool = True,
888
+ honor_primitives: bool = True,
889
+ truncate_at_gnd: bool = True,
890
+ ) -> None:
880
891
  self.type = type
881
892
  self.dieltype = dieltype
882
893
  self.diel_hactor = diel_hactor
@@ -962,20 +973,20 @@ class ControlCircuitPt:
962
973
  class ControlFileComponent:
963
974
  """Represents a component in the control file."""
964
975
 
965
- def __init__(self):
966
- self.refdes = "U1"
967
- self.partname = "BGA"
968
- self.parttype = "IC"
969
- self.die_type = "None"
970
- self.die_orientation = "Chip down"
971
- self.solderball_shape = "None"
972
- self.solder_diameter = "65um"
973
- self.solder_height = "65um"
974
- self.solder_material = "solder"
975
- self.pins = []
976
- self.ports = []
977
-
978
- def add_pin(self, name, x, y, layer):
976
+ def __init__(self) -> None:
977
+ self.refdes: str = "U1"
978
+ self.partname: str = "BGA"
979
+ self.parttype: str = "IC"
980
+ self.die_type: str = "None"
981
+ self.die_orientation: str = "Chip down"
982
+ self.solderball_shape: str = "None"
983
+ self.solder_diameter: str = "65um"
984
+ self.solder_height: str = "65um"
985
+ self.solder_material: str = "solder"
986
+ self.pins: List[Dict[str, Union[str, float]]] = []
987
+ self.ports: List[Dict[str, Union[str, float, None]]] = []
988
+
989
+ def add_pin(self, name: str, x: float, y: float, layer: str) -> None:
979
990
  """Add a pin to the component.
980
991
 
981
992
  Parameters
@@ -991,7 +1002,15 @@ class ControlFileComponent:
991
1002
  """
992
1003
  self.pins.append({"Name": name, "x": x, "y": y, "Layer": layer})
993
1004
 
994
- def add_port(self, name, z0, pospin, refpin=None, pos_type="pin", ref_type="pin"):
1005
+ def add_port(
1006
+ self,
1007
+ name: str,
1008
+ z0: float,
1009
+ pospin: str,
1010
+ refpin: Optional[str] = None,
1011
+ pos_type: str = "pin",
1012
+ ref_type: str = "pin",
1013
+ ) -> None:
995
1014
  """Add a port to the component.
996
1015
 
997
1016
  Parameters
@@ -1059,10 +1078,12 @@ class ControlFileComponents:
1059
1078
  """Manages components for the control file."""
1060
1079
 
1061
1080
  def __init__(self):
1062
- self.units = "um"
1063
- self.components = []
1081
+ self.units: str = "um"
1082
+ self.components: List[str] = []
1064
1083
 
1065
- def add_component(self, ref_des, partname, component_type, die_type="None", solderball_shape="None"):
1084
+ def add_component(
1085
+ self, ref_des: str, partname: str, component_type: str, die_type: str = "None", solderball_shape: str = "None"
1086
+ ) -> ControlFileComponent:
1066
1087
  """Add a new component.
1067
1088
 
1068
1089
  Parameters
@@ -1102,14 +1123,16 @@ class ControlFileBoundaries:
1102
1123
  Length units. Default is "um".
1103
1124
  """
1104
1125
 
1105
- def __init__(self, units="um"):
1106
- self.ports = {}
1107
- self.extents = []
1108
- self.circuit_models = {}
1109
- self.circuit_elements = {}
1110
- self.units = units
1126
+ def __init__(self, units: str = "um") -> None:
1127
+ self.ports: Dict[str, ControlCircuitPt] = {}
1128
+ self.extents: List[ControlExtent] = []
1129
+ self.circuit_models: Dict[str, Any] = {}
1130
+ self.circuit_elements: Dict[str, Any] = {}
1131
+ self.units: str = units
1111
1132
 
1112
- def add_port(self, name, x1, y1, layer1, x2, y2, layer2, z0=50):
1133
+ def add_port(
1134
+ self, name: str, x1: float, y1: float, layer1: str, x2: float, y2: float, layer2: str, z0: float = 50
1135
+ ) -> ControlCircuitPt:
1113
1136
  """Add a port.
1114
1137
 
1115
1138
  Parameters
@@ -1141,16 +1164,16 @@ class ControlFileBoundaries:
1141
1164
 
1142
1165
  def add_extent(
1143
1166
  self,
1144
- type="bbox",
1145
- dieltype="bbox",
1146
- diel_hactor=0.25,
1147
- airbox_hfactor=0.25,
1148
- airbox_vr_p=0.25,
1149
- airbox_vr_n=0.25,
1150
- useradiation=True,
1151
- honor_primitives=True,
1152
- truncate_at_gnd=True,
1153
- ):
1167
+ type: str = "bbox",
1168
+ dieltype: str = "bbox",
1169
+ diel_hactor: float = 0.25,
1170
+ airbox_hfactor: float = 0.25,
1171
+ airbox_vr_p: float = 0.25,
1172
+ airbox_vr_n: float = 0.25,
1173
+ useradiation: bool = True,
1174
+ honor_primitives: bool = True,
1175
+ truncate_at_gnd: bool = True,
1176
+ ) -> ControlExtent:
1154
1177
  """Add an extent.
1155
1178
 
1156
1179
  Parameters
@@ -1235,14 +1258,16 @@ class ControlFileSweep:
1235
1258
  Whether to use Q3D for DC point.
1236
1259
  """
1237
1260
 
1238
- def __init__(self, name, start, stop, step, sweep_type, step_type, use_q3d):
1239
- self.name = name
1240
- self.start = start
1241
- self.stop = stop
1242
- self.step = step
1243
- self.sweep_type = sweep_type
1244
- self.step_type = step_type
1245
- self.use_q3d = use_q3d
1261
+ def __init__(
1262
+ self, name: str, start: str, stop: str, step: str, sweep_type: str, step_type: str, use_q3d: bool
1263
+ ) -> None:
1264
+ self.name: str = name
1265
+ self.start: str = start
1266
+ self.stop: str = stop
1267
+ self.step: str = step
1268
+ self.sweep_type: str = sweep_type
1269
+ self.step_type: str = step_type
1270
+ self.use_q3d: bool = use_q3d
1246
1271
 
1247
1272
  def _write_xml(self, root):
1248
1273
  """Write sweep to XML element.
@@ -1286,19 +1311,19 @@ class ControlFileMeshOp:
1286
1311
  Dictionary of nets and layers.
1287
1312
  """
1288
1313
 
1289
- def __init__(self, name, region, type, nets_layers):
1290
- self.name = name
1291
- self.region = name
1292
- self.type = type
1293
- self.nets_layers = nets_layers
1294
- self.num_max_elem = 1000
1295
- self.restrict_elem = False
1296
- self.restrict_length = True
1297
- self.max_length = "20um"
1298
- self.skin_depth = "1um"
1299
- self.surf_tri_length = "1mm"
1300
- self.num_layers = 2
1301
- self.region_solve_inside = False
1314
+ def __init__(self, name: str, region: str, type: str, nets_layers: Dict[str, str]) -> None:
1315
+ self.name: str = name
1316
+ self.region: str = region
1317
+ self.type: str = type
1318
+ self.nets_layers: Dict[str, str] = nets_layers
1319
+ self.num_max_elem: int = 1000
1320
+ self.restrict_elem: bool = False
1321
+ self.restrict_length: bool = True
1322
+ self.max_length: str = "20um"
1323
+ self.skin_depth: str = "1um"
1324
+ self.surf_tri_length: str = "1mm"
1325
+ self.num_layers: int = 2
1326
+ self.region_solve_inside: bool = False
1302
1327
 
1303
1328
  def _write_xml(self, root):
1304
1329
  """Write mesh operation to XML element.
@@ -1353,25 +1378,34 @@ class ControlFileSetup:
1353
1378
  Setup name.
1354
1379
  """
1355
1380
 
1356
- def __init__(self, name):
1357
- self.name = name
1358
- self.enabled = True
1359
- self.save_fields = False
1360
- self.save_rad_fields = False
1361
- self.frequency = "1GHz"
1362
- self.maxpasses = 10
1363
- self.max_delta = 0.02
1364
- self.union_polygons = True
1365
- self.small_voids_area = 0
1366
- self.mode_type = "IC"
1367
- self.ic_model_resolution = "Auto"
1368
- self.order_basis = "FirstOrder"
1369
- self.solver_type = "Auto"
1370
- self.low_freq_accuracy = False
1371
- self.mesh_operations = []
1372
- self.sweeps = []
1373
-
1374
- def add_sweep(self, name, start, stop, step, sweep_type="Interpolating", step_type="LinearStep", use_q3d=True):
1381
+ def __init__(self, name: str) -> None:
1382
+ self.name: str = name
1383
+ self.enabled: bool = True
1384
+ self.save_fields: bool = False
1385
+ self.save_rad_fields: bool = False
1386
+ self.frequency: str = "1GHz"
1387
+ self.maxpasses: int = 10
1388
+ self.max_delta: float = 0.02
1389
+ self.union_polygons: bool = True
1390
+ self.small_voids_area: int = 0
1391
+ self.mode_type: str = "IC"
1392
+ self.ic_model_resolution: str = "Auto"
1393
+ self.order_basis: str = "FirstOrder"
1394
+ self.solver_type: str = "Auto"
1395
+ self.low_freq_accuracy: bool = False
1396
+ self.mesh_operations: List[ControlFileMeshOp] = []
1397
+ self.sweeps: List[ControlFileSweep] = []
1398
+
1399
+ def add_sweep(
1400
+ self,
1401
+ name: str,
1402
+ start: str,
1403
+ stop: str,
1404
+ step: str,
1405
+ sweep_type: str = "Interpolating",
1406
+ step_type: str = "LinearStep",
1407
+ use_q3d: bool = True,
1408
+ ) -> ControlFileSweep:
1375
1409
  """Add a frequency sweep.
1376
1410
 
1377
1411
  Parameters
@@ -1399,7 +1433,7 @@ class ControlFileSetup:
1399
1433
  self.sweeps.append(ControlFileSweep(name, start, stop, step, sweep_type, step_type, use_q3d))
1400
1434
  return self.sweeps[-1]
1401
1435
 
1402
- def add_mesh_operation(self, name, region, type, nets_layers):
1436
+ def add_mesh_operation(self, name: str, region: str, type: str, nets_layers: Dict[str, str]) -> ControlFileMeshOp:
1403
1437
  """Add a mesh operation.
1404
1438
 
1405
1439
  Parameters
@@ -1480,7 +1514,7 @@ class ControlFileSetups:
1480
1514
  def __init__(self):
1481
1515
  self.setups = []
1482
1516
 
1483
- def add_setup(self, name, frequency):
1517
+ def add_setup(self, name: str, frequency: str) -> ControlFileSetup:
1484
1518
  """Add a simulation setup.
1485
1519
 
1486
1520
  Parameters
@@ -1526,12 +1560,25 @@ class ControlFile:
1526
1560
  Path to layer map file.
1527
1561
  """
1528
1562
 
1529
- def __init__(self, xml_input=None, tecnhology=None, layer_map=None):
1563
+ def __init__(
1564
+ self, xml_input: Optional[str] = None, technology: Optional[str] = None, layer_map: Optional[str] = None
1565
+ ) -> None:
1566
+ """Initialize control file object.
1567
+
1568
+ Parameters
1569
+ ----------
1570
+ xml_input : str, optional
1571
+ Path to existing XML file to parse.
1572
+ tecnhology : str, optional
1573
+ Path to technology file to convert.
1574
+ layer_map : str, optional
1575
+ Path to layer map file.
1576
+ """
1530
1577
  self.stackup = ControlFileStackup()
1531
1578
  if xml_input:
1532
1579
  self.parse_xml(xml_input)
1533
- if tecnhology:
1534
- self.parse_technology(tecnhology)
1580
+ if technology:
1581
+ self.parse_technology(technology)
1535
1582
  if layer_map:
1536
1583
  self.parse_layer_map(layer_map)
1537
1584
  self.boundaries = ControlFileBoundaries()
@@ -1543,7 +1590,7 @@ class ControlFile:
1543
1590
  self.import_options = ControlFileImportOptions()
1544
1591
  pass
1545
1592
 
1546
- def parse_technology(self, tecnhology, edbversion=None):
1593
+ def parse_technology(self, tecnhology: str, edbversion: Optional[str] = None) -> bool:
1547
1594
  """Parse a technology file and convert to XML control file.
1548
1595
 
1549
1596
  Parameters
@@ -1563,7 +1610,7 @@ class ControlFile:
1563
1610
  if xml_temp:
1564
1611
  return self.parse_xml(xml_temp)
1565
1612
 
1566
- def parse_layer_map(self, layer_map):
1613
+ def parse_layer_map(self, layer_map: str) -> bool:
1567
1614
  """Parse a layer map file and update stackup.
1568
1615
 
1569
1616
  Parameters
@@ -1613,7 +1660,7 @@ class ControlFile:
1613
1660
  break
1614
1661
  return True
1615
1662
 
1616
- def parse_xml(self, xml_input):
1663
+ def parse_xml(self, xml_input: str) -> bool:
1617
1664
  """Parse an XML control file and populate the object.
1618
1665
 
1619
1666
  Parameters