pyedb 0.56.0__py3-none-any.whl → 0.57.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.

Files changed (99) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_data.py +3 -0
  3. pyedb/configuration/cfg_terminals.py +232 -0
  4. pyedb/configuration/configuration.py +146 -3
  5. pyedb/dotnet/clr_module.py +1 -2
  6. pyedb/dotnet/database/Variables.py +30 -22
  7. pyedb/dotnet/database/cell/layout.py +5 -1
  8. pyedb/dotnet/database/cell/primitive/primitive.py +2 -2
  9. pyedb/dotnet/database/cell/terminal/bundle_terminal.py +12 -0
  10. pyedb/dotnet/database/cell/terminal/pingroup_terminal.py +1 -1
  11. pyedb/dotnet/database/cell/terminal/terminal.py +38 -0
  12. pyedb/dotnet/database/components.py +14 -16
  13. pyedb/dotnet/database/dotnet/database.py +1 -0
  14. pyedb/dotnet/database/edb_data/control_file.py +6 -3
  15. pyedb/dotnet/database/edb_data/nets_data.py +3 -3
  16. pyedb/dotnet/database/edb_data/padstacks_data.py +5 -2
  17. pyedb/dotnet/database/edb_data/ports.py +0 -25
  18. pyedb/dotnet/database/edb_data/primitives_data.py +3 -3
  19. pyedb/dotnet/database/edb_data/raptor_x_simulation_setup_data.py +18 -19
  20. pyedb/dotnet/database/edb_data/simulation_configuration.py +3 -3
  21. pyedb/dotnet/database/hfss.py +9 -8
  22. pyedb/dotnet/database/layout_validation.py +6 -3
  23. pyedb/dotnet/database/materials.py +1 -3
  24. pyedb/dotnet/database/modeler.py +7 -3
  25. pyedb/dotnet/database/nets.py +27 -19
  26. pyedb/dotnet/database/padstack.py +4 -2
  27. pyedb/dotnet/database/sim_setup_data/io/siwave.py +1 -1
  28. pyedb/dotnet/database/siwave.py +4 -3
  29. pyedb/dotnet/database/stackup.py +50 -26
  30. pyedb/dotnet/database/utilities/heatsink.py +0 -1
  31. pyedb/dotnet/database/utilities/simulation_setup.py +7 -5
  32. pyedb/dotnet/database/utilities/siwave_cpa_simulation_setup.py +1 -0
  33. pyedb/dotnet/database/utilities/siwave_simulation_setup.py +5 -2
  34. pyedb/dotnet/edb.py +39 -34
  35. pyedb/exceptions.py +1 -2
  36. pyedb/extensions/create_cell_array.py +19 -5
  37. pyedb/generic/data_handlers.py +13 -23
  38. pyedb/generic/design_types.py +9 -35
  39. pyedb/generic/filesystem.py +4 -2
  40. pyedb/generic/general_methods.py +4 -5
  41. pyedb/generic/plot.py +2 -2
  42. pyedb/grpc/database/_typing.py +0 -0
  43. pyedb/grpc/database/components.py +7 -8
  44. pyedb/grpc/database/control_file.py +14 -35
  45. pyedb/grpc/database/definition/materials.py +1 -1
  46. pyedb/grpc/database/definition/package_def.py +6 -3
  47. pyedb/grpc/database/definition/padstack_def.py +4 -7
  48. pyedb/grpc/database/hfss.py +1 -4
  49. pyedb/grpc/database/hierarchy/component.py +3 -4
  50. pyedb/grpc/database/hierarchy/pingroup.py +16 -3
  51. pyedb/grpc/database/layers/layer.py +1 -2
  52. pyedb/grpc/database/layers/stackup_layer.py +42 -19
  53. pyedb/grpc/database/layout/layout.py +43 -27
  54. pyedb/grpc/database/layout/voltage_regulator.py +6 -1
  55. pyedb/grpc/database/layout_validation.py +5 -2
  56. pyedb/grpc/database/modeler.py +226 -244
  57. pyedb/grpc/database/net/differential_pair.py +9 -2
  58. pyedb/grpc/database/net/extended_net.py +24 -9
  59. pyedb/grpc/database/net/net.py +14 -5
  60. pyedb/grpc/database/net/net_class.py +24 -7
  61. pyedb/grpc/database/nets.py +11 -43
  62. pyedb/grpc/database/padstacks.py +5 -16
  63. pyedb/grpc/database/primitive/bondwire.py +3 -67
  64. pyedb/grpc/database/primitive/circle.py +42 -3
  65. pyedb/grpc/database/primitive/padstack_instance.py +17 -19
  66. pyedb/grpc/database/primitive/path.py +154 -5
  67. pyedb/grpc/database/primitive/polygon.py +73 -7
  68. pyedb/grpc/database/primitive/primitive.py +2 -2
  69. pyedb/grpc/database/primitive/rectangle.py +105 -4
  70. pyedb/grpc/database/simulation_setup/hfss_general_settings.py +0 -2
  71. pyedb/grpc/database/simulation_setup/hfss_settings_options.py +0 -4
  72. pyedb/grpc/database/simulation_setup/siwave_cpa_simulation_setup.py +1 -0
  73. pyedb/grpc/database/simulation_setup/sweep_data.py +1 -3
  74. pyedb/grpc/database/siwave.py +6 -13
  75. pyedb/grpc/database/source_excitations.py +39 -56
  76. pyedb/grpc/database/stackup.py +50 -27
  77. pyedb/grpc/database/terminal/bundle_terminal.py +10 -3
  78. pyedb/grpc/database/terminal/pingroup_terminal.py +8 -1
  79. pyedb/grpc/database/terminal/terminal.py +19 -8
  80. pyedb/grpc/database/utility/heat_sink.py +0 -1
  81. pyedb/grpc/database/utility/hfss_extent_info.py +2 -2
  82. pyedb/grpc/database/utility/xml_control_file.py +6 -3
  83. pyedb/grpc/edb.py +24 -19
  84. pyedb/grpc/edb_init.py +1 -0
  85. pyedb/ipc2581/ecad/cad_data/layer_feature.py +6 -2
  86. pyedb/ipc2581/ecad/cad_data/step.py +1 -1
  87. pyedb/ipc2581/ipc2581.py +8 -7
  88. pyedb/libraries/common.py +3 -4
  89. pyedb/libraries/rf_libraries/base_functions.py +7 -16
  90. pyedb/libraries/rf_libraries/planar_antennas.py +3 -21
  91. pyedb/misc/downloads.py +1 -0
  92. pyedb/misc/misc.py +5 -2
  93. pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +1 -1
  94. pyedb/misc/utilities.py +0 -1
  95. pyedb/modeler/geometry_operators.py +3 -2
  96. {pyedb-0.56.0.dist-info → pyedb-0.57.0.dist-info}/METADATA +3 -3
  97. {pyedb-0.56.0.dist-info → pyedb-0.57.0.dist-info}/RECORD +99 -97
  98. {pyedb-0.56.0.dist-info → pyedb-0.57.0.dist-info}/WHEEL +0 -0
  99. {pyedb-0.56.0.dist-info → pyedb-0.57.0.dist-info}/licenses/LICENSE +0 -0
