diff --git a/doc/changelog.d/7150.miscellaneous.md b/doc/changelog.d/7150.miscellaneous.md new file mode 100644 index 00000000000..fb1d7ff37a3 --- /dev/null +++ b/doc/changelog.d/7150.miscellaneous.md @@ -0,0 +1 @@ +Change property \"desktop_class\" to \"desktop\" diff --git a/doc/changelog.d/7212.fixed.md b/doc/changelog.d/7212.fixed.md new file mode 100644 index 00000000000..5df6470b769 --- /dev/null +++ b/doc/changelog.d/7212.fixed.md @@ -0,0 +1 @@ +Local access to file in example-data repo diff --git a/doc/changelog.d/7231.fixed.md b/doc/changelog.d/7231.fixed.md new file mode 100644 index 00000000000..03b1aebf1f1 --- /dev/null +++ b/doc/changelog.d/7231.fixed.md @@ -0,0 +1 @@ +Test Temp dir race condition diff --git a/doc/source/User_guide/pyaedt_extensions_doc/commandline.rst b/doc/source/User_guide/pyaedt_extensions_doc/commandline.rst index 0c4e3ed9b07..fe5ff5e358f 100644 --- a/doc/source/User_guide/pyaedt_extensions_doc/commandline.rst +++ b/doc/source/User_guide/pyaedt_extensions_doc/commandline.rst @@ -34,8 +34,8 @@ Finally, this code shows how you can run the extension directly from a Python sc file_path = "my_file.stl" hfss = ansys.aedt.core.Hfss() # Specify the AEDT session to connect - os.environ["PYAEDT_DESKTOP_PORT"] = str(hfss.desktop_class.port) - os.environ["PYAEDT_DESKTOP_VERSION"] = hfss.desktop_class.aedt_version_id + os.environ["PYAEDT_DESKTOP_PORT"] = str(hfss.desktop.port) + os.environ["PYAEDT_DESKTOP_VERSION"] = hfss.desktop.aedt_version_id # Launch extension main( { diff --git a/doc/source/User_guide/pyaedt_extensions_doc/project/advanced_fields_calculator.rst b/doc/source/User_guide/pyaedt_extensions_doc/project/advanced_fields_calculator.rst index e059beec339..7dc65e41851 100644 --- a/doc/source/User_guide/pyaedt_extensions_doc/project/advanced_fields_calculator.rst +++ b/doc/source/User_guide/pyaedt_extensions_doc/project/advanced_fields_calculator.rst @@ -56,8 +56,8 @@ Finally, this code shows how you can use the Advanced Field Calculator: hfss = ansys.aedt.core.Hfss() # Specify the AEDT session to connect - os.environ["PYAEDT_DESKTOP_PORT"] = str(hfss.desktop_class.port) - os.environ["PYAEDT_DESKTOP_VERSION"] = hfss.desktop_class.aedt_version_id + os.environ["PYAEDT_DESKTOP_PORT"] = str(hfss.desktop.port) + os.environ["PYAEDT_DESKTOP_VERSION"] = hfss.desktop.aedt_version_id # Add an existing expression in the catalog name = hfss.post.fields_calculator.add_expression("voltage_line", "Polyline1") diff --git a/doc/source/User_guide/pyaedt_extensions_doc/templates/getting_started.rst b/doc/source/User_guide/pyaedt_extensions_doc/templates/getting_started.rst index d7ecde80d58..f97902d066b 100644 --- a/doc/source/User_guide/pyaedt_extensions_doc/templates/getting_started.rst +++ b/doc/source/User_guide/pyaedt_extensions_doc/templates/getting_started.rst @@ -35,8 +35,8 @@ The extension can be run from a Python script in the following way: hfss = ansys.aedt.core.Hfss() # Specify the AEDT session to connect - os.environ["PYAEDT_DESKTOP_PORT"] = str(hfss.desktop_class.port) - os.environ["PYAEDT_DESKTOP_VERSION"] = hfss.desktop_class.aedt_version_id + os.environ["PYAEDT_DESKTOP_PORT"] = str(hfss.desktop.port) + os.environ["PYAEDT_DESKTOP_VERSION"] = hfss.desktop.aedt_version_id main({"origin_x": 2, "radius": 6, "is_test": True}) diff --git a/src/ansys/aedt/core/application/aedt_objects.py b/src/ansys/aedt/core/application/aedt_objects.py index cce390b86c4..12eecc6223f 100644 --- a/src/ansys/aedt/core/application/aedt_objects.py +++ b/src/ansys/aedt/core/application/aedt_objects.py @@ -114,7 +114,7 @@ def oradfield(self): SolutionsHfss.CharacteristicMode, ]: return self._odesign.GetModule("RadField") - if self.desktop_class.aedt_version_id >= "2025.1" and self.design_type == "Q3D Extractor": + if self.desktop.aedt_version_id >= "2025.1" and self.design_type == "Q3D Extractor": return self._odesign.GetModule("RadField") return None @@ -407,12 +407,12 @@ def oeditor(self): self._oeditor = self._odesign.GetEditor("SchematicEditor") if is_linux and settings.aedt_version == "2024.1": # pragma: no cover time.sleep(1) - self.desktop_class.close_windows() + self.desktop.close_windows() elif self.design_type in ["Twin Builder", "Maxwell Circuit", "EMIT"]: self._oeditor = self._odesign.SetActiveEditor("SchematicEditor") if is_linux and settings.aedt_version == "2024.1": # pragma: no cover time.sleep(1) - self.desktop_class.close_windows() + self.desktop.close_windows() elif self.design_type in ["HFSS 3D Layout Design", "HFSS3DLayout"]: self._oeditor = self._odesign.GetEditor("Layout") elif self.design_type in [DesignType.MODELCREATION.NAME, DesignType.RMXPRT.NAME]: diff --git a/src/ansys/aedt/core/application/analysis.py b/src/ansys/aedt/core/application/analysis.py index cb750c384ff..72e88a5dd9e 100644 --- a/src/ansys/aedt/core/application/analysis.py +++ b/src/ansys/aedt/core/application/analysis.py @@ -1829,7 +1829,7 @@ def analyze_setup( ) if name is None: try: - if self.desktop_class.aedt_version_id > "2023.1" and self.design_type not in [ + if self.desktop.aedt_version_id > "2023.1" and self.design_type not in [ "RMxprt", "ModelCreation", ]: @@ -1848,7 +1848,7 @@ def analyze_setup( self.logger.warning("Failed to revert to initial design mesh.") try: self.logger.info("Solving design setup %s", name) - if self.desktop_class.aedt_version_id > "2023.1" and self.design_type not in [ + if self.desktop.aedt_version_id > "2023.1" and self.design_type not in [ "RMxprt", "ModelCreation", ]: @@ -1889,7 +1889,7 @@ def are_there_simulations_running(self): ---------- >>> oDesktop.AreThereSimulationsRunning """ - return self.desktop_class.are_there_simulations_running + return self.desktop.are_there_simulations_running @pyaedt_function_handler() def get_monitor_data(self): @@ -1906,7 +1906,7 @@ def get_monitor_data(self): ---------- >>> oDesktop.GetMonitorData """ - return self.desktop_class.get_monitor_data() + return self.desktop.get_monitor_data() @pyaedt_function_handler() def stop_simulations(self, clean_stop: bool = True): @@ -1923,7 +1923,7 @@ def stop_simulations(self, clean_stop: bool = True): ---------- >>> oDesktop.StopSimulations """ - return self.desktop_class.stop_simulations(clean_stop=clean_stop) + return self.desktop.stop_simulations(clean_stop=clean_stop) # flake8: noqa: E501 @pyaedt_function_handler() @@ -2103,7 +2103,7 @@ def submit_job( ---------- >>> oDesktop.SubmitJob """ - return self.desktop_class.submit_job( + return self.desktop.submit_job( self.project_file, cluster_name, aedt_full_exe_path, nodes, cores, wait_for_license, setting_file ) diff --git a/src/ansys/aedt/core/application/analysis_3d.py b/src/ansys/aedt/core/application/analysis_3d.py index b4e3231f1ce..e6e4d9e2916 100644 --- a/src/ansys/aedt/core/application/analysis_3d.py +++ b/src/ansys/aedt/core/application/analysis_3d.py @@ -1258,7 +1258,7 @@ def import_dxf( """ input_file = Path(input_file) - if self.desktop_class.non_graphical and self.desktop_class.aedt_version_id < "2024.2": # pragma: no cover + if self.desktop.non_graphical and self.desktop.aedt_version_id < "2024.2": # pragma: no cover self.logger.error("Method is supported only in graphical mode.") return False dxf_layers = get_dxf_layers(input_file) @@ -1338,7 +1338,7 @@ def import_gds_3d(self, input_file: str, mapping_layers: dict, units: str = "um" >>> hfss.import_gds_3d(gds_path, gds_number, units="um", import_method=1) """ - if self.desktop_class.non_graphical and self.desktop_class.aedt_version_id < "2024.1": # pragma: no cover + if self.desktop.non_graphical and self.desktop.aedt_version_id < "2024.1": # pragma: no cover self.logger.error("Method is supported only in graphical mode.") return False if not check_if_path_exists(input_file): diff --git a/src/ansys/aedt/core/application/analysis_nexxim.py b/src/ansys/aedt/core/application/analysis_nexxim.py index b3df1e19a87..3bfd8b21449 100644 --- a/src/ansys/aedt/core/application/analysis_nexxim.py +++ b/src/ansys/aedt/core/application/analysis_nexxim.py @@ -160,7 +160,7 @@ def push_down(self, component) -> bool: else: out_name = component try: - self.desktop_class.active_design(self.oproject, out_name, self.design_type) + self.desktop.active_design(self.oproject, out_name, self.design_type) self.__init__(project=self.project_name, design=out_name) except Exception: # pragma: no cover return False @@ -177,7 +177,7 @@ def pop_up(self) -> bool: """ try: parent_name = self.odesign.GetName().split(";")[1].split("/")[0] - self.desktop_class.active_design(self.oproject, parent_name, self.design_type) + self.desktop.active_design(self.oproject, parent_name, self.design_type) self.__init__(project=self.project_name, design=parent_name) except Exception: return False diff --git a/src/ansys/aedt/core/circuit.py b/src/ansys/aedt/core/circuit.py index e1fefb4cbae..19cf1b9acd7 100644 --- a/src/ansys/aedt/core/circuit.py +++ b/src/ansys/aedt/core/circuit.py @@ -229,7 +229,7 @@ def create_schematic_from_netlist(self, input_file: str) -> bool: delta = 0.0508 use_instance = True model = [] - self.desktop_class.close_windows() + self.desktop.close_windows() autosave = False if self._desktop.GetAutoSaveEnabled() == 1: self._desktop.EnableAutoSave(False) @@ -686,7 +686,7 @@ def get_source_pin_names( oDesign = oSrcProject.SetActiveDesign(source_design_name) if is_linux and settings.aedt_version == "2024.1": # pragma: no cover time.sleep(1) - self.desktop_class.close_windows() + self.desktop.close_windows() tmp_oModule = oDesign.GetModule("BoundarySetup") port = None if port_selector == 1: @@ -1637,9 +1637,9 @@ def import_edb_in_circuit(self, input_dir: str | Path) -> CircuitComponent: self.logger.error( "Failed to setup co-simulation settings, make sure the simulation setup is properly defined" ) - active_project = hfss.desktop_class.active_project(hfss.project_name) + active_project = hfss.desktop.active_project(hfss.project_name) active_project.CopyDesign(hfss.design_name) - active_project = hfss.desktop_class.active_project(self.project_name) + active_project = hfss.desktop.active_project(self.project_name) active_project.Paste() hfss_3d_layout_model = self.modeler.schematic.add_subcircuit_3dlayout(hfss.design_name) hfss.close_project(save=False) diff --git a/src/ansys/aedt/core/emit_core/results/results.py b/src/ansys/aedt/core/emit_core/results/results.py index 5d9b924a461..64bce557832 100644 --- a/src/ansys/aedt/core/emit_core/results/results.py +++ b/src/ansys/aedt/core/emit_core/results/results.py @@ -57,7 +57,7 @@ def __init__(self, emit_obj) -> None: self.revisions = [] """List of all result revisions. Only one loaded at a time""" - self.design = emit_obj.desktop_class.active_design(emit_obj.odesktop.GetActiveProject()) + self.design = emit_obj.desktop.active_design(emit_obj.odesktop.GetActiveProject()) """Active design for the EMIT project.""" self.aedt_version = int(self.emit_project.aedt_version_id[-3:]) @@ -271,9 +271,7 @@ def analyze(self): # no changes since last created revision, load it elif ( self.revisions[-1].revision_number - == self.emit_project.desktop_class.active_design( - self.emit_project.desktop_class.active_project() - ).GetRevision() + == self.emit_project.desktop.active_design(self.emit_project.desktop.active_project()).GetRevision() ): self.get_revision(self.revisions[-1].name) else: diff --git a/src/ansys/aedt/core/examples/downloads.py b/src/ansys/aedt/core/examples/downloads.py index be0f1228b05..279fbf66c06 100644 --- a/src/ansys/aedt/core/examples/downloads.py +++ b/src/ansys/aedt/core/examples/downloads.py @@ -115,13 +115,24 @@ def _copy_local_example( source_relative_path: str, target_path: str | Path | None = None, ) -> Path: # pragma: no cover - """Copy a folder from a local copy of the examples repo.""" - dst = Path(target_path) / Path(source_relative_path).name + """Copy a file or folder from a local copy of the examples repo.""" + pyaedt_logger.debug(f"Retrieving local example from '{settings.local_example_folder}'") + source = Path(settings.local_example_folder) / source_relative_path + target_path = Path(target_path) + + if source.is_file(): + target_path.mkdir(parents=True, exist_ok=True) + dst = target_path / source.name + try: + shutil.copy2(source, dst) + except Exception as e: + raise AEDTRuntimeError(f"Failed to copy {str(source)}.") from e + return dst + + dst = target_path / Path(source_relative_path).name dst.mkdir(parents=True, exist_ok=True) - pyaedt_logger.debug(f"Retrieving local folder from '{settings.local_example_folder}'") - source_folder = Path(settings.local_example_folder) / source_relative_path - for p in source_folder.rglob("*"): - target = dst / p.relative_to(source_folder) + for p in source.rglob("*"): + target = dst / p.relative_to(source) if p.is_dir(): target.mkdir(parents=True, exist_ok=True) else: diff --git a/src/ansys/aedt/core/extensions/hfss/mcad_assembly.py b/src/ansys/aedt/core/extensions/hfss/mcad_assembly.py index d209a00abe4..d352acb1f05 100644 --- a/src/ansys/aedt/core/extensions/hfss/mcad_assembly.py +++ b/src/ansys/aedt/core/extensions/hfss/mcad_assembly.py @@ -192,7 +192,7 @@ def run(self, config_data) -> None: del app if "PYTEST_CURRENT_TEST" not in os.environ: # pragma: no cover - hfss.desktop_class.release_desktop(False, False) + hfss.desktop.release_desktop(False, False) else: hfss.close_project(save=False) return diff --git a/src/ansys/aedt/core/extensions/hfss3dlayout/parametrize_edb.py b/src/ansys/aedt/core/extensions/hfss3dlayout/parametrize_edb.py index c11038e8d1d..5af4167d185 100644 --- a/src/ansys/aedt/core/extensions/hfss3dlayout/parametrize_edb.py +++ b/src/ansys/aedt/core/extensions/hfss3dlayout/parametrize_edb.py @@ -397,7 +397,7 @@ def main(data: ParametrizeEdbExtensionData) -> bool: if "PYTEST_CURRENT_TEST" not in os.environ: h3d = Hfss3dLayout(str(new_project_aedb)) h3d.logger.info("Parametric project generated successfully.") - h3d.desktop_class.release_desktop(False, False) + h3d.desktop.release_desktop(False, False) return True diff --git a/src/ansys/aedt/core/extensions/hfss3dlayout/post_layout_design.py b/src/ansys/aedt/core/extensions/hfss3dlayout/post_layout_design.py index 09a415e61a5..df09d46f5d7 100644 --- a/src/ansys/aedt/core/extensions/hfss3dlayout/post_layout_design.py +++ b/src/ansys/aedt/core/extensions/hfss3dlayout/post_layout_design.py @@ -388,7 +388,7 @@ def main(data: PostLayoutDesignExtensionData) -> bool: # Open new project with micro vias new_h3d = ansys.aedt.core.Hfss3dLayout(project=new_edb_path) if "PYTEST_CURRENT_TEST" not in os.environ: - new_h3d.desktop_class.release_desktop(False, False) + new_h3d.desktop.release_desktop(False, False) else: raise AEDTRuntimeError(f"Unknown action: {data.action}") diff --git a/src/ansys/aedt/core/extensions/hfss3dlayout/resources/configure_layout/master_ui.py b/src/ansys/aedt/core/extensions/hfss3dlayout/resources/configure_layout/master_ui.py index 7d11e679d9d..a4ea7adef10 100644 --- a/src/ansys/aedt/core/extensions/hfss3dlayout/resources/configure_layout/master_ui.py +++ b/src/ansys/aedt/core/extensions/hfss3dlayout/resources/configure_layout/master_ui.py @@ -195,7 +195,7 @@ def export_config_from_edb(self): def load_edb_into_hfss3dlayout(self, edb_path: str | Path): app = ansys.aedt.core.Hfss3dLayout(project=str(edb_path), **self.aedt_info.model_dump()) if "PYTEST_CURRENT_TEST" not in os.environ: # pragma: no cover - app.desktop_class.release_desktop(False, False) + app.desktop.release_desktop(False, False) else: app.close_project(save=False) return app diff --git a/src/ansys/aedt/core/extensions/hfss3dlayout/via_clustering.py b/src/ansys/aedt/core/extensions/hfss3dlayout/via_clustering.py index e00ada0c116..22c83983ac7 100644 --- a/src/ansys/aedt/core/extensions/hfss3dlayout/via_clustering.py +++ b/src/ansys/aedt/core/extensions/hfss3dlayout/via_clustering.py @@ -213,7 +213,7 @@ def add_drawing_layer() -> None: ) layer = hfss.modeler.stackup.add_layer("via_merging") layer.usp = True - hfss.desktop_class.release_desktop(False, False) + hfss.desktop.release_desktop(False, False) def callback_merge_vias(extension: ViaClusteringExtension): """Callback for merging via instances.""" @@ -228,7 +228,7 @@ def callback_merge_vias(extension: ViaClusteringExtension): primitives = hfss.modeler.objects_by_layer(layer="via_merging") if not primitives: messagebox.showwarning(message="No primitives found on layer defined for merging padstack instances.") - hfss.desktop_class.release_desktop(False, False) + hfss.desktop.release_desktop(False, False) extension.release_desktop() raise AEDTRuntimeError("No primitives found on layer defined for merging padstack instances.") @@ -260,7 +260,7 @@ def callback_merge_vias(extension: ViaClusteringExtension): contour_list=contour_list, ) extension.data = via_clustering_data - hfss.desktop_class.release_desktop(False, False) + hfss.desktop.release_desktop(False, False) extension.root.destroy() button_add_layer = ttk.Button( @@ -326,7 +326,7 @@ def main(data: ViaClusteringExtensionData) -> bool: if "PYTEST_CURRENT_TEST" not in os.environ: # pragma: no cover h3d = Hfss3dLayout(new_aedb_path) h3d.logger.info("Project generated correctly.") - h3d.desktop_class.release_desktop(False, False) + h3d.desktop.release_desktop(False, False) return True diff --git a/src/ansys/aedt/core/extensions/hfss3dlayout/via_design.py b/src/ansys/aedt/core/extensions/hfss3dlayout/via_design.py index 74cd60ccd01..2f7a179033c 100644 --- a/src/ansys/aedt/core/extensions/hfss3dlayout/via_design.py +++ b/src/ansys/aedt/core/extensions/hfss3dlayout/via_design.py @@ -199,7 +199,7 @@ def create_design(self, create_design_path: Path | None = None): ) if "PYTEST_CURRENT_TEST" not in os.environ: - hfss_3d.desktop_class.release_desktop(False, False) + hfss_3d.desktop.release_desktop(False, False) return True @property diff --git a/src/ansys/aedt/core/generic/configurations.py b/src/ansys/aedt/core/generic/configurations.py index 619a3a0f648..f3acb0d89c4 100644 --- a/src/ansys/aedt/core/generic/configurations.py +++ b/src/ansys/aedt/core/generic/configurations.py @@ -2123,7 +2123,7 @@ def apply_operations_to_native_components(obj, operation_dict, native_dict) -> b native = NativeComponentPCB(self._app, native_dict["Type"], native_name, nc_dict) else: native = NativeComponentObject(self._app, native_dict["Type"], native_name, nc_dict) - prj_list = set(self._app.desktop_class.project_list) + prj_list = set(self._app.desktop.project_list) definition_names = set(self._app.oeditor.Get3DComponentDefinitionNames()) instance_names = { def_name: set(self._app.oeditor.Get3DComponentInstanceNames(def_name)) @@ -2152,7 +2152,7 @@ def apply_operations_to_native_components(obj, operation_dict, native_dict) -> b if nc_dict["NativeComponentDefinitionProvider"]["Type"] == "PCB" and nc_dict[ "NativeComponentDefinitionProvider" ]["DefnLink"]["Project"] not in [self._app.project_file or "This Project*"]: - prj = list(set(self._app.desktop_class.project_list) - prj_list)[0] + prj = list(set(self._app.desktop.project_list) - prj_list)[0] design = nc_dict["NativeComponentDefinitionProvider"]["DefnLink"]["Design"] from ansys.aedt.core.generic.design_types import get_pyaedt_app diff --git a/src/ansys/aedt/core/hfss.py b/src/ansys/aedt/core/hfss.py index db86e9fabc1..120fcfb8cb5 100644 --- a/src/ansys/aedt/core/hfss.py +++ b/src/ansys/aedt/core/hfss.py @@ -2715,7 +2715,7 @@ def create_sbr_custom_array_file( >>> from ansys.aedt.core import Hfss >>> hfss = Hfss() >>> hfss.create_sbr_custom_array_file() - >>> hfss.desktop_class.close_desktop() + >>> hfss.desktop.close_desktop() """ if output_file is None: output_file = Path(self.working_directory) / "custom_array.sarr" @@ -6231,7 +6231,7 @@ def set_phase_center_per_port(self, coordinate_system: list = None) -> bool: >>> hfss.set_phase_center_per_port(["Global", "Global"]) """ - if not self.desktop_class.is_grpc_api: # pragma: no cover + if not self.desktop.is_grpc_api: # pragma: no cover raise AEDTRuntimeError("Set phase center is not supported by AEDT COM API. Set phase center manually.") port_names = self.ports[::] @@ -6489,7 +6489,7 @@ def lumped_port( self.solution_type == SolutionsHfss.DrivenModal or ( self.solution_type in [SolutionsHfss.DrivenTerminal, SolutionsHfss.Transient] - and self.desktop_class.aedt_version_id >= "2024.1" + and self.desktop.aedt_version_id >= "2024.1" ) and not reference ): @@ -6695,7 +6695,7 @@ def wave_port( self.solution_type == SolutionsHfss.DrivenModal or ( self.solution_type in [SolutionsHfss.DrivenTerminal, SolutionsHfss.Transient] - and self.desktop_class.aedt_version_id >= "2024.1" + and self.desktop.aedt_version_id >= "2024.1" ) and not reference ): diff --git a/src/ansys/aedt/core/hfss3dlayout.py b/src/ansys/aedt/core/hfss3dlayout.py index 21c72ff2576..52b5f11619a 100644 --- a/src/ansys/aedt/core/hfss3dlayout.py +++ b/src/ansys/aedt/core/hfss3dlayout.py @@ -785,8 +785,8 @@ def import_edb(self, input_folder: str | Path) -> bool: input_folder = Path(input_folder) / "edb.def" self.oimport_export.ImportEDB(str(input_folder)) self._close_edb() - project_name = self.desktop_class.active_project().GetName() - design_name = self.desktop_class.active_design(self.desktop_class.active_project()).GetName().split(";")[-1] + project_name = self.desktop.active_project().GetName() + design_name = self.desktop.active_design(self.desktop.active_project()).GetName().split(";")[-1] self.__init__(project=project_name, design=design_name) return True @@ -2073,7 +2073,7 @@ def enable_rigid_flex(self) -> bool: """ if settings.aedt_version >= "2022.2": self.modeler.oeditor.ProcessBentModelCmd() - if self.desktop_class.non_graphical: + if self.desktop.non_graphical: return True return True if self.variable_manager["BendModel"].expression == "1" else False diff --git a/src/ansys/aedt/core/icepak.py b/src/ansys/aedt/core/icepak.py index a6ed71bd36e..148ba0a9b0b 100644 --- a/src/ansys/aedt/core/icepak.py +++ b/src/ansys/aedt/core/icepak.py @@ -1969,16 +1969,16 @@ def copy_group_from( >>> oEditor.Copy >>> oeditor.Paste """ - pj_names = self.desktop_class.project_list + pj_names = self.desktop.project_list if source_project_name == self.project_name or source_project_name is None: - active_project = self.desktop_class.active_project() + active_project = self.desktop.active_project() else: self.oproject = source_project_path # self._desktop.OpenProject(source_project_path) - active_project = self.desktop_class.active_project(source_project_name) + active_project = self.desktop.active_project(source_project_name) - active_design = self.desktop_class.active_design(active_project, source_design) + active_design = self.desktop.active_design(active_project, source_design) active_editor = active_design.SetActiveEditor("3D Modeler") active_editor.Copy(["NAME:Selections", "Selections:=", group_name]) @@ -2462,7 +2462,7 @@ def import_idf( ---------- >>> oDesign.ImportIDF """ - active_design_name = self.desktop_class.active_design(self.oproject).GetName() + active_design_name = self.desktop.active_design(self.oproject).GetName() if not library_path: if board_path.endswith(".emn"): library_path = board_path[:-3] + "emp" @@ -2554,7 +2554,7 @@ def import_idf( ) self.modeler.add_new_objects() if active_design_name: - self.desktop_class.active_design(self.oproject, active_design_name) + self.desktop.active_design(self.oproject, active_design_name) return True @pyaedt_function_handler() diff --git a/src/ansys/aedt/core/internal/checks.py b/src/ansys/aedt/core/internal/checks.py index 3a85c43806c..c8571e82996 100644 --- a/src/ansys/aedt/core/internal/checks.py +++ b/src/ansys/aedt/core/internal/checks.py @@ -77,12 +77,12 @@ def fetch_odesktop_from_private_app_attribute(item): if app is not None: return app.odesktop - def fetch_odesktop_from_desktop_class(item): - attributes_to_check = ["desktop_class", "_desktop_class"] + def fetch_odesktop_from_desktop(item): + attributes_to_check = ["desktop", "_desktop_instance"] for attribute in attributes_to_check: - desktop_class = getattr(item, attribute, None) - if desktop_class is not None: - return desktop_class.odesktop + desktop_obj = getattr(item, attribute, None) + if desktop_obj is not None: + return desktop_obj.odesktop def aedt_version_decorator(method): """Decorator to check AEDT version compatibility for a method.""" @@ -92,7 +92,7 @@ def wrapper(self, *args, **kwargs): odesktop = ( fetch_odesktop_from_common_attributes_names(self) or fetch_odesktop_from_private_app_attribute(self) - or fetch_odesktop_from_desktop_class(self) + or fetch_odesktop_from_desktop(self) ) if odesktop is None: raise AEDTRuntimeError("The AEDT desktop object is not available.") diff --git a/src/ansys/aedt/core/maxwellcircuit.py b/src/ansys/aedt/core/maxwellcircuit.py index 9a6cabef738..4a91c3f74f1 100644 --- a/src/ansys/aedt/core/maxwellcircuit.py +++ b/src/ansys/aedt/core/maxwellcircuit.py @@ -247,7 +247,7 @@ def export_netlist_from_schematic(self, output_file: str | Path) -> str | bool: >>> gnd.pins[0].connect_to_component(v.pins[0], use_wire=True) Export circuit netlist. >>> circ.export_netlist_from_schematic(output_file="C:\\Users\\netlist.sph") - >>> circ.desktop_class.close_desktop() + >>> circ.desktop.close_desktop() """ if Path(output_file).suffix != ".sph": self.logger.error("Invalid file extension. It must be ``.sph``.") diff --git a/src/ansys/aedt/core/mechanical.py b/src/ansys/aedt/core/mechanical.py index a4e0d7f2015..7e20fa9951f 100644 --- a/src/ansys/aedt/core/mechanical.py +++ b/src/ansys/aedt/core/mechanical.py @@ -671,7 +671,7 @@ def assign_2way_coupling(self, setup: str | None = None, number_of_iterations: i >>> mech = Mechanical() >>> setup = mech.create_setup() >>> mech.assign_2way_coupling(setup.name, 1) - >>> mech.desktop_class.close_desktop() + >>> mech.desktop.close_desktop() """ if not setup: diff --git a/src/ansys/aedt/core/modeler/cad/components_3d.py b/src/ansys/aedt/core/modeler/cad/components_3d.py index a318ed55481..619a3bb81e7 100644 --- a/src/ansys/aedt/core/modeler/cad/components_3d.py +++ b/src/ansys/aedt/core/modeler/cad/components_3d.py @@ -873,7 +873,7 @@ def edit_definition(self, password=None): if password is None: password = os.getenv("PYAEDT_ENCRYPTED_PASSWORD", "") - project_list = [i for i in self._primitives._app.desktop_class.project_list] + project_list = [i for i in self._primitives._app.desktop.project_list] self._primitives.oeditor.Edit3DComponentDefinition( [ @@ -882,12 +882,12 @@ def edit_definition(self, password=None): ] ) - new_project = [i for i in self._primitives._app.desktop_class.project_list if i not in project_list] + new_project = [i for i in self._primitives._app.desktop.project_list if i not in project_list] if new_project: from ansys.aedt.core.generic.design_types import get_pyaedt_app - project = self._primitives._app.desktop_class.active_project(new_project[0]) + project = self._primitives._app.desktop.active_project(new_project[0]) # project = self._primitives._app.odesktop.GetActiveProject() project_name = project.GetName() project.GetDesigns()[0].GetName() @@ -896,7 +896,7 @@ def edit_definition(self, password=None): # design_name = project.GetDesigns()[0].GetName() # else: # design_name = project.GetActiveDesign().GetName() - return get_pyaedt_app(project_name, design_name, desktop=self._primitives._app.desktop_class) + return get_pyaedt_app(project_name, design_name, desktop=self._primitives._app.desktop) return False diff --git a/src/ansys/aedt/core/modeler/cad/object_3d.py b/src/ansys/aedt/core/modeler/cad/object_3d.py index b06be69213b..6d3cd4e37ee 100644 --- a/src/ansys/aedt/core/modeler/cad/object_3d.py +++ b/src/ansys/aedt/core/modeler/cad/object_3d.py @@ -166,7 +166,7 @@ def _bounding_box_unmodel(self): self._odesign.Undo() if not modeled: self._odesign.Undo() - if not self._primitives._app.desktop_class.non_graphical: + if not self._primitives._app.desktop.non_graphical: self._primitives._app.odesktop.ClearMessages( self._primitives._app.project_name, self._primitives._app.design_name, 1 ) diff --git a/src/ansys/aedt/core/modeler/circuits/object_3d_circuit.py b/src/ansys/aedt/core/modeler/circuits/object_3d_circuit.py index fdd5ca9d56b..3868ab05a73 100644 --- a/src/ansys/aedt/core/modeler/circuits/object_3d_circuit.py +++ b/src/ansys/aedt/core/modeler/circuits/object_3d_circuit.py @@ -855,7 +855,7 @@ def angle(self, angle=None) -> None: angle = self._circuit_components._app.value_with_units(self._angle, "deg") vMaterial = ["NAME:Component Angle", "Value:=", angle] self.change_property(vMaterial) - elif not self._circuit_components._app.desktop_class.is_grpc_api: + elif not self._circuit_components._app.desktop.is_grpc_api: if not angle: angle = str(self._angle) + "°" else: diff --git a/src/ansys/aedt/core/modeler/circuits/primitives_circuit.py b/src/ansys/aedt/core/modeler/circuits/primitives_circuit.py index 5b840557080..91ccefd7dff 100644 --- a/src/ansys/aedt/core/modeler/circuits/primitives_circuit.py +++ b/src/ansys/aedt/core/modeler/circuits/primitives_circuit.py @@ -1132,7 +1132,7 @@ def create_component( >>> aedtapp = TwinBuilder() >>> cmp = aedtapp.modeler.schematic.create_component(component_library="", component_name="ExcitationComponent") >>> cmp.set_property("ShowPin", True) - >>> aedtapp.desktop_class.close_desktop() + >>> aedtapp.desktop.close_desktop() """ # id = self.create_unique_id() if component_library: diff --git a/src/ansys/aedt/core/modeler/circuits/primitives_maxwell_circuit.py b/src/ansys/aedt/core/modeler/circuits/primitives_maxwell_circuit.py index 2ec19d0ae88..fc7727dcbc0 100644 --- a/src/ansys/aedt/core/modeler/circuits/primitives_maxwell_circuit.py +++ b/src/ansys/aedt/core/modeler/circuits/primitives_maxwell_circuit.py @@ -121,7 +121,7 @@ def create_resistor( >>> from ansys.aedt.core import MaxwellCircuit >>> circ = MaxwellCircuit() >>> circ.modeler.schematic.create_resistor(value=10) - >>> circ.desktop_class.close_desktop() + >>> circ.desktop.close_desktop() """ if location is None: location = [] @@ -179,7 +179,7 @@ def create_inductor( >>> from ansys.aedt.core import MaxwellCircuit >>> circ = MaxwellCircuit() >>> circ.modeler.schematic.create_inductor(value=10) - >>> circ.desktop_class.close_desktop() + >>> circ.desktop.close_desktop() """ if location is None: location = [] @@ -237,7 +237,7 @@ def create_capacitor( >>> from ansys.aedt.core import MaxwellCircuit >>> circ = MaxwellCircuit() >>> circ.modeler.schematic.create_capacitor(value=10) - >>> circ.desktop_class.close_desktop() + >>> circ.desktop.close_desktop() """ if location is None: location = [] @@ -287,7 +287,7 @@ def create_diode( >>> from ansys.aedt.core import MaxwellCircuit >>> circ = MaxwellCircuit() >>> circ.modeler.schematic.create_diode() - >>> circ.desktop_class.close_desktop() + >>> circ.desktop.close_desktop() """ if location is None: location = [] @@ -337,7 +337,7 @@ def create_winding( >>> from ansys.aedt.core import MaxwellCircuit >>> circ = MaxwellCircuit() >>> circ.modeler.schematic.create_winding(name="winding") - >>> circ.desktop_class.close_desktop() + >>> circ.desktop.close_desktop() """ if location is None: location = [] diff --git a/src/ansys/aedt/core/modeler/circuits/primitives_nexxim.py b/src/ansys/aedt/core/modeler/circuits/primitives_nexxim.py index 22eb4c23c49..534d62d0931 100644 --- a/src/ansys/aedt/core/modeler/circuits/primitives_nexxim.py +++ b/src/ansys/aedt/core/modeler/circuits/primitives_nexxim.py @@ -213,14 +213,14 @@ def create_subcircuit(self, location=None, angle=None, name: str | None = None, self._app.odesign.InsertDesign("Circuit Design", name, "", parent_name) if is_linux and settings.aedt_version == "2024.1": # pragma: no cover time.sleep(1) - self._app.desktop_class.close_windows() + self._app.desktop.close_windows() if nested_subcircuit_id: pname = f"{self._app.design_name.split('/')[0]}:{nested_subcircuit_id}" - odes = self._app.desktop_class.active_design(self._app.oproject, pname) + odes = self._app.desktop.active_design(self._app.oproject, pname) oed = odes.SetActiveEditor("SchematicEditor") if is_linux and settings.aedt_version == "2024.1": # pragma: no cover time.sleep(1) - self._app.desktop_class.close_windows() + self._app.desktop.close_windows() objs = oed.GetAllElements() match = [i for i in objs if name in i] o = CircuitComponent(self, tabname=self.tab_name, custom_editor=oed) @@ -895,7 +895,7 @@ def create_voltage_probe( >>> from ansys.aedt.core import Circuit >>> cir = Circuit() >>> cir.modeler.components.create_voltage_probe(name="probe") - >>> cir.desktop_class.release_desktop(False, False) + >>> cir.desktop.release_desktop(False, False) """ return self.__create_probe( name=name, @@ -945,7 +945,7 @@ def create_current_probe( >>> from ansys.aedt.core import Circuit >>> cir = Circuit() >>> cir.modeler.components.create_current_probe(name="probe") - >>> cir.desktop_class.release_desktop(False, False) + >>> cir.desktop.release_desktop(False, False) """ return self.__create_probe( name=name, @@ -2226,7 +2226,7 @@ def create_component_from_spicemodel( >>> cir = Circuit(version="2025.2") >>> model = Path("Your path") / "test.lib" >>> cir.modeler.schematic.create_component_from_spicemodel(input_file=model, model="GRM1234", symbol="nexx_cap") - >>> cir.desktop_class.release_desktop(False, False) + >>> cir.desktop.release_desktop(False, False) """ if isinstance(input_file, str): input_file = Path(input_file) diff --git a/src/ansys/aedt/core/modeler/circuits/primitives_twin_builder.py b/src/ansys/aedt/core/modeler/circuits/primitives_twin_builder.py index bf0132e6fb6..9fb32bc128a 100644 --- a/src/ansys/aedt/core/modeler/circuits/primitives_twin_builder.py +++ b/src/ansys/aedt/core/modeler/circuits/primitives_twin_builder.py @@ -536,7 +536,7 @@ def create_component_from_sml( >>> model = "Thermal_ROM_SML" >>> pins_names = ["Input1_InternalHeatGeneration", "Input2_HeatFlow", "Output1_Temp1,Output2_Temp2"] >>> tb.modeler.schematic.create_component_from_sml(input_file=model, model=model, pins_names=pins_names) - >>> tb.desktop_class.release_desktop(False, False) + >>> tb.desktop.release_desktop(False, False) """ pins_names_str = ",".join(pins_names) arg = ["NAME:Options", "Mode:=", 1] @@ -581,7 +581,7 @@ def update_quantity_value(self, component_name, name: str, value, netlist_units: >>> modelpath = "Simplorer Elements\\Basic Elements\\Tools\\Time Functions:DATAPAIRS" >>> source1 = tb.modeler.schematic.create_component("source1", "", modelpath, [20 * G, 29 * G]) >>> tb.modeler.schematic.update_quantity_value(source1.composed_name, "PERIO", "0") - >>> tb.desktop_class.release_desktop(False, False) + >>> tb.desktop.release_desktop(False, False) """ try: self.oeditor.ChangeProperty( diff --git a/src/ansys/aedt/core/modeler/modeler_3d.py b/src/ansys/aedt/core/modeler/modeler_3d.py index f0694880e06..dd1cb283aca 100644 --- a/src/ansys/aedt/core/modeler/modeler_3d.py +++ b/src/ansys/aedt/core/modeler/modeler_3d.py @@ -1051,7 +1051,7 @@ def import_nastran( if save_only_stl: return output_stls, nas_to_dict - self._app.desktop_class.close_windows() + self._app.desktop.close_windows() self.logger.info("Importing STL in 3D Modeler") if output_stls: for output_stl in output_stls: diff --git a/src/ansys/aedt/core/modeler/modeler_pcb.py b/src/ansys/aedt/core/modeler/modeler_pcb.py index a2ce724f599..8a1137c0d43 100644 --- a/src/ansys/aedt/core/modeler/modeler_pcb.py +++ b/src/ansys/aedt/core/modeler/modeler_pcb.py @@ -492,7 +492,7 @@ def import_cadence_brd(self, input_file: str, output_dir=None, name: str | None self._oimportexport.ImportExtracta( input_file, str(Path(output_dir) / (name + ".aedb")), str(Path(output_dir) / (name + ".xml")) ) - self._app.__init__(self._app.desktop_class.active_project().GetName()) + self._app.__init__(self._app.desktop.active_project().GetName()) return True @pyaedt_function_handler() @@ -545,7 +545,7 @@ def import_ipc2581(self, input_file: str, output_dir=None, name: str | None = No self._oimportexport.ImportIPC( input_file, str(Path(output_dir) / (name + ".aedb")), str(Path(output_dir) / (name + ".xml")) ) - self._app.__init__(self._app.desktop_class.active_project().GetName()) + self._app.__init__(self._app.desktop.active_project().GetName()) return True @pyaedt_function_handler() diff --git a/src/ansys/aedt/core/modeler/schematic.py b/src/ansys/aedt/core/modeler/schematic.py index 4878b8e40e1..28d7db98cd1 100644 --- a/src/ansys/aedt/core/modeler/schematic.py +++ b/src/ansys/aedt/core/modeler/schematic.py @@ -624,7 +624,7 @@ def move(self, assignment, offset, units=None) -> bool: >>> oEditor.Move """ # TODO: Remove this once https://github.com/ansys/pyaedt/issues/6333 is fixed - if is_linux and self._app.desktop_class.non_graphical: + if is_linux and self._app.desktop.non_graphical: self.logger.error("Move is not supported in non-graphical mode on Linux.") return False sels = self._get_components_selections(assignment) diff --git a/src/ansys/aedt/core/modules/material.py b/src/ansys/aedt/core/modules/material.py index 8b06884eda1..f3ca68fcefb 100644 --- a/src/ansys/aedt/core/modules/material.py +++ b/src/ansys/aedt/core/modules/material.py @@ -2175,7 +2175,7 @@ def get_core_loss_coefficients( ... points_at_frequency={60: [[0, 0], [1, 3], [2, 7]]}, thickness="0.5mm", conductivity=0 ... ) >>> print(coefficients) - >>> m3d.desktop_class.close_desktop() + >>> m3d.desktop.close_desktop() """ if not isinstance(points_at_frequency, dict): raise TypeError("Points list at frequency must be provided as a dictionary.") @@ -2293,7 +2293,7 @@ def set_coreloss_at_frequency( >>> m3d.materials["magnesium"].set_coreloss_at_frequency( ... points_at_frequency={60 : [[0,0], [1,3.5], [2,7.4]]} ... ) - >>> m3d.desktop_class.close_desktop() + >>> m3d.desktop.close_desktop() The second case shows how to set properties for core losses versus frequencies: @@ -2306,7 +2306,7 @@ def set_coreloss_at_frequency( ... 100 : [[0,0], [1,8], [2,9]], ... 150 : [[0,0], [1,10], [2,19]]} ... ) - >>> m3d.desktop_class.close_desktop() + >>> m3d.desktop.close_desktop() """ if not isinstance(points_at_frequency, dict): diff --git a/src/ansys/aedt/core/modules/solve_setup.py b/src/ansys/aedt/core/modules/solve_setup.py index fef8ba67d53..f790caf7c16 100644 --- a/src/ansys/aedt/core/modules/solve_setup.py +++ b/src/ansys/aedt/core/modules/solve_setup.py @@ -942,9 +942,9 @@ def add_mesh_link( >>> m3d.set_active_design("target_design") The mesh link is assigned to the target design. >>> target_setup.add_mesh_link("source_design") - >>> m3d.desktop_class.close_desktop() + >>> m3d.desktop.close_desktop() """ - dkp = self._app.desktop_class + dkp = self._app.desktop source_design = design auto_update = self.auto_update try: @@ -3702,7 +3702,7 @@ def add_eddy_current_sweep( ... ) >>> sweep.props["RangeStart"] = "0.1Hz" >>> sweep.update() - >>> m2d.desktop_class.close_desktop() + >>> m2d.desktop.close_desktop() """ if self.setuptype not in [7, 60]: self._app.logger.warning("This method only applies to Maxwell Eddy Current Solution.") @@ -3870,7 +3870,7 @@ def set_save_fields( >>> setup.set_save_fields( ... enable=True, range_type="Custom", subrange_type="LinearStep", start=0, stop=8, count=2, units="ms" ... ) - >>> m2d.desktop_class.close_desktop() + >>> m2d.desktop.close_desktop() """ if self.setuptype != 5: if enable: @@ -4094,7 +4094,7 @@ def create_frequency_sweep( >>> q3d = Q3d() >>> setup = q3d.create_setup("LinearCountSetup") >>> sweep = setup.create_frequency_sweep(unit="GHz", start_frequency=0.5, stop_frequency=1.5, name="Sweep1") - >>> q3d.desktop_class.close_desktop() + >>> q3d.desktop.close_desktop() """ if sweep_type in ["Interpolating", "Fast"]: num_of_freq_points = num_of_freq_points or 401 @@ -4181,7 +4181,7 @@ def create_linear_step_sweep( ... name="LinearStepSweep", unit="MHz", start_frequency=1.1e3, stop_frequency=1200.1, step_size=153.8 ... ) >>> type(linear_step_sweep) - >>> q3d.desktop_class.close_desktop() + >>> q3d.desktop.close_desktop() """ if sweep_type not in ["Discrete", "Interpolating", "Fast"]: raise AttributeError("Invalid in `sweep_type`. It has to be either 'Discrete', 'Interpolating', or 'Fast'") @@ -4258,7 +4258,7 @@ def create_single_point_sweep( >>> setup = q3d.create_setup("SinglePointSetup") >>> single_point_sweep = setup.create_single_point_sweep(name="SinglePointSweep", unit="MHz", freq=1.1e3) >>> type(single_point_sweep) - >>> q3d.desktop_class.close_desktop() + >>> q3d.desktop.close_desktop() """ if name is None: name = generate_unique_name("SinglePoint") @@ -4359,7 +4359,7 @@ def get_sweep(self, name: str | None = None): >>> sweep.add_subrange("LinearCount", 0, 10, 1, "Hz") >>> sweep.add_subrange("LogScale", 10, 1e8, 100, "Hz") >>> sweep = setup.get_sweep("Sweep1") - >>> q3d.desktop_class.close_desktop() + >>> q3d.desktop.close_desktop() """ if name: for sweep in self.sweeps: diff --git a/src/ansys/aedt/core/q3d.py b/src/ansys/aedt/core/q3d.py index 063eb118e95..889b2325076 100644 --- a/src/ansys/aedt/core/q3d.py +++ b/src/ansys/aedt/core/q3d.py @@ -1857,7 +1857,7 @@ def set_material_thresholds( if not magnetic_threshold: magnetic_threshold = 1.01 - if not self.desktop_class.is_grpc_api: + if not self.desktop.is_grpc_api: insulator_threshold = np.longdouble(insulator_threshold) perfect_conductor_threshold = np.longdouble(perfect_conductor_threshold) magnetic_threshold = np.longdouble(magnetic_threshold) diff --git a/src/ansys/aedt/core/twinbuilder.py b/src/ansys/aedt/core/twinbuilder.py index 0a706491864..38f35a68b99 100644 --- a/src/ansys/aedt/core/twinbuilder.py +++ b/src/ansys/aedt/core/twinbuilder.py @@ -458,9 +458,9 @@ def add_q3d_dynamic_component( >>> tb.add_q3d_dynamic_component( ... "Q2D_ArmouredCableExample", "2D_Extractor_Cable", "MySetupAuto", "sweep1", "Original", "100mm" ... ) - >>> tb.desktop_class.close_desktop() + >>> tb.desktop.close_desktop() """ - dkp = self.desktop_class + dkp = self.desktop is_loaded = False if Path(source_project).is_file(): project_path = source_project @@ -714,14 +714,14 @@ def add_excitation_model( -------- >>> from ansys.aedt.core import TwinBuilder >>> tb = TwinBuilder(specified_version="2025.2") - >>> maxwell_app = tb.desktop_class[[project_name, "my_maxwell_design"]] + >>> maxwell_app = tb.desktop[[project_name, "my_maxwell_design"]] >>> excitations = {} >>> for e in maxwell_app.excitations_by_type["Winding Group"]: ... excitations[e.name] = ["20", True, e.props["Type"], False] >>> comp = tb.add_excitation_model(project=project_name, design="my_maxwell_design", excitations=excitations) - >>> tb.desktop_class.release_desktop(False, False) + >>> tb.desktop.release_desktop(False, False) """ - dkp = self.desktop_class + dkp = self.desktop project_selection = 0 if Path(project).is_file(): project_path = project @@ -731,7 +731,7 @@ def add_excitation_model( else: maxwell_app = dkp.load_project(project_path, design) project_selection = 1 - elif project in self.desktop_class.project_list: + elif project in self.desktop.project_list: project_name = "$PROJECTDIR/{}.aedt".format(project) maxwell_app = dkp[[project, design]] else: diff --git a/src/ansys/aedt/core/visualization/advanced/farfield_visualization.py b/src/ansys/aedt/core/visualization/advanced/farfield_visualization.py index b9a98b7155c..50d9bacef7a 100644 --- a/src/ansys/aedt/core/visualization/advanced/farfield_visualization.py +++ b/src/ansys/aedt/core/visualization/advanced/farfield_visualization.py @@ -84,7 +84,7 @@ class FfdSolutionData(PyAedtBase): >>> app = Hfss(version="2025.2", design="Antenna") >>> data = app.get_antenna_data() >>> metadata_file = data.metadata_file - >>> app.desktop_class.close_desktop() + >>> app.desktop.close_desktop() >>> farfield_data = FfdSolutionData(input_file=metadata_file) >>> farfield_data.plot_3d(quantity_format="dB10") """ diff --git a/src/ansys/aedt/core/visualization/post/compliance.py b/src/ansys/aedt/core/visualization/post/compliance.py index df507e06d0c..e9ce5963041 100644 --- a/src/ansys/aedt/core/visualization/post/compliance.py +++ b/src/ansys/aedt/core/visualization/post/compliance.py @@ -603,7 +603,7 @@ def __init__(self, desktop, template) -> None: self._project_name = None self._output_folder = None self._parse_template() - self._desktop_class = desktop + self._desktop_instance = desktop self._dut = None self._summary = [["Test", "Results"]] self._summary_font = [["", None]] @@ -654,10 +654,10 @@ def load_project(self) -> bool: bool """ if not self._project_file: - self._desktop_class.logger.error("Project path has not been provided.") + self._desktop_instance.logger.error("Project path has not been provided.") return False - self._desktop_class.load_project(self._project_file) - project = self._desktop_class.active_project() + self._desktop_instance.load_project(self._project_file) + project = self._desktop_instance.active_project() self._project_name = project.GetName() self._output_folder = os.path.join( project.GetPath(), self._project_name + ".pyaedt", generate_unique_name(self._template_name) @@ -781,7 +781,7 @@ def _parse_reports(self, report, is_parameter: bool = False, is_report_parameter name = report["name"] if name in self._reports.values(): - self._desktop_class.logger.warning(f"{name} already exists. The name must be unique.") + self._desktop_instance.logger.warning(f"{name} already exists. The name must be unique.") else: if is_parameter: self._parameters[report["name"]] = ParametersTemplate(report) @@ -894,7 +894,7 @@ def _add_skew(self, _design, aedt_report, chapter, name: str, pass_fail_criteria ] if not trace_data: # pragma: no cover msg = "Failed to get solution data. Check if the design is solved or if the report data is correct." - self._desktop_class.logger.error(msg) + self._desktop_instance.logger.error(msg) else: units = trace_data.units_sweeps["Time"] pass_fail_table = [ @@ -976,13 +976,13 @@ def _create_derived_reports(self) -> None: return compliance_reports = self.report_data.add_chapter("Report Derived Parameters Results") for tpx, template_report in enumerate(self._reports_parameters.values()): - if self._desktop_class: + if self._desktop_instance: time.sleep(1) - self._desktop_class.odesktop.CloseAllWindows() + self._desktop_instance.odesktop.CloseAllWindows() settings.logger.info(f"Adding report {template_report.name}.") config_file = template_report.config_file if not os.path.exists(config_file) and not os.path.exists(os.path.join(self._template_folder, config_file)): - self._desktop_class.logger.error(f"{config_file} is not found.") + self._desktop_instance.logger.error(f"{config_file} is not found.") continue name = template_report.name traces = template_report.traces @@ -990,16 +990,16 @@ def _create_derived_reports(self) -> None: design_name = template_report.design_name report_type = template_report.report_type if template_report.project_name: - if template_report.project_name not in self._desktop_class.project_list: - self._desktop_class.load_project(template_report.project) + if template_report.project_name not in self._desktop_instance.project_list: + self._desktop_instance.load_project(template_report.project) else: template_report.project_name = self._project_name if _design and _design.design_name != design_name or _design is None: try: _design = get_pyaedt_app(template_report.project_name, design_name) - self._desktop_class.odesktop.CloseAllWindows() + self._desktop_instance.odesktop.CloseAllWindows() except Exception: # pragma: no cover - self._desktop_class.logger.error(f"Failed to retrieve design {design_name}") + self._desktop_instance.logger.error(f"Failed to retrieve design {design_name}") continue if os.path.exists(os.path.join(self._template_folder, config_file)): config_file = os.path.join(self._template_folder, config_file) @@ -1071,16 +1071,16 @@ def _create_aedt_reports(self) -> bool: return False compliance_reports = self.report_data.add_chapter("Compliance Results") for tpx, template_report in enumerate(self._reports.values()): - if self._desktop_class: + if self._desktop_instance: time.sleep(1) - self._desktop_class.odesktop.CloseAllWindows() + self._desktop_instance.odesktop.CloseAllWindows() try: settings.logger.info(f"Adding report {template_report.name}.") config_file = template_report.config_file if not os.path.exists(config_file) and not os.path.exists( os.path.join(self._template_folder, config_file) ): - self._desktop_class.logger.error(f"{config_file} is not found.") + self._desktop_instance.logger.error(f"{config_file} is not found.") continue name = template_report.name traces = template_report.traces @@ -1090,16 +1090,16 @@ def _create_aedt_reports(self) -> bool: report_type = template_report.report_type group = template_report.group_plots if template_report.project_name: - if template_report.project_name not in self._desktop_class.project_list: - self._desktop_class.load_project(template_report.project) + if template_report.project_name not in self._desktop_instance.project_list: + self._desktop_instance.load_project(template_report.project) else: template_report.project_name = self._project_name if _design and _design.design_name != design_name or _design is None: try: _design = get_pyaedt_app(template_report.project_name, design_name) - self._desktop_class.odesktop.CloseAllWindows() + self._desktop_instance.odesktop.CloseAllWindows() except Exception: # pragma: no cover - self._desktop_class.logger.error(f"Failed to retrieve design {design_name}") + self._desktop_instance.logger.error(f"Failed to retrieve design {design_name}") continue if os.path.exists(os.path.join(self._template_folder, config_file)): config_file = os.path.join(self._template_folder, config_file) @@ -1286,7 +1286,7 @@ def _create_aedt_reports(self) -> bool: else: # pragma: no cover msg = f"Failed to create the report. Check {config_file} configuration file." - self._desktop_class.logger.error(msg) + self._desktop_instance.logger.error(msg) settings.logger.info(f"Report {template_report.name} added to the pdf.") except Exception: settings.logger.error(f"Failed to add {template_report.name} to the pdf.") @@ -1303,7 +1303,7 @@ def _create_parameters(self) -> None: if not os.path.exists(config_file): config_file = os.path.join(self._template_folder, config_file) if not os.path.exists(config_file): - self._desktop_class.logger.error(f"{config_file} not found.") + self._desktop_instance.logger.error(f"{config_file} not found.") continue name = template_report.name pass_fail = template_report.pass_fail @@ -1386,7 +1386,7 @@ def _add_statistical_violations(self, report, chapter, image_name, pass_fail_cri sols = report.get_solution_data() if not sols: # pragma: no cover msg = "Failed to get Solution Data. Check if the design is solved or the report data are correct." - self._desktop_class.logger.error(msg) + self._desktop_instance.logger.error(msg) return mag_data_in = sols.get_expression_data( sols.expressions[0], formula="magnitude", sweeps=["__UnitInterval", "__Amplitude"] @@ -1473,7 +1473,7 @@ def _add_contour_eye_diagram_violations(self, report, chapter, image_name, pass_ sols = report.get_solution_data() if not sols: # pragma: no cover msg = "Failed to get Solution Data. Check if the design is solved or the report data are correct." - self._desktop_class.logger.error(msg) + self._desktop_instance.logger.error(msg) return bit_error_rates = [1e-3, 1e-6, 1e-9, 1e-12] font_table = [["", None]] @@ -1526,7 +1526,7 @@ def _add_lna_violations(self, report, chapter, image_name, pass_fail_criteria): ] if not trace_data: # pragma: no cover msg = "Failed to get solution data. Check if the design is solved or if the report data is correct." - self._desktop_class.logger.error(msg) + self._desktop_instance.logger.error(msg) return pass_fail_table for trace_name in trace_data.expressions: trace_values = trace_data.get_expression_data(trace_name) @@ -1676,7 +1676,7 @@ def _create_project_info(self, report) -> None: report.add_empty_line(3) if _design.design_type == "Circuit Design": - if not self._desktop_class.non_graphical: + if not self._desktop_instance.non_graphical: for page in range(1, _design.modeler.pages + 1): name = os.path.join(self._output_folder, f"{_design.design_name}_{page}.jpg") image = _design.post.export_model_picture(name, page) @@ -1781,7 +1781,7 @@ def create_pdf(self, file_name: str, close_project: bool = True): if not self.report_data.chapters: self.create_compliance_report() report = AnsysReport() - report.aedt_version = self._desktop_class.aedt_version_id + report.aedt_version = self._desktop_instance.aedt_version_id report.design_name = self._template_name report.report_specs.table_font_size = 7 report.report_specs.revision = f"Revision {self.revision}" @@ -1813,7 +1813,7 @@ def create_pdf(self, file_name: str, close_project: bool = True): report.add_toc() output = report.save_pdf(self._output_folder, file_name=file_name) if close_project: - self._desktop_class.odesktop.CloseProject(self.project_name) + self._desktop_instance.odesktop.CloseProject(self.project_name) if output: - self._desktop_class.logger.info(f"Report has been saved in {output}") + self._desktop_instance.logger.info(f"Report has been saved in {output}") return output diff --git a/src/ansys/aedt/core/visualization/post/farfield_exporter.py b/src/ansys/aedt/core/visualization/post/farfield_exporter.py index b34f8548dba..7c574c6a1fa 100644 --- a/src/ansys/aedt/core/visualization/post/farfield_exporter.py +++ b/src/ansys/aedt/core/visualization/post/farfield_exporter.py @@ -122,7 +122,7 @@ def __init__( self.__farfield_data = None self.__metadata_file = "" - if self.__app.desktop_class.is_grpc_api and set_phase_center_per_port: + if self.__app.desktop.is_grpc_api and set_phase_center_per_port: self.__app.set_phase_center_per_port() else: # pragma: no cover self.__app.logger.warning("Set phase center in port location manually.") @@ -159,7 +159,7 @@ def export_farfield(self): file_path_txt = os.path.join(export_path, exported_name_map) input_file = file_path_xml - if self.__app.desktop_class.aedt_version_id < "2024.1": # pragma: no cover + if self.__app.desktop.aedt_version_id < "2024.1": # pragma: no cover input_file = file_path_txt # Create directory or check if files already exist @@ -176,7 +176,7 @@ def export_farfield(self): # Export far field if self.overwrite or not file_exists: - if self.__app.desktop_class.aedt_version_id < "2024.1": # pragma: no cover + if self.__app.desktop.aedt_version_id < "2024.1": # pragma: no cover is_exported = self.__app.export_element_pattern( frequencies=self.frequencies, setup=self.setup_name, @@ -245,7 +245,7 @@ def export_farfield(self): power = {} - if self.__app.desktop_class.aedt_version_id < "2024.1": + if self.__app.desktop.aedt_version_id < "2024.1": available_categories = self.__app.post.available_quantities_categories() excitations = [] is_power = True diff --git a/src/ansys/aedt/core/visualization/post/fields_calculator.py b/src/ansys/aedt/core/visualization/post/fields_calculator.py index b26b03661e3..500217315cb 100644 --- a/src/ansys/aedt/core/visualization/post/fields_calculator.py +++ b/src/ansys/aedt/core/visualization/post/fields_calculator.py @@ -80,7 +80,7 @@ class FieldsCalculator(PyAedtBase): ... "report": ["Data Table", "Rectangular Plot"], ... } >>> expr_name = hfss.post.fields_calculator.add_expression(my_expression, "Polyline1") - >>> hfss.desktop_class.release_desktop(False, False) + >>> hfss.desktop.release_desktop(False, False) or they can be added from the ``expression_catalog.toml``: @@ -88,7 +88,7 @@ class FieldsCalculator(PyAedtBase): >>> hfss = Hfss() >>> poly = hfss.modeler.create_polyline([[0, 0, 0], [1, 0, 1]], name="Polyline1") >>> expr_name = hfss.post.fields_calculator.add_expression("voltage_line", "Polyline1") - >>> hfss.desktop_class.release_desktop(False, False) + >>> hfss.desktop.release_desktop(False, False) """ @@ -163,7 +163,7 @@ def add_expression(self, calculation, assignment, name: str | None = None): ... "report": ["Data Table", "Rectangular Plot"], ... } >>> expr_name = hfss.post.fields_calculator.add_expression(my_expression, "Polyline1") - >>> hfss.desktop_class.release_desktop(False, False) + >>> hfss.desktop.release_desktop(False, False) """ if assignment is not None: assignment = self.__app.modeler.convert_to_selections(assignment, return_list=True)[0] @@ -309,7 +309,7 @@ def expression_plot(self, calculation, assignment, names, setup: str | None = No >>> poly = hfss.modeler.create_polyline([[0, 0, 0], [1, 0, 1]], name="Polyline1") >>> expr_name = hfss.post.fields_calculator.add_expression("voltage_line", "Polyline1") >>> reports = hfss.post.fields_calculator.expression_plot("voltage_line", "Polyline1", [name]) - >>> hfss.desktop_class.release_desktop(False, False) + >>> hfss.desktop.release_desktop(False, False) """ if assignment is not None: assignment = self.__app.modeler.convert_to_selections(assignment, return_list=True) @@ -396,7 +396,7 @@ def delete_expression(self, name: str | None = None) -> bool: >>> poly = hfss.modeler.create_polyline([[0, 0, 0], [1, 0, 1]], name="Polyline1") >>> expr_name = hfss.post.fields_calculator.add_expression("voltage_line", "Polyline1") >>> hfss.post.fields_calculator.delete_expression(expr_name) - >>> hfss.desktop_class.release_desktop(False, False) + >>> hfss.desktop.release_desktop(False, False) """ if not name: self.ofieldsreporter.ClearAllNamedExpr() @@ -469,7 +469,7 @@ def load_expression_file(self, input_file: str): >>> hfss = Hfss() >>> my_toml = str(Path("my_path_to_toml") / "my_toml.toml") >>> new_catalog = hfss.post.fields_calculator.load_expression_file(my_toml) - >>> hfss.desktop_class.release_desktop(False, False) + >>> hfss.desktop.release_desktop(False, False) """ if not Path(input_file).is_file(): self.__app.logger.error("File does not exist.") @@ -552,7 +552,7 @@ def write(self, expression, output_file, setup: str | None = None, intrinsics=No >>> expr_name = hfss.post.fields_calculator.add_expression("voltage_line", "Polyline1") >>> file_path = Path(hfss.working_directory) / "my_expr.fld" >>> hfss.post.fields_calculator.write("voltage_line", file_path, hfss.nominal_adaptive) - >>> hfss.desktop_class.release_desktop(False, False) + >>> hfss.desktop.release_desktop(False, False) """ if not self.is_expression_defined(expression): self.__app.logger.error("Expression does not exist in current stack.") @@ -838,7 +838,7 @@ def get_expressions(self, field_type: str = None) -> dict: # pragma: no cover >>> hfss = Hfss() >>> poly = hfss.modeler.create_polyline([[0, 0, 0], [1, 0, 1]], name="Polyline1") >>> exprs = hfss.post.fields_calculator.get_expressions() - >>> hfss.desktop_class.release_desktop(False, False) + >>> hfss.desktop.release_desktop(False, False) """ expressions = {} field_type = field_type or "" diff --git a/src/ansys/aedt/core/visualization/post/monitor_icepak.py b/src/ansys/aedt/core/visualization/post/monitor_icepak.py index 83ec89e2dc3..0342854d95a 100644 --- a/src/ansys/aedt/core/visualization/post/monitor_icepak.py +++ b/src/ansys/aedt/core/visualization/post/monitor_icepak.py @@ -95,7 +95,7 @@ def __init__(self, p_app) -> None: self._face_monitors = {} self._point_monitors = {} self._app = p_app - if self._app.desktop_class.aedt_version_id > "2023.2": # pragma: no cover + if self._app.desktop.aedt_version_id > "2023.2": # pragma: no cover self.quantities_dict = quantities_dict_2 else: self.quantities_dict = quantities_dict_1 diff --git a/src/ansys/aedt/core/visualization/post/post_common_3d.py b/src/ansys/aedt/core/visualization/post/post_common_3d.py index ef2a574b50c..eb8dfb5559e 100644 --- a/src/ansys/aedt/core/visualization/post/post_common_3d.py +++ b/src/ansys/aedt/core/visualization/post/post_common_3d.py @@ -978,13 +978,13 @@ def _create_fieldplot( if not setup: setup = self._app.existing_analysis_sweeps[0] - self._app.desktop_class.close_windows() + self._app.desktop.close_windows() try: self._app.modeler.fit_all() except Exception: self.logger.debug("Something went wrong with `fit_all` while creating field plot.") # pragma: no cover self._desktop.TileWindows(0) - self._app.desktop_class.active_design(self._oproject, self._app.design_name) + self._app.desktop.active_design(self._oproject, self._app.design_name) char_set = string.ascii_uppercase + string.digits if not plot_name: @@ -1504,7 +1504,7 @@ def export_model_picture( full_name = Path(self._app.working_directory) / (generate_unique_name(self._app.design_name) + ".jpg") # open the 3D modeler and remove the selection on other objects - if not self._app.desktop_class.non_graphical: # pragma: no cover + if not self._app.desktop.non_graphical: # pragma: no cover if self._app.design_type not in [ "HFSS 3D Layout Design", "Circuit Design", @@ -1548,7 +1548,7 @@ def export_model_picture( height = 1080 self.oeditor.ExportImage(str(full_name), width, height) else: - if self._app.desktop_class.non_graphical: + if self._app.desktop.non_graphical: if width == 0: width = 500 if height == 0: diff --git a/src/ansys/aedt/core/visualization/post/post_maxwell.py b/src/ansys/aedt/core/visualization/post/post_maxwell.py index ac6c70a6bf4..a8cd4b648eb 100644 --- a/src/ansys/aedt/core/visualization/post/post_maxwell.py +++ b/src/ansys/aedt/core/visualization/post/post_maxwell.py @@ -77,13 +77,13 @@ def _create_fieldplot_line_traces( for i in self._app.setups: if i.name == setup.split(" : ")[0]: intrinsics = i.default_intrinsics - self._app.desktop_class.close_windows() + self._app.desktop.close_windows() try: self._app.modeler.fit_all() except Exception: # pragma: no cover self.logger.debug("Something went wrong with `fit_all` while creating field plot with line traces.") self._desktop.TileWindows(0) - self._app.desktop_class.active_design(self._oproject, self._app.design_name) + self._app.desktop.active_design(self._oproject, self._app.design_name) char_set = string.ascii_uppercase + string.digits if not plot_name: @@ -401,7 +401,7 @@ def evaluate_inception_voltage(self, plot_name, field_line_number=None) -> bool: Now the inception voltage evaluation can be performed on all (or a subset) of the created field line traces. >>> m2d.post.evaluate_inception_voltage(plot_name=plot.name, field_line_number=[1, 2, 4]) - >>> m2d.desktop_class.release_desktop() + >>> m2d.desktop.release_desktop() """ if self._app.solution_type != SolutionsMaxwell3D.ElectroStatic: raise AEDTRuntimeError("Field line traces is valid only for electrostatic solution") @@ -464,7 +464,7 @@ def export_inception_voltage(self, plot_name, output_file, field_line_number=Non ... output_file=str(Path(m2d.working_directory, "my_file.txt")), ... field_line_number=[1, 2, 4], ... ) - >>> m2d.desktop_class.release_desktop() + >>> m2d.desktop.release_desktop() """ if self._app.solution_type != "Electrostatic": raise AEDTRuntimeError("Field line traces is valid only for Electrostatic solution.") @@ -566,7 +566,7 @@ def modify_inception_parameters( The inception voltage evaluation can be performed on all (or a subset) of the created field line traces and inception voltage parameters can be edited >>> m2d.modify_inception_parameters() - >>> m2d.desktop_class.release_desktop() + >>> m2d.desktop.release_desktop() """ if not ionization_dataset: ionization_dataset = [0] diff --git a/src/ansys/aedt/core/visualization/post/solution_data.py b/src/ansys/aedt/core/visualization/post/solution_data.py index 81692c2fec9..13d8638feac 100644 --- a/src/ansys/aedt/core/visualization/post/solution_data.py +++ b/src/ansys/aedt/core/visualization/post/solution_data.py @@ -72,11 +72,11 @@ def __init__(self, aedtdata) -> None: else: self._primary_sweep = self._sweeps_names[0] end = time.time() - start - print(f"Time to initialize solution data:{end}") + settings.logger.debug(f"Time to initialize solution data:{end}") self.init_solutions_data() self._ifft = None end = time.time() - start - print(f"Time to initialize solution data:{end}") + settings.logger.debug(f"Time to initialize solution data:{end}") @property def active_variation(self): diff --git a/tests/conftest.py b/tests/conftest.py index a264b158f40..7b38cd434db 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -261,10 +261,11 @@ def desktop(tmp_path_factory, request): def test_tmp_dir(file_tmp_root, request): d = file_tmp_root / request.node.name.split("[", 1)[0] - if d.exists(): + yield d + try: shutil.rmtree(d, ignore_errors=True) - d.mkdir(parents=True, exist_ok=True) - return d + except Exception: + pyaedt_logger.warning(f"Failed to cleanup temporary directory {d}") @pytest.fixture diff --git a/tests/system/filter_solutions/test_desktop_types.py b/tests/system/filter_solutions/test_desktop_types.py index 346b85e3de3..f21c50b84eb 100644 --- a/tests/system/filter_solutions/test_desktop_types.py +++ b/tests/system/filter_solutions/test_desktop_types.py @@ -50,7 +50,7 @@ def test_lumped_exported_desktop(self, lumped_design) -> None: assert variables["C1"].value == pytest.approx(1.967e-12) assert variables["L2"].value == pytest.approx(1.288e-8) assert variables["C3"].value == pytest.approx(6.366e-12) - app.desktop_class.close_desktop() + app.desktop.close_desktop() def test_distributed_circuit_exported_desktop(self, distributed_design) -> None: schem_name = distributed_design.export_to_aedt.schematic_name @@ -69,7 +69,7 @@ def test_distributed_circuit_exported_desktop(self, distributed_design) -> None: assert variables["S1"].value == pytest.approx(3.362e-3) assert variables["S2"].value == pytest.approx(2.172e-2) assert variables["S3"].value == pytest.approx(1.008e-2) - app.desktop_class.close_desktop() + app.desktop.close_desktop() def test_distributed_hfss3dl_exported_desktop(self, distributed_design) -> None: schem_name = distributed_design.export_to_aedt.schematic_name @@ -89,7 +89,7 @@ def test_distributed_hfss3dl_exported_desktop(self, distributed_design) -> None: assert variables["S1"].value == pytest.approx(3.36225452227e-3) assert variables["S2"].value == pytest.approx(2.17231965814e-2) assert variables["S3"].value == pytest.approx(1.00773795179e-2) - app.desktop_class.close_desktop() + app.desktop.close_desktop() def test_distributed_hfss_exported_desktop(self, distributed_design) -> None: schem_name = distributed_design.export_to_aedt.schematic_name @@ -109,4 +109,4 @@ def test_distributed_hfss_exported_desktop(self, distributed_design) -> None: assert variables["S1"].value == pytest.approx(3.36225452227e-3) assert variables["S2"].value == pytest.approx(2.17231965814e-2) assert variables["S3"].value == pytest.approx(1.00773795179e-2) - app.desktop_class.close_desktop() + app.desktop.close_desktop() diff --git a/tests/system/filter_solutions/test_export_to_aedt/test_export_to_aedt.py b/tests/system/filter_solutions/test_export_to_aedt/test_export_to_aedt.py index 2bd9bd71343..57c733b6604 100644 --- a/tests/system/filter_solutions/test_export_to_aedt/test_export_to_aedt.py +++ b/tests/system/filter_solutions/test_export_to_aedt/test_export_to_aedt.py @@ -483,7 +483,7 @@ def test_import_tuned_variables(self, lumped_design) -> None: assert lumped_design.export_to_aedt.import_tuned_variables().splitlines() == read_resource_file( "imported_netlist.ckt", "Lumped" ) - app.desktop_class.close_desktop() + app.desktop.close_desktop() def test_part_libraries(self, lumped_design) -> None: assert lumped_design.export_to_aedt.part_libraries == PartLibraries.LUMPED diff --git a/tests/system/general/test_circuit.py b/tests/system/general/test_circuit.py index 69a22382619..4fc3cb6454c 100644 --- a/tests/system/general/test_circuit.py +++ b/tests/system/general/test_circuit.py @@ -510,7 +510,7 @@ def test_push_down(aedt_app) -> None: active_project = aedt_app.oproject.GetActiveDesign() if is_linux and DESKTOP_VERSION == "2024.1": time.sleep(1) - aedt_app.desktop_class.close_windows() + aedt_app.desktop.close_windows() active_project_name_1 = active_project.GetName() aedt_app.pop_up() subcircuit_2 = aedt_app.modeler.schematic.create_subcircuit( @@ -519,7 +519,7 @@ def test_push_down(aedt_app) -> None: active_project = aedt_app.oproject.GetActiveDesign() if is_linux and DESKTOP_VERSION == "2024.1": time.sleep(1) - aedt_app.desktop_class.close_windows() + aedt_app.desktop.close_windows() active_project_name_3 = active_project.GetName() assert active_project_name_1 == active_project_name_3 assert subcircuit_2.component_info["RefDes"] == "U2" @@ -531,14 +531,14 @@ def test_pop_up(aedt_app) -> None: active_project = aedt_app.oproject.GetActiveDesign() if is_linux and DESKTOP_VERSION == "2024.1": time.sleep(1) - aedt_app.desktop_class.close_windows() + aedt_app.desktop.close_windows() active_project_name_1 = active_project.GetName() aedt_app.modeler.schematic.create_subcircuit(location=[0.0, 0.0]) assert aedt_app.pop_up() active_project = aedt_app.oproject.GetActiveDesign() if is_linux and DESKTOP_VERSION == "2024.1": time.sleep(1) - aedt_app.desktop_class.close_windows() + aedt_app.desktop.close_windows() active_project_name_2 = active_project.GetName() assert active_project_name_1 == active_project_name_2 diff --git a/tests/system/general/test_hfss.py b/tests/system/general/test_hfss.py index 120a5823fee..698b1d64a50 100644 --- a/tests/system/general/test_hfss.py +++ b/tests/system/general/test_hfss.py @@ -1789,7 +1789,7 @@ def test_set_phase_center_per_port(aedt_app) -> None: name="Wave2", renormalize=False, ) - if aedt_app.desktop_class.is_grpc_api: + if aedt_app.desktop.is_grpc_api: assert aedt_app.set_phase_center_per_port() assert aedt_app.set_phase_center_per_port(["Global", "Global"]) else: diff --git a/tests/system/general/test_message_manager.py b/tests/system/general/test_message_manager.py index df7d153b1f5..99b1bfb2b22 100644 --- a/tests/system/general/test_message_manager.py +++ b/tests/system/general/test_message_manager.py @@ -143,5 +143,5 @@ def test_messaging(icepak_app) -> None: # pragma: no cover assert len(msg.aedt_messages.design_level) >= 4 settings.enable_desktop_logs = False - assert icepak_app.desktop_class.messenger - assert icepak_app.desktop_class.clear_messages() + assert icepak_app.desktop.messenger + assert icepak_app.desktop.clear_messages() diff --git a/tests/system/general/test_twinbuilder.py b/tests/system/general/test_twinbuilder.py index 200ab6c7676..ced7335148f 100644 --- a/tests/system/general/test_twinbuilder.py +++ b/tests/system/general/test_twinbuilder.py @@ -235,7 +235,7 @@ def test_add_excitation_model(add_app, test_tmp_dir) -> None: design="2 simplorer circuit", ) project_name = tb.project_name - dkp = tb.desktop_class + dkp = tb.desktop maxwell_app = dkp[[project_name, "1 maxwell busbar"]] assert not tb.add_excitation_model(project="invalid", design="1 maxwell busbar") diff --git a/tests/system/layout/test_3dlayout_modeler.py b/tests/system/layout/test_3dlayout_modeler.py index ada261f7b6e..043f3d6c901 100644 --- a/tests/system/layout/test_3dlayout_modeler.py +++ b/tests/system/layout/test_3dlayout_modeler.py @@ -1006,7 +1006,7 @@ def test_import_gerber(aedt_app, test_tmp_dir) -> None: ) assert aedt_app.modeler.polygons aedt_app.close_project(save=False) - aedt_app.desktop_class.active_project(active_project) + aedt_app.desktop.active_project(active_project) @pytest.mark.skipif(is_linux, reason="Fails in linux") @@ -1025,7 +1025,7 @@ def test_import_gds(aedt_app, test_tmp_dir) -> None: assert aedt_app.import_gds(str(gds_file), output_dir=str(aedb_file), control_file=str(control_file)) aedt_app.close_project(save=False) - aedt_app.desktop_class.active_project(active_project) + aedt_app.desktop.active_project(active_project) @pytest.mark.skipif(is_linux, reason="Fails in linux") @@ -1041,7 +1041,7 @@ def test_import_dxf(aedt_app, test_tmp_dir) -> None: assert aedt_app.import_gerber(str(dxf_file), output_dir=str(aedb_file), control_file=str(control_file)) aedt_app.close_project(save=False) - aedt_app.desktop_class.active_project(active_project) + aedt_app.desktop.active_project(active_project) def test_import_ipc(aedt_app, test_tmp_dir) -> None: @@ -1052,7 +1052,7 @@ def test_import_ipc(aedt_app, test_tmp_dir) -> None: assert aedt_app.import_ipc2581(str(ipc_file), output_dir=str(aedb_file), control_file="") aedt_app.close_project(save=False) - aedt_app.desktop_class.active_project(active_project) + aedt_app.desktop.active_project(active_project) @pytest.mark.skipif(DESKTOP_VERSION < "2022.2", reason="Not working on AEDT 22R1") diff --git a/tests/system/solvers/sequential/test_launch_desktop.py b/tests/system/solvers/sequential/test_launch_desktop.py index 279ec072c06..4ad42278db4 100644 --- a/tests/system/solvers/sequential/test_launch_desktop.py +++ b/tests/system/solvers/sequential/test_launch_desktop.py @@ -273,8 +273,8 @@ def test_run_desktop_rmxprt(desktop) -> None: def test_run_desktop_settings(desktop) -> None: aedtapp = Hfss() - assert aedtapp.desktop_class.disable_optimetrics() + assert aedtapp.desktop.disable_optimetrics() assert aedtapp.get_registry_key_int("Desktop/Settings/ProjectOptions/EnableLegacyOptimetricsTools") == 0 - assert aedtapp.desktop_class.enable_optimetrics() + assert aedtapp.desktop.enable_optimetrics() assert aedtapp.get_registry_key_int("Desktop/Settings/ProjectOptions/EnableLegacyOptimetricsTools") == 1 aedtapp.close_project(save=False) diff --git a/tests/system/solvers/test_analyze.py b/tests/system/solvers/test_analyze.py index 115c6f417d8..85c7c3dffc2 100644 --- a/tests/system/solvers/test_analyze.py +++ b/tests/system/solvers/test_analyze.py @@ -138,12 +138,14 @@ def m3dtransient(add_app_example): app.close_project(save=False) -def test_3dl_generate_mesh(hfss3dl_solve) -> None: +def test_3dl_generate_mesh(hfss3dl_solve): assert hfss3dl_solve.mesh.generate_mesh("Setup1") @pytest.mark.skipif(DESKTOP_VERSION < "2023.2", reason="Working only from 2023 R2") -def test_3dl_analyze_setup(hfss3dl_solve) -> None: +def test_3dl_analyze_setup(hfss3dl_solve): + logger = hfss3dl_solve.logger + assert hfss3dl_solve.export_touchstone_on_completion(export=False) assert hfss3dl_solve.export_touchstone_on_completion(export=True) if DESKTOP_VERSION > "2024.2": @@ -151,12 +153,53 @@ def test_3dl_analyze_setup(hfss3dl_solve) -> None: else: with pytest.raises(AEDTRuntimeError): hfss3dl_solve.set_export_touchstone() - assert hfss3dl_solve.analyze_setup("Setup1", cores=4, blocking=False) - assert hfss3dl_solve.are_there_simulations_running - assert hfss3dl_solve.stop_simulations() + + logger.info("test_3dl_analyze_setup: calling analyze_setup('Setup1', cores=4, blocking=False)") + analyze_result = hfss3dl_solve.analyze_setup("Setup1", cores=4, blocking=False) + logger.info(f"test_3dl_analyze_setup: analyze_setup returned {analyze_result}") + assert analyze_result + + running = hfss3dl_solve.are_there_simulations_running + logger.info(f"test_3dl_analyze_setup: initial are_there_simulations_running={running}") + start = time.time() + poll_count = 0 + while not running and time.time() - start < 10: + time.sleep(0.5) + running = hfss3dl_solve.are_there_simulations_running + poll_count += 1 + logger.info( + f"test_3dl_analyze_setup: poll #{poll_count} at {time.time() - start:.1f}s, " + f"are_there_simulations_running={running}" + ) + elapsed_poll = time.time() - start + logger.info( + f"test_3dl_analyze_setup: polling loop done after {elapsed_poll:.1f}s, " + f"poll_count={poll_count}, running={running}" + ) + + if not running: + setup_solved = hfss3dl_solve.setups[0].is_solved if hfss3dl_solve.setups else None + logger.warning( + f"test_3dl_analyze_setup: simulations NOT detected as running. " + f"setup_solved={setup_solved}, num_setups={len(hfss3dl_solve.setups)}" + ) + assert running, ( + f"Simulations not detected as running after {elapsed_poll:.1f}s " + f"(poll_count={poll_count}). Check AEDT logs for errors." + ) + + stop_result = hfss3dl_solve.stop_simulations() + logger.info(f"test_3dl_analyze_setup: stop_simulations returned {stop_result}") + assert stop_result + + wait_start = time.time() + wait_count = 0 while hfss3dl_solve.are_there_simulations_running: time.sleep(1) + wait_count += 1 + profile = hfss3dl_solve.setups[0].get_profile() + logger.info(f"test_3dl_analyze_setup: profile keys={list(profile.keys()) if profile else None}") key0 = list(profile.keys())[0] assert key0 == "Setup1" assert isinstance(profile[key0], SimulationProfile) @@ -165,7 +208,7 @@ def test_3dl_analyze_setup(hfss3dl_solve) -> None: assert profile[key0].max_memory() > MemoryGB(0.01) -def test_3dl_export_profile(hfss3dl_solved, test_tmp_dir) -> None: +def test_3dl_export_profile(hfss3dl_solved, test_tmp_dir): profile_file = test_tmp_dir / "temp.prof" profile_file = Path(hfss3dl_solved.export_profile("Setup1", output_file=profile_file)) assert profile_file.exists() @@ -195,7 +238,7 @@ def test_3dl_export_profile(hfss3dl_solved, test_tmp_dir) -> None: @pytest.mark.skipif(is_linux or sys.version_info < (3, 8), reason="Not supported.") -def test_sbr_link_array(sbr_platform, add_app_example) -> None: +def test_sbr_link_array(sbr_platform, add_app_example): app = add_app_example(project=ARRAY_ANTENNA, subfolder=TEST_SUBFOLDER, close_projects=False) assert sbr_platform.create_sbr_linked_antenna(app, target_cs="antenna_CS", field_type="farfield") profile = sbr_platform.setups[0].get_profile() @@ -204,7 +247,7 @@ def test_sbr_link_array(sbr_platform, add_app_example) -> None: @pytest.mark.skipif(is_linux or sys.version_info < (3, 8), reason="Not supported.") -def test_sbr_link_array_solved(sbr_platform_solved, test_tmp_dir) -> None: +def test_sbr_link_array_solved(sbr_platform_solved, test_tmp_dir): profile = sbr_platform_solved.setups[0].get_profile() assert isinstance(profile, Profiles) key0 = list(profile.keys())[0] @@ -232,7 +275,7 @@ def test_sbr_link_array_solved(sbr_platform_solved, test_tmp_dir) -> None: assert Path(ffdata2.metadata_file).is_file() -def test_sbr_create_vrt(sbr_app) -> None: +def test_sbr_create_vrt(sbr_app): sbr_app.rename_design("vtr") sbr_app.modeler.create_sphere([10, 10, 10], 5, material="copper") vrt = sbr_app.post.create_sbr_plane_visual_ray_tracing(max_frequency="10GHz", incident_theta="40deg") @@ -247,7 +290,7 @@ def test_sbr_create_vrt(sbr_app) -> None: assert vrt.delete() -def test_sbr_create_vrt_creeping(sbr_app) -> None: +def test_sbr_create_vrt_creeping(sbr_app): sbr_app.rename_design("vtr_creeping") sbr_app.modeler.create_sphere([10, 10, 10], 5, material="copper") vrt = sbr_app.post.create_creeping_plane_visual_ray_tracing(max_frequency="10GHz") @@ -266,7 +309,7 @@ def test_sbr_create_vrt_creeping(sbr_app) -> None: DESKTOP_VERSION < "2022.2", reason="Not working in non-graphical in version lower than 2022.2", ) -def test_hfss_export_results(hfss_app, test_tmp_dir) -> None: +def test_hfss_export_results(hfss_app, test_tmp_dir): hfss_app.insert_design("Array_simple_resuts", "Modal") from ansys.aedt.core.generic.file_utils import read_json @@ -340,7 +383,7 @@ def test_hfss_export_results(hfss_app, test_tmp_dir) -> None: assert hfss_app.export_touchstone_on_completion(export=True) -def test_icepak_analyze_and_export_summary(icepak_solved) -> None: +def test_icepak_analyze_and_export_summary(icepak_solved): assert icepak_solved.create_output_variable("OutputVariable2", "abs(Variable1)") # test creation assert icepak_solved.create_output_variable("OutputVariable2", "asin(Variable1)") # test update icepak_solved.save_project() @@ -406,7 +449,7 @@ def test_icepak_analyze_and_export_summary(icepak_solved) -> None: assert profile.product == "Icepak" -def test_icepak_get_output_variable(icepak_solved) -> None: +def test_icepak_get_output_variable(icepak_solved): with pytest.raises(KeyError): icepak_solved.get_output_variable("invalid") value = icepak_solved.get_output_variable("OutputVariable1") @@ -414,14 +457,14 @@ def test_icepak_get_output_variable(icepak_solved) -> None: assert abs(value - 0.5235987755982988) < tol -def test_icepak_get_monitor_output(icepak_solved) -> None: +def test_icepak_get_monitor_output(icepak_solved): assert icepak_solved.monitor.all_monitors["test_monitor"].value() assert icepak_solved.monitor.all_monitors["test_monitor"].value(quantity="Temperature") assert icepak_solved.monitor.all_monitors["test_monitor"].value(setup=icepak_solved.existing_analysis_sweeps[0]) assert icepak_solved.monitor.all_monitors["test_monitor2"].value(quantity="HeatFlowRate") -def test_icepak_eval_tempc(icepak_solved) -> None: +def test_icepak_eval_tempc(icepak_solved): assert Path( icepak_solved.eval_volume_quantity_from_field_summary( ["box"], "Temperature", savedir=icepak_solved.working_directory @@ -429,7 +472,7 @@ def test_icepak_eval_tempc(icepak_solved) -> None: ).exists() -def test_icepak_export_fld(icepak_solved, test_tmp_dir) -> None: +def test_icepak_export_fld(icepak_solved, test_tmp_dir): fld_file = test_tmp_dir / "test_fld.fld" icepak_solved.post.export_field_file( quantity="Temp", @@ -478,7 +521,7 @@ def test_icepak_export_fld(icepak_solved, test_tmp_dir) -> None: @pytest.mark.skipif(is_linux, reason="To be investigated on linux.") -def test_3dl_export_touchstone(hfss3dl_solved, test_tmp_dir) -> None: +def test_3dl_export_touchstone(hfss3dl_solved, test_tmp_dir): filename = Path(test_tmp_dir) / "touchstone.s2p" solution_name = "Setup1" sweep_name = "Sweep1" @@ -489,19 +532,19 @@ def test_3dl_export_touchstone(hfss3dl_solved, test_tmp_dir) -> None: assert hfss3dl_solved.export_touchstone(solution_name, sweep_name) -def test_3dl_export_results(hfss3dl_solved) -> None: +def test_3dl_export_results(hfss3dl_solved): files = hfss3dl_solved.export_results() assert len(files) > 0 -def test_3dl_set_export_touchstone(hfss3dl_solved) -> None: +def test_3dl_set_export_touchstone(hfss3dl_solved): assert hfss3dl_solved.export_touchstone_on_completion(True) assert hfss3dl_solved.export_touchstone_on_completion(False) if DESKTOP_VERSION > "2024.2": assert hfss3dl_solved.set_export_touchstone() -def test_3dl_touchstone_results(hfss3dl_solved) -> None: +def test_3dl_touchstone_results(hfss3dl_solved): assert hfss3dl_solved.get_all_return_loss_list() == ["S(Port1,Port1)", "S(Port2,Port2)"] assert hfss3dl_solved.get_all_sparameter_list == ["S(Port1,Port1)", "S(Port1,Port2)", "S(Port2,Port2)"] assert hfss3dl_solved.get_all_insertion_loss_list(drivers_prefix_name="Port1", receivers_prefix_name="Port2") == [ @@ -511,7 +554,7 @@ def test_3dl_touchstone_results(hfss3dl_solved) -> None: assert hfss3dl_solved.get_fext_xtalk_list() == ["S(Port1,Port2)", "S(Port2,Port1)"] -def test_circuit_add_3dlayout_component(circuit_app) -> None: +def test_circuit_add_3dlayout_component(circuit_app): setup = circuit_app.create_setup("test_06b_LNA") setup.add_sweep_step(start=0, stop=5, step_size=0.01) myedb = circuit_app.modeler.schematic.add_subcircuit_3dlayout("main") @@ -543,14 +586,14 @@ def test_circuit_add_3dlayout_component(circuit_app) -> None: assert new_report.create() -def test_circuit_add_hfss_component(circuit_app) -> None: +def test_circuit_add_hfss_component(circuit_app): my_model, _ = circuit_app.modeler.schematic.create_field_model( "uUSB", "Setup1 : Sweep", ["usb_N_conn", "usb_N_pcb", "usb_P_conn", "usb_P_pcb"] ) assert isinstance(my_model, int) -def test_circuit_push_excitation(circuit_app) -> None: +def test_circuit_push_excitation(circuit_app): setup_name = "test_07a_LNA" circuit_app.modeler.schematic.add_subcircuit_3dlayout("main") setup = circuit_app.create_setup(setup_name) @@ -559,21 +602,21 @@ def test_circuit_push_excitation(circuit_app) -> None: assert circuit_app.push_excitations(instance="U1", thevenin_calculation=True, setup=setup_name) -def test_circuit_push_excitation_time(circuit_app) -> None: +def test_circuit_push_excitation_time(circuit_app): setup_name = "test_07b_Transient" circuit_app.modeler.schematic.add_subcircuit_3dlayout("main") circuit_app.create_setup(setup_name, setup_type="NexximTransient") assert circuit_app.push_time_excitations(instance="U1", setup=setup_name) -def test_m3d_harmonic_forces(m3dtransient) -> None: +def test_m3d_harmonic_forces(m3dtransient): assert m3dtransient.export_element_based_harmonic_force( start_frequency=1, stop_frequency=100, number_of_frequency=None ) assert m3dtransient.export_element_based_harmonic_force(number_of_frequency=5) -def test_export_maxwell_fields(m3dtransient, test_tmp_dir) -> None: +def test_export_maxwell_fields(m3dtransient, test_tmp_dir): fld_file_3 = test_tmp_dir / "test_fld_3.fld" assert m3dtransient.post.export_field_file( quantity="Mag_B", @@ -606,7 +649,7 @@ def test_export_maxwell_fields(m3dtransient, test_tmp_dir) -> None: new_setup.update() -def test_compute_erl(circuit_erl) -> None: +def test_compute_erl(circuit_erl): sp = circuit_erl.export_touchstone() spisim = SpiSim(sp) @@ -628,7 +671,7 @@ def test_compute_erl(circuit_erl) -> None: assert erl_data_3 -def test_compute_com_exported_touchstone(circuit_com) -> None: +def test_compute_com_exported_touchstone(circuit_com): sp = circuit_com.export_touchstone() spisim = SpiSim(sp) @@ -641,7 +684,7 @@ def test_compute_com_exported_touchstone(circuit_com) -> None: assert com -def test_compute_com(test_tmp_dir) -> None: +def test_compute_com(test_tmp_dir): com_example_file_folder = Path(TESTS_SOLVERS_PATH) / "example_models" / TEST_SUBFOLDER / "com_unit_test_sparam" thru_s4p = shutil.copy2(com_example_file_folder / "SerDes_Demo_02_Thru.s4p", test_tmp_dir / "thru.s4p") @@ -667,7 +710,7 @@ def test_compute_com(test_tmp_dir) -> None: assert com_0 and com_1 -def test_compute_com_parameter_ver_3p4(test_tmp_dir) -> None: +def test_compute_com_parameter_ver_3p4(test_tmp_dir): com_example_file_folder = Path(TESTS_SOLVERS_PATH) / "example_models" / TEST_SUBFOLDER / "com_unit_test_sparam" thru_s4p = shutil.copy2(com_example_file_folder / "SerDes_Demo_02_Thru.s4p", test_tmp_dir / "thru.s4p") spisim = SpiSim(thru_s4p) @@ -685,7 +728,7 @@ def test_compute_com_parameter_ver_3p4(test_tmp_dir) -> None: assert com_0 and com_1 -def test_export_to_maxwell(add_app_example, add_app, test_tmp_dir) -> None: +def test_export_to_maxwell(add_app_example, add_app, test_tmp_dir): app = add_app_example( project="assm_test", design="assm-1", application=Rmxprt, subfolder="T00", solution_type="ASSM" ) @@ -698,7 +741,7 @@ def test_export_to_maxwell(add_app_example, add_app, test_tmp_dir) -> None: assert app2.circuit -def test_output_variables_3dlayout(hfss3dl_solved) -> None: +def test_output_variables_3dlayout(hfss3dl_solved): hfss3dl_solved.set_differential_pair( assignment="Port1", reference="Port2", differential_mode="Diff", common_mode="Comm" ) @@ -713,7 +756,7 @@ def test_output_variables_3dlayout(hfss3dl_solved) -> None: ) -def test_spisim_advanced_report_ucie(test_tmp_dir) -> None: +def test_spisim_advanced_report_ucie(test_tmp_dir): spisim_advanced_report_exmaple_folder = ( Path(TESTS_SOLVERS_PATH) / "example_models" / TEST_SUBFOLDER / "spisim_advanced_report" ) @@ -722,7 +765,7 @@ def test_spisim_advanced_report_ucie(test_tmp_dir) -> None: assert spisim.compute_ucie([0, 2, 4, 6, 8, 10], [1, 3, 5, 7, 9, 11], [1, 3]) -def test_set_hpc_from_file(hfss3dl_solve) -> None: +def test_set_hpc_from_file(hfss3dl_solve): acf_file = Path(hfss3dl_solve.pyaedt_dir) / "misc" / "pyaedt_local_config.acf" with pytest.raises(AEDTRuntimeError): hfss3dl_solve.set_hpc_from_file() @@ -731,7 +774,7 @@ def test_set_hpc_from_file(hfss3dl_solve) -> None: assert hfss3dl_solve.set_hpc_from_file(configuration_name="Local") -def test_custom_hpc_from_file(icepak_solved) -> None: +def test_custom_hpc_from_file(icepak_solved): allowed_distributed = ["Variations", "Frequencies", "Transient Excitations", "Domain Solver"] assert icepak_solved.set_custom_hpc_options() diff --git a/tests/system/solvers/test_pdf.py b/tests/system/solvers/test_pdf.py index 5aac0a133bd..582d41ee3b6 100644 --- a/tests/system/solvers/test_pdf.py +++ b/tests/system/solvers/test_pdf.py @@ -179,7 +179,7 @@ def test_virtual_compliance(aedt_app, test_tmp_dir) -> None: ) vc.save_configuration(compliance_folder / "main.json") assert (compliance_folder / "main.json").exists() - v = VirtualCompliance(aedt_app.desktop_class, compliance_folder / "main.json") + v = VirtualCompliance(aedt_app.desktop, compliance_folder / "main.json") assert v.create_compliance_report(close_project=False) diff --git a/tests/unit/extensions/test_via_clustering.py b/tests/unit/extensions/test_via_clustering.py index df2ea624f2f..f2ad891737f 100644 --- a/tests/unit/extensions/test_via_clustering.py +++ b/tests/unit/extensions/test_via_clustering.py @@ -169,7 +169,7 @@ def test_via_clustering_extension_add_layer_button(mock_hfss_3d_layout_app_with_ # Verify that usp was set to True assert mock_layer.usp is True # Verify desktop was released - mock_hfss.desktop_class.release_desktop.assert_called_once_with(False, False) + mock_hfss.desktop.release_desktop.assert_called_once_with(False, False) extension.root.destroy() @@ -221,7 +221,7 @@ def test_via_clustering_extension_merge_vias_button_with_primitives(mock_hfss_3d assert extension.data.contour_list == expected_contours # Verify desktop was released - mock_hfss.desktop_class.release_desktop.assert_called_once_with(False, False) + mock_hfss.desktop.release_desktop.assert_called_once_with(False, False) def test_via_clustering_extension_merge_vias_unsupported_primitive(mock_hfss_3d_layout_app_with_layers) -> None: @@ -364,7 +364,7 @@ def test_main_function_without_pytest_env() -> None: # Verify HFSS 3D Layout was instantiated and used mock_logger.info.assert_called_once_with("Project generated correctly.") - mock_h3d.desktop_class.release_desktop.assert_called_once_with(False, False) + mock_h3d.desktop.release_desktop.assert_called_once_with(False, False) def test_via_clustering_extension_wrong_design_type() -> None: diff --git a/tests/unit/test_cli.py b/tests/unit/test_cli.py index dd254f3b70d..e368082980c 100644 --- a/tests/unit/test_cli.py +++ b/tests/unit/test_cli.py @@ -368,7 +368,7 @@ def test_stop_command_by_port_no_port_info(mock_get_port, mock_process_iter, cli def mock_start_command(): """Mock all dependencies for the start command tests.""" with ( - patch("ansys.aedt.core.desktop.Desktop") as mock_desktop_class, + patch("ansys.aedt.core.desktop.Desktop") as mock_desktop, patch("ansys.aedt.core.settings") as mock_settings, patch("threading.Thread") as mock_thread, patch("time.sleep") as mock_sleep, @@ -378,10 +378,10 @@ def mock_start_command(): # Configure mock Desktop class to return a mock instance mock_desktop_instance = Mock() - mock_desktop_class.return_value = mock_desktop_instance + mock_desktop.return_value = mock_desktop_instance yield { - "desktop_class": mock_desktop_class, + "desktop": mock_desktop, "desktop_instance": mock_desktop_instance, "settings": mock_settings, "thread": mock_thread, diff --git a/tests/unit/test_downloads.py b/tests/unit/test_downloads.py index 9c54b3e4599..2c909bb281d 100644 --- a/tests/unit/test_downloads.py +++ b/tests/unit/test_downloads.py @@ -23,12 +23,15 @@ # SOFTWARE. from pathlib import Path +from unittest.mock import patch import pytest from ansys.aedt.core.examples import downloads +from ansys.aedt.core.examples.downloads import _copy_local_example from ansys.aedt.core.generic.file_utils import generate_unique_name from ansys.aedt.core.generic.settings import is_linux +from ansys.aedt.core.internal.errors import AEDTRuntimeError @pytest.fixture(scope="module", autouse=True) @@ -120,3 +123,190 @@ def test_download_icepak_3d_component(test_tmp_dir) -> None: def test_download_fss_file(test_tmp_dir) -> None: example_folder = downloads.download_fss_3dcomponent(local_path=test_tmp_dir) assert Path(example_folder).exists() + + +# ================================ +# _copy_local_example unit tests +# ================================ + + +@pytest.fixture +def local_example_folder(test_tmp_dir): + """Create a mock local example folder structure for testing.""" + example_root = test_tmp_dir / "mock_example_data" + example_root.mkdir(parents=True, exist_ok=True) + return example_root + + +@pytest.fixture +def mock_settings(local_example_folder): + """Patch settings.local_example_folder to use the mock folder.""" + with patch("ansys.aedt.core.examples.downloads.settings") as mock_settings: + mock_settings.local_example_folder = str(local_example_folder) + yield mock_settings + + +class TestCopyLocalExampleFile: + """Tests for _copy_local_example when source is a file.""" + + def test_copy_single_file(self, test_tmp_dir, local_example_folder, mock_settings): + """Test copying a single file to target directory.""" + # Create a source file + source_file = local_example_folder / "test_file.txt" + source_file.write_text("test content") + + # Copy the file + target_dir = test_tmp_dir / "target" + result = _copy_local_example("test_file.txt", target_dir) + + # Verify + assert result.exists() + assert result.is_file() + assert result.name == "test_file.txt" + assert result.parent == target_dir + assert result.read_text() == "test content" + + def test_copy_file_in_subdirectory(self, test_tmp_dir, local_example_folder, mock_settings): + """Test copying a file from a subdirectory.""" + # Create a source file in a subdirectory + subdir = local_example_folder / "pyaedt" / "sbr" + subdir.mkdir(parents=True) + source_file = subdir / "Cassegrain.aedt" + source_file.write_text("aedt file content") + + # Copy the file + target_dir = test_tmp_dir / "target" + result = _copy_local_example("pyaedt/sbr/Cassegrain.aedt", target_dir) + + # Verify + assert result.exists() + assert result.is_file() + assert result.name == "Cassegrain.aedt" + assert result.parent == target_dir + assert result.read_text() == "aedt file content" + + def test_copy_file_creates_target_directory(self, test_tmp_dir, local_example_folder, mock_settings): + """Test that target directory is created if it doesn't exist.""" + # Create a source file + source_file = local_example_folder / "test_file.txt" + source_file.write_text("test content") + + # Copy to a non-existent nested target directory + target_dir = test_tmp_dir / "nested" / "target" / "dir" + assert not target_dir.exists() + + result = _copy_local_example("test_file.txt", target_dir) + + # Verify target directory was created + assert target_dir.exists() + assert result.exists() + + +class TestCopyLocalExampleFolder: + """Tests for _copy_local_example when source is a folder.""" + + def test_copy_folder_with_files(self, test_tmp_dir, local_example_folder, mock_settings): + """Test copying a folder containing multiple files.""" + # Create a source folder with files + source_folder = local_example_folder / "test_folder" + source_folder.mkdir() + (source_folder / "file1.txt").write_text("content 1") + (source_folder / "file2.txt").write_text("content 2") + + # Copy the folder + target_dir = test_tmp_dir / "target" + result = _copy_local_example("test_folder", target_dir) + + # Verify + assert result.exists() + assert result.is_dir() + assert result.name == "test_folder" + assert (result / "file1.txt").read_text() == "content 1" + assert (result / "file2.txt").read_text() == "content 2" + + def test_copy_folder_with_nested_structure(self, test_tmp_dir, local_example_folder, mock_settings): + """Test copying a folder with nested subdirectories.""" + # Create a source folder with nested structure + source_folder = local_example_folder / "parent_folder" + source_folder.mkdir() + (source_folder / "root_file.txt").write_text("root content") + + nested = source_folder / "subdir1" / "subdir2" + nested.mkdir(parents=True) + (nested / "nested_file.txt").write_text("nested content") + + # Copy the folder + target_dir = test_tmp_dir / "target" + result = _copy_local_example("parent_folder", target_dir) + + # Verify + assert result.exists() + assert (result / "root_file.txt").read_text() == "root content" + assert (result / "subdir1" / "subdir2" / "nested_file.txt").read_text() == "nested content" + + def test_copy_folder_preserves_empty_subdirectories(self, test_tmp_dir, local_example_folder, mock_settings): + """Test that empty subdirectories are preserved when copying.""" + # Create a source folder with an empty subdirectory + source_folder = local_example_folder / "folder_with_empty" + source_folder.mkdir() + (source_folder / "empty_subdir").mkdir() + (source_folder / "file.txt").write_text("content") + + # Copy the folder + target_dir = test_tmp_dir / "target" + result = _copy_local_example("folder_with_empty", target_dir) + + # Verify empty subdirectory exists + assert (result / "empty_subdir").exists() + assert (result / "empty_subdir").is_dir() + + def test_copy_folder_from_subdirectory(self, test_tmp_dir, local_example_folder, mock_settings): + """Test copying a folder from a subdirectory path.""" + # Create nested source folder + pyaedt = local_example_folder / "pyaedt" + pyaedt.mkdir() + source_folder = pyaedt / "custom_reports" + source_folder.mkdir() + (source_folder / "report.json").write_text('{"key": "value"}') + + # Copy the folder + target_dir = test_tmp_dir / "target" + result = _copy_local_example("pyaedt/custom_reports", target_dir) + + # Verify + assert result.exists() + assert result.name == "custom_reports" + assert (result / "report.json").read_text() == '{"key": "value"}' + + +class TestCopyLocalExampleErrors: + """Tests for error handling in _copy_local_example.""" + + def test_copy_file_raises_error_on_failure(self, test_tmp_dir, local_example_folder, mock_settings): + """Test that AEDTRuntimeError is raised when file copy fails.""" + # Create a source file + source_file = local_example_folder / "test_file.txt" + source_file.write_text("test content") + + target_dir = test_tmp_dir / "target" + + # Mock shutil.copy2 to raise an exception + with patch("ansys.aedt.core.examples.downloads.shutil.copy2") as mock_copy: + mock_copy.side_effect = PermissionError("Access denied") + with pytest.raises(AEDTRuntimeError, match="Failed to copy"): + _copy_local_example("test_file.txt", target_dir) + + def test_copy_folder_raises_error_on_failure(self, test_tmp_dir, local_example_folder, mock_settings): + """Test that AEDTRuntimeError is raised when folder file copy fails.""" + # Create a source folder with a file + source_folder = local_example_folder / "test_folder" + source_folder.mkdir() + (source_folder / "file.txt").write_text("content") + + target_dir = test_tmp_dir / "target" + + # Mock shutil.copy2 to raise an exception + with patch("ansys.aedt.core.examples.downloads.shutil.copy2") as mock_copy: + mock_copy.side_effect = PermissionError("Access denied") + with pytest.raises(AEDTRuntimeError, match="Failed to copy"): + _copy_local_example("test_folder", target_dir)