pyedb 0.57.0__py3-none-any.whl → 0.59.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.
- pyedb/__init__.py +1 -1
- pyedb/configuration/cfg_pin_groups.py +2 -0
- pyedb/dotnet/database/cell/hierarchy/component.py +2 -8
- pyedb/dotnet/database/cell/layout.py +1 -1
- pyedb/dotnet/database/components.py +38 -42
- pyedb/dotnet/database/edb_data/control_file.py +13 -5
- pyedb/dotnet/database/edb_data/padstacks_data.py +34 -12
- pyedb/dotnet/database/edb_data/sources.py +21 -2
- pyedb/dotnet/database/general.py +4 -8
- pyedb/dotnet/database/layout_validation.py +8 -0
- pyedb/dotnet/database/sim_setup_data/data/settings.py +2 -2
- pyedb/dotnet/database/sim_setup_data/io/siwave.py +53 -0
- pyedb/dotnet/database/stackup.py +5 -32
- pyedb/dotnet/database/utilities/hfss_simulation_setup.py +81 -0
- pyedb/dotnet/database/utilities/siwave_simulation_setup.py +259 -11
- pyedb/dotnet/edb.py +26 -13
- pyedb/extensions/create_cell_array.py +48 -44
- pyedb/generic/general_methods.py +24 -36
- pyedb/generic/plot.py +8 -23
- pyedb/generic/process.py +78 -10
- pyedb/grpc/database/components.py +7 -5
- pyedb/grpc/database/control_file.py +13 -5
- pyedb/grpc/database/definition/padstack_def.py +10 -5
- pyedb/grpc/database/hierarchy/component.py +2 -9
- pyedb/grpc/database/modeler.py +28 -8
- pyedb/grpc/database/padstacks.py +62 -103
- pyedb/grpc/database/primitive/padstack_instance.py +41 -12
- pyedb/grpc/database/primitive/path.py +13 -13
- pyedb/grpc/database/simulation_setup/hfss_simulation_setup.py +79 -0
- pyedb/grpc/database/source_excitations.py +7 -7
- pyedb/grpc/database/stackup.py +5 -33
- pyedb/grpc/database/terminal/padstack_instance_terminal.py +9 -11
- pyedb/grpc/database/terminal/point_terminal.py +30 -0
- pyedb/grpc/database/terminal/terminal.py +16 -2
- pyedb/grpc/database/utility/xml_control_file.py +13 -5
- pyedb/grpc/edb.py +46 -20
- pyedb/grpc/edb_init.py +7 -19
- pyedb/misc/aedtlib_personalib_install.py +2 -2
- pyedb/misc/downloads.py +18 -3
- pyedb/misc/siw_feature_config/emc_rule_checker_settings.py +2 -1
- pyedb/misc/siw_feature_config/xtalk_scan/scan_config.py +0 -1
- pyedb/workflows/sipi/hfss_auto_configuration.py +711 -0
- {pyedb-0.57.0.dist-info → pyedb-0.59.0.dist-info}/METADATA +4 -5
- {pyedb-0.57.0.dist-info → pyedb-0.59.0.dist-info}/RECORD +46 -45
- {pyedb-0.57.0.dist-info → pyedb-0.59.0.dist-info}/WHEEL +0 -0
- {pyedb-0.57.0.dist-info → pyedb-0.59.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -22,9 +22,20 @@
|
|
|
22
22
|
|
|
23
23
|
from ansys.edb.core.geometry.point_data import PointData as GrpcPointData
|
|
24
24
|
from ansys.edb.core.terminal.point_terminal import PointTerminal as GrpcPointTerminal
|
|
25
|
+
from ansys.edb.core.terminal.terminal import BoundaryType as GrpcBoundaryType
|
|
25
26
|
|
|
26
27
|
from pyedb.grpc.database.utility.value import Value
|
|
27
28
|
|
|
29
|
+
mapping_boundary_type = {
|
|
30
|
+
"port": GrpcBoundaryType.PORT,
|
|
31
|
+
"dc_terminal": GrpcBoundaryType.DC_TERMINAL,
|
|
32
|
+
"voltage_probe": GrpcBoundaryType.VOLTAGE_PROBE,
|
|
33
|
+
"voltage_source": GrpcBoundaryType.VOLTAGE_SOURCE,
|
|
34
|
+
"current_source": GrpcBoundaryType.CURRENT_SOURCE,
|
|
35
|
+
"rlc": GrpcBoundaryType.RLC,
|
|
36
|
+
"pec": GrpcBoundaryType.PEC,
|
|
37
|
+
}
|
|
38
|
+
|
|
28
39
|
|
|
29
40
|
class PointTerminal(GrpcPointTerminal):
|
|
30
41
|
"""Manages point terminal properties."""
|
|
@@ -33,6 +44,25 @@ class PointTerminal(GrpcPointTerminal):
|
|
|
33
44
|
super().__init__(edb_object.msg)
|
|
34
45
|
self._pedb = pedb
|
|
35
46
|
|
|
47
|
+
@property
|
|
48
|
+
def boundary_type(self):
|
|
49
|
+
"""Boundary type.
|
|
50
|
+
|
|
51
|
+
Returns
|
|
52
|
+
-------
|
|
53
|
+
str : boundary type.
|
|
54
|
+
|
|
55
|
+
"""
|
|
56
|
+
return super().boundary_type.name.lower()
|
|
57
|
+
|
|
58
|
+
@boundary_type.setter
|
|
59
|
+
def boundary_type(self, value):
|
|
60
|
+
if isinstance(value, str):
|
|
61
|
+
value = mapping_boundary_type.get(value.lower(), None)
|
|
62
|
+
if not isinstance(value, GrpcBoundaryType):
|
|
63
|
+
raise ValueError("Value must be a string or BoundaryType enum.")
|
|
64
|
+
super(PointTerminal, self.__class__).boundary_type.__set__(self, value)
|
|
65
|
+
|
|
36
66
|
@property
|
|
37
67
|
def location(self) -> list[float]:
|
|
38
68
|
"""Terminal position.
|
|
@@ -38,6 +38,16 @@ from ansys.edb.core.terminal.terminal import (
|
|
|
38
38
|
from pyedb.grpc.database.primitive.primitive import Primitive
|
|
39
39
|
from pyedb.grpc.database.utility.value import Value
|
|
40
40
|
|
|
41
|
+
mapping_boundary_type = {
|
|
42
|
+
"port": GrpcBoundaryType.PORT,
|
|
43
|
+
"dc_terminal": GrpcBoundaryType.DC_TERMINAL,
|
|
44
|
+
"voltage_probe": GrpcBoundaryType.VOLTAGE_PROBE,
|
|
45
|
+
"voltage_source": GrpcBoundaryType.VOLTAGE_SOURCE,
|
|
46
|
+
"current_source": GrpcBoundaryType.CURRENT_SOURCE,
|
|
47
|
+
"rlc": GrpcBoundaryType.RLC,
|
|
48
|
+
"pec": GrpcBoundaryType.PEC,
|
|
49
|
+
}
|
|
50
|
+
|
|
41
51
|
|
|
42
52
|
class Terminal(GrpcTerminal):
|
|
43
53
|
def __init__(self, pedb, edb_object):
|
|
@@ -202,7 +212,11 @@ class Terminal(GrpcTerminal):
|
|
|
202
212
|
|
|
203
213
|
@boundary_type.setter
|
|
204
214
|
def boundary_type(self, value):
|
|
205
|
-
|
|
215
|
+
if isinstance(value, str):
|
|
216
|
+
value = mapping_boundary_type.get(value.lower(), None)
|
|
217
|
+
if not isinstance(value, GrpcBoundaryType):
|
|
218
|
+
raise ValueError("Value must be a string or BoundaryType enum.")
|
|
219
|
+
super(Terminal, self.__class__).boundary_type.__set__(self, value)
|
|
206
220
|
|
|
207
221
|
@property
|
|
208
222
|
def is_port(self) -> bool:
|
|
@@ -250,7 +264,7 @@ class Terminal(GrpcTerminal):
|
|
|
250
264
|
|
|
251
265
|
@impedance.setter
|
|
252
266
|
def impedance(self, value):
|
|
253
|
-
self.impedance
|
|
267
|
+
super(Terminal, self.__class__).impedance.__set__(self, self._pedb.value(value))
|
|
254
268
|
|
|
255
269
|
@property
|
|
256
270
|
def reference_object(self) -> any:
|
|
@@ -23,9 +23,11 @@
|
|
|
23
23
|
import copy
|
|
24
24
|
import os
|
|
25
25
|
import re
|
|
26
|
-
import subprocess
|
|
26
|
+
import subprocess # nosec B404
|
|
27
27
|
import sys
|
|
28
28
|
|
|
29
|
+
from defusedxml.ElementTree import parse as defused_parse
|
|
30
|
+
|
|
29
31
|
from pyedb.generic.general_methods import ET, env_path, env_value, is_linux
|
|
30
32
|
from pyedb.generic.settings import settings
|
|
31
33
|
from pyedb.misc.aedtlib_personalib_install import write_pretty_xml
|
|
@@ -35,6 +37,11 @@ from pyedb.misc.misc import list_installed_ansysem
|
|
|
35
37
|
def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
36
38
|
"""Convert a technology file to edb control file (xml).
|
|
37
39
|
|
|
40
|
+
.. warning::
|
|
41
|
+
Do not execute this function with untrusted function argument, environment
|
|
42
|
+
variables or pyedb global settings.
|
|
43
|
+
See the :ref:`security guide<ref_security_consideration>` for details.
|
|
44
|
+
|
|
38
45
|
Parameters
|
|
39
46
|
----------
|
|
40
47
|
tech_file : str
|
|
@@ -98,10 +105,11 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
|
|
|
98
105
|
]
|
|
99
106
|
commands.append(command)
|
|
100
107
|
commands.append(["rm", "-r", vlc_file_name + ".aedb"])
|
|
101
|
-
my_env = os.environ.copy()
|
|
102
108
|
for command in commands:
|
|
103
|
-
|
|
104
|
-
|
|
109
|
+
try:
|
|
110
|
+
subprocess.run(command, check=True) # nosec
|
|
111
|
+
except subprocess.CalledProcessError as e: # nosec
|
|
112
|
+
raise RuntimeError("An error occurred while converting a technology file to edb control file") from e
|
|
105
113
|
if os.path.exists(control_file):
|
|
106
114
|
settings.logger.info("Xml file created.")
|
|
107
115
|
return control_file
|
|
@@ -1188,7 +1196,7 @@ class ControlFile:
|
|
|
1188
1196
|
-------
|
|
1189
1197
|
bool
|
|
1190
1198
|
"""
|
|
1191
|
-
tree =
|
|
1199
|
+
tree = defused_parse(xml_input)
|
|
1192
1200
|
root = tree.getroot()
|
|
1193
1201
|
for el in root:
|
|
1194
1202
|
if el.tag == "Stackup":
|
pyedb/grpc/edb.py
CHANGED
|
@@ -60,7 +60,7 @@ from itertools import combinations
|
|
|
60
60
|
import os
|
|
61
61
|
import re
|
|
62
62
|
import shutil
|
|
63
|
-
import subprocess
|
|
63
|
+
import subprocess # nosec B404
|
|
64
64
|
import sys
|
|
65
65
|
import tempfile
|
|
66
66
|
import time
|
|
@@ -217,8 +217,8 @@ class Edb(EdbInit):
|
|
|
217
217
|
self.standalone = True
|
|
218
218
|
self.oproject = oproject
|
|
219
219
|
self._main = sys.modules["__main__"]
|
|
220
|
-
self.
|
|
221
|
-
if not float(self.
|
|
220
|
+
self.version = edbversion
|
|
221
|
+
if not float(self.version) >= 2025.2:
|
|
222
222
|
raise "EDB gRPC is only supported with ANSYS release 2025R2 and higher."
|
|
223
223
|
self.logger.info("Using PyEDB with gRPC as Beta until ANSYS 2025R2 official release.")
|
|
224
224
|
self.isaedtowned = isaedtowned
|
|
@@ -620,7 +620,7 @@ class Edb(EdbInit):
|
|
|
620
620
|
if self.db.is_null:
|
|
621
621
|
self.logger.warning("Error Opening db")
|
|
622
622
|
self._active_cell = None
|
|
623
|
-
self.logger.info(f"Database {os.path.split(self.edbpath)[-1]} Opened in {self.
|
|
623
|
+
self.logger.info(f"Database {os.path.split(self.edbpath)[-1]} Opened in {self.version}")
|
|
624
624
|
self._active_cell = None
|
|
625
625
|
if self.cellname:
|
|
626
626
|
for cell in self.active_db.circuit_cells:
|
|
@@ -761,6 +761,11 @@ class Edb(EdbInit):
|
|
|
761
761
|
|
|
762
762
|
This function supports all AEDT formats, including DXF, GDS, SML (IPC2581), BRD, MCM, SIP, ZIP and TGZ.
|
|
763
763
|
|
|
764
|
+
.. warning::
|
|
765
|
+
Do not execute this function with untrusted function argument, environment
|
|
766
|
+
variables or pyedb global settings.
|
|
767
|
+
See the :ref:`security guide<ref_security_consideration>` for details.
|
|
768
|
+
|
|
764
769
|
Parameters
|
|
765
770
|
----------
|
|
766
771
|
input_file : str
|
|
@@ -803,16 +808,16 @@ class Edb(EdbInit):
|
|
|
803
808
|
self._nets = None
|
|
804
809
|
aedb_name = os.path.splitext(os.path.basename(input_file))[0] + ".aedb"
|
|
805
810
|
if anstranslator_full_path and os.path.exists(anstranslator_full_path):
|
|
806
|
-
|
|
811
|
+
executable_path = anstranslator_full_path
|
|
807
812
|
else:
|
|
808
|
-
|
|
813
|
+
executable_path = os.path.join(self.base_path, "anstranslator")
|
|
809
814
|
if is_windows:
|
|
810
|
-
|
|
815
|
+
executable_path += ".exe"
|
|
811
816
|
|
|
812
817
|
if not working_dir:
|
|
813
818
|
working_dir = os.path.dirname(input_file)
|
|
814
819
|
cmd_translator = [
|
|
815
|
-
|
|
820
|
+
executable_path,
|
|
816
821
|
input_file,
|
|
817
822
|
os.path.join(working_dir, aedb_name),
|
|
818
823
|
"-l={}".format(os.path.join(working_dir, "Translator.log")),
|
|
@@ -830,7 +835,10 @@ class Edb(EdbInit):
|
|
|
830
835
|
cmd_translator.append('-t="{}"'.format(tech_file))
|
|
831
836
|
if layer_filter:
|
|
832
837
|
cmd_translator.append('-f="{}"'.format(layer_filter))
|
|
833
|
-
|
|
838
|
+
try:
|
|
839
|
+
subprocess.run(cmd_translator, check=True) # nosec
|
|
840
|
+
except subprocess.CalledProcessError as e: # nosec
|
|
841
|
+
raise RuntimeError("An error occurred while translating board file to ``edb.def`` file") from e
|
|
834
842
|
if not os.path.exists(os.path.join(working_dir, aedb_name)):
|
|
835
843
|
self.logger.error("Translator failed to translate.")
|
|
836
844
|
return False
|
|
@@ -1340,6 +1348,11 @@ class Edb(EdbInit):
|
|
|
1340
1348
|
):
|
|
1341
1349
|
"""Import GDS file.
|
|
1342
1350
|
|
|
1351
|
+
.. warning::
|
|
1352
|
+
Do not execute this function with untrusted function argument, environment
|
|
1353
|
+
variables or pyedb global settings.
|
|
1354
|
+
See the :ref:`security guide<ref_security_consideration>` for details.
|
|
1355
|
+
|
|
1343
1356
|
Parameters
|
|
1344
1357
|
----------
|
|
1345
1358
|
inputGDS : str
|
|
@@ -1358,7 +1371,7 @@ class Edb(EdbInit):
|
|
|
1358
1371
|
Layer filter file.
|
|
1359
1372
|
"""
|
|
1360
1373
|
control_file_temp = os.path.join(tempfile.gettempdir(), os.path.split(inputGDS)[-1][:-3] + "xml")
|
|
1361
|
-
if float(self.
|
|
1374
|
+
if float(self.version) < 2024.1:
|
|
1362
1375
|
if not is_linux and tech_file:
|
|
1363
1376
|
self.logger.error("Technology files are supported only in Linux. Use control file instead.")
|
|
1364
1377
|
return False
|
|
@@ -1403,9 +1416,12 @@ class Edb(EdbInit):
|
|
|
1403
1416
|
f'-f="{layer_filter}"',
|
|
1404
1417
|
]
|
|
1405
1418
|
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1419
|
+
try:
|
|
1420
|
+
result = subprocess.run(command, capture_output=True, text=True, check=True) # nosec
|
|
1421
|
+
print(result.stdout)
|
|
1422
|
+
print(command)
|
|
1423
|
+
except subprocess.CalledProcessError as e: # nosec
|
|
1424
|
+
raise RuntimeError("An error occurred while converting file") from e
|
|
1409
1425
|
temp_inputGDS = inputGDS.split(".gds")[0]
|
|
1410
1426
|
self.edbpath = temp_inputGDS + ".aedb"
|
|
1411
1427
|
return self.open()
|
|
@@ -3046,7 +3062,7 @@ class Edb(EdbInit):
|
|
|
3046
3062
|
if name in self.setups:
|
|
3047
3063
|
self.logger.error("Setup name already used in the layout")
|
|
3048
3064
|
return False
|
|
3049
|
-
version = self.
|
|
3065
|
+
version = self.version.split(".")
|
|
3050
3066
|
if int(version[0]) >= 2024 and int(version[-1]) >= 2 or int(version[0]) > 2024:
|
|
3051
3067
|
setup = GrpcRaptorXSimulationSetup.create(cell=self.active_cell, name=name)
|
|
3052
3068
|
return RaptorXSimulationSetup(self, setup)
|
|
@@ -3237,7 +3253,7 @@ class Edb(EdbInit):
|
|
|
3237
3253
|
defined_ports = {}
|
|
3238
3254
|
project_connexions = None
|
|
3239
3255
|
for edb_path, zone_info in zone_dict.items():
|
|
3240
|
-
edb = Edb(edbversion=self.
|
|
3256
|
+
edb = Edb(edbversion=self.version, edbpath=edb_path)
|
|
3241
3257
|
edb.cutout(
|
|
3242
3258
|
use_pyaedt_cutout=True,
|
|
3243
3259
|
custom_extent=zone_info[1],
|
|
@@ -3779,7 +3795,7 @@ class Edb(EdbInit):
|
|
|
3779
3795
|
"No padstack instances found inside evaluated voids during model creation for arbitrary waveports"
|
|
3780
3796
|
)
|
|
3781
3797
|
return False
|
|
3782
|
-
cloned_edb = Edb(edbpath=output_edb, edbversion=self.
|
|
3798
|
+
cloned_edb = Edb(edbpath=output_edb, edbversion=self.version, restart_rpc_server=True)
|
|
3783
3799
|
|
|
3784
3800
|
cloned_edb.stackup.add_layer(
|
|
3785
3801
|
layer_name="ports",
|
|
@@ -3908,6 +3924,11 @@ class Edb(EdbInit):
|
|
|
3908
3924
|
def compare(self, input_file, results=""):
|
|
3909
3925
|
"""Compares current open database with another one.
|
|
3910
3926
|
|
|
3927
|
+
.. warning::
|
|
3928
|
+
Do not execute this function with untrusted function argument, environment
|
|
3929
|
+
variables or pyedb global settings.
|
|
3930
|
+
See the :ref:`security guide<ref_security_consideration>` for details.
|
|
3931
|
+
|
|
3911
3932
|
Parameters
|
|
3912
3933
|
----------
|
|
3913
3934
|
input_file : str
|
|
@@ -3924,13 +3945,18 @@ class Edb(EdbInit):
|
|
|
3924
3945
|
if not results:
|
|
3925
3946
|
results = self.edbpath[:-5] + "_compare_results"
|
|
3926
3947
|
os.mkdir(results)
|
|
3927
|
-
|
|
3948
|
+
executable_path = os.path.join(self.base_path, "EDBDiff.exe")
|
|
3928
3949
|
if is_linux:
|
|
3929
3950
|
mono_path = os.path.join(self.base_path, "common/mono/Linux64/bin/mono")
|
|
3930
|
-
|
|
3951
|
+
command = [mono_path, executable_path, input_file, self.edbpath, results]
|
|
3931
3952
|
else:
|
|
3932
|
-
|
|
3933
|
-
|
|
3953
|
+
command = [executable_path, input_file, self.edbpath, results]
|
|
3954
|
+
try:
|
|
3955
|
+
subprocess.run(command, check=True) # nosec
|
|
3956
|
+
except subprocess.CalledProcessError as e: # nosec
|
|
3957
|
+
raise RuntimeError(
|
|
3958
|
+
"EDBDiff.exe execution failed. Please check if the executable is present in the base path."
|
|
3959
|
+
)
|
|
3934
3960
|
|
|
3935
3961
|
if not os.path.exists(os.path.join(results, "EDBDiff.csv")):
|
|
3936
3962
|
self.logger.error("Comparison execution failed")
|
pyedb/grpc/edb_init.py
CHANGED
|
@@ -43,23 +43,23 @@ class EdbInit(object):
|
|
|
43
43
|
def __init__(self, edbversion):
|
|
44
44
|
self.logger = settings.logger
|
|
45
45
|
self._db = None
|
|
46
|
-
self.
|
|
46
|
+
self.version = edbversion
|
|
47
47
|
self.logger.info("Logger is initialized in EDB.")
|
|
48
48
|
self.logger.info("legacy v%s", __version__)
|
|
49
49
|
self.logger.info("Python version %s", sys.version)
|
|
50
50
|
self.session = None
|
|
51
51
|
if is_linux:
|
|
52
|
-
if env_value(self.
|
|
53
|
-
self.base_path = env_path(self.
|
|
52
|
+
if env_value(self.version) in os.environ:
|
|
53
|
+
self.base_path = env_path(self.version)
|
|
54
54
|
sys.path.append(self.base_path)
|
|
55
55
|
else:
|
|
56
56
|
edb_path = os.getenv("PYAEDT_SERVER_AEDT_PATH")
|
|
57
57
|
if edb_path:
|
|
58
58
|
self.base_path = edb_path
|
|
59
59
|
sys.path.append(edb_path)
|
|
60
|
-
os.environ[env_value(self.
|
|
60
|
+
os.environ[env_value(self.version)] = self.base_path
|
|
61
61
|
else:
|
|
62
|
-
self.base_path = env_path(self.
|
|
62
|
+
self.base_path = env_path(self.version)
|
|
63
63
|
sys.path.append(self.base_path)
|
|
64
64
|
os.environ["ECAD_TRANSLATORS_INSTALL_DIR"] = self.base_path
|
|
65
65
|
oa_directory = os.path.join(self.base_path, "common", "oa")
|
|
@@ -100,7 +100,7 @@ class EdbInit(object):
|
|
|
100
100
|
"""
|
|
101
101
|
if not RpcSession.pid:
|
|
102
102
|
RpcSession.start(
|
|
103
|
-
edb_version=self.
|
|
103
|
+
edb_version=self.version,
|
|
104
104
|
port=port,
|
|
105
105
|
restart_server=restart_rpc_server,
|
|
106
106
|
)
|
|
@@ -133,7 +133,7 @@ class EdbInit(object):
|
|
|
133
133
|
RpcSession.pid = 0
|
|
134
134
|
if not RpcSession.pid:
|
|
135
135
|
RpcSession.start(
|
|
136
|
-
edb_version=self.
|
|
136
|
+
edb_version=self.version,
|
|
137
137
|
port=port,
|
|
138
138
|
restart_server=restart_rpc_server,
|
|
139
139
|
)
|
|
@@ -372,18 +372,6 @@ class EdbInit(object):
|
|
|
372
372
|
"""
|
|
373
373
|
self._db.import_material_from_control_file(control_file, schema_dir, append)
|
|
374
374
|
|
|
375
|
-
@property
|
|
376
|
-
def version(self):
|
|
377
|
-
"""Get version of the Database.
|
|
378
|
-
|
|
379
|
-
Returns
|
|
380
|
-
-------
|
|
381
|
-
tuple(int, int)
|
|
382
|
-
A tuple of the version numbers [major, minor]
|
|
383
|
-
"""
|
|
384
|
-
major, minor = self._db.version
|
|
385
|
-
return major, minor
|
|
386
|
-
|
|
387
375
|
def scale(self, scale_factor):
|
|
388
376
|
"""Uniformly scale all geometry and their locations by a positive factor.
|
|
389
377
|
|
|
@@ -20,8 +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
|
-
|
|
24
|
-
|
|
23
|
+
import defusedxml.ElementTree as ET
|
|
24
|
+
from defusedxml.minidom import parseString
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
def write_pretty_xml(root, file_path):
|
pyedb/misc/downloads.py
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
import os
|
|
26
26
|
import shutil
|
|
27
|
+
import subprocess # nosec B404
|
|
27
28
|
import tempfile
|
|
28
29
|
import urllib.request
|
|
29
30
|
import zipfile
|
|
@@ -48,7 +49,18 @@ def _get_file_url(directory, filename=None):
|
|
|
48
49
|
|
|
49
50
|
|
|
50
51
|
def _retrieve_file(url, filename, directory, destination=None, local_paths=[]): # pragma: no cover
|
|
51
|
-
"""Download a file from a url
|
|
52
|
+
"""Download a file from a url
|
|
53
|
+
|
|
54
|
+
.. warning::
|
|
55
|
+
Do not execute this function with untrusted function argument, environment
|
|
56
|
+
variables or pyedb global settings.
|
|
57
|
+
See the :ref:`security guide<ref_security_consideration>` for details.
|
|
58
|
+
|
|
59
|
+
"""
|
|
60
|
+
# Check that provided url is pointing to pyaedt-example repo
|
|
61
|
+
if not url.startswith(EXAMPLE_REPO):
|
|
62
|
+
raise ValueError(f"Attempting to download file(s) from url {url} not pointing the to example-data repo.")
|
|
63
|
+
|
|
52
64
|
# First check if file has already been downloaded
|
|
53
65
|
if not destination:
|
|
54
66
|
destination = EXAMPLES_PATH
|
|
@@ -64,8 +76,11 @@ def _retrieve_file(url, filename, directory, destination=None, local_paths=[]):
|
|
|
64
76
|
os.makedirs(destination_dir)
|
|
65
77
|
# Perform download
|
|
66
78
|
if is_linux:
|
|
67
|
-
command = "wget
|
|
68
|
-
|
|
79
|
+
command = ["wget", url, "-O", local_path]
|
|
80
|
+
try:
|
|
81
|
+
subprocess.run(command, check=True) # nosec
|
|
82
|
+
except subprocess.CalledProcessError as e: # nosec
|
|
83
|
+
raise RuntimeError("An error occurred while downloading wget") from e
|
|
69
84
|
else:
|
|
70
85
|
_, resp = urlretrieve(url, local_path)
|
|
71
86
|
local_paths.append(local_path)
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
from copy import deepcopy as copy
|
|
24
24
|
import json
|
|
25
25
|
|
|
26
|
+
from defusedxml.ElementTree import parse as defused_parse
|
|
26
27
|
import numpy as np
|
|
27
28
|
|
|
28
29
|
from pyedb.generic.general_methods import ET
|
|
@@ -78,7 +79,7 @@ class EMCRuleCheckerSettings:
|
|
|
78
79
|
fpath: str
|
|
79
80
|
Path to file.
|
|
80
81
|
"""
|
|
81
|
-
tree =
|
|
82
|
+
tree = defused_parse(fpath)
|
|
82
83
|
root = tree.getroot()
|
|
83
84
|
|
|
84
85
|
self.tag_library = TagLibrary(root.find("TagLibrary"))
|