@@ -3,6 +3,8 @@ import secrets
3
3
  import shutil
4
4
  import string
5
5
 
6
+ from pyedb.generic.settings import settings
7
+
6
8
 
7
9
  def search_files(dirname, pattern="*"):
8
10
  """Search for files inside a directory given a specific pattern.
@@ -65,8 +67,8 @@ class Scratch:
65
67
  try:
66
68
  # TODO check why on Anaconda 3.7 get errors with os.path.exists
67
69
  shutil.rmtree(self._scratch_path, ignore_errors=True)
68
- except:
69
- pass
70
+ except Exception:
71
+ settings.logger.error(f"An error occurred while removing {self._scratch_path}")
70
72
 
71
73
  def copyfile(self, src_file, dst_filename=None):
72
74
  """
@@ -118,7 +118,6 @@ def _exception(ex_info, func, args, kwargs, message="Type Error"):
118
118
  if message_to_print:
119
119
  _write_mes("Last Electronics Desktop Message - " + message_to_print)
120
120
 
121
- args_name = []
122
121
  try:
123
122
  args_dict = _get_args_dicts(func, args, kwargs)
124
123
  first_time_log = True
@@ -129,13 +128,13 @@ def _exception(ex_info, func, args, kwargs, message="Type Error"):
129
128
  _write_mes("Method arguments: ")
130
129
  first_time_log = False
131
130
  _write_mes(" {} = {} ".format(el, args_dict[el]))
132
- except:
133
- pass
134
- args = [func.__name__] + [i for i in args_name if i not in ["self"]]
131
+ except Exception:
132
+ settings.logger.error(f"An error occurred while parsing and logging an error with method {func.__name__}.")
133
+
135
134
  if not func.__name__.startswith("_"):
136
135
  _write_mes(
137
136
  "Check Online documentation on: https://edb.docs.pyansys.com/version/stable/search.html?q={}".format(
138
- "+".join(args)
137
+ func.__name__
139
138
  )
140
139
  )
141
140
 
pyedb/generic/plot.py CHANGED
@@ -24,8 +24,8 @@ except ImportError:
24
24
  "The Matplotlib module is required to run some functionalities of PostProcess.\n"
25
25
  "Install with \n\npip install matplotlib\n\nRequires CPython."
26
26
  )
27
- except:
28
- pass
27
+ except Exception:
28
+ warnings.warn("Unknown error occurred while attempting to import Matplotlib.")
29
29
 
30
30
 
