pyedb 0.56.0__py3-none-any.whl → 0.58.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 (110) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_data.py +3 -0
  3. pyedb/configuration/cfg_pin_groups.py +2 -0
  4. pyedb/configuration/cfg_terminals.py +232 -0
  5. pyedb/configuration/configuration.py +146 -3
  6. pyedb/dotnet/clr_module.py +1 -2
  7. pyedb/dotnet/database/Variables.py +30 -22
  8. pyedb/dotnet/database/cell/hierarchy/component.py +2 -8
  9. pyedb/dotnet/database/cell/layout.py +5 -1
  10. pyedb/dotnet/database/cell/primitive/primitive.py +2 -2
  11. pyedb/dotnet/database/cell/terminal/bundle_terminal.py +12 -0
  12. pyedb/dotnet/database/cell/terminal/pingroup_terminal.py +1 -1
  13. pyedb/dotnet/database/cell/terminal/terminal.py +38 -0
  14. pyedb/dotnet/database/components.py +15 -19
  15. pyedb/dotnet/database/dotnet/database.py +1 -0
  16. pyedb/dotnet/database/edb_data/control_file.py +19 -8
  17. pyedb/dotnet/database/edb_data/nets_data.py +3 -3
  18. pyedb/dotnet/database/edb_data/padstacks_data.py +39 -14
  19. pyedb/dotnet/database/edb_data/ports.py +0 -25
  20. pyedb/dotnet/database/edb_data/primitives_data.py +3 -3
  21. pyedb/dotnet/database/edb_data/raptor_x_simulation_setup_data.py +18 -19
  22. pyedb/dotnet/database/edb_data/simulation_configuration.py +3 -3
  23. pyedb/dotnet/database/edb_data/sources.py +21 -2
  24. pyedb/dotnet/database/general.py +1 -6
  25. pyedb/dotnet/database/hfss.py +9 -8
  26. pyedb/dotnet/database/layout_validation.py +14 -3
  27. pyedb/dotnet/database/materials.py +1 -3
  28. pyedb/dotnet/database/modeler.py +7 -3
  29. pyedb/dotnet/database/nets.py +27 -19
  30. pyedb/dotnet/database/padstack.py +4 -2
  31. pyedb/dotnet/database/sim_setup_data/io/siwave.py +54 -1
  32. pyedb/dotnet/database/siwave.py +4 -3
  33. pyedb/dotnet/database/stackup.py +55 -58
  34. pyedb/dotnet/database/utilities/heatsink.py +0 -1
  35. pyedb/dotnet/database/utilities/hfss_simulation_setup.py +81 -0
  36. pyedb/dotnet/database/utilities/simulation_setup.py +7 -5
  37. pyedb/dotnet/database/utilities/siwave_cpa_simulation_setup.py +1 -0
  38. pyedb/dotnet/database/utilities/siwave_simulation_setup.py +264 -13
  39. pyedb/dotnet/edb.py +65 -47
  40. pyedb/exceptions.py +1 -2
  41. pyedb/extensions/create_cell_array.py +67 -49
  42. pyedb/generic/data_handlers.py +13 -23
  43. pyedb/generic/design_types.py +9 -35
  44. pyedb/generic/filesystem.py +4 -2
  45. pyedb/generic/general_methods.py +28 -41
  46. pyedb/generic/plot.py +8 -23
  47. pyedb/generic/process.py +78 -10
  48. pyedb/grpc/database/_typing.py +0 -0
  49. pyedb/grpc/database/components.py +14 -13
  50. pyedb/grpc/database/control_file.py +27 -40
  51. pyedb/grpc/database/definition/materials.py +1 -1
  52. pyedb/grpc/database/definition/package_def.py +6 -3
  53. pyedb/grpc/database/definition/padstack_def.py +14 -12
  54. pyedb/grpc/database/hfss.py +1 -4
  55. pyedb/grpc/database/hierarchy/component.py +5 -13
  56. pyedb/grpc/database/hierarchy/pingroup.py +16 -3
  57. pyedb/grpc/database/layers/layer.py +1 -2
  58. pyedb/grpc/database/layers/stackup_layer.py +42 -19
  59. pyedb/grpc/database/layout/layout.py +43 -27
  60. pyedb/grpc/database/layout/voltage_regulator.py +6 -1
  61. pyedb/grpc/database/layout_validation.py +5 -2
  62. pyedb/grpc/database/modeler.py +254 -252
  63. pyedb/grpc/database/net/differential_pair.py +9 -2
  64. pyedb/grpc/database/net/extended_net.py +24 -9
  65. pyedb/grpc/database/net/net.py +14 -5
  66. pyedb/grpc/database/net/net_class.py +24 -7
  67. pyedb/grpc/database/nets.py +11 -43
  68. pyedb/grpc/database/padstacks.py +67 -119
  69. pyedb/grpc/database/primitive/bondwire.py +3 -67
  70. pyedb/grpc/database/primitive/circle.py +42 -3
  71. pyedb/grpc/database/primitive/padstack_instance.py +58 -31
  72. pyedb/grpc/database/primitive/path.py +160 -11
  73. pyedb/grpc/database/primitive/polygon.py +73 -7
  74. pyedb/grpc/database/primitive/primitive.py +2 -2
  75. pyedb/grpc/database/primitive/rectangle.py +105 -4
  76. pyedb/grpc/database/simulation_setup/hfss_general_settings.py +0 -2
  77. pyedb/grpc/database/simulation_setup/hfss_settings_options.py +0 -4
  78. pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +79 -0
  79. pyedb/grpc/database/simulation_setup/siwave_cpa_simulation_setup.py +1 -0
  80. pyedb/grpc/database/simulation_setup/sweep_data.py +1 -3
  81. pyedb/grpc/database/siwave.py +6 -13
  82. pyedb/grpc/database/source_excitations.py +46 -63
  83. pyedb/grpc/database/stackup.py +55 -60
  84. pyedb/grpc/database/terminal/bundle_terminal.py +10 -3
  85. pyedb/grpc/database/terminal/padstack_instance_terminal.py +9 -11
  86. pyedb/grpc/database/terminal/pingroup_terminal.py +8 -1
  87. pyedb/grpc/database/terminal/point_terminal.py +30 -0
  88. pyedb/grpc/database/terminal/terminal.py +35 -10
  89. pyedb/grpc/database/utility/heat_sink.py +0 -1
  90. pyedb/grpc/database/utility/hfss_extent_info.py +2 -2
  91. pyedb/grpc/database/utility/xml_control_file.py +19 -8
  92. pyedb/grpc/edb.py +63 -32
  93. pyedb/grpc/edb_init.py +1 -0
  94. pyedb/ipc2581/ecad/cad_data/layer_feature.py +6 -2
  95. pyedb/ipc2581/ecad/cad_data/step.py +1 -1
  96. pyedb/ipc2581/ipc2581.py +8 -7
  97. pyedb/libraries/common.py +3 -4
  98. pyedb/libraries/rf_libraries/base_functions.py +7 -16
  99. pyedb/libraries/rf_libraries/planar_antennas.py +3 -21
  100. pyedb/misc/aedtlib_personalib_install.py +2 -2
  101. pyedb/misc/downloads.py +19 -3
  102. pyedb/misc/misc.py +5 -2
  103. pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +3 -2
  104. pyedb/misc/siw_feature_config/xtalk_scan/scan_config.py +0 -1
  105. pyedb/misc/utilities.py +0 -1
  106. pyedb/modeler/geometry_operators.py +3 -2
  107. {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/METADATA +6 -7
  108. {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/RECORD +110 -108
  109. {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/WHEEL +0 -0
  110. {pyedb-0.56.0.dist-info → pyedb-0.58.0.dist-info}/licenses/LICENSE +0 -0
@@ -15,6 +15,7 @@ from pyedb.dotnet.database.sim_setup_data.io.siwave import (
15
15
  )
16
16
  from pyedb.dotnet.database.utilities.simulation_setup import SimulationSetup
17
17
  from pyedb.generic.general_methods import is_linux
18
+ from pyedb.generic.settings import settings
18
19
 
19
20
 
20
21
  def _parse_value(v):
@@ -79,8 +80,10 @@ def clone_edb_sim_setup_info(source, target):
79
80
  except TypeError:
80
81
  try:
81
82
  setter.__setattr__(k, str(value))
82
- except:
83
- pass
83
+ except Exception as e:
84
+ settings.logger.warning(
85
+ f"Failed to update attribute {k} with value {value} - {type(e).__name__}: {str(e)}"
86
+ )
84
87
 
85
88
 
86
89
  class SiwaveSimulationSetup(SimulationSetup):
@@ -182,6 +185,7 @@ class SiwaveSimulationSetup(SimulationSetup):
182
185
 
183
186
  @enabled.setter
184
187
  def enabled(self, value: bool):
188
+ """Set the enabled flag for the setup."""
185
189
  self.sim_setup_info.simulation_settings.Enabled = value
186
190
 
187
191
  @property
@@ -321,6 +325,21 @@ class SiwaveDCSimulationSetup(SimulationSetup):
321
325
  self.set_dc_slider(1)
322
326
  return self
323
327
 
328
+ @property
329
+ def enabled(self):
330
+ """Flag indicating if the setup is enabled.
331
+
332
+ .. deprecated:: 0.57.0
333
+ Use :property:`settings.enabled` property instead.
334
+
335
+ Returns
336
+ -------
337
+ bool
338
+ """
339
+
340
+ warnings.warn("`enabled` property is deprecated. Use `settings.enabled` property instead.", DeprecationWarning)
341
+ return self.settings.enabled
342
+
324
343
  @property
325
344
  def sim_setup_info(self):
326
345
  """Overrides the default sim_setup_info object."""
@@ -343,7 +362,7 @@ class SiwaveDCSimulationSetup(SimulationSetup):
343
362
  @property
344
363
  def dc_ir_settings(self):
345
364
  """DC IR settings."""
346
- return SiwaveDCIRSettings(self)
365
+ return self.settings
347
366
 
348
367
  def get_configurations(self):
349
368
  """Get SIwave DC simulation settings.
@@ -367,36 +386,270 @@ class SiwaveDCSimulationSetup(SimulationSetup):
367
386
  - ``1``: Balanced
368
387
  - ``2``: Optimal accuracy
369
388
  """
370
- self.use_custom_settings = False
371
- self.dc_settings.dc_slider_position = value
372
- self.dc_advanced_settings.set_dc_slider(value)
389
+ self.settings.use_custom_settings = False
390
+ self.settings.dc.dc_slider_position = value
391
+ self.settings.dc_advanced.set_dc_slider(value)
373
392
 
374
393
  @property
375
394
  def dc_settings(self):
376
- """SIwave DC setting."""
377
- return DCSettings(self)
395
+ """SIwave DC setting.
396
+
397
+ deprecated:: 0.57.0
398
+ Use :property:`settings` property instead.
399
+
400
+ """
401
+ warnings.warn("`dc_settings` is deprecated. Use `settings.dc` property instead.", DeprecationWarning)
402
+ return self.settings.dc
403
+
404
+ @property
405
+ def settings(self):
406
+ """Get the settings interface for SIwave DC simulation.
407
+
408
+ Returns
409
+ -------
410
+ Settings
411
+ An instance of the Settings class providing access to SIwave DC simulation settings.
412
+ """
413
+ return Settings(self, self.sim_setup_info)
378
414
 
379
415
  @property
380
416
  def dc_advanced_settings(self):
381
417
  """Siwave DC advanced settings.
382
418
 
419
+ .. deprecated :: 0.57.0
420
+ Use :property:`settings` property instead.
421
+
383
422
  Returns
384
423
  -------
385
424
  :class:`pyedb.dotnet.database.edb_data.siwave_simulation_setup_data.SiwaveDCAdvancedSettings`
386
425
  """
387
- return DCAdvancedSettings(self)
426
+ warnings.warn(
427
+ "`dc_advanced_settings` is deprecated. Use `settings.dc_advanced` property instead.", DeprecationWarning
428
+ )
429
+ return self.settings.dc_advanced
388
430
 
389
431
  @property
390
432
  def source_terms_to_ground(self):
391
433
  """Dictionary of grounded terminals.
392
434
 
435
+ .. deprecated:: 0.57.0
436
+ Use :property:`settings.source_terms_to_ground` property instead.
437
+
393
438
  Returns
394
439
  -------
395
440
  Dictionary
396
441
  {str, int}, keys is source name, value int 0 unspecified, 1 negative node, 2 positive one.
397
442
 
398
443
  """
399
- return convert_netdict_to_pydict(self.get_sim_setup_info.simulation_settings.DCIRSettings.SourceTermsToGround)
444
+ warnings.warn(
445
+ "`source_terms_to_ground` is deprecated. Use `settings.source_terms_to_ground` property instead.",
446
+ DeprecationWarning,
447
+ )
448
+ return self.settings.source_terms_to_ground
449
+
450
+ def add_source_terminal_to_ground(self, source_name, terminal=0):
451
+ """Add a source terminal to ground.
452
+
453
+ .. deprecated:: 0.57.0
454
+ Use :method:`settings.add_source_terminal_to_ground` method instead.
455
+
456
+ Parameters
457
+ ----------
458
+ source_name : str,
459
+ Source name.
460
+ terminal : int, optional
461
+ Terminal to assign. Options are:
462
+
463
+ - 0=Unspecified
464
+ - 1=Negative node
465
+ - 2=Positive none
466
+
467
+ Returns
468
+ -------
469
+ bool
470
+
471
+ """
472
+ warnings.warn(
473
+ "`add_source_terminal_to_ground` is deprecated. Use "
474
+ "`settings.add_source_terminal_to_ground` method instead.",
475
+ DeprecationWarning,
476
+ )
477
+ return self.settings.add_source_terminal_to_ground(source_name, terminal)
478
+
479
+
480
+ class General:
481
+ """Class to manage global settings for the Siwave simulation setup module.
482
+ Added to be compliant with ansys-edbe-core settings structure."""
483
+
484
+ def __init__(self, parent):
485
+ self._parent = parent
486
+
487
+ @property
488
+ def pi_slider_pos(self):
489
+ return self._parent.dc_slider_position
490
+
491
+ @property
492
+ def si_slider_pos(self):
493
+ return self._parent.si_slider_position
494
+
495
+ @property
496
+ def use_custom_settings(self):
497
+ return self._parent.use_dc_custom_settings
498
+
499
+ @property
500
+ def use_si_settings(self):
501
+ return self._parent.use_si_settings
502
+
503
+
504
+ class SIwaveSParameterSettings:
505
+ def __init__(self, parent):
506
+ self._parent = parent
507
+
508
+ @property
509
+ def dc_behavior(self):
510
+ return
511
+
512
+ @property
513
+ def extrapolation(self):
514
+ return
515
+
516
+ @property
517
+ def interpolation(self):
518
+ return
519
+
520
+ @property
521
+ def use_state_space(self):
522
+ return True
523
+
524
+
525
+ class Settings(SimulationSetup, SiwaveDCIRSettings):
526
+ """Class to manage global settings for the Siwave simulation setup module.
527
+ Added to be compliant with ansys-edbe-core settings structure."""
528
+
529
+ def __init__(self, parent, sim_setup_info):
530
+ SimulationSetup.__init__(self, pedb=parent._pedb, edb_object=parent._edb_object)
531
+ SiwaveDCIRSettings.__init__(self, parent)
532
+ self._parent = parent
533
+ self._sim_setup_info = sim_setup_info
534
+
535
+ @property
536
+ def advanced(self):
537
+ return True
538
+
539
+ @property
540
+ def dc(self):
541
+ return DCSettings(self._parent)
542
+
543
+ @property
544
+ def dc_advanced(self):
545
+ return DCAdvancedSettings(self._parent)
546
+
547
+ @property
548
+ def general(self):
549
+ return DCSettings(self._parent)
550
+
551
+ @property
552
+ def dc_report_config_file(self) -> str:
553
+ """Path to the DC report configuration file."""
554
+ # return self._sim_setup_info._edb_object.SimulationSettings.DCIRSettings.DCReportConfigFile
555
+ return super().dc_report_config_file
556
+
557
+ @dc_report_config_file.setter
558
+ def dc_report_config_file(self, value: str):
559
+ SiwaveDCIRSettings.dc_report_config_file = value
560
+
561
+ @property
562
+ def dc_report_show_active_devices(self) -> bool:
563
+ """Flag to show active devices in the DC report."""
564
+ return super().dc_report_show_active_devices
565
+
566
+ @dc_report_show_active_devices.setter
567
+ def dc_report_show_active_devices(self, value: bool):
568
+ SiwaveDCIRSettings.dc_report_show_active_devices = value
569
+
570
+ @property
571
+ def enabled(self) -> bool:
572
+ """Flag indicating if the setup is enabled."""
573
+ return self._sim_setup_info.simulation_settings.Enabled
574
+
575
+ @enabled.setter
576
+ def enabled(self, value: bool):
577
+ self._sim_setup_info.simulation_settings.Enabled = value
578
+
579
+ @property
580
+ def export_dc_thermal_data(self) -> bool:
581
+ """Flag to export DC thermal data."""
582
+ return SiwaveDCIRSettings.export_dc_thermal_data
583
+
584
+ @export_dc_thermal_data.setter
585
+ def export_dc_thermal_data(self, value: bool):
586
+ SiwaveDCIRSettings.export_dc_thermal_data = value
587
+
588
+ @property
589
+ def full_dc_report_path(self) -> str:
590
+ """Full path to the DC report."""
591
+ return SiwaveDCIRSettings.full_dc_report_path
592
+
593
+ @full_dc_report_path.setter
594
+ def full_dc_report_path(self, value: str):
595
+ SiwaveDCIRSettings.full_dc_report_path = value
596
+
597
+ @property
598
+ def icepak_temp_file_path(self) -> str:
599
+ """Path to the Icepak temporary file."""
600
+ return SiwaveDCIRSettings.icepak_temp_file_path
601
+
602
+ @icepak_temp_file_path.setter
603
+ def icepak_temp_file_path(self, value: str):
604
+ SiwaveDCIRSettings.icepak_temp_file_path = value
605
+
606
+ @property
607
+ def import_thermal_data(self) -> bool:
608
+ """Flag to import thermal data."""
609
+ return super().import_thermal_data
610
+
611
+ @import_thermal_data.setter
612
+ def import_thermal_data(self, value: bool):
613
+ SiwaveDCIRSettings.import_thermal_data = value
614
+
615
+ @property
616
+ def s_parameter(self) -> SIwaveSParameterSettings:
617
+ """S-parameter settings."""
618
+ return SIwaveSParameterSettings(self._parent)
619
+
620
+ @property
621
+ def source_terms_to_ground(self) -> dict[str, int]:
622
+ """Dictionary of grounded terminals.
623
+
624
+ Returns
625
+ -------
626
+ Dictionary
627
+ {str, int}, keys is source name, value int 0 unspecified, 1 negative node, 2 positive one.
628
+
629
+ """
630
+ return convert_netdict_to_pydict(super().source_terms_to_ground)
631
+
632
+ @source_terms_to_ground.setter
633
+ def source_terms_to_ground(self, value: dict[str, int]):
634
+ SiwaveDCIRSettings.source_terms_to_ground = convert_pydict_to_netdict(value)
635
+
636
+ @property
637
+ def use_loop_res_for_per_pin(self):
638
+ """Flag to use loop resistance for per-pin calculations."""
639
+ return super().use_loop_res_for_per_pin
640
+
641
+ @use_loop_res_for_per_pin.setter
642
+ def use_loop_res_for_per_pin(self, value: bool):
643
+ SiwaveDCIRSettings.use_loop_res_for_per_pin = value
644
+
645
+ @property
646
+ def via_report_path(self) -> str:
647
+ """Path to the via report."""
648
+ return super().via_report_path
649
+
650
+ @via_report_path.setter
651
+ def via_report_path(self, value: str):
652
+ SiwaveDCIRSettings.via_report_path = value
400
653
 
401
654
  def add_source_terminal_to_ground(self, source_name, terminal=0):
402
655
  """Add a source terminal to ground.
@@ -419,7 +672,5 @@ class SiwaveDCSimulationSetup(SimulationSetup):
419
672
  """
420
673
  terminals = self.source_terms_to_ground
421
674
  terminals[source_name] = terminal
422
- self.get_sim_setup_info.simulation_settings.DCIRSettings.SourceTermsToGround = convert_pydict_to_netdict(
423
- terminals
424
- )
675
+ self._sim_setup_info.simulation_settings.DCIRSettings.SourceTermsToGround = convert_pydict_to_netdict(terminals)
425
676
  return self._update_setup()
pyedb/dotnet/edb.py CHANGED
@@ -25,13 +25,14 @@
25
25
  This module is implicitly loaded in HFSS 3D Layout when launched.
26
26
 
27
27
  """
28
+
28
29
  from datetime import datetime
29
30
  from itertools import combinations
30
31
  import os
31
32
  from pathlib import Path
32
33
  import re
33
34
  import shutil
34
- import subprocess
35
+ import subprocess # nosec B404
35
36
  import sys
36
37
  import time
37
38
  import traceback
@@ -43,7 +44,6 @@ import rtree
43
44
 
44
45
  from pyedb.configuration.configuration import Configuration
45
46
  import pyedb.dotnet
46
- from pyedb.dotnet.database.Variables import decompose_variable_value
47
47
  from pyedb.dotnet.database.cell.layout import Layout
48
48
  from pyedb.dotnet.database.cell.terminal.terminal import Terminal
49
49
  from pyedb.dotnet.database.components import Components
@@ -92,6 +92,7 @@ from pyedb.dotnet.database.utilities.siwave_simulation_setup import (
92
92
  SiwaveSimulationSetup,
93
93
  )
94
94
  from pyedb.dotnet.database.utilities.value import Value
95
+ from pyedb.dotnet.database.Variables import decompose_variable_value
95
96
  from pyedb.generic.constants import AEDT_UNITS, SolverType, unit_converter
96
97
  from pyedb.generic.general_methods import generate_unique_name, is_linux, is_windows
97
98
  from pyedb.generic.process import SiwaveSolve
@@ -152,19 +153,19 @@ class Edb:
152
153
 
153
154
  Add a new variable named "s1" to the ``Edb`` instance.
154
155
 
155
- >>> app['s1'] = "0.25 mm"
156
- >>> app['s1'].tofloat
156
+ >>> app["s1"] = "0.25 mm"
157
+ >>> app["s1"].tofloat
157
158
  >>> 0.00025
158
- >>> app['s1'].tostring
159
+ >>> app["s1"].tostring
159
160
  >>> "0.25mm"
160
161
 
161
162
  or add a new parameter with description:
162
163
 
163
- >>> app['s2'] = ["20um", "Spacing between traces"]
164
- >>> app['s2'].value
164
+ >>> app["s2"] = ["20um", "Spacing between traces"]
165
+ >>> app["s2"].value
165
166
  >>> 1.9999999999999998e-05
166
- >>> app['s2'].description
167
- >>> 'Spacing between traces'
167
+ >>> app["s2"].description
168
+ >>> "Spacing between traces"
168
169
 
169
170
  Create an ``Edb`` object and open the specified project.
170
171
 
@@ -753,6 +754,11 @@ class Edb:
753
754
 
754
755
  This function supports all AEDT formats, including DXF, GDS, SML (IPC2581), BRD, MCM, SIP, ZIP and TGZ.
755
756
 
757
+ .. warning::
758
+ Do not execute this function with untrusted function argument, environment
759
+ variables or pyedb global settings.
760
+ See the :ref:`security guide<ref_security_consideration>` for details.
761
+
756
762
  Parameters
757
763
  ----------
758
764
  input_file : str
@@ -789,16 +795,16 @@ class Edb:
789
795
  self._nets = None
790
796
  aedb_name = os.path.splitext(os.path.basename(input_file))[0] + ".aedb"
791
797
  if anstranslator_full_path and os.path.exists(anstranslator_full_path):
792
- command = anstranslator_full_path
798
+ executable_path = anstranslator_full_path
793
799
  else:
794
- command = os.path.join(self.base_path, "anstranslator")
800
+ executable_path = os.path.join(self.base_path, "anstranslator")
795
801
  if is_windows:
796
- command += ".exe"
802
+ executable_path += ".exe"
797
803
 
798
804
  if not working_dir:
799
805
  working_dir = os.path.dirname(input_file)
800
806
  cmd_translator = [
801
- command,
807
+ executable_path,
802
808
  input_file,
803
809
  os.path.join(working_dir, aedb_name),
804
810
  "-l={}".format(os.path.join(working_dir, "Translator.log")),
@@ -816,7 +822,10 @@ class Edb:
816
822
  cmd_translator.append('-t="{}"'.format(tech_file))
817
823
  if layer_filter:
818
824
  cmd_translator.append('-f="{}"'.format(layer_filter))
819
- subprocess.run(cmd_translator)
825
+ try:
826
+ subprocess.run(cmd_translator, check=True) # nosec
827
+ except subprocess.CalledProcessError as e: # nosec
828
+ raise RuntimeError("An error occurred while translating board file to ``edb.def`` file") from e
820
829
  if not os.path.exists(os.path.join(working_dir, aedb_name)):
821
830
  raise RuntimeWarning(f"Translator failed. command : {' '.join(cmd_translator)}")
822
831
  else:
@@ -1852,8 +1861,11 @@ class Edb:
1852
1861
  convert_py_list_to_net_list(list(obj_data)),
1853
1862
  convert_py_list_to_net_list(voids_poly),
1854
1863
  )
1855
- except:
1856
- pass
1864
+ except Exception as e:
1865
+ self.logger.error(
1866
+ f"A(n) {type(e).__name__} error occurred in method _create_conformal of "
1867
+ f"class Edb at iteration {k} for data {i}: {str(e)}"
1868
+ )
1857
1869
  finally:
1858
1870
  unite_polys.extend(list(obj_data))
1859
1871
  _poly_unite = self.core.Geometry.PolygonData.Unite(convert_py_list_to_net_list(unite_polys))
@@ -2048,7 +2060,7 @@ class Edb:
2048
2060
  Examples
2049
2061
  --------
2050
2062
  >>> from pyedb import Edb
2051
- >>> edb = Edb(r'C:\\test.aedb', version="2022.2")
2063
+ >>> edb = Edb(r"C:\\test.aedb", version="2022.2")
2052
2064
  >>> edb.logger.info_timer("Edb Opening")
2053
2065
  >>> edb.logger.reset_timer()
2054
2066
  >>> start = time.time()
@@ -2058,7 +2070,7 @@ class Edb:
2058
2070
  >>> signal_list.append(net)
2059
2071
  >>> power_list = ["PGND"]
2060
2072
  >>> edb.cutout(signal_list=signal_list, reference_list=power_list, extent_type="Conforming")
2061
- >>> end_time = str((time.time() - start)/60)
2073
+ >>> end_time = str((time.time() - start) / 60)
2062
2074
  >>> edb.logger.info("Total legacy cutout time in min %s", end_time)
2063
2075
  >>> edb.nets.plot(signal_list, None, color_by_net=True)
2064
2076
  >>> edb.nets.plot(power_list, None, color_by_net=True)
@@ -2291,8 +2303,8 @@ class Edb:
2291
2303
  if os.path.exists(source) and not os.path.exists(target):
2292
2304
  try:
2293
2305
  shutil.copy(source, target)
2294
- except:
2295
- pass
2306
+ except Exception as e:
2307
+ self.logger.error(f"Failed to copy {source} to {target} - {type(e).__name__}: {str(e)}")
2296
2308
  elif open_cutout_at_end:
2297
2309
  self._active_cell = _cutout
2298
2310
  self._init_objects()
@@ -2708,7 +2720,7 @@ class Edb:
2708
2720
  Examples
2709
2721
  --------
2710
2722
  >>> from pyedb import Edb
2711
- >>> edb = Edb(r'C:\\test.aedb', version="2022.2")
2723
+ >>> edb = Edb(r"C:\\test.aedb", version="2022.2")
2712
2724
  >>> edb.logger.info_timer("Edb Opening")
2713
2725
  >>> edb.logger.reset_timer()
2714
2726
  >>> start = time.time()
@@ -2718,7 +2730,7 @@ class Edb:
2718
2730
  >>> signal_list.append(net)
2719
2731
  >>> power_list = ["PGND"]
2720
2732
  >>> edb.create_cutout_multithread(signal_list=signal_list, reference_list=power_list, extent_type="Conforming")
2721
- >>> end_time = str((time.time() - start)/60)
2733
+ >>> end_time = str((time.time() - start) / 60)
2722
2734
  >>> edb.logger.info("Total legacy cutout time in min %s", end_time)
2723
2735
  >>> edb.nets.plot(signal_list, None, color_by_net=True)
2724
2736
  >>> edb.nets.plot(power_list, None, color_by_net=True)
@@ -2977,8 +2989,8 @@ class Edb:
2977
2989
  try:
2978
2990
  shutil.copy(source, target)
2979
2991
  self.logger.warning("aedb def file manually created.")
2980
- except:
2981
- pass
2992
+ except Exception as e:
2993
+ self.logger.error(f"Failed to copy {source} to {target} - {type(e).__name__}: {str(e)}")
2982
2994
  return [[pt.X.ToDouble(), pt.Y.ToDouble()] for pt in list(polygonData.GetPolygonWithoutArcs().Points)]
2983
2995
 
2984
2996
  def create_cutout_on_point_list(
@@ -3107,7 +3119,7 @@ class Edb:
3107
3119
  >>> from pyedb import Edb
3108
3120
  >>> edb = Edb(edbpath="C:\\temp\\myproject.aedb", version="2023.2")
3109
3121
 
3110
- >>> options_config = {'UNITE_NETS' : 1, 'LAUNCH_Q3D' : 0}
3122
+ >>> options_config = {"UNITE_NETS": 1, "LAUNCH_Q3D": 0}
3111
3123
  >>> edb.write_export3d_option_config_file(r"C:\\temp", options_config)
3112
3124
  >>> edb.export_hfss(r"C:\\temp")
3113
3125
  """
@@ -3149,7 +3161,7 @@ class Edb:
3149
3161
 
3150
3162
  >>> from pyedb import Edb
3151
3163
  >>> edb = Edb(edbpath="C:\\temp\\myproject.aedb", version="2021.2")
3152
- >>> options_config = {'UNITE_NETS' : 1, 'LAUNCH_Q3D' : 0}
3164
+ >>> options_config = {"UNITE_NETS": 1, "LAUNCH_Q3D": 0}
3153
3165
  >>> edb.write_export3d_option_config_file("C:\\temp", options_config)
3154
3166
  >>> edb.export_q3d("C:\\temp")
3155
3167
  """
@@ -3201,7 +3213,7 @@ class Edb:
3201
3213
 
3202
3214
  >>> edb = Edb(edbpath="C:\\temp\\myproject.aedb", version="2021.2")
3203
3215
 
3204
- >>> options_config = {'UNITE_NETS' : 1, 'LAUNCH_Q3D' : 0}
3216
+ >>> options_config = {"UNITE_NETS": 1, "LAUNCH_Q3D": 0}
3205
3217
  >>> edb.write_export3d_option_config_file("C:\\temp", options_config)
3206
3218
  >>> edb.export_maxwell("C:\\temp")
3207
3219
  """
@@ -3369,8 +3381,8 @@ class Edb:
3369
3381
  >>> from pyedb import Edb
3370
3382
  >>> edb_app = Edb()
3371
3383
  >>> boolean_1, ant_length = edb_app.add_project_variable("my_local_variable", "1cm")
3372
- >>> print(edb_app["$my_local_variable"]) #using getitem
3373
- >>> edb_app["$my_local_variable"] = "1cm" #using setitem
3384
+ >>> print(edb_app["$my_local_variable"]) # using getitem
3385
+ >>> edb_app["$my_local_variable"] = "1cm" # using setitem
3374
3386
 
3375
3387
  """
3376
3388
  if not variable_name.startswith("$"):
@@ -3408,8 +3420,8 @@ class Edb:
3408
3420
  >>> from pyedb import Edb
3409
3421
  >>> edb_app = Edb()
3410
3422
  >>> boolean_1, ant_length = edb_app.add_design_variable("my_local_variable", "1cm")
3411
- >>> print(edb_app["my_local_variable"]) #using getitem
3412
- >>> edb_app["my_local_variable"] = "1cm" #using setitem
3423
+ >>> print(edb_app["my_local_variable"]) # using getitem
3424
+ >>> edb_app["my_local_variable"] = "1cm" # using setitem
3413
3425
  >>> boolean_2, para_length = edb_app.change_design_variable_value("my_parameter", "1m", is_parameter=True
3414
3426
  >>> boolean_3, project_length = edb_app.change_design_variable_value("$my_project_variable", "1m")
3415
3427
 
@@ -3449,7 +3461,7 @@ class Edb:
3449
3461
  >>> edb_app = Edb()
3450
3462
  >>> boolean, ant_length = edb_app.add_design_variable("ant_length", "1cm")
3451
3463
  >>> boolean, ant_length = edb_app.change_design_variable_value("ant_length", "1m")
3452
- >>> print(edb_app["ant_length"]) #using getitem
3464
+ >>> print(edb_app["ant_length"]) # using getitem
3453
3465
  """
3454
3466
  var_server = self.variable_exists(variable_name)
3455
3467
  if var_server[0]:
@@ -3928,11 +3940,13 @@ class Edb:
3928
3940
  >>> from pyedb import Edb
3929
3941
  >>> edbapp = Edb()
3930
3942
  >>> setup1 = edbapp.create_siwave_syz_setup("setup1")
3931
- >>> setup1.add_frequency_sweep(frequency_sweep=[
3932
- ... ["linear count", "0", "1kHz", 1],
3933
- ... ["log scale", "1kHz", "0.1GHz", 10],
3934
- ... ["linear scale", "0.1GHz", "10GHz", "0.1GHz"],
3935
- ... ])
3943
+ >>> setup1.add_frequency_sweep(
3944
+ ... frequency_sweep=[
3945
+ ... ["linear count", "0", "1kHz", 1],
3946
+ ... ["log scale", "1kHz", "0.1GHz", 10],
3947
+ ... ["linear scale", "0.1GHz", "10GHz", "0.1GHz"],
3948
+ ... ]
3949
+ ... )
3936
3950
  """
3937
3951
  if not name:
3938
3952
  name = generate_unique_name("Siwave_SYZ")
@@ -4687,8 +4701,7 @@ class Edb:
4687
4701
  ]
4688
4702
  if not polys:
4689
4703
  raise RuntimeWarning(
4690
- f"No polygon found with voids on layer {reference_layer} during model creation for "
4691
- f"arbitrary wave ports"
4704
+ f"No polygon found with voids on layer {reference_layer} during model creation for arbitrary wave ports"
4692
4705
  )
4693
4706
  void_padstacks = []
4694
4707
  for poly in polys:
@@ -4705,7 +4718,7 @@ class Edb:
4705
4718
 
4706
4719
  if not void_padstacks:
4707
4720
  raise RuntimeWarning(
4708
- "No padstack instances found inside evaluated voids during model creation for arbitrary" "waveports"
4721
+ "No padstack instances found inside evaluated voids during model creation for arbitrary waveports"
4709
4722
  )
4710
4723
  cloned_edb = Edb(edbpath=output_edb)
4711
4724
 
@@ -4832,6 +4845,11 @@ class Edb:
4832
4845
  def compare(self, input_file, results=""):
4833
4846
  """Compares current open database with another one.
4834
4847
 
4848
+ .. warning::
4849
+ Do not execute this function with untrusted function argument, environment
4850
+ variables or pyedb global settings.
4851
+ See the :ref:`security guide<ref_security_consideration>` for details.
4852
+
4835
4853
  Parameters
4836
4854
  ----------
4837
4855
  input_file : str
@@ -4847,16 +4865,16 @@ class Edb:
4847
4865
  if not results:
4848
4866
  results = self.edbpath[:-5] + "_compare_results"
4849
4867
  os.mkdir(results)
4850
- command = os.path.join(self.base_path, "EDBDiff.exe")
4868
+ executable_path = os.path.join(self.base_path, "EDBDiff.exe")
4851
4869
  if is_linux:
4852
4870
  mono_path = os.path.join(self.base_path, "common/mono/Linux64/bin/mono")
4853
- cmd_input = [mono_path, command, input_file, self.edbpath, results]
4871
+ command = [mono_path, executable_path, input_file, self.edbpath, results]
4854
4872
  else:
4855
- cmd_input = [command, input_file, self.edbpath, results]
4856
- p = subprocess.run(cmd_input)
4857
- if p.returncode == 0:
4873
+ command = [executable_path, input_file, self.edbpath, results]
4874
+ try:
4875
+ subprocess.run(command, check=True) # nosec
4858
4876
  return str(Path(self.base_path).joinpath("EDBDiff.exe"))
4859
- else:
4877
+ except subprocess.CalledProcessError as e: # nosec
4860
4878
  raise RuntimeError(
4861
4879
  "EDBDiff.exe execution failed. Please check if the executable is present in the base path."
4862
- )
4880
+ ) from e
pyedb/exceptions.py CHANGED
@@ -1,5 +1,4 @@
1
- """
2
- """
1
+ """ """
3
2
 
4
3
 
5
4
  class MaterialModelException(Exception):