31
31
  def plot_matplotlib(
File without changes
@@ -20,9 +20,8 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
- """This module contains the `Components` class.
23
+ """This module contains the `Components` class."""
24
24
 
25
- """
26
25
  import codecs
27
26
  import json
28
27
  import math
@@ -31,8 +30,7 @@ import re
31
30
  from typing import Any, Dict, List, Optional, Tuple, Union
32
31
  import warnings
33
32
 
34
- from ansys.edb.core.definition.die_property import DieOrientation as GrpDieOrientation
35
- from ansys.edb.core.definition.die_property import DieType as GrpcDieType
33
+ from ansys.edb.core.definition.die_property import DieOrientation as GrpDieOrientation, DieType as GrpcDieType
36
34
  from ansys.edb.core.definition.solder_ball_property import (
37
35
  SolderballShape as GrpcSolderballShape,
38
36
  )
@@ -996,8 +994,7 @@ class Components(object):
996
994
  """
997
995
  component_definition = ComponentDef.find(self._db, name)
998
996
  if component_definition.is_null:
999
- from ansys.edb.core.layout.cell import Cell as GrpcCell
1000
- from ansys.edb.core.layout.cell import CellType as GrpcCellType
997
+ from ansys.edb.core.layout.cell import Cell as GrpcCell, CellType as GrpcCellType
1001
998
 
1002
999
  foot_print_cell = GrpcCell.create(self._pedb.active_db, GrpcCellType.FOOTPRINT_CELL, name)
1003
1000
  component_definition = ComponentDef.create(self._db, name, fp=foot_print_cell)
@@ -1078,7 +1075,9 @@ class Components(object):
1078
1075
  return False
1079
1076
  new_cmp = GrpcComponentGroup.create(self._active_layout, component_name, compdef.name)
1080
1077
  if hasattr(pins[0], "component") and pins[0].component:
1081
- hosting_component_location = pins[0].component.transform
1078
+ hosting_component_location = None
1079
+ if not pins[0].component.is_null:
1080
+ hosting_component_location = pins[0].component.transform
1082
1081
  else:
1083
1082
  hosting_component_location = None
1084
1083
  if not len(pins) == len(compdef.component_pins):
@@ -2228,7 +2227,7 @@ class Components(object):
2228
2227
  Examples
2229
2228
  --------
2230
2229
  >>> from pyedb import Edb
2231
- >>> edb_file = r'C:\my_edb_file.aedb'
2230
+ >>> edb_file = r"C:\my_edb_file.aedb"
2232
2231
  >>> edb = Edb(edb_file)
2233
2232
  >>> for cmp in list(edb.components.instances.keys()):
2234
2233
  >>> edb.components.deactivate_rlc_component(component=cmp, create_circuit_port=False)
@@ -58,40 +58,26 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
58
58
  -------
59
59
  # Example 1: Converting a technology file to control file
60
60
  >>> converted_file = convert_technology_file(
61
- >>> tech_file="/path/to/tech.t",
62
- >>> edbversion="2025.2",
63
- >>> control_file="/path/to/output.xml"
64
- >>> )
61
+ ... tech_file="/path/to/tech.t", edbversion="2025.2", control_file="/path/to/output.xml"
62
+ ... )
65
63
  >>> if converted_file:
66
64
  >>> print(f"Converted to: {converted_file}")
67
65
 
68
66
  # Example 2: Creating a material
69
67
  >>> from pyedb import ControlFileMaterial
70
- >>> material = ControlFileMaterial(
71
- >>> "Copper",
72
- >>> {"Permittivity": 1.0, "Conductivity": 5.8e7}
73
- >>> )
68
+ >>> material = ControlFileMaterial("Copper", {"Permittivity": 1.0, "Conductivity": 5.8e7})
74
69
 
75
70
  # Example 3: Creating a dielectric layer
76
71
  >>> from pyedb import ControlFileDielectric
77
- >>> dielectric = ControlFileDielectric(
78
- >>> "Core",
79
- >>> {"Thickness": "0.2mm", "Material": "FR4"}
80
- >>> )
72
+ >>> dielectric = ControlFileDielectric("Core", {"Thickness": "0.2mm", "Material": "FR4"})
81
73
 
82
74
  # Example 4: Creating a signal layer
83
75
  >>> from pyedb import ControlFileLayer
84
- >>> signal_layer = ControlFileLayer(
85
- >>> "TopLayer",
86
- >>> {"Type": "signal", "Material": "Copper", "Thickness": "0.035mm"}
87
- >>> )
76
+ >>> signal_layer = ControlFileLayer("TopLayer", {"Type": "signal", "Material": "Copper", "Thickness": "0.035mm"})
88
77
 
89
78
  # Example 5: Creating a via layer
90
79
  >>> from pyedb import ControlFileVia
91
- >>> via_layer = ControlFileVia(
92
- >>> "Via1",
93
- >>> {"StartLayer": "TopLayer", "StopLayer": "BottomLayer"}
94
- >>> )
80
+ >>> via_layer = ControlFileVia("Via1", {"StartLayer": "TopLayer", "StopLayer": "BottomLayer"})
95
81
  >>> via_layer.create_via_group = True
96
82
  >>> via_layer.tolerance = "0.1mm"
97
83
 
@@ -111,11 +97,7 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
111
97
 
112
98
  # Example 8: Setting up simulation extents
113
99
  >>> from pyedb import ControlExtent
114
- >>> extent = ControlExtent(
115
- >>> type="Conforming",
116
- >>> diel_hactor=0.3,
117
- >>> airbox_hfactor=0.5
118
- >>> )
100
+ >>> extent = ControlExtent(type="Conforming", diel_hactor=0.3, airbox_hfactor=0.5)
119
101
 
120
102
  # Example 9: Creating circuit ports
121
103
  >>> from pyedb import ControlCircuitPt
@@ -142,17 +124,11 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
142
124
 
143
125
  # Example 13: Frequency sweep configuration
144
126
  >>> from pyedb import ControlFileSweep
145
- >>> sweep = ControlFileSweep(
146
- >>> "Sweep1", "1GHz", "10GHz", "0.1GHz",
147
- >>> "Interpolating", "LinearStep", True
148
- >>> )
127
+ >>> sweep = ControlFileSweep("Sweep1", "1GHz", "10GHz", "0.1GHz", "Interpolating", "LinearStep", True)
149
128
 
150
129
  # Example 14: Mesh operation setup
151
130
  >>> from pyedb import ControlFileMeshOp
152
- >>> mesh_op = ControlFileMeshOp(
153
- >>> "FineMesh", "Region1", "MeshOperationSkinDepth",
154
- >>> {"Net1": "TopLayer"}
155
- >>> )
131
+ >>> mesh_op = ControlFileMeshOp("FineMesh", "Region1", "MeshOperationSkinDepth", {"Net1": "TopLayer"})
156
132
  >>> mesh_op.skin_depth = "1um"
157
133
 
158
134
  # Example 15: Simulation setup configuration
@@ -290,8 +266,11 @@ class ControlProperty:
290
266
  double.text = str(self.value)
291
267
  else:
292
268
  pass
293
- except:
294
- pass
269
+ except Exception as e:
270
+ settings.logger.error(
271
+ f"A(n) {type(e).__name__} error occurred while attempting to create a new sub-element {self.name} "
272
+ f"for element {root}: {str(e)}"
273
+ )
295
274
 
296
275
 
297
276
  class ControlFileMaterial:
@@ -34,9 +34,9 @@ from ansys.edb.core.definition.djordjecvic_sarkar_model import (
34
34
  DjordjecvicSarkarModel as GrpcDjordjecvicSarkarModel,
35
35
  )
36
36
  from ansys.edb.core.definition.material_def import (
37
+ MaterialDef as GrpcMaterialDef,
37
38
  MaterialProperty as GrpcMaterialProperty,
38
39
  )
39
- from ansys.edb.core.definition.material_def import MaterialDef as GrpcMaterialDef
40
40
  from ansys.edb.core.definition.multipole_debye_model import (
41
41
  MultipoleDebyeModel as GrpcMultipoleDebyeModel,
42
42
  )
@@ -193,8 +193,11 @@ class PackageDef(GrpcPackageDef):
193
193
  """
194
194
  try:
195
195
  return HeatSink(self._pedb, super().heat_sink)
196
- except:
197
- pass
196
+ except Exception as e:
197
+ settings.logger.error(
198
+ f"A(n) {type(e).__name__} error occurred while attempting to access 'heatsink' "
199
+ f"property for object {self}: {str(e)}"
200
+ )
198
201
 
199
202
  @property
200
203
  @deprecated_property
@@ -222,9 +225,9 @@ class PackageDef(GrpcPackageDef):
222
225
  Fin thickness.
223
226
  """
224
227
  from ansys.edb.core.utility.heat_sink import (
228
+ HeatSink as GrpcHeatSink,
225
229
  HeatSinkFinOrientation as GrpcHeatSinkFinOrientation,
226
230
  )
227
- from ansys.edb.core.utility.heat_sink import HeatSink as GrpcHeatSink
228
231
 
229
232
  if fin_orientation == "x_oriented":
230
233
  fin_orientation = GrpcHeatSinkFinOrientation.X_ORIENTED
@@ -26,15 +26,12 @@ import warnings
26
26
  from ansys.edb.core.definition.padstack_def import PadstackDef as GrpcPadstackDef
27
27
  from ansys.edb.core.definition.padstack_def_data import (
28
28
  PadGeometryType as GrpcPadGeometryType,
29
- )
30
- from ansys.edb.core.definition.padstack_def_data import (
31
29
  PadstackHoleRange as GrpcPadstackHoleRange,
30
+ PadType as GrpcPadType,
32
31
  )
33
- from ansys.edb.core.definition.padstack_def_data import PadType as GrpcPadType
34
32
  import ansys.edb.core.geometry.polygon_data
35
33
  from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
36
- from ansys.edb.core.hierarchy.structure3d import MeshClosure as GrpcMeshClosure
37
- from ansys.edb.core.hierarchy.structure3d import Structure3D as GrpcStructure3D
34
+ from ansys.edb.core.hierarchy.structure3d import MeshClosure as GrpcMeshClosure, Structure3D as GrpcStructure3D
38
35
  from ansys.edb.core.primitive.circle import Circle as GrpcCircle
39
36
 
40
37
  from pyedb.generic.general_methods import generate_unique_name
@@ -127,7 +124,7 @@ class PadProperties:
127
124
  self._update_pad_parameters_parameters(geom_type=GrpcPadGeometryType.PADGEOMTYPE_POLYGON)
128
125
  else:
129
126
  raise ValueError(
130
- f"Unsupported pad shape: {value}. Supported shapes are 'circle', " f"'rectangle', and 'polygon'."
127
+ f"Unsupported pad shape: {value}. Supported shapes are 'circle', 'rectangle', and 'polygon'."
131
128
  )
132
129
 
133
130
  @property
@@ -771,7 +768,7 @@ class PadstackDef(GrpcPadstackDef):
771
768
  s3d.add_member(cloned_circle2)
772
769
  if not self.data.material.value:
773
770
  self._pedb.logger.warning(
774
- f"Padstack definution {self.name} has no material defined." f"Defaulting to copper"
771
+ f"Padstack definution {self.name} has no material defined.Defaulting to copper"
775
772
  )
776
773
  self.data.material = "copper"
777
774
  s3d.set_material(self.data.material.value)
@@ -23,6 +23,7 @@
23
23
  """
24
24
  This module contains the ``EdbHfss`` class.
25
25
  """
26
+
26
27
  import math
27
28
  import warnings
28
29
 
@@ -1259,11 +1260,7 @@ class Hfss(object):
1259
1260
  )
1260
1261
  from ansys.edb.core.simulation_setup.simulation_setup import (
1261
1262
  Distribution as GrpcDistribution,
1262
- )
1263
- from ansys.edb.core.simulation_setup.simulation_setup import (
1264
1263
  FrequencyData as GrpcFrequencyData,
1265
- )
1266
- from ansys.edb.core.simulation_setup.simulation_setup import (
1267
1264
  SweepData as GrpcSweepData,
1268
1265
  )
1269
1266
 
@@ -28,14 +28,13 @@ import warnings
28
28
  from ansys.edb.core.definition.component_model import (
29
29
  NPortComponentModel as GrpcNPortComponentModel,
30
30
  )
31
- from ansys.edb.core.definition.die_property import DieOrientation as GrpcDieOrientation
32
- from ansys.edb.core.definition.die_property import DieType as GrpcDieType
31
+ from ansys.edb.core.definition.die_property import DieOrientation as GrpcDieOrientation, DieType as GrpcDieType
33
32
  from ansys.edb.core.definition.solder_ball_property import SolderballShape
34
33
  from ansys.edb.core.geometry.polygon_data import PolygonData as GrpcPolygonData
35
34
  from ansys.edb.core.hierarchy.component_group import (
36
35
  ComponentGroup as GrpcComponentGroup,
36
+ ComponentType as GrpcComponentType,
37
37
  )
38
- from ansys.edb.core.hierarchy.component_group import ComponentType as GrpcComponentType
39
38
  from ansys.edb.core.hierarchy.netlist_model import NetlistModel as GrpcNetlistModel
40
39
  from ansys.edb.core.hierarchy.pin_pair_model import PinPairModel as GrpcPinPairModel
41
40
  from ansys.edb.core.hierarchy.sparameter_model import (
@@ -1102,7 +1101,7 @@ class Component(GrpcComponentGroup):
1102
1101
  return False
1103
1102
  if not reference_net:
1104
1103
  self._pedb.logger.warning(
1105
- f"No reference net provided for S parameter file {file_path}, net `GND` is " f"assigned by default"
1104
+ f"No reference net provided for S parameter file {file_path}, net `GND` is assigned by default"
1106
1105
  )
1107
1106
  reference_net = "GND"
1108
1107
  n_port_model = GrpcNPortComponentModel.find_by_name(self.component_def, name)
@@ -20,16 +20,20 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
+ from __future__ import annotations
23
24
 
25
+ from typing import TYPE_CHECKING
26
+
27
+ if TYPE_CHECKING:
28
+ from pyedb.grpc.database.hierarchy.component import Component
29
+ from pyedb.grpc.database.net.net import Net
30
+ from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
24
31
  from typing import Union
25
32
 
26
33
  from ansys.edb.core.hierarchy.pin_group import PinGroup as GrpcPinGroup
27
34
  from ansys.edb.core.terminal.terminal import BoundaryType as GrpcBoundaryType
28
35
 
29
36
  from pyedb.generic.general_methods import generate_unique_name
30
- from pyedb.grpc.database.hierarchy.component import Component
31
- from pyedb.grpc.database.net.net import Net
32
- from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
33
37
  from pyedb.grpc.database.terminal.pingroup_terminal import PinGroupTerminal
34
38
  from pyedb.grpc.database.utility.value import Value
35
39
 
@@ -63,10 +67,13 @@ class PinGroup(GrpcPinGroup):
63
67
  :class:`Component <pyedb.grpc.database.hierarchy.component.Component>`
64
68
  Pin group component.
65
69
  """
70
+
66
71
  return Component(self._pedb, super().component)
67
72
 
68
73
  @component.setter
69
74
  def component(self, value):
75
+ from pyedb.grpc.database.hierarchy.component import Component
76
+
70
77
  if isinstance(value, Component):
71
78
  super(PinGroup, self.__class__).component.__set__(self, value)
72
79
 
@@ -78,6 +85,8 @@ class PinGroup(GrpcPinGroup):
78
85
  -------
79
86
  Dict[:class:`PadstackInstance <pyedb.grpc.database.primitive.padstack_instance.PadstackInstance>`].
80
87
  """
88
+ from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
89
+
81
90
  return {i.name: PadstackInstance(self._pedb, i) for i in super().pins}
82
91
 
83
92
  @property
@@ -88,10 +97,14 @@ class PinGroup(GrpcPinGroup):
88
97
  -------
89
98
  :class:`Net <ansys.edb.core.net.net.Net>`.
90
99
  """
100
+ from pyedb.grpc.database.net.net import Net
101
+
91
102
  return Net(self._pedb, super().net)
92
103
 
93
104
  @net.setter
94
105
  def net(self, value):
106
+ from pyedb.grpc.database.net.net import Net
107
+
95
108
  if isinstance(value, Net):
96
109
  super(PinGroup, self.__class__).net.__set__(self, value)
97
110
 
@@ -6,8 +6,7 @@
6
6
 
7
7
  from __future__ import absolute_import
8
8
 
9
- from ansys.edb.core.layer.layer import Layer as GrpcLayer
10
- from ansys.edb.core.layer.layer import LayerType as GrpcLayerType
9
+ from ansys.edb.core.layer.layer import Layer as GrpcLayer, LayerType as GrpcLayerType
11
10
 
12
11
 
13
12
  class Layer(GrpcLayer):
@@ -23,8 +23,7 @@
23
23
  from __future__ import absolute_import
24
24
 
25
25
  from ansys.edb.core.layer.layer import LayerType as GrpcLayerType
26
- from ansys.edb.core.layer.stackup_layer import RoughnessRegion as GrpcRoughnessRegion
27
- from ansys.edb.core.layer.stackup_layer import StackupLayer as GrpcStackupLayer
26
+ from ansys.edb.core.layer.stackup_layer import RoughnessRegion as GrpcRoughnessRegion, StackupLayer as GrpcStackupLayer
28
27
 
29
28
  from pyedb.grpc.database.utility.value import Value
30
29
 
@@ -354,8 +353,11 @@ class StackupLayer(GrpcStackupLayer):
354
353
  if len(top_roughness_model) == 2:
355
354
  top_roughness_model[0] = Value(value)
356
355
  self.set_roughness_model(top_roughness_model, GrpcRoughnessRegion.TOP)
357
- except:
358
- pass
356
+ except Exception as e:
357
+ self._pedb.logger.error(
358
+ f"Failed to update property top_hallhuray_nodule_radius with value {value} "
359
+ f"- {type(e).__name__}: {str(e)}"
360
+ )
359
361
 
360
362
  @property
361
363
  def top_hallhuray_surface_ratio(self) -> float:
@@ -382,8 +384,11 @@ class StackupLayer(GrpcStackupLayer):
382
384
  if len(top_roughness_model) == 2:
383
385
  top_roughness_model[1] = Value(value)
384
386
  self.set_roughness_model(top_roughness_model, GrpcRoughnessRegion.TOP)
385
- except:
386
- pass
387
+ except Exception as e:
388
+ self._pedb.logger.error(
389
+ f"Failed to update property top_hallhuray_surface_ratio with value {value} "
390
+ f"- {type(e).__name__}: {str(e)}"
391
+ )
387
392
 
388
393
  @property
389
394
  def bottom_hallhuray_nodule_radius(self) -> float:
@@ -410,8 +415,11 @@ class StackupLayer(GrpcStackupLayer):
410
415
  if len(bottom_roughness_model) == 2:
411
416
  bottom_roughness_model[0] = Value(value)
412
417
  self.set_roughness_model(bottom_roughness_model, GrpcRoughnessRegion.BOTTOM)
413
- except:
414
- pass
418
+ except Exception as e:
419
+ self._pedb.logger.error(
420
+ f"Failed to update property bottom_hallhuray_nodule_radius with value {value} "
421
+ f"- {type(e).__name__}: {str(e)}"
422
+ )
415
423
 
416
424
  @property
417
425
  def bottom_hallhuray_surface_ratio(self) -> float:
@@ -438,8 +446,11 @@ class StackupLayer(GrpcStackupLayer):
438
446
  if len(bottom_roughness_model) == 2:
439
447
  bottom_roughness_model[1] = Value(value)
440
448
  self.set_roughness_model(bottom_roughness_model, GrpcRoughnessRegion.BOTTOM)
441
- except:
442
- pass
449
+ except Exception as e:
450
+ self._pedb.logger.error(
451
+ f"Failed to update property bottom_hallhuray_surface_ratio with value {value} "
452
+ f"- {type(e).__name__}: {str(e)}"
453
+ )
443
454
 
444
455
  @property
445
456
  def side_hallhuray_nodule_radius(self) -> float:
@@ -466,8 +477,11 @@ class StackupLayer(GrpcStackupLayer):
466
477
  if len(side_roughness_model) == 2:
467
478
  side_roughness_model[0] = Value(value)
468
479
  self.set_roughness_model(side_roughness_model, GrpcRoughnessRegion.SIDE)
469
- except:
470
- pass
480
+ except Exception as e:
481
+ self._pedb.logger.error(
482
+ f"Failed to update property side_hallhuray_nodule_radius with value {value} "
483
+ f"- {type(e).__name__}: {str(e)}"
484
+ )
471
485
 
472
486
  @property
473
487
  def side_hallhuray_surface_ratio(self) -> float:
@@ -493,8 +507,11 @@ class StackupLayer(GrpcStackupLayer):
493
507
  if len(side_roughness_model) == 2:
494
508
  side_roughness_model[1] = Value(value)
495
509
  self.set_roughness_model(side_roughness_model, GrpcRoughnessRegion.SIDE)
496
- except:
497
- pass
510
+ except Exception as e:
511
+ self._pedb.logger.error(
512
+ f"Failed to update property side_hallhuray_surface_ratio with value {value} "
513
+ f"- {type(e).__name__}: {str(e)}"
514
+ )
498
515
 
499
516
  @property
500
517
  def top_groisse_roughness(self) -> float:
@@ -521,8 +538,10 @@ class StackupLayer(GrpcStackupLayer):
521
538
  if isinstance(top_roughness_model, Value):
522
539
  top_roughness_model = Value(value)
523
540
  self.set_roughness_model(top_roughness_model, GrpcRoughnessRegion.TOP)
524
- except:
525
- pass
541
+ except Exception as e:
542
+ self._pedb.logger.error(
543
+ f"Failed to update property top_groisse_roughness with value {value} - {type(e).__name__}: {str(e)}"
544
+ )
526
545
 
527
546
  @property
528
547
  def bottom_groisse_roughness(self) -> float:
@@ -549,8 +568,10 @@ class StackupLayer(GrpcStackupLayer):
549
568
  if isinstance(bottom_roughness_model, Value):
550
569
  bottom_roughness_model = Value(value)
551
570
  self.set_roughness_model(bottom_roughness_model, GrpcRoughnessRegion.BOTTOM)
552
- except:
553
- pass
571
+ except Exception as e:
572
+ self._pedb.logger.error(
573
+ f"Failed to update property bottom_groisse_roughness with value {value} - {type(e).__name__}: {str(e)}"
574
+ )
554
575
 
555
576
  @property
556
577
  def side_groisse_roughness(self) -> float:
@@ -578,7 +599,9 @@ class StackupLayer(GrpcStackupLayer):
578
599
  side_roughness_model = Value(value)
579
600
  self.set_roughness_model(side_roughness_model, GrpcRoughnessRegion.BOTTOM)
580
601
  except Exception as e:
581
- self._pedb.logger.error(e)
602
+ self._pedb.logger.error(
603
+ f"Failed to update property side_groisse_roughness with value {value} - {type(e).__name__}: {str(e)}"
604
+ )
582
605
 
583
606
  def assign_roughness_model(
584
607
  self,
@@ -23,30 +23,25 @@
23
23
  """
24
24
  This module contains these classes: `EdbLayout` and `Shape`.
25
25
  """
26
+
27
+ from __future__ import annotations
28
+
29
+ from typing import TYPE_CHECKING
30
+
31
+ if TYPE_CHECKING:
32
+ from pyedb.grpc.database.hierarchy.component import Component
33
+ from pyedb.grpc.database.net.net import Net
34
+ from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
26
35
  from typing import Dict, List, Union
27
36
 
28
37
  from ansys.edb.core.layout.layout import Layout as GrpcLayout
29
- import ansys.edb.core.primitive.bondwire
30
- import ansys.edb.core.primitive.circle
31
- import ansys.edb.core.primitive.padstack_instance
32
- import ansys.edb.core.primitive.path
33
- import ansys.edb.core.primitive.polygon
34
- import ansys.edb.core.primitive.primitive
35
- import ansys.edb.core.primitive.rectangle
36
-
37
- from pyedb.grpc.database.hierarchy.component import Component
38
+
38
39
  from pyedb.grpc.database.hierarchy.pingroup import PinGroup
39
40
  from pyedb.grpc.database.layout.voltage_regulator import VoltageRegulator
40
41
  from pyedb.grpc.database.net.differential_pair import DifferentialPair
41
42
  from pyedb.grpc.database.net.extended_net import ExtendedNet
42
- from pyedb.grpc.database.net.net import Net
43
43
  from pyedb.grpc.database.net.net_class import NetClass
44
44
  from pyedb.grpc.database.primitive.bondwire import Bondwire
45
- from pyedb.grpc.database.primitive.circle import Circle
46
- from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
47
- from pyedb.grpc.database.primitive.path import Path
48
- from pyedb.grpc.database.primitive.polygon import Polygon
49
- from pyedb.grpc.database.primitive.rectangle import Rectangle
50
45
  from pyedb.grpc.database.terminal.bundle_terminal import BundleTerminal
51
46
  from pyedb.grpc.database.terminal.edge_terminal import EdgeTerminal
52
47
  from pyedb.grpc.database.terminal.padstack_instance_terminal import (
@@ -55,6 +50,30 @@ from pyedb.grpc.database.terminal.padstack_instance_terminal import (
55
50
  from pyedb.grpc.database.terminal.pingroup_terminal import PinGroupTerminal
56
51
  from pyedb.grpc.database.terminal.point_terminal import PointTerminal
57
52
 
53
+ _PRIMITIVE_TYPE_MAP = {
54
+ "Path": ("pyedb.grpc.database.primitive.path", "Path"),
55
+ "Polygon": ("pyedb.grpc.database.primitive.polygon", "Polygon"),
56
+ "PadstackInstance": ("pyedb.grpc.database.primitive.padstack_instance", "PadstackInstance"),
57
+ "Rectangle": ("pyedb.grpc.database.primitive.rectangle", "Rectangle"),
58
+ "Circle": ("pyedb.grpc.database.primitive.circle", "Circle"),
59
+ "Bondwire": ("pyedb.grpc.database.primitive.bondwire", "Bondwire"),
60
+ }
61
+
62
+ # Cache wrapper classes after first import
63
+ _WRAPPER_CLASS_CACHE = {}
64
+
65
+
66
+ def _get_wrapper_class(prim_type: str):
67
+ """Cached wrapper class retrieval"""
68
+ if prim_type not in _WRAPPER_CLASS_CACHE:
69
+ if prim_type in _PRIMITIVE_TYPE_MAP:
70
+ module_path, class_name = _PRIMITIVE_TYPE_MAP[prim_type]
71
+ # Import only once per type
72
+ module = __import__(module_path, fromlist=[class_name])
73
+ _WRAPPER_CLASS_CACHE[prim_type] = getattr(module, class_name)
74
+
75
+ return _WRAPPER_CLASS_CACHE.get(prim_type)
76
+
58
77
 
59
78
  class Layout(GrpcLayout):
60
79
  """Manage Layout class."""
@@ -78,18 +97,9 @@ class Layout(GrpcLayout):
78
97
  primitives = super().primitives
79
98
  self.__primitives = []
80
99
  for prim in primitives:
81
- if isinstance(prim, ansys.edb.core.primitive.path.Path):
82
- self.__primitives.append(Path(self._pedb, prim))
83
- elif isinstance(prim, ansys.edb.core.primitive.polygon.Polygon):
84
- self.__primitives.append(Polygon(self._pedb, prim))
85
- elif isinstance(prim, ansys.edb.core.primitive.padstack_instance.PadstackInstance):
86
- self.__primitives.append(PadstackInstance(self._pedb, prim))
87
- elif isinstance(prim, ansys.edb.core.primitive.rectangle.Rectangle):
88
- self.__primitives.append(Rectangle(self._pedb, prim))
89
- elif isinstance(prim, ansys.edb.core.primitive.circle.Circle):
90
- self.__primitives.append(Circle(self._pedb, prim))
91
- elif isinstance(prim, ansys.edb.core.primitive.bondwire.Bondwire):
92
- self.__primitives.append(Bondwire(self._pedb, prim))
100
+ wrapper_class = _get_wrapper_class(prim.__class__.__name__)
101
+ if wrapper_class:
102
+ self.__primitives.append(wrapper_class(self._pedb, prim))
93
103
  return self.__primitives
94
104
 
95
105
  @property
@@ -124,6 +134,8 @@ class Layout(GrpcLayout):
124
134
  List[:class:`Net <pyedb.grpc.database.net.net.Net>`]
125
135
  List of Net.
126
136
  """
137
+ from pyedb.grpc.database.net.net import Net
138
+
127
139
  return [Net(self._pedb, net) for net in super().nets]
128
140
 
129
141
  @property
@@ -147,6 +159,8 @@ class Layout(GrpcLayout):
147
159
  List of Component.
148
160
 
149
161
  """
162
+ from pyedb.grpc.database.hierarchy.component import Component
163
+
150
164
  return [Component(self._pedb, g) for g in self._pedb.active_cell.layout.groups]
151
165
 
152
166
  @property
@@ -200,6 +214,8 @@ class Layout(GrpcLayout):
200
214
  @property
201
215
  def padstack_instances(self) -> Dict[int, PadstackInstance]:
202
216
  """Get all padstack instances in a list."""
217
+ from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
218
+
203
219
  pad_stack_inst = super().padstack_instances
204
220
  self.__padstack_instances = {i.edb_uid: PadstackInstance(self._pedb, i) for i in pad_stack_inst}
205
221
  return self.__padstack_instances
@@ -20,11 +20,16 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
+ from __future__ import annotations
24
+
25
+ from typing import TYPE_CHECKING
26
+
27
+ if TYPE_CHECKING:
28
+ from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
23
29
  from ansys.edb.core.layout.voltage_regulator import (
24
30
  VoltageRegulator as GrpcVoltageRegulator,
25
31
  )
26
32
 
27
- from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
28
33
  from pyedb.grpc.database.utility.value import Value
29
34
 
30
35