From 1a41115eaf3ce6ad6f5151cdc96f4afb1aff8cd2 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Mon, 17 Nov 2025 13:28:19 +0100 Subject: [PATCH 01/33] docs(examples): escape backslash in Young's modulus math expression in bracket_static example --- examples/00-mapdl-examples/bracket_static.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/00-mapdl-examples/bracket_static.py b/examples/00-mapdl-examples/bracket_static.py index b3fbdeaaf7c..c0ddb1fdacc 100644 --- a/examples/00-mapdl-examples/bracket_static.py +++ b/examples/00-mapdl-examples/bracket_static.py @@ -68,7 +68,7 @@ ~~~~~~~~~~~~~ The dimensions of the corner bracket are shown in the following figure. -The bracket is made of A36 steel with a Young's modulus of :math:`3\cdot 10^7` psi +The bracket is made of A36 steel with a Young's modulus of :math:`3\\cdot 10^7` psi and Poisson's ratio of :math:`0.27`. .. figure:: ../../../images/bracket_dimensions.png From 9f9f7aa57f39aa908b13a1fe40a65cc2ec082b45 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Mon, 17 Nov 2025 13:34:16 +0100 Subject: [PATCH 02/33] refactor(commands): introduce CommandsBase with typed run() and make command mixins inherit Add a CommandsBase class (with a typed run(command, write_to_log, mute, **kwargs) stub) to declare the interface used by APDL command mixins. Update numerous command modules to import and inherit from CommandsBase so mixins consistently express the expected run() contract for the parent MAPDL class. --- src/ansys/mapdl/core/_commands/__init__.py | 43 +++++++++++++++++++ .../core/_commands/apdl/abbreviations.py | 4 +- .../core/_commands/apdl/array_parameters.py | 4 +- .../_commands/apdl/encryption_decryption.py | 4 +- .../mapdl/core/_commands/apdl/macro_files.py | 4 +- .../core/_commands/apdl/matrix_operations.py | 4 +- .../_commands/apdl/parameter_definition.py | 4 +- .../core/_commands/apdl/process_controls.py | 4 +- .../core/_commands/aux12/general_radiation.py | 4 +- .../aux12/radiation_matrix_method.py | 4 +- .../core/_commands/aux12/radiosity_solver.py | 4 +- src/ansys/mapdl/core/_commands/aux15/iges.py | 4 +- .../core/_commands/aux2/binary_file_dump.py | 4 +- .../aux2/binary_file_manipulation.py | 4 +- .../core/_commands/aux3/results_files.py | 4 +- src/ansys/mapdl/core/_commands/conn.py | 4 +- .../core/_commands/database/components.py | 4 +- .../_commands/database/coordinate_system.py | 4 +- .../mapdl/core/_commands/database/picking.py | 4 +- .../core/_commands/database/selecting.py | 4 +- .../mapdl/core/_commands/database/set_up.py | 4 +- .../core/_commands/database/working_plane.py | 4 +- .../core/_commands/graphics/annotation.py | 4 +- .../mapdl/core/_commands/graphics/graphs.py | 4 +- .../mapdl/core/_commands/graphics/labeling.py | 4 +- .../mapdl/core/_commands/graphics/scaling.py | 4 +- .../mapdl/core/_commands/graphics/set_up.py | 4 +- .../mapdl/core/_commands/graphics/style.py | 4 +- .../mapdl/core/_commands/graphics/views.py | 4 +- src/ansys/mapdl/core/_commands/hidden.py | 4 +- src/ansys/mapdl/core/_commands/inq_func.py | 4 +- .../core/_commands/map/pressure_mapping.py | 4 +- src/ansys/mapdl/core/_commands/misc/misc.py | 4 +- .../mapdl/core/_commands/post1/_fatigue.py | 4 +- .../core/_commands/post1/_special_purpose.py | 4 +- .../mapdl/core/_commands/post1/animation.py | 4 +- .../mapdl/core/_commands/post1/controls.py | 4 +- .../core/_commands/post1/element_table.py | 4 +- .../core/_commands/post1/failure_criteria.py | 4 +- .../mapdl/core/_commands/post1/listing.py | 4 +- .../_commands/post1/load_case_calculations.py | 4 +- .../_commands/post1/magnetics_calculations.py | 4 +- .../core/_commands/post1/path_operations.py | 4 +- .../mapdl/core/_commands/post1/results.py | 4 +- .../mapdl/core/_commands/post1/set_up.py | 4 +- .../core/_commands/post1/special_purpose.py | 4 +- .../mapdl/core/_commands/post1/status.py | 4 +- .../_commands/post1/surface_operations.py | 4 +- .../core/_commands/post1/trace_points.py | 4 +- .../mapdl/core/_commands/post26/_set_up.py | 4 +- .../mapdl/core/_commands/post26/controls.py | 4 +- .../mapdl/core/_commands/post26/display.py | 4 +- .../mapdl/core/_commands/post26/listing.py | 4 +- .../mapdl/core/_commands/post26/operations.py | 4 +- .../mapdl/core/_commands/post26/set_up.py | 4 +- .../core/_commands/post26/special_purpose.py | 4 +- .../mapdl/core/_commands/post26/status.py | 4 +- .../mapdl/core/_commands/preproc/areas.py | 4 +- .../preproc/artificially_matched_layers.py | 4 +- .../mapdl/core/_commands/preproc/booleans.py | 4 +- .../_commands/preproc/constraint_equations.py | 4 +- .../core/_commands/preproc/coupled_dof.py | 4 +- .../mapdl/core/_commands/preproc/database.py | 4 +- .../core/_commands/preproc/digitizing.py | 4 +- .../core/_commands/preproc/element_type.py | 4 +- .../mapdl/core/_commands/preproc/elements.py | 4 +- .../_commands/preproc/explicit_dynamics.py | 3 +- .../core/_commands/preproc/hard_points.py | 4 +- .../mapdl/core/_commands/preproc/keypoints.py | 4 +- .../mapdl/core/_commands/preproc/lines.py | 4 +- .../_commands/preproc/material_data_tables.py | 4 +- .../mapdl/core/_commands/preproc/materials.py | 4 +- .../mapdl/core/_commands/preproc/meshing.py | 3 +- .../mapdl/core/_commands/preproc/morphing.py | 4 +- .../mapdl/core/_commands/preproc/nodes.py | 4 +- .../core/_commands/preproc/primitives.py | 4 +- .../core/_commands/preproc/real_constants.py | 4 +- .../mapdl/core/_commands/preproc/sections.py | 4 +- .../core/_commands/preproc/special_purpose.py | 4 +- .../mapdl/core/_commands/preproc/status.py | 4 +- .../core/_commands/preproc/superelements.py | 4 +- .../mapdl/core/_commands/preproc/volumes.py | 4 +- .../mapdl/core/_commands/session/files.py | 4 +- .../core/_commands/session/list_controls.py | 4 +- .../core/_commands/session/processor_entry.py | 4 +- .../core/_commands/session/run_controls.py | 3 +- .../_commands/solution/analysis_options.py | 3 +- .../_commands/solution/birth_and_death.py | 3 +- .../_commands/solution/dynamic_options.py | 4 +- .../core/_commands/solution/fe_body_loads.py | 4 +- .../core/_commands/solution/fe_constraints.py | 4 +- .../core/_commands/solution/fe_forces.py | 4 +- .../_commands/solution/fe_surface_loads.py | 4 +- .../core/_commands/solution/gap_conditions.py | 4 +- .../mapdl/core/_commands/solution/inertia.py | 4 +- .../solution/load_step_operations.py | 4 +- .../_commands/solution/load_step_options.py | 4 +- .../core/_commands/solution/master_dof.py | 4 +- .../_commands/solution/miscellaneous_loads.py | 4 +- ...multi_field_solver_convergence_controls.py | 4 +- .../multi_field_solver_definition_commands.py | 4 +- .../multi_field_solver_global_controls.py | 4 +- .../multi_field_solver_interface_mapping.py | 4 +- .../multi_field_solver_load_transfer.py | 4 +- .../multi_field_solver_time_controls.py | 4 +- .../_commands/solution/nonlinear_options.py | 4 +- .../mapdl/core/_commands/solution/ocean.py | 4 +- .../core/_commands/solution/radiosity.py | 4 +- .../mapdl/core/_commands/solution/rezoning.py | 4 +- .../_commands/solution/solid_body_loads.py | 4 +- .../_commands/solution/solid_constraints.py | 4 +- .../core/_commands/solution/solid_forces.py | 4 +- .../_commands/solution/solid_surface_loads.py | 4 +- .../_commands/solution/solution_status.py | 4 +- .../_commands/solution/spectrum_options.py | 4 +- .../_commands/solution/twod_to_3d_analysis.py | 4 +- 116 files changed, 374 insertions(+), 124 deletions(-) diff --git a/src/ansys/mapdl/core/_commands/__init__.py b/src/ansys/mapdl/core/_commands/__init__.py index b55dfdc0127..e965579d725 100644 --- a/src/ansys/mapdl/core/_commands/__init__.py +++ b/src/ansys/mapdl/core/_commands/__init__.py @@ -19,3 +19,46 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. + +from typing import Any, Optional + + +class CommandsBase: + """Base class for MAPDL command mixin classes. + + This class declares the interface that command mixin classes rely on. + The actual implementation of the run method is provided by the parent + MAPDL class when these command mixins are combined via multiple inheritance. + """ + + def run( + self, + command: str, + write_to_log: bool = True, + mute: Optional[bool] = None, + **kwargs: Any, + ) -> str: + """Run a single APDL command. + + This method is implemented by the parent MAPDL class. + Command mixins can call this method to execute APDL commands. + + Parameters + ---------- + command : str + ANSYS APDL command. + write_to_log : bool, optional + Whether to write command to log. Default ``True``. + mute : bool, optional + Whether to mute command output. + **kwargs : Any + Additional keyword arguments. + + Returns + ------- + str + Command output from MAPDL. + """ + raise NotImplementedError( + "The run method must be provided by the parent MAPDL class" + ) diff --git a/src/ansys/mapdl/core/_commands/apdl/abbreviations.py b/src/ansys/mapdl/core/_commands/apdl/abbreviations.py index e9736dc81a6..38b9d44d888 100644 --- a/src/ansys/mapdl/core/_commands/apdl/abbreviations.py +++ b/src/ansys/mapdl/core/_commands/apdl/abbreviations.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Abbreviations: + +class Abbreviations(CommandsBase): def abbr(self, abbr: str = "", string: str = "", **kwargs): r"""Defines an abbreviation. diff --git a/src/ansys/mapdl/core/_commands/apdl/array_parameters.py b/src/ansys/mapdl/core/_commands/apdl/array_parameters.py index 4de67041d82..e6a58fb48dd 100644 --- a/src/ansys/mapdl/core/_commands/apdl/array_parameters.py +++ b/src/ansys/mapdl/core/_commands/apdl/array_parameters.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class ArrayParameters: + +class ArrayParameters(CommandsBase): def mfouri( self, diff --git a/src/ansys/mapdl/core/_commands/apdl/encryption_decryption.py b/src/ansys/mapdl/core/_commands/apdl/encryption_decryption.py index 578572b6b9a..482be1582d9 100644 --- a/src/ansys/mapdl/core/_commands/apdl/encryption_decryption.py +++ b/src/ansys/mapdl/core/_commands/apdl/encryption_decryption.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class EncryptionDecryption: + +class EncryptionDecryption(CommandsBase): def dbdecrypt( self, diff --git a/src/ansys/mapdl/core/_commands/apdl/macro_files.py b/src/ansys/mapdl/core/_commands/apdl/macro_files.py index 9de669016b0..d081fbde08d 100644 --- a/src/ansys/mapdl/core/_commands/apdl/macro_files.py +++ b/src/ansys/mapdl/core/_commands/apdl/macro_files.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class MacroFiles: + +class MacroFiles(CommandsBase): def cfclos(self, **kwargs): r"""Closes the "command" file. diff --git a/src/ansys/mapdl/core/_commands/apdl/matrix_operations.py b/src/ansys/mapdl/core/_commands/apdl/matrix_operations.py index fd4bdd8e55d..35a1f1c2d0d 100644 --- a/src/ansys/mapdl/core/_commands/apdl/matrix_operations.py +++ b/src/ansys/mapdl/core/_commands/apdl/matrix_operations.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class MatrixOperations: + +class MatrixOperations(CommandsBase): def axpy( self, diff --git a/src/ansys/mapdl/core/_commands/apdl/parameter_definition.py b/src/ansys/mapdl/core/_commands/apdl/parameter_definition.py index 2a8d2cfda41..75a808b1062 100644 --- a/src/ansys/mapdl/core/_commands/apdl/parameter_definition.py +++ b/src/ansys/mapdl/core/_commands/apdl/parameter_definition.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class ParameterDefinition: + +class ParameterDefinition(CommandsBase): def afun(self, lab: str = "", **kwargs): r"""Specifies units for angular functions in parameter expressions. diff --git a/src/ansys/mapdl/core/_commands/apdl/process_controls.py b/src/ansys/mapdl/core/_commands/apdl/process_controls.py index 64abfcb7493..fb47b1bacd7 100644 --- a/src/ansys/mapdl/core/_commands/apdl/process_controls.py +++ b/src/ansys/mapdl/core/_commands/apdl/process_controls.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class ProcessControls: + +class ProcessControls(CommandsBase): def starexit(self, **kwargs): r"""Exits a do-loop. diff --git a/src/ansys/mapdl/core/_commands/aux12/general_radiation.py b/src/ansys/mapdl/core/_commands/aux12/general_radiation.py index 6c886108879..64b03ef2222 100644 --- a/src/ansys/mapdl/core/_commands/aux12/general_radiation.py +++ b/src/ansys/mapdl/core/_commands/aux12/general_radiation.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class GeneralRadiation: + +class GeneralRadiation(CommandsBase): def aux12(self, **kwargs): r"""Enters the radiation processor. diff --git a/src/ansys/mapdl/core/_commands/aux12/radiation_matrix_method.py b/src/ansys/mapdl/core/_commands/aux12/radiation_matrix_method.py index a69aa293608..7084c4ab206 100644 --- a/src/ansys/mapdl/core/_commands/aux12/radiation_matrix_method.py +++ b/src/ansys/mapdl/core/_commands/aux12/radiation_matrix_method.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class RadiationMatrixMethod: + +class RadiationMatrixMethod(CommandsBase): def emis(self, mat: str = "", evalu: str = "", **kwargs): r"""Specifies emissivity as a material property for the Radiation Matrix method. diff --git a/src/ansys/mapdl/core/_commands/aux12/radiosity_solver.py b/src/ansys/mapdl/core/_commands/aux12/radiosity_solver.py index c853b436e59..de2a60a5b6e 100644 --- a/src/ansys/mapdl/core/_commands/aux12/radiosity_solver.py +++ b/src/ansys/mapdl/core/_commands/aux12/radiosity_solver.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class RadiositySolver: + +class RadiositySolver(CommandsBase): def vfco(self, action: str = "", encl: str = "", level: int | str = "", **kwargs): r"""Controls the use and level of view factor condensation for symmetric radiation. diff --git a/src/ansys/mapdl/core/_commands/aux15/iges.py b/src/ansys/mapdl/core/_commands/aux15/iges.py index c70b28b1a54..fda711f2233 100644 --- a/src/ansys/mapdl/core/_commands/aux15/iges.py +++ b/src/ansys/mapdl/core/_commands/aux15/iges.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Iges: + +class Iges(CommandsBase): def aux15(self, **kwargs): r"""Enters the IGES file transfer processor. diff --git a/src/ansys/mapdl/core/_commands/aux2/binary_file_dump.py b/src/ansys/mapdl/core/_commands/aux2/binary_file_dump.py index 106680a4153..8f0fc278e8b 100644 --- a/src/ansys/mapdl/core/_commands/aux2/binary_file_dump.py +++ b/src/ansys/mapdl/core/_commands/aux2/binary_file_dump.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class BinaryFileDump: + +class BinaryFileDump(CommandsBase): def aux2(self, **kwargs): r"""Enters the binary file dumping processor. diff --git a/src/ansys/mapdl/core/_commands/aux2/binary_file_manipulation.py b/src/ansys/mapdl/core/_commands/aux2/binary_file_manipulation.py index cdde3964717..2291ef477a7 100644 --- a/src/ansys/mapdl/core/_commands/aux2/binary_file_manipulation.py +++ b/src/ansys/mapdl/core/_commands/aux2/binary_file_manipulation.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class BinaryFileManipulation: + +class BinaryFileManipulation(CommandsBase): def combine(self, filetype: str = "", num: str = "", **kwargs): r"""Combines distributed memory parallel ( DMP ) files. diff --git a/src/ansys/mapdl/core/_commands/aux3/results_files.py b/src/ansys/mapdl/core/_commands/aux3/results_files.py index 96fcee01e19..a5caf5f8cc6 100644 --- a/src/ansys/mapdl/core/_commands/aux3/results_files.py +++ b/src/ansys/mapdl/core/_commands/aux3/results_files.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class ResultsFiles: + +class ResultsFiles(CommandsBase): def aux3(self, **kwargs): r"""Enters the results file editing processor. diff --git a/src/ansys/mapdl/core/_commands/conn.py b/src/ansys/mapdl/core/_commands/conn.py index 9d179627f46..f31f12eafa8 100644 --- a/src/ansys/mapdl/core/_commands/conn.py +++ b/src/ansys/mapdl/core/_commands/conn.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Conn: + +class Conn(CommandsBase): def cat5in( self, name="", diff --git a/src/ansys/mapdl/core/_commands/database/components.py b/src/ansys/mapdl/core/_commands/database/components.py index 152afda7d96..ed3e1f20143 100644 --- a/src/ansys/mapdl/core/_commands/database/components.py +++ b/src/ansys/mapdl/core/_commands/database/components.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Components: + +class Components(CommandsBase): def cm(self, cname: str = "", entity: str = "", kopt: str = "", **kwargs): r"""Groups geometry items into a component. diff --git a/src/ansys/mapdl/core/_commands/database/coordinate_system.py b/src/ansys/mapdl/core/_commands/database/coordinate_system.py index 54182356969..947812ad151 100644 --- a/src/ansys/mapdl/core/_commands/database/coordinate_system.py +++ b/src/ansys/mapdl/core/_commands/database/coordinate_system.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class CoordinateSystem: + +class CoordinateSystem(CommandsBase): def clocal( self, diff --git a/src/ansys/mapdl/core/_commands/database/picking.py b/src/ansys/mapdl/core/_commands/database/picking.py index 3302d5790d9..103f6433850 100644 --- a/src/ansys/mapdl/core/_commands/database/picking.py +++ b/src/ansys/mapdl/core/_commands/database/picking.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Picking: + +class Picking(CommandsBase): def fitem( self, diff --git a/src/ansys/mapdl/core/_commands/database/selecting.py b/src/ansys/mapdl/core/_commands/database/selecting.py index 779836c9f0d..a16897bf6b7 100644 --- a/src/ansys/mapdl/core/_commands/database/selecting.py +++ b/src/ansys/mapdl/core/_commands/database/selecting.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Selecting: + +class Selecting(CommandsBase): def allsel(self, labt: str = "", entity: str = "", **kwargs): r"""Selects all entities with a single command. diff --git a/src/ansys/mapdl/core/_commands/database/set_up.py b/src/ansys/mapdl/core/_commands/database/set_up.py index 4a74d2b7ebf..904bcdea53b 100644 --- a/src/ansys/mapdl/core/_commands/database/set_up.py +++ b/src/ansys/mapdl/core/_commands/database/set_up.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SetUp: + +class SetUp(CommandsBase): def clear(self, read: str = "", **kwargs): r"""Clears the database. diff --git a/src/ansys/mapdl/core/_commands/database/working_plane.py b/src/ansys/mapdl/core/_commands/database/working_plane.py index c3add7d5ec1..5f2c2f9950e 100644 --- a/src/ansys/mapdl/core/_commands/database/working_plane.py +++ b/src/ansys/mapdl/core/_commands/database/working_plane.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class WorkingPlane: + +class WorkingPlane(CommandsBase): def kwpave( self, diff --git a/src/ansys/mapdl/core/_commands/graphics/annotation.py b/src/ansys/mapdl/core/_commands/graphics/annotation.py index 1bac42ede5a..9da6d040b76 100644 --- a/src/ansys/mapdl/core/_commands/graphics/annotation.py +++ b/src/ansys/mapdl/core/_commands/graphics/annotation.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Annotation: + +class Annotation(CommandsBase): def an3d(self, **kwargs): r"""Specifies 3D annotation functions diff --git a/src/ansys/mapdl/core/_commands/graphics/graphs.py b/src/ansys/mapdl/core/_commands/graphics/graphs.py index f6e1e89e241..3e2c1612ae0 100644 --- a/src/ansys/mapdl/core/_commands/graphics/graphs.py +++ b/src/ansys/mapdl/core/_commands/graphics/graphs.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Graphs: + +class Graphs(CommandsBase): def axlab(self, axis: str = "", lab: str = "", **kwargs): r"""Labels the X and Y axes on graph displays. diff --git a/src/ansys/mapdl/core/_commands/graphics/labeling.py b/src/ansys/mapdl/core/_commands/graphics/labeling.py index 7fe630dcf1c..c6b9d84a71e 100644 --- a/src/ansys/mapdl/core/_commands/graphics/labeling.py +++ b/src/ansys/mapdl/core/_commands/graphics/labeling.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Labeling: + +class Labeling(CommandsBase): def cformat(self, nfirst: str = "", nlast: str = "", **kwargs): r"""Controls the graphical display of alphanumeric character strings for parameters, components, diff --git a/src/ansys/mapdl/core/_commands/graphics/scaling.py b/src/ansys/mapdl/core/_commands/graphics/scaling.py index 7a8c8be4620..4872c8b6631 100644 --- a/src/ansys/mapdl/core/_commands/graphics/scaling.py +++ b/src/ansys/mapdl/core/_commands/graphics/scaling.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Scaling: + +class Scaling(CommandsBase): def iclwid(self, factor: str = "", **kwargs): r"""Scales the line width of circuit builder icons. diff --git a/src/ansys/mapdl/core/_commands/graphics/set_up.py b/src/ansys/mapdl/core/_commands/graphics/set_up.py index bf61947aa0a..983c0395c39 100644 --- a/src/ansys/mapdl/core/_commands/graphics/set_up.py +++ b/src/ansys/mapdl/core/_commands/graphics/set_up.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SetUp: + +class SetUp(CommandsBase): def cmap( self, fname: str = "", ext: str = "", kywrd: str = "", ncntr: str = "", **kwargs diff --git a/src/ansys/mapdl/core/_commands/graphics/style.py b/src/ansys/mapdl/core/_commands/graphics/style.py index 8077e2ea6c5..a0669aa79ca 100644 --- a/src/ansys/mapdl/core/_commands/graphics/style.py +++ b/src/ansys/mapdl/core/_commands/graphics/style.py @@ -22,8 +22,10 @@ import warnings +from ansys.mapdl.core._commands import CommandsBase -class Style: + +class Style(CommandsBase): def cplane(self, key: int | str = "", **kwargs): r"""Specifies the cutting plane for section and capped displays. diff --git a/src/ansys/mapdl/core/_commands/graphics/views.py b/src/ansys/mapdl/core/_commands/graphics/views.py index d89a57a7947..a65b7bfa33a 100644 --- a/src/ansys/mapdl/core/_commands/graphics/views.py +++ b/src/ansys/mapdl/core/_commands/graphics/views.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Views: + +class Views(CommandsBase): def angle( self, diff --git a/src/ansys/mapdl/core/_commands/hidden.py b/src/ansys/mapdl/core/_commands/hidden.py index 6e41315652c..41edcd1ae41 100644 --- a/src/ansys/mapdl/core/_commands/hidden.py +++ b/src/ansys/mapdl/core/_commands/hidden.py @@ -20,12 +20,14 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase + """These commands may be run by PyMAPDL, but are not supported from a user-context. """ -class _Hidden: +class _Hidden(CommandsBase): def _batch(self, lab="", **kwargs): """APDL Command: /BATCH diff --git a/src/ansys/mapdl/core/_commands/inq_func.py b/src/ansys/mapdl/core/_commands/inq_func.py index abb6ab0304b..5964dc50513 100644 --- a/src/ansys/mapdl/core/_commands/inq_func.py +++ b/src/ansys/mapdl/core/_commands/inq_func.py @@ -21,8 +21,10 @@ # SOFTWARE. """Inquire undocumented functions""" +from ansys.mapdl.core._commands import CommandsBase -class inq_function: + +class inq_function(CommandsBase): def ndinqr(self, node, key, pname="__tmpvar__", **kwargs): """Get information about a node. diff --git a/src/ansys/mapdl/core/_commands/map/pressure_mapping.py b/src/ansys/mapdl/core/_commands/map/pressure_mapping.py index ec647322972..45a772d478d 100644 --- a/src/ansys/mapdl/core/_commands/map/pressure_mapping.py +++ b/src/ansys/mapdl/core/_commands/map/pressure_mapping.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class PressureMapping: + +class PressureMapping(CommandsBase): def ftype(self, filetype: str = "", prestype: int | str = "", **kwargs): r"""Specifies the file type and pressure type for the subsequent import of source points and pressures. diff --git a/src/ansys/mapdl/core/_commands/misc/misc.py b/src/ansys/mapdl/core/_commands/misc/misc.py index 01baca7ae13..68c34e17655 100644 --- a/src/ansys/mapdl/core/_commands/misc/misc.py +++ b/src/ansys/mapdl/core/_commands/misc/misc.py @@ -20,10 +20,12 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase + """Miscellaneous methods not covered in the documentation.""" -class Misc: +class Misc(CommandsBase): def verify(self, case="", level="", **kwargs): """Enter the verification run mode. diff --git a/src/ansys/mapdl/core/_commands/post1/_fatigue.py b/src/ansys/mapdl/core/_commands/post1/_fatigue.py index 77669a54cd4..ae6cd73eacb 100644 --- a/src/ansys/mapdl/core/_commands/post1/_fatigue.py +++ b/src/ansys/mapdl/core/_commands/post1/_fatigue.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Fatigue: + +class Fatigue(CommandsBase): def fe( self, nev: str = "", cycle: str = "", fact: str = "", title: str = "", **kwargs diff --git a/src/ansys/mapdl/core/_commands/post1/_special_purpose.py b/src/ansys/mapdl/core/_commands/post1/_special_purpose.py index 00023ed4c68..0caf79862b8 100644 --- a/src/ansys/mapdl/core/_commands/post1/_special_purpose.py +++ b/src/ansys/mapdl/core/_commands/post1/_special_purpose.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SpecialPurpose: + +class SpecialPurpose(CommandsBase): def kcalc( self, diff --git a/src/ansys/mapdl/core/_commands/post1/animation.py b/src/ansys/mapdl/core/_commands/post1/animation.py index 20f72067a07..a7d81d54ffc 100644 --- a/src/ansys/mapdl/core/_commands/post1/animation.py +++ b/src/ansys/mapdl/core/_commands/post1/animation.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Animation: + +class Animation(CommandsBase): def ancntr(self, nfram: str = "", delay: str = "", ncycl: str = "", **kwargs): r"""Produces an animated sequence of a contoured deformed shape. diff --git a/src/ansys/mapdl/core/_commands/post1/controls.py b/src/ansys/mapdl/core/_commands/post1/controls.py index bb4e1c25cd8..f92ab71b9ff 100644 --- a/src/ansys/mapdl/core/_commands/post1/controls.py +++ b/src/ansys/mapdl/core/_commands/post1/controls.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Controls: + +class Controls(CommandsBase): def avprin(self, key: int | str = "", effnu: str = "", **kwargs): r"""Specifies how principal and vector sums are to be calculated. diff --git a/src/ansys/mapdl/core/_commands/post1/element_table.py b/src/ansys/mapdl/core/_commands/post1/element_table.py index 58e6b0e0ade..31735e2d9f8 100644 --- a/src/ansys/mapdl/core/_commands/post1/element_table.py +++ b/src/ansys/mapdl/core/_commands/post1/element_table.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class ElementTable: + +class ElementTable(CommandsBase): def esort( self, diff --git a/src/ansys/mapdl/core/_commands/post1/failure_criteria.py b/src/ansys/mapdl/core/_commands/post1/failure_criteria.py index 2332f44b488..dd8ab64a38a 100644 --- a/src/ansys/mapdl/core/_commands/post1/failure_criteria.py +++ b/src/ansys/mapdl/core/_commands/post1/failure_criteria.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class FailureCriteria: + +class FailureCriteria(CommandsBase): def fctyp(self, oper: str = "", lab: str = "", **kwargs): r"""Activates or removes failure-criteria types for postprocessing. diff --git a/src/ansys/mapdl/core/_commands/post1/listing.py b/src/ansys/mapdl/core/_commands/post1/listing.py index 9a40b1fe60f..69aaeaf5d95 100644 --- a/src/ansys/mapdl/core/_commands/post1/listing.py +++ b/src/ansys/mapdl/core/_commands/post1/listing.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Listing: + +class Listing(CommandsBase): def format( self, diff --git a/src/ansys/mapdl/core/_commands/post1/load_case_calculations.py b/src/ansys/mapdl/core/_commands/post1/load_case_calculations.py index 5b1f8ec9e0b..8db13a5c19a 100644 --- a/src/ansys/mapdl/core/_commands/post1/load_case_calculations.py +++ b/src/ansys/mapdl/core/_commands/post1/load_case_calculations.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class LoadCaseCalculations: + +class LoadCaseCalculations(CommandsBase): def lcabs(self, lcno: str = "", kabs: int | str = "", **kwargs): r"""Specifies absolute values for load case operations. diff --git a/src/ansys/mapdl/core/_commands/post1/magnetics_calculations.py b/src/ansys/mapdl/core/_commands/post1/magnetics_calculations.py index de95af266cc..fadfaa3507c 100644 --- a/src/ansys/mapdl/core/_commands/post1/magnetics_calculations.py +++ b/src/ansys/mapdl/core/_commands/post1/magnetics_calculations.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class MagneticsCalculations: + +class MagneticsCalculations(CommandsBase): def curr2d(self, **kwargs): r"""Calculates current flow in a 2D conductor. diff --git a/src/ansys/mapdl/core/_commands/post1/path_operations.py b/src/ansys/mapdl/core/_commands/post1/path_operations.py index b37caf4c547..3de94f3482a 100644 --- a/src/ansys/mapdl/core/_commands/post1/path_operations.py +++ b/src/ansys/mapdl/core/_commands/post1/path_operations.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class PathOperations: + +class PathOperations(CommandsBase): def fssect( self, diff --git a/src/ansys/mapdl/core/_commands/post1/results.py b/src/ansys/mapdl/core/_commands/post1/results.py index eb380b03528..e360c39d34b 100644 --- a/src/ansys/mapdl/core/_commands/post1/results.py +++ b/src/ansys/mapdl/core/_commands/post1/results.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Results: + +class Results(CommandsBase): def lcsum(self, lab: str = "", **kwargs): r"""Specifies whether to process non-summable items in load case operations. diff --git a/src/ansys/mapdl/core/_commands/post1/set_up.py b/src/ansys/mapdl/core/_commands/post1/set_up.py index 2932eb14f60..c78038b3872 100644 --- a/src/ansys/mapdl/core/_commands/post1/set_up.py +++ b/src/ansys/mapdl/core/_commands/post1/set_up.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SetUp: + +class SetUp(CommandsBase): def append( self, diff --git a/src/ansys/mapdl/core/_commands/post1/special_purpose.py b/src/ansys/mapdl/core/_commands/post1/special_purpose.py index 50100b72788..0320072a365 100644 --- a/src/ansys/mapdl/core/_commands/post1/special_purpose.py +++ b/src/ansys/mapdl/core/_commands/post1/special_purpose.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SpecialPurpose: + +class SpecialPurpose(CommandsBase): def bfint( self, diff --git a/src/ansys/mapdl/core/_commands/post1/status.py b/src/ansys/mapdl/core/_commands/post1/status.py index ed8598e1647..0e0ebabf4e3 100644 --- a/src/ansys/mapdl/core/_commands/post1/status.py +++ b/src/ansys/mapdl/core/_commands/post1/status.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Status: + +class Status(CommandsBase): def calc(self, **kwargs): r"""Specifies "Calculation settings" as the subsequent status topic. diff --git a/src/ansys/mapdl/core/_commands/post1/surface_operations.py b/src/ansys/mapdl/core/_commands/post1/surface_operations.py index ef33b997f41..399fd4bd093 100644 --- a/src/ansys/mapdl/core/_commands/post1/surface_operations.py +++ b/src/ansys/mapdl/core/_commands/post1/surface_operations.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SurfaceOperations: + +class SurfaceOperations(CommandsBase): def sucalc( self, diff --git a/src/ansys/mapdl/core/_commands/post1/trace_points.py b/src/ansys/mapdl/core/_commands/post1/trace_points.py index fa928d14378..73a8236ca6f 100644 --- a/src/ansys/mapdl/core/_commands/post1/trace_points.py +++ b/src/ansys/mapdl/core/_commands/post1/trace_points.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class TracePoints: + +class TracePoints(CommandsBase): def pltrac( self, diff --git a/src/ansys/mapdl/core/_commands/post26/_set_up.py b/src/ansys/mapdl/core/_commands/post26/_set_up.py index 049fef8a540..527beecbe65 100644 --- a/src/ansys/mapdl/core/_commands/post26/_set_up.py +++ b/src/ansys/mapdl/core/_commands/post26/_set_up.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SetUp: + +class SetUp(CommandsBase): def gapf(self, nvar: str = "", num: str = "", name: str = "", **kwargs): r"""Defines the gap force data to be stored in a variable. diff --git a/src/ansys/mapdl/core/_commands/post26/controls.py b/src/ansys/mapdl/core/_commands/post26/controls.py index 633aedc26fc..81c495b42eb 100644 --- a/src/ansys/mapdl/core/_commands/post26/controls.py +++ b/src/ansys/mapdl/core/_commands/post26/controls.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Controls: + +class Controls(CommandsBase): def cfact( self, diff --git a/src/ansys/mapdl/core/_commands/post26/display.py b/src/ansys/mapdl/core/_commands/post26/display.py index 2e722c24d7a..ee245978d4c 100644 --- a/src/ansys/mapdl/core/_commands/post26/display.py +++ b/src/ansys/mapdl/core/_commands/post26/display.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Display: + +class Display(CommandsBase): def keep(self, key: str = "", **kwargs): r"""Stores POST26 definitions and data during active session. diff --git a/src/ansys/mapdl/core/_commands/post26/listing.py b/src/ansys/mapdl/core/_commands/post26/listing.py index f52961ca80c..25589230c11 100644 --- a/src/ansys/mapdl/core/_commands/post26/listing.py +++ b/src/ansys/mapdl/core/_commands/post26/listing.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Listing: + +class Listing(CommandsBase): def extrem(self, nvar1: str = "", nvar2: str = "", ninc: str = "", **kwargs): r"""Lists the extreme values for variables. diff --git a/src/ansys/mapdl/core/_commands/post26/operations.py b/src/ansys/mapdl/core/_commands/post26/operations.py index 099e9ad1241..7090fb22e9a 100644 --- a/src/ansys/mapdl/core/_commands/post26/operations.py +++ b/src/ansys/mapdl/core/_commands/post26/operations.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Operations: + +class Operations(CommandsBase): def abs( self, ir: str = "", ia: str = "", name: str = "", facta: str = "", **kwargs diff --git a/src/ansys/mapdl/core/_commands/post26/set_up.py b/src/ansys/mapdl/core/_commands/post26/set_up.py index d5fd9cc9d88..b1493243bac 100644 --- a/src/ansys/mapdl/core/_commands/post26/set_up.py +++ b/src/ansys/mapdl/core/_commands/post26/set_up.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SetUp: + +class SetUp(CommandsBase): def ansol( self, diff --git a/src/ansys/mapdl/core/_commands/post26/special_purpose.py b/src/ansys/mapdl/core/_commands/post26/special_purpose.py index 2bd60d3f1cc..3a94ccc26d1 100644 --- a/src/ansys/mapdl/core/_commands/post26/special_purpose.py +++ b/src/ansys/mapdl/core/_commands/post26/special_purpose.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SpecialPurpose: + +class SpecialPurpose(CommandsBase): def cvar( self, diff --git a/src/ansys/mapdl/core/_commands/post26/status.py b/src/ansys/mapdl/core/_commands/post26/status.py index ac5383a480f..c7dc52165f5 100644 --- a/src/ansys/mapdl/core/_commands/post26/status.py +++ b/src/ansys/mapdl/core/_commands/post26/status.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Status: + +class Status(CommandsBase): def operate(self, **kwargs): r"""Specifies "Operation data" as the subsequent status topic. diff --git a/src/ansys/mapdl/core/_commands/preproc/areas.py b/src/ansys/mapdl/core/_commands/preproc/areas.py index b126136fc81..060a9fdad59 100644 --- a/src/ansys/mapdl/core/_commands/preproc/areas.py +++ b/src/ansys/mapdl/core/_commands/preproc/areas.py @@ -20,10 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from ansys.mapdl.core._commands import parse +from ansys.mapdl.core._commands import CommandsBase, parse -class Areas: +class Areas(CommandsBase): def a( self, p1="", diff --git a/src/ansys/mapdl/core/_commands/preproc/artificially_matched_layers.py b/src/ansys/mapdl/core/_commands/preproc/artificially_matched_layers.py index af1fee0f825..4e32bfca438 100644 --- a/src/ansys/mapdl/core/_commands/preproc/artificially_matched_layers.py +++ b/src/ansys/mapdl/core/_commands/preproc/artificially_matched_layers.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class ArtificiallyMatchedLayers: + +class ArtificiallyMatchedLayers(CommandsBase): def pmlopt( self, esys="", diff --git a/src/ansys/mapdl/core/_commands/preproc/booleans.py b/src/ansys/mapdl/core/_commands/preproc/booleans.py index d15cea4f964..c1048d4baa0 100644 --- a/src/ansys/mapdl/core/_commands/preproc/booleans.py +++ b/src/ansys/mapdl/core/_commands/preproc/booleans.py @@ -20,10 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from ansys.mapdl.core._commands import parse +from ansys.mapdl.core._commands import CommandsBase, parse -class Booleans: +class Booleans(CommandsBase): def aadd( self, na1="", diff --git a/src/ansys/mapdl/core/_commands/preproc/constraint_equations.py b/src/ansys/mapdl/core/_commands/preproc/constraint_equations.py index cccd16e21c7..5ccbba95d94 100644 --- a/src/ansys/mapdl/core/_commands/preproc/constraint_equations.py +++ b/src/ansys/mapdl/core/_commands/preproc/constraint_equations.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class ConstraintEquations: + +class ConstraintEquations(CommandsBase): def ce( self, neqn="", diff --git a/src/ansys/mapdl/core/_commands/preproc/coupled_dof.py b/src/ansys/mapdl/core/_commands/preproc/coupled_dof.py index 4a3f8150d61..b1cb85de15d 100644 --- a/src/ansys/mapdl/core/_commands/preproc/coupled_dof.py +++ b/src/ansys/mapdl/core/_commands/preproc/coupled_dof.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class CoupledDOF: + +class CoupledDOF(CommandsBase): def cp( self, nset="", diff --git a/src/ansys/mapdl/core/_commands/preproc/database.py b/src/ansys/mapdl/core/_commands/preproc/database.py index 84445dd4c60..c37883f0034 100644 --- a/src/ansys/mapdl/core/_commands/preproc/database.py +++ b/src/ansys/mapdl/core/_commands/preproc/database.py @@ -25,8 +25,10 @@ database. """ +from ansys.mapdl.core._commands import CommandsBase -class Database: + +class Database(CommandsBase): def aflist(self, **kwargs): """Lists the current data in the database. diff --git a/src/ansys/mapdl/core/_commands/preproc/digitizing.py b/src/ansys/mapdl/core/_commands/preproc/digitizing.py index 822cea44505..8193c4c5130 100644 --- a/src/ansys/mapdl/core/_commands/preproc/digitizing.py +++ b/src/ansys/mapdl/core/_commands/preproc/digitizing.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Digitizing: + +class Digitizing(CommandsBase): def dig(self, node1="", node2="", ninc="", **kwargs): """Digitizes nodes to a surface. diff --git a/src/ansys/mapdl/core/_commands/preproc/element_type.py b/src/ansys/mapdl/core/_commands/preproc/element_type.py index 0bab7846063..06743c7e455 100644 --- a/src/ansys/mapdl/core/_commands/preproc/element_type.py +++ b/src/ansys/mapdl/core/_commands/preproc/element_type.py @@ -24,11 +24,11 @@ """ from typing import Optional, Union -from ansys.mapdl.core._commands import parse +from ansys.mapdl.core._commands import CommandsBase, parse from ansys.mapdl.core.mapdl_types import MapdlInt -class ElementType: +class ElementType(CommandsBase): def dof( self, lab1="", diff --git a/src/ansys/mapdl/core/_commands/preproc/elements.py b/src/ansys/mapdl/core/_commands/preproc/elements.py index 56927e8f9ab..f0f8939d846 100644 --- a/src/ansys/mapdl/core/_commands/preproc/elements.py +++ b/src/ansys/mapdl/core/_commands/preproc/elements.py @@ -22,11 +22,11 @@ from typing import Optional, Union -from ansys.mapdl.core._commands import parse +from ansys.mapdl.core._commands import CommandsBase, parse from ansys.mapdl.core.mapdl_types import MapdlFloat, MapdlInt -class Elements: +class Elements(CommandsBase): def afsurf(self, sarea="", tline="", **kwargs): """Generates surface elements overlaid on the surface of existing solid elements. diff --git a/src/ansys/mapdl/core/_commands/preproc/explicit_dynamics.py b/src/ansys/mapdl/core/_commands/preproc/explicit_dynamics.py index 901962d3a3b..db44a9ef3da 100644 --- a/src/ansys/mapdl/core/_commands/preproc/explicit_dynamics.py +++ b/src/ansys/mapdl/core/_commands/preproc/explicit_dynamics.py @@ -22,10 +22,11 @@ from typing import Optional +from ansys.mapdl.core._commands import CommandsBase from ansys.mapdl.core.mapdl_types import MapdlFloat, MapdlInt -class ExplicitDynamics: +class ExplicitDynamics(CommandsBase): def edasmp( self, option="", diff --git a/src/ansys/mapdl/core/_commands/preproc/hard_points.py b/src/ansys/mapdl/core/_commands/preproc/hard_points.py index c5877aca89e..b194d4083bc 100644 --- a/src/ansys/mapdl/core/_commands/preproc/hard_points.py +++ b/src/ansys/mapdl/core/_commands/preproc/hard_points.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class HardPoints: + +class HardPoints(CommandsBase): def hptcreate( self, type_="", diff --git a/src/ansys/mapdl/core/_commands/preproc/keypoints.py b/src/ansys/mapdl/core/_commands/preproc/keypoints.py index d9c8926d4c4..98872825a9c 100644 --- a/src/ansys/mapdl/core/_commands/preproc/keypoints.py +++ b/src/ansys/mapdl/core/_commands/preproc/keypoints.py @@ -20,10 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from ansys.mapdl.core._commands import parse +from ansys.mapdl.core._commands import CommandsBase, parse -class KeyPoints: +class KeyPoints(CommandsBase): def k(self, npt="", x="", y="", z="", **kwargs) -> int: """Define a keypoint. diff --git a/src/ansys/mapdl/core/_commands/preproc/lines.py b/src/ansys/mapdl/core/_commands/preproc/lines.py index a0a85facd26..b646d1cee1c 100644 --- a/src/ansys/mapdl/core/_commands/preproc/lines.py +++ b/src/ansys/mapdl/core/_commands/preproc/lines.py @@ -20,10 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from ansys.mapdl.core._commands import parse +from ansys.mapdl.core._commands import CommandsBase, parse -class Lines: +class Lines(CommandsBase): def bsplin( self, p1="", diff --git a/src/ansys/mapdl/core/_commands/preproc/material_data_tables.py b/src/ansys/mapdl/core/_commands/preproc/material_data_tables.py index 15eef221592..9259f037e9a 100644 --- a/src/ansys/mapdl/core/_commands/preproc/material_data_tables.py +++ b/src/ansys/mapdl/core/_commands/preproc/material_data_tables.py @@ -20,13 +20,15 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase + """ These PREP7 commands create and modify the material data tables (that is, to specify and define material models). """ -class MaterialDataTables: +class MaterialDataTables(CommandsBase): def tb( self, lab="", diff --git a/src/ansys/mapdl/core/_commands/preproc/materials.py b/src/ansys/mapdl/core/_commands/preproc/materials.py index 942b44407e4..650a222c189 100644 --- a/src/ansys/mapdl/core/_commands/preproc/materials.py +++ b/src/ansys/mapdl/core/_commands/preproc/materials.py @@ -20,12 +20,14 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase + """ These PREP7 commands are used to define the linear material properties. """ -class Materials: +class Materials(CommandsBase): def emunit(self, lab="", value="", **kwargs): """APDL Command: EMUNIT diff --git a/src/ansys/mapdl/core/_commands/preproc/meshing.py b/src/ansys/mapdl/core/_commands/preproc/meshing.py index 01fe838e09d..b65793164d2 100644 --- a/src/ansys/mapdl/core/_commands/preproc/meshing.py +++ b/src/ansys/mapdl/core/_commands/preproc/meshing.py @@ -22,10 +22,11 @@ from typing import Optional, Union +from ansys.mapdl.core._commands import CommandsBase from ansys.mapdl.core.mapdl_types import MapdlFloat, MapdlInt -class Meshing: +class Meshing(CommandsBase): def accat(self, na1="", na2="", **kwargs): """Concatenates multiple areas in preparation for mapped meshing. diff --git a/src/ansys/mapdl/core/_commands/preproc/morphing.py b/src/ansys/mapdl/core/_commands/preproc/morphing.py index 895174a398b..2f1266b2016 100644 --- a/src/ansys/mapdl/core/_commands/preproc/morphing.py +++ b/src/ansys/mapdl/core/_commands/preproc/morphing.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Morphing: + +class Morphing(CommandsBase): def morph( self, option="", diff --git a/src/ansys/mapdl/core/_commands/preproc/nodes.py b/src/ansys/mapdl/core/_commands/preproc/nodes.py index c9ff5ff5336..3bb017a4ede 100644 --- a/src/ansys/mapdl/core/_commands/preproc/nodes.py +++ b/src/ansys/mapdl/core/_commands/preproc/nodes.py @@ -20,10 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from ansys.mapdl.core._commands import parse +from ansys.mapdl.core._commands import CommandsBase, parse -class Nodes: +class Nodes(CommandsBase): def center(self, node="", node1="", node2="", node3="", radius="", **kwargs): """Defines a node at the center of curvature of 2 or 3 nodes. diff --git a/src/ansys/mapdl/core/_commands/preproc/primitives.py b/src/ansys/mapdl/core/_commands/preproc/primitives.py index c2ea4a83519..a164298f66f 100644 --- a/src/ansys/mapdl/core/_commands/preproc/primitives.py +++ b/src/ansys/mapdl/core/_commands/preproc/primitives.py @@ -20,10 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from ansys.mapdl.core._commands import parse +from ansys.mapdl.core._commands import CommandsBase, parse -class Primitives: +class Primitives(CommandsBase): def blc4( self, xcorner="", ycorner="", width="", height="", depth="", **kwargs ) -> int: diff --git a/src/ansys/mapdl/core/_commands/preproc/real_constants.py b/src/ansys/mapdl/core/_commands/preproc/real_constants.py index 35a0b6bff9a..438e2d65846 100644 --- a/src/ansys/mapdl/core/_commands/preproc/real_constants.py +++ b/src/ansys/mapdl/core/_commands/preproc/real_constants.py @@ -20,12 +20,14 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase + """ These PREP7 commands define the model real constants. """ -class RealConstants: +class RealConstants(CommandsBase): def r(self, nset="", r1="", r2="", r3="", r4="", r5="", r6="", **kwargs): """APDL Command: R diff --git a/src/ansys/mapdl/core/_commands/preproc/sections.py b/src/ansys/mapdl/core/_commands/preproc/sections.py index a5ca7c7b695..3e551967ab0 100644 --- a/src/ansys/mapdl/core/_commands/preproc/sections.py +++ b/src/ansys/mapdl/core/_commands/preproc/sections.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Sections: + +class Sections(CommandsBase): def bsax(self, val1="", val2="", t="", **kwargs): """Specifies the axial strain and axial force relationship for beam diff --git a/src/ansys/mapdl/core/_commands/preproc/special_purpose.py b/src/ansys/mapdl/core/_commands/preproc/special_purpose.py index 18bf3da44c8..5afe6b7f75e 100644 --- a/src/ansys/mapdl/core/_commands/preproc/special_purpose.py +++ b/src/ansys/mapdl/core/_commands/preproc/special_purpose.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SpecialPurpose: + +class SpecialPurpose(CommandsBase): def aerocoeff( self, aeromodetype="", diff --git a/src/ansys/mapdl/core/_commands/preproc/status.py b/src/ansys/mapdl/core/_commands/preproc/status.py index 010139d8f3f..c425c19d51e 100644 --- a/src/ansys/mapdl/core/_commands/preproc/status.py +++ b/src/ansys/mapdl/core/_commands/preproc/status.py @@ -22,8 +22,10 @@ from typing import Optional +from ansys.mapdl.core._commands import CommandsBase -class Status: + +class Status(CommandsBase): def areas(self, **kwargs): """Specifies "Areas" as the subsequent status topic. diff --git a/src/ansys/mapdl/core/_commands/preproc/superelements.py b/src/ansys/mapdl/core/_commands/preproc/superelements.py index 9a329e729d9..34600a9b8f2 100644 --- a/src/ansys/mapdl/core/_commands/preproc/superelements.py +++ b/src/ansys/mapdl/core/_commands/preproc/superelements.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Superelements: + +class Superelements(CommandsBase): def se(self, file="", toler="", **kwargs): """Defines a superelement. diff --git a/src/ansys/mapdl/core/_commands/preproc/volumes.py b/src/ansys/mapdl/core/_commands/preproc/volumes.py index fadf81ce7c3..f75fc84bc7c 100644 --- a/src/ansys/mapdl/core/_commands/preproc/volumes.py +++ b/src/ansys/mapdl/core/_commands/preproc/volumes.py @@ -22,11 +22,11 @@ from typing import Optional, Union -from ansys.mapdl.core._commands import parse +from ansys.mapdl.core._commands import CommandsBase, parse from ansys.mapdl.core.mapdl_types import MapdlInt -class Volumes: +class Volumes(CommandsBase): def extopt( self, lab: str = "", diff --git a/src/ansys/mapdl/core/_commands/session/files.py b/src/ansys/mapdl/core/_commands/session/files.py index a3bbe02fa7f..847f9c1a76c 100644 --- a/src/ansys/mapdl/core/_commands/session/files.py +++ b/src/ansys/mapdl/core/_commands/session/files.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Files: + +class Files(CommandsBase): def anstoaqwa( self, diff --git a/src/ansys/mapdl/core/_commands/session/list_controls.py b/src/ansys/mapdl/core/_commands/session/list_controls.py index 4771121a0f9..9a4cae4398e 100644 --- a/src/ansys/mapdl/core/_commands/session/list_controls.py +++ b/src/ansys/mapdl/core/_commands/session/list_controls.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class ListControls: + +class ListControls(CommandsBase): def com(self, comment: str = "", **kwargs): r"""Places a comment in the output. diff --git a/src/ansys/mapdl/core/_commands/session/processor_entry.py b/src/ansys/mapdl/core/_commands/session/processor_entry.py index 7614c6b2e18..18d0f7beaaa 100644 --- a/src/ansys/mapdl/core/_commands/session/processor_entry.py +++ b/src/ansys/mapdl/core/_commands/session/processor_entry.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class ProcessorEntry: + +class ProcessorEntry(CommandsBase): def finish(self, **kwargs): r"""Exits normally from a processor. diff --git a/src/ansys/mapdl/core/_commands/session/run_controls.py b/src/ansys/mapdl/core/_commands/session/run_controls.py index 80704880b54..d8794ae0698 100644 --- a/src/ansys/mapdl/core/_commands/session/run_controls.py +++ b/src/ansys/mapdl/core/_commands/session/run_controls.py @@ -20,10 +20,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase from ansys.mapdl.core.errors import MapdlRuntimeError -class RunControls: +class RunControls(CommandsBase): def config(self, lab: str = "", val: str = "", **kwargs): r"""Assigns values to Mechanical APDL configuration parameters. diff --git a/src/ansys/mapdl/core/_commands/solution/analysis_options.py b/src/ansys/mapdl/core/_commands/solution/analysis_options.py index cf17f3c3235..3544ad58076 100644 --- a/src/ansys/mapdl/core/_commands/solution/analysis_options.py +++ b/src/ansys/mapdl/core/_commands/solution/analysis_options.py @@ -22,10 +22,11 @@ from typing import Optional +from ansys.mapdl.core._commands import CommandsBase from ansys.mapdl.core.mapdl_types import MapdlInt -class AnalysisOptions: +class AnalysisOptions(CommandsBase): def abextract(self, mode1="", mode2="", **kwargs): """Extracts the alpha-beta damping multipliers for Rayleigh damping. diff --git a/src/ansys/mapdl/core/_commands/solution/birth_and_death.py b/src/ansys/mapdl/core/_commands/solution/birth_and_death.py index 8f541e853d7..da203c659d7 100644 --- a/src/ansys/mapdl/core/_commands/solution/birth_and_death.py +++ b/src/ansys/mapdl/core/_commands/solution/birth_and_death.py @@ -22,10 +22,11 @@ from typing import Optional, Union +from ansys.mapdl.core._commands import CommandsBase from ansys.mapdl.core.mapdl_types import MapdlFloat -class BirthAndDeath: +class BirthAndDeath(CommandsBase): def ealive(self, elem: str = "", **kwargs) -> Optional[str]: """Reactivates an element (for the birth and death capability). diff --git a/src/ansys/mapdl/core/_commands/solution/dynamic_options.py b/src/ansys/mapdl/core/_commands/solution/dynamic_options.py index 9e12aa400aa..44c2b31ef23 100644 --- a/src/ansys/mapdl/core/_commands/solution/dynamic_options.py +++ b/src/ansys/mapdl/core/_commands/solution/dynamic_options.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class DynamicOptions: + +class DynamicOptions(CommandsBase): def alphad(self, value="", **kwargs): """Defines the mass matrix multiplier for damping. diff --git a/src/ansys/mapdl/core/_commands/solution/fe_body_loads.py b/src/ansys/mapdl/core/_commands/solution/fe_body_loads.py index a5db23013f2..28b5dfe4bc4 100644 --- a/src/ansys/mapdl/core/_commands/solution/fe_body_loads.py +++ b/src/ansys/mapdl/core/_commands/solution/fe_body_loads.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class FeBodyLoads: + +class FeBodyLoads(CommandsBase): def bf( self, node="", diff --git a/src/ansys/mapdl/core/_commands/solution/fe_constraints.py b/src/ansys/mapdl/core/_commands/solution/fe_constraints.py index 03c3a1fc414..c3044bf45a8 100644 --- a/src/ansys/mapdl/core/_commands/solution/fe_constraints.py +++ b/src/ansys/mapdl/core/_commands/solution/fe_constraints.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class FeConstraints: + +class FeConstraints(CommandsBase): def d( self, node="", diff --git a/src/ansys/mapdl/core/_commands/solution/fe_forces.py b/src/ansys/mapdl/core/_commands/solution/fe_forces.py index 1ed9f362b2d..20eeaadaeda 100644 --- a/src/ansys/mapdl/core/_commands/solution/fe_forces.py +++ b/src/ansys/mapdl/core/_commands/solution/fe_forces.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class FeForces: + +class FeForces(CommandsBase): def f(self, node="", lab="", value="", value2="", nend="", ninc="", **kwargs): """Specifies force loads at nodes. diff --git a/src/ansys/mapdl/core/_commands/solution/fe_surface_loads.py b/src/ansys/mapdl/core/_commands/solution/fe_surface_loads.py index 97be8b4776a..ac33702890d 100644 --- a/src/ansys/mapdl/core/_commands/solution/fe_surface_loads.py +++ b/src/ansys/mapdl/core/_commands/solution/fe_surface_loads.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class FeSurfaceLoads: + +class FeSurfaceLoads(CommandsBase): def sf(self, nlist="", lab="", value="", value2="", **kwargs): """Specifies surface loads on nodes. diff --git a/src/ansys/mapdl/core/_commands/solution/gap_conditions.py b/src/ansys/mapdl/core/_commands/solution/gap_conditions.py index 0cfe0a5bb34..0c27e8f5965 100644 --- a/src/ansys/mapdl/core/_commands/solution/gap_conditions.py +++ b/src/ansys/mapdl/core/_commands/solution/gap_conditions.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class GapConditions: + +class GapConditions(CommandsBase): def gp(self, node1="", node2="", lab="", stif="", gap="", damp="", **kwargs): """Defines a gap condition for transient analyses. diff --git a/src/ansys/mapdl/core/_commands/solution/inertia.py b/src/ansys/mapdl/core/_commands/solution/inertia.py index f79e72af263..69569cf1935 100644 --- a/src/ansys/mapdl/core/_commands/solution/inertia.py +++ b/src/ansys/mapdl/core/_commands/solution/inertia.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Inertia: + +class Inertia(CommandsBase): def acel(self, acel_x="", acel_y="", acel_z="", **kwargs): """Specifies the linear acceleration of the global Cartesian reference diff --git a/src/ansys/mapdl/core/_commands/solution/load_step_operations.py b/src/ansys/mapdl/core/_commands/solution/load_step_operations.py index c3420f611c1..f82e87b1b62 100644 --- a/src/ansys/mapdl/core/_commands/solution/load_step_operations.py +++ b/src/ansys/mapdl/core/_commands/solution/load_step_operations.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class LoadStepOperations: + +class LoadStepOperations(CommandsBase): def lsclear(self, lab="", **kwargs): """Clears loads and load step options from the database. diff --git a/src/ansys/mapdl/core/_commands/solution/load_step_options.py b/src/ansys/mapdl/core/_commands/solution/load_step_options.py index 0f12b9aefed..b45695aa1a9 100644 --- a/src/ansys/mapdl/core/_commands/solution/load_step_options.py +++ b/src/ansys/mapdl/core/_commands/solution/load_step_options.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class LoadStepOptions: + +class LoadStepOptions(CommandsBase): def autots(self, key="", **kwargs): """Specifies whether to use automatic time stepping or load stepping. diff --git a/src/ansys/mapdl/core/_commands/solution/master_dof.py b/src/ansys/mapdl/core/_commands/solution/master_dof.py index 451bad85394..736a7c447c1 100644 --- a/src/ansys/mapdl/core/_commands/solution/master_dof.py +++ b/src/ansys/mapdl/core/_commands/solution/master_dof.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class MasterDOF: + +class MasterDOF(CommandsBase): def m( self, node="", diff --git a/src/ansys/mapdl/core/_commands/solution/miscellaneous_loads.py b/src/ansys/mapdl/core/_commands/solution/miscellaneous_loads.py index 54552319ac4..3fa86cdd62c 100644 --- a/src/ansys/mapdl/core/_commands/solution/miscellaneous_loads.py +++ b/src/ansys/mapdl/core/_commands/solution/miscellaneous_loads.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class MiscellaneousLoads: + +class MiscellaneousLoads(CommandsBase): def anpres(self, nfram="", delay="", ncycl="", refframe="", **kwargs): """Produces an animated sequence of the time-harmonic pressure variation diff --git a/src/ansys/mapdl/core/_commands/solution/multi_field_solver_convergence_controls.py b/src/ansys/mapdl/core/_commands/solution/multi_field_solver_convergence_controls.py index 263c209d936..ac8fc235902 100644 --- a/src/ansys/mapdl/core/_commands/solution/multi_field_solver_convergence_controls.py +++ b/src/ansys/mapdl/core/_commands/solution/multi_field_solver_convergence_controls.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class MultiFieldConvergenceControls: + +class MultiFieldConvergenceControls(CommandsBase): def mfconv(self, lab="", toler="", minref="", **kwargs): """Sets convergence values for an ANSYS Multi-field solver analysis. diff --git a/src/ansys/mapdl/core/_commands/solution/multi_field_solver_definition_commands.py b/src/ansys/mapdl/core/_commands/solution/multi_field_solver_definition_commands.py index 7c984d82a7a..503663b9ba1 100644 --- a/src/ansys/mapdl/core/_commands/solution/multi_field_solver_definition_commands.py +++ b/src/ansys/mapdl/core/_commands/solution/multi_field_solver_definition_commands.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class MultiFieldSolverDefinitionCommands: + +class MultiFieldSolverDefinitionCommands(CommandsBase): def mfcmmand(self, fnumb="", fname="", ext="", **kwargs): """Captures field solution options in a command file. diff --git a/src/ansys/mapdl/core/_commands/solution/multi_field_solver_global_controls.py b/src/ansys/mapdl/core/_commands/solution/multi_field_solver_global_controls.py index 23f2c06f0e2..221e949c44c 100644 --- a/src/ansys/mapdl/core/_commands/solution/multi_field_solver_global_controls.py +++ b/src/ansys/mapdl/core/_commands/solution/multi_field_solver_global_controls.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class MultiFieldSolverGlobalControls: + +class MultiFieldSolverGlobalControls(CommandsBase): def mfanalysis(self, key="", **kwargs): """Activates or deactivates an ANSYS Multi-field solver analysis. diff --git a/src/ansys/mapdl/core/_commands/solution/multi_field_solver_interface_mapping.py b/src/ansys/mapdl/core/_commands/solution/multi_field_solver_interface_mapping.py index 3b13664bb13..f6f2c1a8b7e 100644 --- a/src/ansys/mapdl/core/_commands/solution/multi_field_solver_interface_mapping.py +++ b/src/ansys/mapdl/core/_commands/solution/multi_field_solver_interface_mapping.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class MultiFieldSolverInterfaceMapping: + +class MultiFieldSolverInterfaceMapping(CommandsBase): def mfbucket(self, key="", value="", **kwargs): """Turns a bucket search on or off. diff --git a/src/ansys/mapdl/core/_commands/solution/multi_field_solver_load_transfer.py b/src/ansys/mapdl/core/_commands/solution/multi_field_solver_load_transfer.py index 3f9ce0dc3b4..8b9f1eaae24 100644 --- a/src/ansys/mapdl/core/_commands/solution/multi_field_solver_load_transfer.py +++ b/src/ansys/mapdl/core/_commands/solution/multi_field_solver_load_transfer.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class MultiFieldSolverLoadTransfer: + +class MultiFieldSolverLoadTransfer(CommandsBase): def mflcomm( self, type_="", diff --git a/src/ansys/mapdl/core/_commands/solution/multi_field_solver_time_controls.py b/src/ansys/mapdl/core/_commands/solution/multi_field_solver_time_controls.py index a97645aa2c1..2283ff4a5de 100644 --- a/src/ansys/mapdl/core/_commands/solution/multi_field_solver_time_controls.py +++ b/src/ansys/mapdl/core/_commands/solution/multi_field_solver_time_controls.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class MultiFieldSolverTimeControls: + +class MultiFieldSolverTimeControls(CommandsBase): def mfcalc(self, fnumb="", freq="", **kwargs): """Specifies a calculation frequency for a field in an ANSYS Multi-field diff --git a/src/ansys/mapdl/core/_commands/solution/nonlinear_options.py b/src/ansys/mapdl/core/_commands/solution/nonlinear_options.py index d990be3a8f8..ac1bc0fc630 100644 --- a/src/ansys/mapdl/core/_commands/solution/nonlinear_options.py +++ b/src/ansys/mapdl/core/_commands/solution/nonlinear_options.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class NonLinearOptions: + +class NonLinearOptions(CommandsBase): def arclen(self, key="", maxarc="", minarc="", **kwargs): """Activates the arc-length method. diff --git a/src/ansys/mapdl/core/_commands/solution/ocean.py b/src/ansys/mapdl/core/_commands/solution/ocean.py index ac609817c96..2f1e83ce583 100644 --- a/src/ansys/mapdl/core/_commands/solution/ocean.py +++ b/src/ansys/mapdl/core/_commands/solution/ocean.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Ocean: + +class Ocean(CommandsBase): def ocdata( self, val1: str = "", diff --git a/src/ansys/mapdl/core/_commands/solution/radiosity.py b/src/ansys/mapdl/core/_commands/solution/radiosity.py index 8bab8c3e4be..aa488647848 100644 --- a/src/ansys/mapdl/core/_commands/solution/radiosity.py +++ b/src/ansys/mapdl/core/_commands/solution/radiosity.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Radiosity: + +class Radiosity(CommandsBase): def rdec(self, option="", reduc="", nplace="", **kwargs): """Defines the decimation parameters. diff --git a/src/ansys/mapdl/core/_commands/solution/rezoning.py b/src/ansys/mapdl/core/_commands/solution/rezoning.py index d47d47db9a2..f89f887f3e4 100644 --- a/src/ansys/mapdl/core/_commands/solution/rezoning.py +++ b/src/ansys/mapdl/core/_commands/solution/rezoning.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class Rezoning: + +class Rezoning(CommandsBase): def rezone(self, option="", ldstep="", sbstep="", **kwargs): """Initiates the rezoning process, sets rezoning options, and rebuilds the diff --git a/src/ansys/mapdl/core/_commands/solution/solid_body_loads.py b/src/ansys/mapdl/core/_commands/solution/solid_body_loads.py index 53e690e6ddb..e6093dfdfa2 100644 --- a/src/ansys/mapdl/core/_commands/solution/solid_body_loads.py +++ b/src/ansys/mapdl/core/_commands/solution/solid_body_loads.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SolidBodyLoads: + +class SolidBodyLoads(CommandsBase): def bfa(self, area="", lab="", val1="", val2="", val3="", val4="", **kwargs): """Defines a body force load on an area. diff --git a/src/ansys/mapdl/core/_commands/solution/solid_constraints.py b/src/ansys/mapdl/core/_commands/solution/solid_constraints.py index 19300657ce2..4298195d0ff 100644 --- a/src/ansys/mapdl/core/_commands/solution/solid_constraints.py +++ b/src/ansys/mapdl/core/_commands/solution/solid_constraints.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SolidConstraints: + +class SolidConstraints(CommandsBase): def da(self, area="", lab="", value1="", value2="", **kwargs): """Defines degree-of-freedom constraints on areas. diff --git a/src/ansys/mapdl/core/_commands/solution/solid_forces.py b/src/ansys/mapdl/core/_commands/solution/solid_forces.py index 4ed81c47bd3..43e7ca416c2 100644 --- a/src/ansys/mapdl/core/_commands/solution/solid_forces.py +++ b/src/ansys/mapdl/core/_commands/solution/solid_forces.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SolidForces: + +class SolidForces(CommandsBase): def fk(self, kpoi="", lab="", value="", value2="", **kwargs): """Defines force loads at keypoints. diff --git a/src/ansys/mapdl/core/_commands/solution/solid_surface_loads.py b/src/ansys/mapdl/core/_commands/solution/solid_surface_loads.py index 02ed56ce75b..1586eb0456d 100644 --- a/src/ansys/mapdl/core/_commands/solution/solid_surface_loads.py +++ b/src/ansys/mapdl/core/_commands/solution/solid_surface_loads.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SolidSurfaceLoads: + +class SolidSurfaceLoads(CommandsBase): def sfa(self, area="", lkey="", lab="", value="", value2="", **kwargs): """Specifies surface loads on the selected areas. diff --git a/src/ansys/mapdl/core/_commands/solution/solution_status.py b/src/ansys/mapdl/core/_commands/solution/solution_status.py index 9dc68213b48..ab21042f5bb 100644 --- a/src/ansys/mapdl/core/_commands/solution/solution_status.py +++ b/src/ansys/mapdl/core/_commands/solution/solution_status.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SolutionStatus: + +class SolutionStatus(CommandsBase): def atype(self, **kwargs): """Specifies "Analysis types" as the subsequent status topic. diff --git a/src/ansys/mapdl/core/_commands/solution/spectrum_options.py b/src/ansys/mapdl/core/_commands/solution/spectrum_options.py index 596a441774b..2961b85f25b 100644 --- a/src/ansys/mapdl/core/_commands/solution/spectrum_options.py +++ b/src/ansys/mapdl/core/_commands/solution/spectrum_options.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class SpectrumOptions: + +class SpectrumOptions(CommandsBase): def addam(self, af="", aa="", ab="", ac="", ad="", amin="", **kwargs): """Specifies the acceleration spectrum computation constants for the diff --git a/src/ansys/mapdl/core/_commands/solution/twod_to_3d_analysis.py b/src/ansys/mapdl/core/_commands/solution/twod_to_3d_analysis.py index e354bff5314..5fe6d4caeac 100644 --- a/src/ansys/mapdl/core/_commands/solution/twod_to_3d_analysis.py +++ b/src/ansys/mapdl/core/_commands/solution/twod_to_3d_analysis.py @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from ansys.mapdl.core._commands import CommandsBase -class TwoDTo3DAnalysis: + +class TwoDTo3DAnalysis(CommandsBase): def map2dto3d(self, action="", ldstep="", sbstep="", option="", **kwargs): """Initiates a 2-D to 3-D analysis and maps variables. From c7d256a4c13580d67dc4d2157e3afd292b87c57a Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Mon, 17 Nov 2025 13:42:31 +0100 Subject: [PATCH 03/33] typing: use TypeAlias for Literal-based type aliases and add type annotations Convert several Literal tuple usages to explicit TypeAlias (ENTITIES_TYP, RESIDUAL_ALGORITHM_LITERAL, VALID_DEVICES_LITERAL, VALID_FILE_TYPE_FOR_PLOT_LITERAL), import TypeAlias where needed, and add typing annotations for base_report_class. Minor typing cleanup and ignore-type for Report subclassing. --- src/ansys/mapdl/core/component.py | 5 ++++- src/ansys/mapdl/core/krylov.py | 8 ++++++-- src/ansys/mapdl/core/mapdl_core.py | 18 +++++++++++++++--- src/ansys/mapdl/core/report.py | 7 ++++--- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/ansys/mapdl/core/component.py b/src/ansys/mapdl/core/component.py index 760da85719b..0f1ea893e7d 100644 --- a/src/ansys/mapdl/core/component.py +++ b/src/ansys/mapdl/core/component.py @@ -32,6 +32,7 @@ Literal, Optional, Tuple, + TypeAlias, Union, get_args, ) @@ -48,10 +49,12 @@ if TYPE_CHECKING: # pragma: no cover import logging -ENTITIES_TYP: List[str] = Literal[ +# Entity type options - single source of truth +ENTITIES_TYP: TypeAlias = Literal[ "NODE", "NODES", "ELEM", "ELEMS", "ELEMENTS", "VOLU", "AREA", "LINE", "KP" ] +# Runtime list derived from the type alias above VALID_ENTITIES: List[str] = list(get_args(ENTITIES_TYP)) SELECTOR_FUNCTION: List[str] = [ diff --git a/src/ansys/mapdl/core/krylov.py b/src/ansys/mapdl/core/krylov.py index 80a87636a99..e3279119b07 100644 --- a/src/ansys/mapdl/core/krylov.py +++ b/src/ansys/mapdl/core/krylov.py @@ -21,7 +21,7 @@ # SOFTWARE. import os -from typing import List, Literal, Optional, Tuple, Union +from typing import List, Literal, Optional, Tuple, TypeAlias, Union import weakref from ansys.math.core.math import AnsMath, AnsVec @@ -30,6 +30,7 @@ from ansys.mapdl.core import Mapdl from ansys.mapdl.core.errors import MapdlRuntimeError +# Residual algorithm options - single source of truth RESIDUAL_ALGORITHM: List[str] = [ "l-inf", "linf", @@ -39,7 +40,10 @@ "l2", ] -RESIDUAL_ALGORITHM_LITERAL = Literal[tuple(RESIDUAL_ALGORITHM)] +# Type alias derived from the list above +RESIDUAL_ALGORITHM_LITERAL: TypeAlias = Literal[ + "l-inf", "linf", "l-1", "l1", "l-2", "l2" +] class KrylovSolver: diff --git a/src/ansys/mapdl/core/mapdl_core.py b/src/ansys/mapdl/core/mapdl_core.py index b5c03d0c446..737d2d0a9e4 100644 --- a/src/ansys/mapdl/core/mapdl_core.py +++ b/src/ansys/mapdl/core/mapdl_core.py @@ -36,7 +36,17 @@ from subprocess import DEVNULL, call # nosec B404 import tempfile import time -from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Tuple, Union +from typing import ( + TYPE_CHECKING, + Any, + Dict, + List, + Literal, + Optional, + Tuple, + TypeAlias, + Union, +) from uuid import uuid4 from warnings import warn import weakref @@ -100,12 +110,14 @@ DEBUG_LEVELS = Literal["DEBUG", "INFO", "WARNING", "ERROR"] +# Graphics device options - single source of truth VALID_DEVICES = ["PNG", "TIFF", "VRML", "TERM", "CLOSE"] -VALID_DEVICES_LITERAL = Literal[tuple(["PNG", "TIFF", "VRML", "TERM", "CLOSE"])] +VALID_DEVICES_LITERAL: TypeAlias = Literal["PNG", "TIFF", "VRML", "TERM", "CLOSE"] +# Plot file types (devices minus CLOSE) - derived from VALID_DEVICES VALID_FILE_TYPE_FOR_PLOT = VALID_DEVICES.copy() VALID_FILE_TYPE_FOR_PLOT.remove("CLOSE") -VALID_FILE_TYPE_FOR_PLOT_LITERAL = Literal[tuple(VALID_FILE_TYPE_FOR_PLOT)] +VALID_FILE_TYPE_FOR_PLOT_LITERAL: TypeAlias = Literal["PNG", "TIFF", "VRML", "TERM"] _PERMITTED_ERRORS = [ r"(\*\*\* ERROR \*\*\*).*(?:[\r\n]+.*)+highly distorted.", diff --git a/src/ansys/mapdl/core/report.py b/src/ansys/mapdl/core/report.py index 48230f2972e..ec56cd8cedd 100644 --- a/src/ansys/mapdl/core/report.py +++ b/src/ansys/mapdl/core/report.py @@ -22,6 +22,7 @@ """Module for report features""" import os +from typing import Type from ansys.mapdl.core import _HAS_ATP, _HAS_PYANSYS_REPORT, _HAS_PYVISTA @@ -189,12 +190,12 @@ def mapdl_info(self): # Determine which type of report will be used (depending on the # available packages) if _HAS_PYANSYS_REPORT: - base_report_class = pyansys_report.Report + base_report_class: Type[pyansys_report.Report] = pyansys_report.Report else: # pragma: no cover - base_report_class = Plain_Report + base_report_class: Type[Plain_Report] = Plain_Report -class Report(base_report_class): +class Report(base_report_class): # type: ignore[misc] """A class for custom scooby.Report.""" def __init__( From d2fef9487370d76e372d200bc16d622f656ef588 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Mon, 17 Nov 2025 15:25:23 +0100 Subject: [PATCH 04/33] typing: refine type annotations, add type ignores, and fix minor issues - common_grpc: annotate parse_chunks as grpc.CallIterator (ignore name-defined) - component: correct ENTITIES_MAPPING typing, tighten Component __new__/repr/type signatures and add attr type ignores - helpers: fix namedtuple import from collections - krylov: guard residuals with None check and add attr type ignore on append - logging: add type ignores for dynamic logger handler attributes - mapdl_core: fix mesh check (grid.n_node), accept pathlib.Path in _decompose_fname, add asserts for newly created/opened resources, and local rename for clarity - mapdl_geometry: allow ndarray for _select_items parameter - misc: broaden routine parameters to accept str or ROUTINES and add type ignores for mapdl attribute access - pool: avoid shadowing timeout by renaming and add type ignore for progress bar update These changes improve typing correctness, silence false-positive type errors, and address several small bugs/clarifications. --- src/ansys/mapdl/core/common_grpc.py | 8 ++++---- src/ansys/mapdl/core/component.py | 18 +++++++----------- src/ansys/mapdl/core/helpers.py | 2 +- src/ansys/mapdl/core/krylov.py | 4 ++-- src/ansys/mapdl/core/logging.py | 14 +++++++------- src/ansys/mapdl/core/mapdl_core.py | 17 +++++++++++------ src/ansys/mapdl/core/mapdl_geometry.py | 4 ++-- src/ansys/mapdl/core/misc.py | 12 ++++++------ src/ansys/mapdl/core/pool.py | 6 +++--- 9 files changed, 43 insertions(+), 42 deletions(-) diff --git a/src/ansys/mapdl/core/common_grpc.py b/src/ansys/mapdl/core/common_grpc.py index 27239d73ff2..91d7c1ee3f7 100644 --- a/src/ansys/mapdl/core/common_grpc.py +++ b/src/ansys/mapdl/core/common_grpc.py @@ -22,9 +22,8 @@ """Common gRPC functions""" import time -from typing import Dict, Iterable, List, Literal, Optional, get_args +from typing import Dict, List, Literal, Optional, get_args -from ansys.api.mapdl.v0 import ansys_kernel_pb2 as anskernel import grpc import numpy as np @@ -185,13 +184,14 @@ def check_vget_input(entity: str, item: str, itnum: str) -> str: def parse_chunks( - chunks: Iterable[anskernel.Chunk], dtype: Optional[np.typing.DTypeLike] = None + chunks: grpc.CallIterator, # type: ignore[name-defined] + dtype: Optional[np.typing.DTypeLike] = None, ) -> np.ndarray: """Deserialize gRPC chunks into a numpy array. Parameters ---------- - chunks : generator + chunks : grpc.CallIterator generator from grpc. Each chunk contains a bytes payload dtype : np.dtype diff --git a/src/ansys/mapdl/core/component.py b/src/ansys/mapdl/core/component.py index 0f1ea893e7d..aed69aeb648 100644 --- a/src/ansys/mapdl/core/component.py +++ b/src/ansys/mapdl/core/component.py @@ -25,7 +25,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Dict, Iterator, List, @@ -69,7 +68,7 @@ "KSEL", ] -ENTITIES_MAPPING: Dict[str, Callable] = { +ENTITIES_MAPPING: Dict[str, str] = { entity.upper(): func for entity, func in zip(VALID_ENTITIES, SELECTOR_FUNCTION) } @@ -143,32 +142,29 @@ def __init__(self, *args: Tuple[Any], **kwargs: Dict[Any, Any]) -> None: # https://stackoverflow.com/questions/47627298/how-is-tuple-init-different-from-super-init-in-a-subclass-of-tuple tuple.__init__(*args, **kwargs) - def __new__( - cls, - type_: ENTITIES_TYP, - items_: Tuple[str, Union[Tuple[int], List[int], NDArray[np.int_]]], - ): + def __new__(cls, items_: Tuple[int, ...], type_: ENTITIES_TYP) -> "Component": + """Create a new Component instance.""" if not isinstance(type_, str) or type_.upper() not in VALID_ENTITIES: raise ValueError( f"The value '{type_}' is not allowed for 'type' definition." ) obj = super().__new__(cls, items_) - obj._type: ENTITIES_TYP = type_ + obj._type: ENTITIES_TYP = type_ # type: ignore[attr-defined] return obj def __str__(self) -> str: tup_str = super().__str__() - return f"Component(type='{self._type}', items={tup_str})" + return f"Component(type='{self._type}', items={tup_str})" # type: ignore[attr-defined] def __repr__(self) -> str: tup_str = super().__repr__() - return f"Component(type='{self._type}', items={tup_str})" + return f"Component(type='{self._type}', items={tup_str}')" # type: ignore[attr-defined] @property def type(self) -> ENTITIES_TYP: """Return the type of the component. For instance "NODES", "KP", etc.""" - return self._type + return self._type # type: ignore[attr-defined] @property def items(self) -> Tuple[int]: diff --git a/src/ansys/mapdl/core/helpers.py b/src/ansys/mapdl/core/helpers.py index 69b726042ef..e66ac221ebb 100644 --- a/src/ansys/mapdl/core/helpers.py +++ b/src/ansys/mapdl/core/helpers.py @@ -22,7 +22,7 @@ """Module for helper functions""" -from functools import namedtuple +from collections import namedtuple import importlib.util import os import sys diff --git a/src/ansys/mapdl/core/krylov.py b/src/ansys/mapdl/core/krylov.py index e3279119b07..807ffc5cb40 100644 --- a/src/ansys/mapdl/core/krylov.py +++ b/src/ansys/mapdl/core/krylov.py @@ -645,10 +645,10 @@ def expand( "off", ]: norm_rz, norm_fz = self.compute_residuals(iFreq, RzV, Xi, omega) - if not self.residuals: + if self.residuals is None: self.residuals = [] - self.residuals.append([iFreq, norm_rz, norm_fz]) + self.residuals.append([iFreq, norm_rz, norm_fz]) # type: ignore[attr-defined] # Storing solution in class if compute_solution_vectors: diff --git a/src/ansys/mapdl/core/logging.py b/src/ansys/mapdl/core/logging.py index e617327ff82..64a4d596faa 100644 --- a/src/ansys/mapdl/core/logging.py +++ b/src/ansys/mapdl/core/logging.py @@ -214,8 +214,8 @@ def __init__(self, logger: logging.Logger, extra: Optional["MapdlBase"] = None): self.extra = weakref.proxy(extra) else: self.extra = None - self.file_handler = logger.file_handler - self.std_out_handler = logger.std_out_handler + self.file_handler = logger.file_handler # type: ignore[attr-defined] + self.std_out_handler = logger.std_out_handler # type: ignore[attr-defined] def process(self, msg: str, kwargs: MutableMapping[str, Dict[str, str]]): kwargs["extra"] = {} @@ -469,16 +469,16 @@ def _make_child_logger( logger and the new one. """ logger = logging.getLogger(logger_name) - logger.std_out_handler = None - logger.file_handler = None + logger.std_out_handler = None # type: ignore[attr-defined] + logger.file_handler = None # type: ignore[attr-defined] if self.logger.hasHandlers(): for each_handler in self.logger.handlers: new_handler = copy(each_handler) if each_handler == self.file_handler: - logger.file_handler = new_handler + logger.file_handler = new_handler # type: ignore[attr-defined] elif each_handler == self.std_out_handler: - logger.std_out_handler = new_handler + logger.std_out_handler = new_handler # type: ignore[attr-defined] if level: # The logger handlers are copied and changed the loglevel is @@ -655,7 +655,7 @@ def addfile_handler( logger.logger.addHandler(file_handler) elif isinstance(logger, logging.Logger): - logger.file_handler = file_handler + logger.file_handler = file_handler # type: ignore[attr-defined] logger.addHandler(file_handler) if write_headers: diff --git a/src/ansys/mapdl/core/mapdl_core.py b/src/ansys/mapdl/core/mapdl_core.py index 737d2d0a9e4..7b466528725 100644 --- a/src/ansys/mapdl/core/mapdl_core.py +++ b/src/ansys/mapdl/core/mapdl_core.py @@ -1309,12 +1309,13 @@ def _mesh(self) -> "Archive": self.cmsel("S", "__ELEM__", "ELEM", mute=True) self._archive_cache = Archive(arch_filename, parse_vtk=False, name="Mesh") + assert self._archive_cache is not None # just created above grid = self._archive_cache._parse_vtk(additional_checking=True) self._archive_cache._grid = grid # rare bug if grid is not None: - if grid.n_points != self._archive_cache.n_node: + if grid.n_node != self._archive_cache.n_node: self._archive_cache = Archive( arch_filename, parse_vtk=True, name="Mesh" ) @@ -1723,6 +1724,7 @@ def open_apdl_log( ) self._apdl_log = open(filename, mode=mode, buffering=1) # line buffered + assert self._apdl_log is not None # just opened above self._apdl_log.write( f"! APDL log script generated using PyMAPDL (ansys.mapdl.core {pymapdl.__version__})\n" ) @@ -2462,6 +2464,7 @@ def run( text = text.replace("\\r\\n", "\n").replace("\\n", "\n") if text: self._response = StringWithLiteralRepr(text.strip()) + assert self._response is not None # just assigned above response_ = "\n".join(self._response.splitlines()[:20]) self._log.info(response_) else: @@ -3096,12 +3099,14 @@ def _check_on_docker(self): self.slashdelete("__outputcmd__.txt") # cleaning return sys_output == "true" - def _decompose_fname(self, fname: str) -> Tuple[str, str, str]: + def _decompose_fname( + self, fname: Union[str, pathlib.Path] + ) -> Tuple[str, str, pathlib.Path]: """Decompose a file name (with or without path) into filename and extension. Parameters ---------- - fname : str + fname : str or pathlib.Path File name with or without path. Returns @@ -3112,11 +3117,11 @@ def _decompose_fname(self, fname: str) -> Tuple[str, str, str]: str File extension (without dot) - str + pathlib.Path File path """ - fname = pathlib.Path(fname) - return (fname.stem, fname.suffix.replace(".", ""), fname.parent) + fname_path = pathlib.Path(fname) + return (fname_path.stem, fname_path.suffix.replace(".", ""), fname_path.parent) class _force_output: """Allows user to enter commands that need to run with forced text output.""" diff --git a/src/ansys/mapdl/core/mapdl_geometry.py b/src/ansys/mapdl/core/mapdl_geometry.py index 0cddd543639..4abcf204b3b 100644 --- a/src/ansys/mapdl/core/mapdl_geometry.py +++ b/src/ansys/mapdl/core/mapdl_geometry.py @@ -1383,7 +1383,7 @@ def volume_select( def _select_items( self, - items: Sequence[int], + items: Union[Sequence[int], np.ndarray], item_type: VALID_SELECTION_ENTITY_TP, sel_type: VALID_SELECTION_TYPE_TP, ) -> None: @@ -1391,7 +1391,7 @@ def _select_items( Parameters ---------- - items : sequence + items : sequence or np.ndarray Sequence of items. item_type : str diff --git a/src/ansys/mapdl/core/misc.py b/src/ansys/mapdl/core/misc.py index f25b7636b15..306c361a031 100644 --- a/src/ansys/mapdl/core/misc.py +++ b/src/ansys/mapdl/core/misc.py @@ -72,7 +72,7 @@ class ROUTINES(Enum): R = TypeVar("R") -def check_valid_routine(routine: ROUTINES) -> bool: +def check_valid_routine(routine: Union[str, ROUTINES]) -> bool: """Check if a routine is valid. Acceptable aliases for "Begin level" include "begin". @@ -174,25 +174,25 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> R: mapdl = args[0] if not issubclass(type(mapdl), (MapdlBase)): # Assuming we are on a module object. - mapdl = mapdl._mapdl + mapdl = mapdl._mapdl # type: ignore[attr-defined] if not issubclass(type(mapdl), (MapdlBase)): raise Exception("This wrapper cannot access MAPDL object") - prior_log_level = mapdl._log.level + prior_log_level = mapdl._log.level # type: ignore[attr-defined] if prior_log_level != "CRITICAL": - mapdl._set_log_level("CRITICAL") + mapdl._set_log_level("CRITICAL") # type: ignore[attr-defined] out = func(*args, **kwargs) if prior_log_level != "CRITICAL": - mapdl._set_log_level(prior_log_level) + mapdl._set_log_level(prior_log_level) # type: ignore[attr-defined] return out return wrapper -def run_as(routine: ROUTINES): +def run_as(routine: Union[str, ROUTINES]): """Run a MAPDL method at PREP7 and always revert to the prior processor""" def decorator(function): diff --git a/src/ansys/mapdl/core/pool.py b/src/ansys/mapdl/core/pool.py index f57db0d60f6..0db6f5439a9 100755 --- a/src/ansys/mapdl/core/pool.py +++ b/src/ansys/mapdl/core/pool.py @@ -905,9 +905,9 @@ def _spawn_mapdl( # Waiting for the instance being fully initialized. # This is introduce to mitigate #2173 - timeout = time.time() + timeout + timeout_end = time.time() + timeout - while timeout > time.time(): + while timeout_end > time.time(): if self.is_initialized(index): break time.sleep(0.1) @@ -919,7 +919,7 @@ def _spawn_mapdl( # LOG.debug("Spawned instance %d. Name '%s'", index, name) if pbar is not None: - pbar.update(1) + pbar.update(1) # type: ignore[attr-defined] self._spawning_i -= 1 From 931bc327764e8476c50d2e62892499eed555ed0b Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Mon, 17 Nov 2025 15:40:36 +0100 Subject: [PATCH 05/33] typing: refine type annotations and improve runtime robustness across core modules - component: broaden Component.__new__ to accept lists, ndarrays, ints, strs, Components and None; coerce items to tuple and handle fallbacks. Make ComponentManager handle cmtype as string or [selection, type] and guard cmlist parsing for None. - krylov: tighten typing (Optional[str] for full_file), accept int/str for frequency inputs, allow residual_algorithm to be Optional and validate only when provided. - licensing: raise OSError when home directory cannot be determined before building license path. - mapdl_core: accept pathlib.Path or str in _wrap_directory. - mapdl_extended / mapdl_grpc: add targeted type ignores and refine parameter types (chunk_size, progress_bar, _mapdl_process, vget/nvar, VAR_IR) to satisfy static typing and avoid mypy issues. - misc: robust MODULE_PATH resolution using inspect.currentframe() with fallback to __file__. --- src/ansys/mapdl/core/component.py | 34 ++++++++++++++++++++++---- src/ansys/mapdl/core/krylov.py | 12 ++++++--- src/ansys/mapdl/core/licensing.py | 2 ++ src/ansys/mapdl/core/mapdl_core.py | 2 +- src/ansys/mapdl/core/mapdl_extended.py | 4 +-- src/ansys/mapdl/core/mapdl_grpc.py | 20 +++++++-------- src/ansys/mapdl/core/misc.py | 7 +++++- 7 files changed, 58 insertions(+), 23 deletions(-) diff --git a/src/ansys/mapdl/core/component.py b/src/ansys/mapdl/core/component.py index aed69aeb648..4b6ad2affb6 100644 --- a/src/ansys/mapdl/core/component.py +++ b/src/ansys/mapdl/core/component.py @@ -142,12 +142,32 @@ def __init__(self, *args: Tuple[Any], **kwargs: Dict[Any, Any]) -> None: # https://stackoverflow.com/questions/47627298/how-is-tuple-init-different-from-super-init-in-a-subclass-of-tuple tuple.__init__(*args, **kwargs) - def __new__(cls, items_: Tuple[int, ...], type_: ENTITIES_TYP) -> "Component": + def __new__( + cls, + type_: ENTITIES_TYP, + items_: Union[Tuple[int, ...], List[int], "Component", NDArray, int, str, None], + ) -> "Component": """Create a new Component instance.""" if not isinstance(type_, str) or type_.upper() not in VALID_ENTITIES: raise ValueError( f"The value '{type_}' is not allowed for 'type' definition." ) + # Convert to tuple if needed + if isinstance(items_, Component): + items_ = tuple(items_) + elif isinstance(items_, (list, np.ndarray)): + items_ = tuple(items_) + elif items_ is None: + items_ = tuple() + elif isinstance(items_, (int, str)): + # Handle single values + items_ = (int(items_),) if isinstance(items_, (int, str)) else tuple() + elif not isinstance(items_, tuple): + # Fallback for any iterable + try: + items_ = tuple(items_) # type: ignore[arg-type] + except (TypeError, ValueError): + items_ = tuple() obj = super().__new__(cls, items_) obj._type: ENTITIES_TYP = type_ # type: ignore[attr-defined] @@ -323,7 +343,9 @@ def __getitem__(self, key: str) -> ITEMS_VALUES: forced_to_select = True try: - cmtype = self._comp[key.upper()] + cmtype_raw = self._comp[key.upper()] + # cmtype can be a string (just type) or a list [selection, type] + cmtype: str = cmtype_raw[1] if isinstance(cmtype_raw, list) else cmtype_raw # type: ignore[assignment] except KeyError: # testing if the CM exists or not # it seems you can use `*get` with components which are not selected. @@ -338,12 +360,12 @@ def __getitem__(self, key: str) -> ITEMS_VALUES: f"The component named '{key}' does not exist in the MAPDL instance." ) - output = self._mapdl._parse_cmlist_indiv(key, cmtype) + output: List[int] = self._mapdl._parse_cmlist_indiv(key, cmtype) if forced_to_select: # Unselect to keep the state of the things as before calling this method. self._mapdl.cmsel("U", key) - return Component(cmtype, output) + return Component(cmtype, output) # type: ignore[arg-type] def __setitem__(self, key: str, value: ITEMS_VALUES) -> None: if not isinstance(key, str): @@ -566,7 +588,7 @@ def _parse_cmlist_indiv( cmlist = "\n\n".join( re.findall( r"(?s)" + header + r"\s+(.*?)\s*(?=\n\s*\n|\Z)", - cmlist, + cmlist or "", # Handle None case flags=re.DOTALL, ) ) @@ -584,6 +606,8 @@ def _parse_cmlist_indiv( def _parse_cmlist(cmlist: Optional[str] = None) -> Dict[str, Any]: include_selection = False + if cmlist is None: + return {} if re.search(r"NAME\s+TYPE\s+SUBCOMPONENTS", cmlist): # header # "NAME TYPE SUBCOMPONENTS" diff --git a/src/ansys/mapdl/core/krylov.py b/src/ansys/mapdl/core/krylov.py index 807ffc5cb40..75b9df7f6b5 100644 --- a/src/ansys/mapdl/core/krylov.py +++ b/src/ansys/mapdl/core/krylov.py @@ -114,7 +114,7 @@ def _mapdl(self) -> Mapdl: """Return the weakly referenced instance of mapdl.""" return self._mapdl_weakref() - def _check_full_file_exists(self, full_file: str = None) -> None: + def _check_full_file_exists(self, full_file: Optional[str] = None) -> None: """Check full file exists.""" current_dir = self._mapdl.directory # Check if full file exists @@ -173,7 +173,11 @@ def _check_input_gensubspace( ) def _check_input_solve( - self, freq_start: int, freq_end: int, freq_steps: int, ramped_load: bool + self, + freq_start: Union[int, str], + freq_end: Union[int, str], + freq_steps: Union[int, str], + ramped_load: bool, ): """Validate the inputs to the ``solve`` method.""" @@ -205,7 +209,7 @@ def _check_input_expand( self, return_solution: bool, residual_computation: bool, - residual_algorithm: RESIDUAL_ALGORITHM_LITERAL, + residual_algorithm: Optional[RESIDUAL_ALGORITHM_LITERAL], ): """Validate the inputs to the ``expand`` method.""" @@ -215,7 +219,7 @@ def _check_input_expand( ) if not isinstance(residual_computation, bool): raise ValueError("The 'residual_computation' must be True or False.") - if ( + if residual_algorithm is not None and ( not isinstance(residual_algorithm, str) or residual_algorithm.lower() not in RESIDUAL_ALGORITHM ): diff --git a/src/ansys/mapdl/core/licensing.py b/src/ansys/mapdl/core/licensing.py index 2924678b8bd..abe1f7d927c 100644 --- a/src/ansys/mapdl/core/licensing.py +++ b/src/ansys/mapdl/core/licensing.py @@ -547,6 +547,8 @@ def get_ansys_license_debug_file_path() -> str: # pragma: no cover else: raise OSError(f"Unsupported OS {os.name}") + if folder is None: + raise OSError(f"Could not determine home directory for OS {os.name}") return os.path.join(folder, ".ansys") diff --git a/src/ansys/mapdl/core/mapdl_core.py b/src/ansys/mapdl/core/mapdl_core.py index 7b466528725..a081380685d 100644 --- a/src/ansys/mapdl/core/mapdl_core.py +++ b/src/ansys/mapdl/core/mapdl_core.py @@ -545,7 +545,7 @@ def default_file_type_for_plots(self, value: VALID_FILE_TYPE_FOR_PLOT_LITERAL): raise ValueError(f"'{value}' is not allowed as file output for plots.") return self._default_file_type_for_plots - def _wrap_directory(self, path: str) -> pathlib.PurePath: + def _wrap_directory(self, path: Union[str, pathlib.Path]) -> pathlib.PurePath: if self._platform is None: # MAPDL is not initialized yet so returning the path as is. return pathlib.PurePath(path) diff --git a/src/ansys/mapdl/core/mapdl_extended.py b/src/ansys/mapdl/core/mapdl_extended.py index 8cf1e6486ea..2f8daf38914 100644 --- a/src/ansys/mapdl/core/mapdl_extended.py +++ b/src/ansys/mapdl/core/mapdl_extended.py @@ -3053,8 +3053,8 @@ def _get_array( return np.empty(0) with self.non_interactive: - self.vwrite("%s(1)" % parm_name) - self.run("(F20.12)") + self.vwrite("%s(1)" % parm_name) # type: ignore[arg-type] + self.run("(F20.12)") # type: ignore[arg-type] array = np.fromstring(self.last_response, sep="\n") diff --git a/src/ansys/mapdl/core/mapdl_grpc.py b/src/ansys/mapdl/core/mapdl_grpc.py index 53c76f40836..d628db9cbd8 100644 --- a/src/ansys/mapdl/core/mapdl_grpc.py +++ b/src/ansys/mapdl/core/mapdl_grpc.py @@ -434,7 +434,7 @@ def __init__( self._subscribe_to_channel() # connect and validate to the channel - self._mapdl_process: subprocess.Popen = start_parm.pop("process", None) + self._mapdl_process: Optional[subprocess.Popen] = start_parm.pop("process", None) # type: ignore[arg-type] # saving for later use (for example open_gui) self._start_parm: Dict[str, Any] = start_parm @@ -2485,8 +2485,8 @@ def _download_from_remote( # numpydoc ignore=RT01 files: Union[str, List[str], Tuple[str, ...]], target_dir: str, extension: Optional[str] = None, - chunk_size: Optional[str] = None, - progress_bar: Optional[str] = None, + chunk_size: Optional[int] = None, + progress_bar: Optional[bool] = None, ) -> List[str]: """Download files when we are connected to a remote session.""" @@ -3222,7 +3222,7 @@ def nsol( # numpydoc ignore=RT01 ): """Wraps NSOL to return the variable as an array.""" super().nsol( - nvar=nvar, + nvar=nvar, # type: ignore[arg-type] node=node, item=item, comp=comp, @@ -3230,7 +3230,7 @@ def nsol( # numpydoc ignore=RT01 sector=sector, **kwargs, ) - return self.vget("_temp", nvar) + return self.vget("_temp", nvar) # type: ignore[arg-type] @wraps(MapdlBase.esol) def esol( # numpydoc ignore=RT01 @@ -3245,7 +3245,7 @@ def esol( # numpydoc ignore=RT01 ) -> NDArray[np.float64]: """Wraps ESOL to return the variable as an array.""" super().esol( - nvar=nvar, + nvar=nvar, # type: ignore[arg-type] elem=elem, node=node, item=item, @@ -3253,7 +3253,7 @@ def esol( # numpydoc ignore=RT01 name=name, **kwargs, ) - return self.vget("_temp", nvar) + return self.vget("_temp", nvar) # type: ignore[arg-type] @wraps(MapdlBase.rpsd) def rpsd( # numpydoc ignore=RT01 @@ -3278,7 +3278,7 @@ def rpsd( # numpydoc ignore=RT01 signif=signif, **kwargs, ) - return self.vget("_temp", ir) + return self.vget("_temp", ir) # type: ignore[arg-type] def get_nsol( self, @@ -3339,7 +3339,7 @@ def get_nsol( labels TBOT, TE2, TE3, . . ., TTOP instead of TEMP. """ return self.nsol( - VAR_IR, + VAR_IR, # type: ignore[arg-type] node=node, item=item, comp=comp, @@ -3445,7 +3445,7 @@ def get_esol( Technology Guide. """ self.esol( - VAR_IR, + VAR_IR, # type: ignore[arg-type] elem=elem, node=node, item=item, diff --git a/src/ansys/mapdl/core/misc.py b/src/ansys/mapdl/core/misc.py index 306c361a031..497acba53e1 100644 --- a/src/ansys/mapdl/core/misc.py +++ b/src/ansys/mapdl/core/misc.py @@ -51,7 +51,12 @@ from ansys.mapdl.core.plotting import GraphicsBackend # path of this module -MODULE_PATH = os.path.dirname(inspect.getfile(inspect.currentframe())) +_frame = inspect.currentframe() +MODULE_PATH = ( + os.path.dirname(inspect.getfile(_frame)) + if _frame is not None + else os.path.dirname(__file__) +) class ROUTINES(Enum): From 7254066aba1bb9fe13a735efabdb7cef5e034cb1 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 09:45:40 +0100 Subject: [PATCH 06/33] fix(core): improve robustness for regex matches, None handling, and parent/type guards - component: refine __getitem__ return annotation to Component (type: ignore[override]) - krylov: guard residual_algorithm against None before calling .lower() - licensing: handle missing subprocess.stdout, ensure licenses is a list, and check output type before searching for error messages - logging: check self.extra is not None before accessing .name - mapdl_core: cache parent reference in WithInterativePlotting and assert it's not None; avoid repeated _parent() calls - mapdl_extended: safely search for the table block before parsing and only populate the table if a match is found - mapdl_grpc: return empty string instead of None from command response helper - mesh_grpc: use safe regex matches when extracting REAL CONSTANT SET, ITEMS, and TO values - parameters: guard regex searches when extracting parameter names and string elements to avoid AttributeError --- src/ansys/mapdl/core/component.py | 2 +- src/ansys/mapdl/core/krylov.py | 27 ++++++++++++++------ src/ansys/mapdl/core/licensing.py | 10 ++++++-- src/ansys/mapdl/core/logging.py | 5 ++-- src/ansys/mapdl/core/mapdl_core.py | 34 +++++++++++++++----------- src/ansys/mapdl/core/mapdl_extended.py | 16 ++++++------ src/ansys/mapdl/core/mapdl_grpc.py | 2 +- src/ansys/mapdl/core/mesh_grpc.py | 10 +++++--- src/ansys/mapdl/core/parameters.py | 11 +++++---- 9 files changed, 74 insertions(+), 43 deletions(-) diff --git a/src/ansys/mapdl/core/component.py b/src/ansys/mapdl/core/component.py index 4b6ad2affb6..cebc6799001 100644 --- a/src/ansys/mapdl/core/component.py +++ b/src/ansys/mapdl/core/component.py @@ -330,7 +330,7 @@ def _comp(self) -> UNDERLYING_DICT: def _comp(self, value) -> None: self.__comp = value - def __getitem__(self, key: str) -> ITEMS_VALUES: + def __getitem__(self, key: str) -> "Component": # type: ignore[override] forced_to_select = False if key.upper() not in self._comp and self._autoselect_components: diff --git a/src/ansys/mapdl/core/krylov.py b/src/ansys/mapdl/core/krylov.py index 75b9df7f6b5..7a7cc767857 100644 --- a/src/ansys/mapdl/core/krylov.py +++ b/src/ansys/mapdl/core/krylov.py @@ -644,10 +644,14 @@ def expand( xii_usr_ordered.append(dof_each_freq) # Compute residual norm (if requested) - if residual_computation or residual_algorithm.lower() in [ - "no", - "off", - ]: + if residual_computation or ( + residual_algorithm + and residual_algorithm.lower() + in [ + "no", + "off", + ] + ): norm_rz, norm_fz = self.compute_residuals(iFreq, RzV, Xi, omega) if self.residuals is None: self.residuals = [] @@ -704,19 +708,28 @@ def compute_residuals( # Output norms of residual vector norm_rz = 0.0 - if self._residual_algorithm.lower() in ["l-inf", "linf"]: # L-inf norm + if self._residual_algorithm and self._residual_algorithm.lower() in [ + "l-inf", + "linf", + ]: # L-inf norm norm_rz = Rzi.norm("NRMINF") norm_fz = self.iRHS.norm("NRMINF") if norm_fz != 0.0: norm_rz = norm_rz / norm_fz - elif self._residual_algorithm.lower() in ["l-1", "l1"]: + elif self._residual_algorithm and self._residual_algorithm.lower() in [ + "l-1", + "l1", + ]: norm_rz = Rzi.norm("NRM1") norm_fz = self.iRHS.norm("NRM1") if norm_fz != 0.0: norm_rz = norm_rz / norm_fz - elif self._residual_algorithm.lower() in ["l-2", "l2"]: + elif self._residual_algorithm and self._residual_algorithm.lower() in [ + "l-2", + "l2", + ]: norm_rz = Rzi.norm("NRM2") norm_fz = self.iRHS.norm("NRM2") if norm_fz != 0.0: diff --git a/src/ansys/mapdl/core/licensing.py b/src/ansys/mapdl/core/licensing.py index abe1f7d927c..9a516f59d1e 100644 --- a/src/ansys/mapdl/core/licensing.py +++ b/src/ansys/mapdl/core/licensing.py @@ -355,7 +355,10 @@ def _checkout_license( stderr=subprocess.STDOUT, env=env, ) # nosec B603 - output = process.stdout.read().decode() + if process.stdout: + output = process.stdout.read().decode() + else: + output = "" t_elap = time.time() - tstart LOG.debug(f"License check complete in {t_elap:.2} seconds.\n") @@ -405,11 +408,14 @@ def _check_mech_license_available( elif isinstance(licenses, str): licenses = [licenses] + # At this point licenses is definitely a list + assert licenses is not None + msg1 = "No such feature exists" msg2 = "The server is down or is not responsive." for each_license in licenses: output = self._checkout_license(each_license, host) - if msg1 in output or msg2 in output: + if isinstance(output, str) and (msg1 in output or msg2 in output): raise LicenseServerConnectionError(output) return True diff --git a/src/ansys/mapdl/core/logging.py b/src/ansys/mapdl/core/logging.py index 64a4d596faa..1b7d440eab9 100644 --- a/src/ansys/mapdl/core/logging.py +++ b/src/ansys/mapdl/core/logging.py @@ -220,9 +220,8 @@ def __init__(self, logger: logging.Logger, extra: Optional["MapdlBase"] = None): def process(self, msg: str, kwargs: MutableMapping[str, Dict[str, str]]): kwargs["extra"] = {} # This are the extra parameters sent to log - kwargs["extra"][ - "instance_name" - ] = self.extra.name # here self.extra is the argument pass to the log records. + if self.extra is not None: + kwargs["extra"]["instance_name"] = self.extra.name # type: ignore[union-attr] return msg, kwargs def log_to_file( diff --git a/src/ansys/mapdl/core/mapdl_core.py b/src/ansys/mapdl/core/mapdl_core.py index a081380685d..a195547f519 100644 --- a/src/ansys/mapdl/core/mapdl_core.py +++ b/src/ansys/mapdl/core/mapdl_core.py @@ -1988,31 +1988,37 @@ def __init__(self, parent: "MapdlBase", pixel_res: int) -> None: @requires_graphics def __enter__(self) -> None: - self._parent()._log.debug("Entering in 'WithInterativePlotting' mode") + parent = self._parent() + assert parent is not None, "Parent reference is None" - if not self._parent()._store_commands: - if not self._parent()._png_mode: - self._parent().show("PNG", mute=True) - self._parent().gfile(self._pixel_res, mute=True) + parent._log.debug("Entering in 'WithInterativePlotting' mode") - self.previous_device = self._parent().file_type_for_plots + if not parent._store_commands: + if not parent._png_mode: + parent.show("PNG", mute=True) + parent.gfile(self._pixel_res, mute=True) - if self._parent().file_type_for_plots not in [ + self.previous_device = parent.file_type_for_plots + + if parent.file_type_for_plots not in [ "PNG", "TIFF", "PNG", "VRML", ]: - self._parent().show(self._parent().default_file_type_for_plots) + parent.show(parent.default_file_type_for_plots) def __exit__(self, *args) -> None: - self._parent()._log.debug("Exiting in 'WithInterativePlotting' mode") - self._parent().show("close", mute=True) + parent = self._parent() + assert parent is not None, "Parent reference is None" + + parent._log.debug("Exiting in 'WithInterativePlotting' mode") + parent.show("close", mute=True) - if not self._parent()._store_commands: - if not self._parent()._png_mode: - self._parent().show("PNG", mute=True) - self._parent().gfile(self._pixel_res, mute=True) + if not parent._store_commands: + if not parent._png_mode: + parent.show("PNG", mute=True) + parent.gfile(self._pixel_res, mute=True) self._parent().file_type_for_plots = self.previous_device diff --git a/src/ansys/mapdl/core/mapdl_extended.py b/src/ansys/mapdl/core/mapdl_extended.py index 2f8daf38914..882d08ed364 100644 --- a/src/ansys/mapdl/core/mapdl_extended.py +++ b/src/ansys/mapdl/core/mapdl_extended.py @@ -2656,16 +2656,18 @@ def osresult(self, item="", comp="", freq="", cname="", **kwargs) -> CommandOutp columns_names = ["ITEM", "FREQUENCY", "COMPONENT"] result = CommandListingOutput(result) - table = re.search( + table_match = re.search( r"ITEM\s+FREQUENCY\s+COMPONENT(.*)", result, flags=re.DOTALL - ).group(1) - table = [each.split() for each in table.splitlines() if each.strip()] - table = expand_all_inner_lists( - table, target_length=len(columns_names), fill_value="" ) + if table_match: + table = table_match.group(1) + table = [each.split() for each in table.splitlines() if each.strip()] + table = expand_all_inner_lists( + table, target_length=len(columns_names), fill_value="" + ) - result._columns_names = columns_names - result._cache = np.array(table) + result._columns_names = columns_names + result._cache = np.array(table) return result diff --git a/src/ansys/mapdl/core/mapdl_grpc.py b/src/ansys/mapdl/core/mapdl_grpc.py index d628db9cbd8..e9879307e38 100644 --- a/src/ansys/mapdl/core/mapdl_grpc.py +++ b/src/ansys/mapdl/core/mapdl_grpc.py @@ -1184,7 +1184,7 @@ def _send_command( resp = grpc_response.response if resp is not None: return resp.strip() - return None + return "" @protect_grpc def _send_command_stream(self, cmd, verbose=False) -> str: # numpydoc ignore=RT01 diff --git a/src/ansys/mapdl/core/mesh_grpc.py b/src/ansys/mapdl/core/mesh_grpc.py index cd4d73d1923..d43209c6309 100644 --- a/src/ansys/mapdl/core/mesh_grpc.py +++ b/src/ansys/mapdl/core/mesh_grpc.py @@ -872,10 +872,14 @@ def _parse_rlist(self) -> Dict[int, float]: const_ = {} for each in constants_: values = [0 for i in range(18)] - set_ = int(re.match(r"REAL CONSTANT SET\s+(\d+)\s+", each).groups()[0]) + set_match = re.match(r"REAL CONSTANT SET\s+(\d+)\s+", each) + set_ = int(set_match.groups()[0]) if set_match else 0 + + items_match = re.match(r".*ITEMS\s+(\d+)\s+", each) + to_match = re.match(r".*TO\s+(\d+)\s*", each) limits = ( - int(re.match(r".*ITEMS\s+(\d+)\s+", each).groups()[0]), - int(re.match(r".*TO\s+(\d+)\s*", each).groups()[0]), + int(items_match.groups()[0]) if items_match else 0, + int(to_match.groups()[0]) if to_match else 0, ) values_ = [float(i) for i in each.strip().splitlines()[1].split()] diff --git a/src/ansys/mapdl/core/parameters.py b/src/ansys/mapdl/core/parameters.py index 410a1caab28..6c794661d2e 100644 --- a/src/ansys/mapdl/core/parameters.py +++ b/src/ansys/mapdl/core/parameters.py @@ -785,13 +785,15 @@ def interp_star_status(status: str) -> dict[str, str]: # listing of one array parameter header = "LOCATION VALUE" incr = 30 - name_ = re.search(r"STATUS-(.*)[^\(]\(", status).group(1).strip() + match = re.search(r"STATUS-(.*)[^\(]\(", status) + name_ = match.group(1).strip() if match else "" else: # listing of a string array is_string_array = True header = "" # no header. Find will return 0. incr = sum([len(each) for each in status.splitlines()[0:2]]) + 1 - name_ = re.search(r"STATUS-(.*)[^\(]\(", status).group(1).strip() + match = re.search(r"STATUS-(.*)[^\(]\(", status) + name_ = match.group(1).strip() if match else "" st = status.find(header) @@ -835,9 +837,8 @@ def interp_star_status(status: str) -> dict[str, str]: elements.append(items[-1]) elif is_string_array: - last_element = ( - re.search(r"\s*\d+\s+\d+\s+\d+\s+(.*)$", line).group(1).strip() - ) + match = re.search(r"\s*\d+\s+\d+\s+\d+\s+(.*)$", line) + last_element = match.group(1).strip() if match else "" elements.append(last_element) elif len(items) == 5: From 2fe97ff68d4ba8e35121d02b6f4de5bea9c0f4b1 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 10:13:56 +0100 Subject: [PATCH 07/33] typing: refine annotations and add type ignores across core modules - fix Literal alias declaration in common_grpc - tighten Optional/Union signatures and use TypeAlias where appropriate - add explicit variable typings and where necessary - small parsing/type improvements in component, parameters, misc - annotate/adjust dynamic fields in mapdl_core, mapdl_grpc, licensing, pool, krylov, logging Improve type clarity and runtime robustness while keeping dynamic assignments compatible with runtime values. --- src/ansys/mapdl/core/common_grpc.py | 2 +- src/ansys/mapdl/core/component.py | 18 +++++++-------- src/ansys/mapdl/core/krylov.py | 4 ++-- src/ansys/mapdl/core/licensing.py | 10 +++++---- src/ansys/mapdl/core/logging.py | 2 +- src/ansys/mapdl/core/mapdl_core.py | 17 +++++++------- src/ansys/mapdl/core/mapdl_geometry.py | 2 +- src/ansys/mapdl/core/mapdl_grpc.py | 31 ++++++++++++++------------ src/ansys/mapdl/core/misc.py | 7 ++++-- src/ansys/mapdl/core/parameters.py | 13 ++++++++--- src/ansys/mapdl/core/pool.py | 8 +++---- 11 files changed, 65 insertions(+), 49 deletions(-) diff --git a/src/ansys/mapdl/core/common_grpc.py b/src/ansys/mapdl/core/common_grpc.py index 91d7c1ee3f7..85e5a6cb580 100644 --- a/src/ansys/mapdl/core/common_grpc.py +++ b/src/ansys/mapdl/core/common_grpc.py @@ -47,7 +47,7 @@ } -VGET_ENTITY_TYPES_TYPING: List[str] = Literal[ +VGET_ENTITY_TYPES_TYPING = Literal[ "NODE", "ELEM", "KP", diff --git a/src/ansys/mapdl/core/component.py b/src/ansys/mapdl/core/component.py index cebc6799001..a276986766e 100644 --- a/src/ansys/mapdl/core/component.py +++ b/src/ansys/mapdl/core/component.py @@ -294,7 +294,7 @@ def default_entity(self, value: ENTITIES_TYP): raise ValueError( f"Only the following entities are allowed:\n{', '.join(VALID_ENTITIES)}" ) - self._default_entity = value.upper() + self._default_entity = value.upper() # type: ignore[assignment] @property def default_entity_warning(self) -> bool: @@ -392,7 +392,7 @@ def __setitem__(self, key: str, value: ITEMS_VALUES) -> None: ) cmname = key - cmtype = value[0].upper() + cmtype: ENTITIES_TYP = value[0].upper() # type: ignore[assignment] cmitems = value[1] else: @@ -408,8 +408,8 @@ def __setitem__(self, key: str, value: ITEMS_VALUES) -> None: ) cmname = key - cmtype = self.default_entity - cmitems = value + cmtype = self.default_entity # type: ignore[assignment] + cmitems = value # type: ignore[assignment] elif isinstance(value, str): # create a component with the already selected elements @@ -419,7 +419,7 @@ def __setitem__(self, key: str, value: ITEMS_VALUES) -> None: ) cmname = key - cmtype = value + cmtype: ENTITIES_TYP = value # type: ignore[assignment] self._mapdl.cm(cmname, cmtype) @@ -439,7 +439,7 @@ def __setitem__(self, key: str, value: ITEMS_VALUES) -> None: cmname = key cmtype = self.default_entity - cmitems = value + cmitems: Union[List[int], NDArray[Any]] = value # type: ignore[assignment] else: raise ValueError("Only strings or tuples are allowed for assignment.") @@ -598,10 +598,10 @@ def _parse_cmlist_indiv( items = "\n".join(re.findall(rg, cmlist, flags=re.DOTALL)) # Joining them together and giving them format. - items = items.replace("\n", " ").split() - items = [int(each) for each in items if is_float(each)] + items_raw: List[str] = items.replace("\n", " ").split() + items_int: List[int] = [int(each) for each in items_raw if is_float(each)] - return items + return items_int def _parse_cmlist(cmlist: Optional[str] = None) -> Dict[str, Any]: diff --git a/src/ansys/mapdl/core/krylov.py b/src/ansys/mapdl/core/krylov.py index 7a7cc767857..00b6fd0cf22 100644 --- a/src/ansys/mapdl/core/krylov.py +++ b/src/ansys/mapdl/core/krylov.py @@ -596,7 +596,7 @@ def expand( # To avoid having to set residual computation. residual_computation = True elif residual_algorithm is None: - residual_algorithm = "L-Inf" + residual_algorithm = "L-Inf" # type: ignore[assignment] # Check inputs before executing the method self._check_input_expand( @@ -654,7 +654,7 @@ def expand( ): norm_rz, norm_fz = self.compute_residuals(iFreq, RzV, Xi, omega) if self.residuals is None: - self.residuals = [] + self.residuals = [] # type: ignore[assignment] self.residuals.append([iFreq, norm_rz, norm_fz]) # type: ignore[attr-defined] diff --git a/src/ansys/mapdl/core/licensing.py b/src/ansys/mapdl/core/licensing.py index 9a516f59d1e..0dd632969dd 100644 --- a/src/ansys/mapdl/core/licensing.py +++ b/src/ansys/mapdl/core/licensing.py @@ -29,7 +29,7 @@ # the input is controlled by the library. Excluding bandit check. import subprocess # nosec B404 import time -from typing import Iterator, Literal +from typing import Any, Iterator, Literal, Union from ansys.mapdl.core import _HAS_ATP, LOG from ansys.mapdl.core.errors import LicenseServerConnectionError @@ -131,6 +131,7 @@ def check_license_file(self): @threaded_daemon def checkout_license(self, host: str | None = None): + self._license_checkout_success: Optional[bool] = None try: self._check_mech_license_available(host) except Exception as error: @@ -367,7 +368,7 @@ def _checkout_license( return output def _check_mech_license_available( - self, host: str | None = None, licenses: Allowable_licenses | None = None + self, host: str | None = None, licenses: Allowable_licenses | str | None = None ) -> bool: # pragma: no cover """Check if there mechanical license available by running 'ansysli_util'. @@ -406,7 +407,7 @@ def _check_mech_license_available( if licenses is None: licenses = LIC_TO_CHECK elif isinstance(licenses, str): - licenses = [licenses] + licenses = [licenses] # type: ignore[assignment] # At this point licenses is definitely a list assert licenses is not None @@ -524,9 +525,10 @@ def get_ansys_license_debug_file_name() -> str: # pragma: no cover hostname = socket.gethostname() appname = APP_NAME # This is the type of license my client requests (Windows 10, 2021R2) - version = version_from_path("mapdl", get_mapdl_path(allow_input=False)) + version: int = version_from_path("mapdl", get_mapdl_path(allow_input=False)) ending = "out" + parts: Union[tuple[str, str, Any, str], tuple[str, str, str, Any, str]] if version < 221: parts = (name, appname, version, ending) else: diff --git a/src/ansys/mapdl/core/logging.py b/src/ansys/mapdl/core/logging.py index 1b7d440eab9..68ad206b6c3 100644 --- a/src/ansys/mapdl/core/logging.py +++ b/src/ansys/mapdl/core/logging.py @@ -211,7 +211,7 @@ class PymapdlCustomAdapter(logging.LoggerAdapter): def __init__(self, logger: logging.Logger, extra: Optional["MapdlBase"] = None): self.logger = logger if extra is not None: - self.extra = weakref.proxy(extra) + self.extra = weakref.proxy(extra) # type: ignore[assignment] else: self.extra = None self.file_handler = logger.file_handler # type: ignore[attr-defined] diff --git a/src/ansys/mapdl/core/mapdl_core.py b/src/ansys/mapdl/core/mapdl_core.py index a195547f519..f999041c617 100644 --- a/src/ansys/mapdl/core/mapdl_core.py +++ b/src/ansys/mapdl/core/mapdl_core.py @@ -43,6 +43,7 @@ List, Literal, Optional, + TextIO, Tuple, TypeAlias, Union, @@ -315,7 +316,7 @@ def __init__( self._response = None self._mode = start_parm.get("mode", None) self._mapdl_process = None - self._launched: bool = start_parm.get("launched", False) + self._launched: bool = start_parm.get("launched", False) # type: ignore[assignment] self._stderr = None self._stdout = None self._file_type_for_plots = file_type_for_plots @@ -323,7 +324,7 @@ def __init__( self._version = None # cached version self._mute = False self._save_selection_obj = None - self._use_reader_backend: bool = start_parm.pop("use_reader_backend", True) + self._use_reader_backend: bool = start_parm.pop("use_reader_backend", True) # type: ignore[assignment] if _HAS_VISUALIZER: if graphics_backend is not None: # pragma: no cover @@ -353,13 +354,13 @@ def __init__( # Start_parameters _sanitize_start_parm(start_parm) self._start_parm: Dict[str, Any] = start_parm - self._jobname: str = start_parm.get("jobname", "file") + self._jobname: str = start_parm.get("jobname", "file") # type: ignore[assignment] self._path: str | pathlib.PurePath | None = ( None # start_parm.get("run_location", None) ) self._check_parameter_names: bool = start_parm.get( "check_parameter_names", True - ) + ) # type: ignore[assignment] # Setting up loggers self._log: logger = logger.add_instance_logger( @@ -644,7 +645,7 @@ def file_type_for_plots(self, value: VALID_DEVICES_LITERAL): self._run( f"/show, {value.upper()}" ) # To avoid recursion we need to use _run. - self._file_type_for_plots = value.upper() + self._file_type_for_plots = value.upper() # type: ignore[assignment] else: raise ValueError(f"'{value}' is not allowed as file output for plots.") @@ -1723,7 +1724,7 @@ def open_apdl_log( " creation ('w', 'a', or 'x')." ) - self._apdl_log = open(filename, mode=mode, buffering=1) # line buffered + self._apdl_log: Optional[TextIO] = open(filename, mode=mode, buffering=1) # type: ignore[assignment] # line buffered assert self._apdl_log is not None # just opened above self._apdl_log.write( f"! APDL log script generated using PyMAPDL (ansys.mapdl.core {pymapdl.__version__})\n" @@ -2049,7 +2050,7 @@ def set_log_level(self, loglevel: DEBUG_LEVELS) -> None: >>> mapdl.set_log_level('ERROR') """ if isinstance(loglevel, str): - loglevel = loglevel.upper() + loglevel = loglevel.upper() # type: ignore[assignment] setup_logger(loglevel=loglevel) def _list(self, command): @@ -2414,7 +2415,7 @@ def run( # Tracking output device if command[:4].upper() == "/SHO" and "," in command: - self._file_type_for_plots = command.split(",")[1].upper() + self._file_type_for_plots = command.split(",")[1].upper() # type: ignore[assignment] # Invalid commands silently ignored. cmd_ = command.split(",")[0].upper() diff --git a/src/ansys/mapdl/core/mapdl_geometry.py b/src/ansys/mapdl/core/mapdl_geometry.py index 4abcf204b3b..13e840c662e 100644 --- a/src/ansys/mapdl/core/mapdl_geometry.py +++ b/src/ansys/mapdl/core/mapdl_geometry.py @@ -643,7 +643,7 @@ def generate_surface( if amin or amax: amax = amax or amin amin = amin or 1 - ninc = ninc or "" + ninc = ninc or "" # type: ignore[assignment] self._mapdl.asel("R", "AREA", vmin=amin, vmax=amax, vinc=ninc) diff --git a/src/ansys/mapdl/core/mapdl_grpc.py b/src/ansys/mapdl/core/mapdl_grpc.py index e9879307e38..b5ea6967c67 100644 --- a/src/ansys/mapdl/core/mapdl_grpc.py +++ b/src/ansys/mapdl/core/mapdl_grpc.py @@ -362,7 +362,7 @@ def __init__( "If `channel` is specified, neither `port` nor `ip` can be specified." ) if ip is None: - ip = start_parm.pop("ip", None) or "127.0.0.1" + ip = start_parm.pop("ip", None) or "127.0.0.1" # type: ignore[assignment] # setting hostname and ip ip, hostname = get_ip_hostname(ip) @@ -378,7 +378,7 @@ def __init__( port = MAPDL_DEFAULT_PORT self._port: int = int(port) - start_parm["port"] = self._port # store for `open_gui` + start_parm["port"] = self._port # type: ignore[assignment] # store for `open_gui` super().__init__( loglevel=loglevel, @@ -399,16 +399,16 @@ def __init__( self._stub: Optional[mapdl_grpc.MapdlServiceStub] = None self._cleanup: bool = cleanup_on_exit self.remove_temp_dir_on_exit: bool = remove_temp_dir_on_exit - self._jobname: str = start_parm.get("jobname", "file") + self._jobname: str = start_parm.get("jobname", "file") # type: ignore[assignment] self._path: Optional[str] = ( None # self._wrap_directory(start_parm.get("run_location")) ) self._start_instance: Optional[str] = ( - start_parm.get("start_instance") or get_start_instance() + start_parm.get("start_instance") or get_start_instance() # type: ignore[assignment] ) self._busy: bool = False # used to check if running a command on the server - self._local: bool = start_parm.get("local", True) - self._launched: bool = start_parm.get("launched", False) + self._local: bool = start_parm.get("local", True) # type: ignore[assignment] + self._launched: bool = start_parm.get("launched", False) # type: ignore[assignment] self._health_response_queue: Optional["Queue"] = None self._exiting: bool = False self._exited: Optional[bool] = None @@ -434,15 +434,15 @@ def __init__( self._subscribe_to_channel() # connect and validate to the channel - self._mapdl_process: Optional[subprocess.Popen] = start_parm.pop("process", None) # type: ignore[arg-type] + self._mapdl_process: Optional[subprocess.Popen] = start_parm.pop("process", None) # type: ignore[assignment] # saving for later use (for example open_gui) self._start_parm: Dict[str, Any] = start_parm # Storing HPC related stuff - self._jobid: int = start_parm.get("jobid") + self._jobid: int = start_parm.get("jobid") # type: ignore[assignment] self._mapdl_on_hpc: bool = bool(self._jobid) - self.finish_job_on_exit: bool = start_parm.get("finish_job_on_exit", True) + self.finish_job_on_exit: bool = start_parm.get("finish_job_on_exit", True) # type: ignore[assignment] # Queueing the stds if not self._mapdl_on_hpc and self._mapdl_process: @@ -515,7 +515,7 @@ def _connect_to_mapdl(self, timeout: int): else: self._log.debug("Connection established") - def reconnect_to_mapdl(self, timeout: int = None): + def reconnect_to_mapdl(self, timeout: Optional[int] = None): """Reconnect to an already instantiated MAPDL instance. Re-establish an stopped or crashed gRPC connection with an already alive @@ -919,7 +919,7 @@ def _server_version(self) -> tuple[int, int, int]: """ # check cache if self.__server_version is None: - self.__server_version = self._get_server_version() + self.__server_version = self._get_server_version() # type: ignore[assignment] return self.__server_version def _get_server_version(self) -> tuple[int, int, int]: @@ -1302,7 +1302,7 @@ def exit(self, save=False, force=False, **kwargs): if self._local and self._port in pymapdl._LOCAL_PORTS: pymapdl._LOCAL_PORTS.remove(self._port) - def _exit_mapdl(self, path: str = None) -> None: + def _exit_mapdl(self, path: Optional[str] = None) -> None: """Exit MAPDL and remove the lock file in `path`""" # This cannot/should not be faked if self._local: @@ -1472,7 +1472,10 @@ def _cache_pids(self): self._log.debug(f"Recaching PIDs: {self._pids}") def _remove_lock_file( - self, mapdl_path: str = None, jobname: str = None, use_cached: bool = False + self, + mapdl_path: Optional[str] = None, + jobname: Optional[str] = None, + use_cached: bool = False, ): """Removes the lock file. @@ -2113,7 +2116,7 @@ def _get_time_step_stream( # numpydoc ignore=RT01 raise ValueError("``time_step`` argument must be greater than 0``") self.logger.debug(f"The time_step argument is set to: {time_step}") - self._time_step_stream = time_step + self._time_step_stream = time_step # type: ignore[assignment] return time_step def _flush_stored(self): diff --git a/src/ansys/mapdl/core/misc.py b/src/ansys/mapdl/core/misc.py index 497acba53e1..69d5e0dc877 100644 --- a/src/ansys/mapdl/core/misc.py +++ b/src/ansys/mapdl/core/misc.py @@ -38,6 +38,7 @@ Dict, Iterable, List, + Optional, ParamSpec, Tuple, TypeVar, @@ -298,7 +299,7 @@ def last_created(filenames: List[str]) -> str: return filenames[idx] -def create_temp_dir(tmpdir: str = None, name: str = None) -> str: +def create_temp_dir(tmpdir: Optional[str] = None, name: Optional[str] = None) -> str: """Create a new unique directory at a given temporary directory""" if tmpdir is None: tmpdir = tempfile.gettempdir() @@ -341,7 +342,9 @@ def get_bounding_box(nodes_xyz: np.ndarray) -> np.ndarray: return max_ - min_ -def load_file(mapdl: "Mapdl", fname: str, priority_mapdl_file: bool = None) -> str: +def load_file( + mapdl: "Mapdl", fname: str, priority_mapdl_file: Optional[bool] = None +) -> str: """ Provide a file to the MAPDL instance. diff --git a/src/ansys/mapdl/core/parameters.py b/src/ansys/mapdl/core/parameters.py index 6c794661d2e..31e1292e552 100644 --- a/src/ansys/mapdl/core/parameters.py +++ b/src/ansys/mapdl/core/parameters.py @@ -23,12 +23,17 @@ import os import re import tempfile +from typing import Optional, Union import weakref +import numpy as np +from numpy.typing import NDArray + try: from ansys.mapdl.reader._reader import write_array _HAS_READER = True + except ModuleNotFoundError: # pragma: no cover from ansys.mapdl.core.misc import write_array @@ -799,21 +804,23 @@ def interp_star_status(status: str) -> dict[str, str]: if st == -1: return {} - lines = status[st + incr :].splitlines() elements = [] if is_array_listing(status): - myarray = np.array([each.split() for each in lines]).astype(float) + myarray_size: NDArray[np.float64] = np.array( + [each.split() for each in lines] + ).astype(float) idim = int(myarray[:, 0].max()) jdim = int(myarray[:, 1].max()) kdim = int(myarray[:, 2].max()) - myarray = np.zeros((idim, jdim, kdim)) + myarray: NDArray[np.float64] = np.zeros((idim, jdim, kdim)) for line in lines: items = line.split() if not items: continue + value: Optional[Union[float, str]] = None # line will contain either a character, scalar, or array name = items[0] if len(items) == 2 or "CHARACTER" in items[-1].upper(): diff --git a/src/ansys/mapdl/core/pool.py b/src/ansys/mapdl/core/pool.py index 0db6f5439a9..6fbe399158d 100755 --- a/src/ansys/mapdl/core/pool.py +++ b/src/ansys/mapdl/core/pool.py @@ -195,7 +195,7 @@ class MapdlPool: def __init__( self, - n_instances: int = None, + n_instances: Optional[int] = None, wait: bool = True, run_location: Optional[str] = None, ip: Optional[Union[str, List[str]]] = None, @@ -205,7 +205,7 @@ def __init__( remove_temp_dir_on_exit: bool = True, names: Optional[str] = None, override=True, - start_instance: bool = None, + start_instance: Optional[bool] = None, exec_file: Optional[str] = None, timeout: int = 30, **kwargs, @@ -876,8 +876,8 @@ def __iter__(self): def _spawn_mapdl( self, index: int, - ip: str = None, - port: int = None, + ip: Optional[str] = None, + port: Optional[int] = None, pbar: Optional[bool] = None, name: str = "", start_instance=True, From 5bc41551b9a470c3a29bf232fcf08c63545f22f0 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 10:15:49 +0100 Subject: [PATCH 08/33] mypy: add exclude paths and enable namespace/explicit package bases in pyproject.toml --- pyproject.toml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 5ed60ca4dc3..05504946b8f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -255,6 +255,18 @@ disable_error_code = [ "return", "return-value", ] +exclude = [ + "^\\.ci/", + "^build/", + "^dist/", + "^doc/", + "^examples/", + "^htmlcov/", + "^tests/", +] +explicit_package_bases = true +namespace_packages = true + [tool.towncrier] directory = "doc/changelog.d" From f1907def3f5715d476db38f032625b9bb0d70460 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 10:52:49 +0100 Subject: [PATCH 09/33] typing: refine annotations and fix mypy issues across core modules Add/adjust type hints (TextIO, Optional, list[str], TYPE_CHECKING imports), tighten function signatures, add targeted type:ignore comments, cast query results to int for SelectionStatus, and improve internal type checks/assertions. Also rename a few tests for clearer descriptions. --- src/ansys/mapdl/core/cli/convert.py | 5 +++-- src/ansys/mapdl/core/component.py | 16 ++++++++++------ src/ansys/mapdl/core/inline_functions/core.py | 8 ++++---- .../inline_functions/selection_queries.py | 12 ++++++------ src/ansys/mapdl/core/jupyter.py | 5 +++++ src/ansys/mapdl/core/licensing.py | 16 ++++++++-------- src/ansys/mapdl/core/logging.py | 2 +- src/ansys/mapdl/core/mapdl_core.py | 5 ++--- src/ansys/mapdl/core/misc.py | 12 +++++++++++- src/ansys/mapdl/core/plotting/__init__.py | 4 ++-- src/ansys/mapdl/core/plotting/visualizer.py | 19 ++++++++++++++----- src/ansys/mapdl/core/report.py | 2 +- tests/test_console.py | 4 ++-- tests/test_geometry.py | 4 ++-- tests/test_licensing.py | 3 ++- 15 files changed, 73 insertions(+), 44 deletions(-) diff --git a/src/ansys/mapdl/core/cli/convert.py b/src/ansys/mapdl/core/cli/convert.py index 5897323421f..176c61341d6 100644 --- a/src/ansys/mapdl/core/cli/convert.py +++ b/src/ansys/mapdl/core/cli/convert.py @@ -21,6 +21,7 @@ # SOFTWARE. import sys +from typing import TextIO import click @@ -198,8 +199,8 @@ help="""Set MAPDL object to avoid parameter name checks (do not raise leading underscored parameter exceptions). Defaults to `False`.""", ) def convert( - file: str, - output: str, + file: TextIO, + output: TextIO, loglevel: str, auto_exit: bool, line_ending: str, diff --git a/src/ansys/mapdl/core/component.py b/src/ansys/mapdl/core/component.py index a276986766e..f9b8805de13 100644 --- a/src/ansys/mapdl/core/component.py +++ b/src/ansys/mapdl/core/component.py @@ -169,7 +169,7 @@ def __new__( except (TypeError, ValueError): items_ = tuple() obj = super().__new__(cls, items_) - obj._type: ENTITIES_TYP = type_ # type: ignore[attr-defined] + obj._type = type_ # type: ignore[misc,attr-defined] return obj @@ -371,6 +371,10 @@ def __setitem__(self, key: str, value: ITEMS_VALUES) -> None: if not isinstance(key, str): raise ValueError("Only strings are allowed for component names.") + cmname: str + cmtype: ENTITIES_TYP + cmitems: Union[Component, List[int], Tuple[int, ...], NDArray[Any]] + if isinstance(value, Component): # Allowing to use a component object to be set. cmname = key @@ -392,7 +396,7 @@ def __setitem__(self, key: str, value: ITEMS_VALUES) -> None: ) cmname = key - cmtype: ENTITIES_TYP = value[0].upper() # type: ignore[assignment] + cmtype = value[0].upper() # type: ignore[assignment] cmitems = value[1] else: @@ -419,7 +423,7 @@ def __setitem__(self, key: str, value: ITEMS_VALUES) -> None: ) cmname = key - cmtype: ENTITIES_TYP = value # type: ignore[assignment] + cmtype = value # type: ignore[assignment] self._mapdl.cm(cmname, cmtype) @@ -439,7 +443,7 @@ def __setitem__(self, key: str, value: ITEMS_VALUES) -> None: cmname = key cmtype = self.default_entity - cmitems: Union[List[int], NDArray[Any]] = value # type: ignore[assignment] + cmitems = value # type: ignore[assignment] else: raise ValueError("Only strings or tuples are allowed for assignment.") @@ -579,10 +583,10 @@ def _parse_cmlist_indiv( cmname: str, cmtype: str, cmlist: Optional[str] = None ) -> List[int]: # Capturing blocks - if "NAME" in cmlist and "SUBCOMPONENTS" in cmlist: + if cmlist and "NAME" in cmlist and "SUBCOMPONENTS" in cmlist: header = r"NAME\s+TYPE\s+SUBCOMPONENTS" - elif "LIST COMPONENT" in cmlist: + elif cmlist and "LIST COMPONENT" in cmlist: header = "" cmlist = "\n\n".join( diff --git a/src/ansys/mapdl/core/inline_functions/core.py b/src/ansys/mapdl/core/inline_functions/core.py index 110cefa6834..a40cb24f08f 100644 --- a/src/ansys/mapdl/core/inline_functions/core.py +++ b/src/ansys/mapdl/core/inline_functions/core.py @@ -82,16 +82,16 @@ def _run_query(self, command: str, integer: bool) -> Union[int, float]: from ansys.mapdl.core.mapdl_grpc import MapdlGrpc # non_interactive mode won't work with these commands - if self._mapdl._store_commands: + if self._mapdl._store_commands: # type: ignore[attr-defined] raise MapdlRuntimeError( "Inline MAPDL functions are incompatible with the " "non_interactive mode." ) # use the underlying gRPC method if available to avoid parsing the string - resp = self._mapdl._run(f"{QUERY_NAME}={command}") - if isinstance(self._mapdl, MapdlGrpc): - value = self._mapdl.scalar_param(QUERY_NAME) + resp = self._mapdl._run(f"{QUERY_NAME}={command}") # type: ignore[attr-defined] + if isinstance(self._mapdl, MapdlGrpc): # type: ignore[attr-defined] + value = self._mapdl.scalar_param(QUERY_NAME) # type: ignore[attr-defined] if value is None: raise MapdlRuntimeError(resp) if integer: diff --git a/src/ansys/mapdl/core/inline_functions/selection_queries.py b/src/ansys/mapdl/core/inline_functions/selection_queries.py index bba1882fd48..41de4431b4d 100644 --- a/src/ansys/mapdl/core/inline_functions/selection_queries.py +++ b/src/ansys/mapdl/core/inline_functions/selection_queries.py @@ -72,7 +72,7 @@ def nsel(self, n: int) -> SelectionStatus: >>> q.nsel(0) """ - return SelectionStatus(self._run_query(f"NSEL({n})", integer=True)) + return SelectionStatus(int(self._run_query(f"NSEL({n})", integer=True))) def ksel(self, k: int) -> SelectionStatus: """Returns selection status of a keypoint. @@ -119,7 +119,7 @@ def ksel(self, k: int) -> SelectionStatus: >>> q.ksel(0) """ - return SelectionStatus(self._run_query(f"KSEL({k})", integer=True)) + return SelectionStatus(int(self._run_query(f"KSEL({k})", integer=True))) def lsel(self, n: int) -> SelectionStatus: """Returns selection status of a line. @@ -168,7 +168,7 @@ def lsel(self, n: int) -> SelectionStatus: >>> q.lsel(0) """ - return SelectionStatus(self._run_query(f"LSEL({n})", integer=True)) + return SelectionStatus(int(self._run_query(f"LSEL({n})", integer=True))) def asel(self, a: int) -> SelectionStatus: """Returns selection status of an area. @@ -218,7 +218,7 @@ def asel(self, a: int) -> SelectionStatus: >>> q.asel(0) """ - return SelectionStatus(self._run_query(f"ASEL({a})", integer=True)) + return SelectionStatus(int(self._run_query(f"ASEL({a})", integer=True))) def esel(self, e: int) -> SelectionStatus: """Returns selection status of an element. @@ -269,7 +269,7 @@ def esel(self, e: int) -> SelectionStatus: >>> q.esel(0) """ - return SelectionStatus(self._run_query(f"ESEL({e})", integer=True)) + return SelectionStatus(int(self._run_query(f"ESEL({e})", integer=True))) def vsel(self, v: int) -> SelectionStatus: """Returns selection status of a volume. @@ -322,7 +322,7 @@ def vsel(self, v: int) -> SelectionStatus: >>> q.vsel(0) """ - return SelectionStatus(self._run_query(f"VSEL({v})", integer=True)) + return SelectionStatus(int(self._run_query(f"VSEL({v})", integer=True))) class _NextSelectedEntityQueries(_QueryExecution): diff --git a/src/ansys/mapdl/core/jupyter.py b/src/ansys/mapdl/core/jupyter.py index f174f172ea1..070a50cea3f 100644 --- a/src/ansys/mapdl/core/jupyter.py +++ b/src/ansys/mapdl/core/jupyter.py @@ -22,6 +22,11 @@ """Contains methods used only when running on ANSYS's jupyterhub cluster""" +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from ansys.mapdl.core.mapdl import MapdlBase as Mapdl + try: from ansys.jupyterhub import manager except ImportError: diff --git a/src/ansys/mapdl/core/licensing.py b/src/ansys/mapdl/core/licensing.py index c20463ad51d..798c7b5191b 100644 --- a/src/ansys/mapdl/core/licensing.py +++ b/src/ansys/mapdl/core/licensing.py @@ -29,7 +29,7 @@ # the input is controlled by the library. Excluding bandit check. import subprocess # nosec B404 import time -from typing import Any, Iterator, Literal, Union +from typing import Any, Iterator, Literal, Optional, Union from ansys.mapdl.core import _HAS_ATC, LOG from ansys.mapdl.core.errors import LicenseServerConnectionError @@ -81,11 +81,11 @@ class LicenseChecker: """ def __init__(self, timeout: int = 30, verbose: bool | None = None): - self._license_file_msg = [] - self._license_file_success = None + self._license_file_msg: list[str] = [] + self._license_file_success: Optional[bool] = None - self._license_checkout_msg = [] - self._license_checkout_success = None + self._license_checkout_msg: list[str] = [] + self._license_checkout_success: Optional[bool] = None self._timeout = timeout if verbose is not None: @@ -131,7 +131,7 @@ def check_license_file(self): @threaded_daemon def checkout_license(self, host: str | None = None): - self._license_checkout_success: Optional[bool] = None + self._license_checkout_success = None try: self._check_mech_license_available(host) except Exception as error: @@ -407,10 +407,10 @@ def _check_mech_license_available( if licenses is None: licenses = LIC_TO_CHECK elif isinstance(licenses, str): - licenses = [licenses] # type: ignore[assignment] + licenses = [licenses] # At this point licenses is definitely a list - assert licenses is not None + assert isinstance(licenses, list) msg1 = "No such feature exists" msg2 = "The server is down or is not responsive." diff --git a/src/ansys/mapdl/core/logging.py b/src/ansys/mapdl/core/logging.py index 68ad206b6c3..155803a135d 100644 --- a/src/ansys/mapdl/core/logging.py +++ b/src/ansys/mapdl/core/logging.py @@ -221,7 +221,7 @@ def process(self, msg: str, kwargs: MutableMapping[str, Dict[str, str]]): kwargs["extra"] = {} # This are the extra parameters sent to log if self.extra is not None: - kwargs["extra"]["instance_name"] = self.extra.name # type: ignore[union-attr] + kwargs["extra"]["instance_name"] = self.extra.name # type: ignore[union-attr,attr-defined] return msg, kwargs def log_to_file( diff --git a/src/ansys/mapdl/core/mapdl_core.py b/src/ansys/mapdl/core/mapdl_core.py index 8d93113d0ba..fe43e6390de 100644 --- a/src/ansys/mapdl/core/mapdl_core.py +++ b/src/ansys/mapdl/core/mapdl_core.py @@ -43,7 +43,6 @@ List, Literal, Optional, - TextIO, Tuple, TypeAlias, Union, @@ -312,7 +311,7 @@ def __init__( self._ignore_errors: bool = False self._apdl_log = None self._store_commands: bool = False - self._stored_commands = [] + self._stored_commands: list[str] = [] self._response = None self._mode = start_parm.get("mode", None) self._mapdl_process = None @@ -1724,7 +1723,7 @@ def open_apdl_log( " creation ('w', 'a', or 'x')." ) - self._apdl_log: Optional[TextIO] = open(filename, mode=mode, buffering=1) # type: ignore[assignment] # line buffered + self._apdl_log = open(filename, mode=mode, buffering=1) # type: ignore[misc,no-redef] # line buffered assert self._apdl_log is not None # just opened above self._apdl_log.write( f"! APDL log script generated using PyMAPDL (ansys.mapdl.core {pymapdl.__version__})\n" diff --git a/src/ansys/mapdl/core/misc.py b/src/ansys/mapdl/core/misc.py index 69d5e0dc877..fff9b795a53 100644 --- a/src/ansys/mapdl/core/misc.py +++ b/src/ansys/mapdl/core/misc.py @@ -33,6 +33,7 @@ import tempfile from threading import Thread from typing import ( + TYPE_CHECKING, Any, Callable, Dict, @@ -51,6 +52,9 @@ from ansys.mapdl.core import _HAS_PYVISTA, _HAS_VISUALIZER, LOG from ansys.mapdl.core.plotting import GraphicsBackend +if TYPE_CHECKING: + from ansys.mapdl.core.mapdl import MapdlBase as Mapdl + # path of this module _frame = inspect.currentframe() MODULE_PATH = ( @@ -98,6 +102,10 @@ def check_valid_routine(routine: Union[str, ROUTINES]) -> bool: ValueError Raised when a routine is invalid. """ + # Convert ROUTINES enum to string if necessary + if isinstance(routine, ROUTINES): + return True + if routine.lower().startswith("/"): routine = routine[1:] @@ -544,7 +552,9 @@ def wrapper(self, *args, **kwargs): return decorator -def _get_args_xsel(*args: Tuple[str], **kwargs: Dict[str, str]) -> Tuple[str]: +def _get_args_xsel( + *args: str, **kwargs: str +) -> Tuple[str, str, str, str, str, str, str, Dict[str, str]]: type_ = kwargs.pop("type_", str(args[0]) if len(args) else "").upper() item = kwargs.pop("item", str(args[1]) if len(args) > 1 else "").upper() comp = kwargs.pop("comp", str(args[2]) if len(args) > 2 else "").upper() diff --git a/src/ansys/mapdl/core/plotting/__init__.py b/src/ansys/mapdl/core/plotting/__init__.py index 39fb194d051..988e1cb64bf 100644 --- a/src/ansys/mapdl/core/plotting/__init__.py +++ b/src/ansys/mapdl/core/plotting/__init__.py @@ -40,8 +40,8 @@ class GraphicsBackend(Enum): This enum is used to set the graphics backend for PyMAPDL. """ - PYVISTA: str = "pyvista" - MAPDL: str = "mapdl" + PYVISTA = "pyvista" + MAPDL = "mapdl" if _HAS_VISUALIZER: diff --git a/src/ansys/mapdl/core/plotting/visualizer.py b/src/ansys/mapdl/core/plotting/visualizer.py index 264b394485a..be9e2fb9d4c 100644 --- a/src/ansys/mapdl/core/plotting/visualizer.py +++ b/src/ansys/mapdl/core/plotting/visualizer.py @@ -84,11 +84,19 @@ def __init__( ) def plot_iter( - self, plottable_object: Any, name_filter: str = None, **plotting_options + self, + plottable_object: Any, + name_filter: Optional[str] = None, + **plotting_options, ): pass - def plot(self, plottable_object: Any, name_filter: str = None, **plotting_options): + def plot( + self, + plottable_object: Any, + name_filter: Optional[str] = None, + **plotting_options, + ): pass @property @@ -131,8 +139,8 @@ def __init__( self._theme = theme if theme is None: self._theme = MapdlTheme() - self._off_screen = None - self._notebook = None + self._off_screen: Optional[bool] = None + self._notebook: Optional[bool] = None self._savefig = None self._title = None self._bc_settings = None @@ -285,7 +293,7 @@ def add_points(self, points: Iterable[float], **plotting_options) -> None: def plot_iter( self, plotting_list: Iterable[Any], - name_filter: str = None, + name_filter: Optional[str] = None, **plotting_options, ) -> None: """Add a list of objects to the plotter. @@ -413,6 +421,7 @@ def add_mesh( if ( "scalars" in mesh + and scalars is not None and scalars.ndim == 2 and (scalars.shape[1] == 3 or scalars.shape[1] == 4) ): diff --git a/src/ansys/mapdl/core/report.py b/src/ansys/mapdl/core/report.py index 89f28d9f753..c63abdbbf35 100644 --- a/src/ansys/mapdl/core/report.py +++ b/src/ansys/mapdl/core/report.py @@ -192,7 +192,7 @@ def mapdl_info(self): if _HAS_PYANSYS_REPORT: base_report_class: Type[pyansys_report.Report] = pyansys_report.Report else: # pragma: no cover - base_report_class: Type[Plain_Report] = Plain_Report + base_report_class = Plain_Report class Report(base_report_class): # type: ignore[misc] diff --git a/tests/test_console.py b/tests/test_console.py index 7e72acae03c..4ddacbb671b 100644 --- a/tests/test_console.py +++ b/tests/test_console.py @@ -211,7 +211,7 @@ def test_bsplin(cleared, mapdl_console): assert l0 == 1 -def test_a(cleared, mapdl_console): +def test_a_bsplin(cleared, mapdl_console): k0 = mapdl_console.k("", 0, 0, 0) k1 = mapdl_console.k("", 1, 0, 0) k2 = mapdl_console.k("", 1, 1, 0) @@ -609,7 +609,7 @@ def test_partial_mesh_n_cells(mapdl_console, make_block): assert mapdl_console.mesh._grid.n_cells == 11 -def test_cyclic_solve(mapdl_console, cleared): +def test_cyclic_solve_partial_mesh(mapdl_console, cleared): # build the cyclic model mapdl_console.prep7() mapdl_console.shpp("off") diff --git a/tests/test_geometry.py b/tests/test_geometry.py index 59c6e5589fe..d0a7e1db6d6 100644 --- a/tests/test_geometry.py +++ b/tests/test_geometry.py @@ -319,7 +319,7 @@ def test_blc4(cleared, mapdl): assert mapdl.blc4(0, 0, 1, 1) == 1 -def test_kbetw(cleared, mapdl): +def test_kbetw_blc4(cleared, mapdl): k0 = mapdl.k("", 0, 0, 0) k1 = mapdl.k("", 1, 0, 0) assert mapdl.kbetw(k0, k1) == 3 @@ -422,7 +422,7 @@ def test_bsplin(cleared, mapdl): assert l0 == 1 -def test_a(cleared, mapdl): +def test_a_bsplin(cleared, mapdl): k0 = mapdl.k("", 0, 0, 0) k1 = mapdl.k("", 1, 0, 0) k2 = mapdl.k("", 1, 1, 0) diff --git a/tests/test_licensing.py b/tests/test_licensing.py index 5457fbdfeae..83662d0a1fe 100644 --- a/tests/test_licensing.py +++ b/tests/test_licensing.py @@ -33,10 +33,11 @@ from conftest import ON_LOCAL as IS_LOCAL from conftest import QUICK_LAUNCH_SWITCHES, requires +LIC_INSTALLED: bool = False try: LIC_INSTALLED = os.path.isfile(licensing.get_ansys_license_utility_path()) except: - LIC_INSTALLED = None + pass skip_no_lic_bin = pytest.mark.skipif( not (LIC_INSTALLED and IS_LOCAL), From 2317d1ce46a368c30a0b605784fe3b878ae50d46 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 10:55:08 +0100 Subject: [PATCH 10/33] Fix licensing.py type annotation for licenses list assignment --- .codacy/codacy.yaml | 11 +++++++++++ src/ansys/mapdl/core/licensing.py | 12 ++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 .codacy/codacy.yaml diff --git a/.codacy/codacy.yaml b/.codacy/codacy.yaml new file mode 100644 index 00000000000..d0b7994f625 --- /dev/null +++ b/.codacy/codacy.yaml @@ -0,0 +1,11 @@ +runtimes: + - java@17.0.10 + - node@22.2.0 + - python@3.11.11 +tools: + - eslint@8.57.0 + - lizard@1.17.31 + - pmd@6.55.0 + - pylint@3.3.7 + - semgrep@1.78.0 + - trivy@0.65.0 diff --git a/src/ansys/mapdl/core/licensing.py b/src/ansys/mapdl/core/licensing.py index 798c7b5191b..6dce2a14b28 100644 --- a/src/ansys/mapdl/core/licensing.py +++ b/src/ansys/mapdl/core/licensing.py @@ -404,17 +404,17 @@ def _check_mech_license_available( When errors messages found in the output of the license file. """ + licenses_list: list[str] if licenses is None: - licenses = LIC_TO_CHECK + licenses_list = list(LIC_TO_CHECK) elif isinstance(licenses, str): - licenses = [licenses] - - # At this point licenses is definitely a list - assert isinstance(licenses, list) + licenses_list = [licenses] + else: + licenses_list = [licenses] msg1 = "No such feature exists" msg2 = "The server is down or is not responsive." - for each_license in licenses: + for each_license in licenses_list: output = self._checkout_license(each_license, host) if isinstance(output, str) and (msg1 in output or msg2 in output): raise LicenseServerConnectionError(output) From 8c7e1123231e20deb9432d3b2a5191e97cde7a53 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 10:58:38 +0100 Subject: [PATCH 11/33] Fix mapdl_grpc.py type issues: None checks, type annotations, timeout handling --- src/ansys/mapdl/core/mapdl_grpc.py | 35 +++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/ansys/mapdl/core/mapdl_grpc.py b/src/ansys/mapdl/core/mapdl_grpc.py index b5ea6967c67..4250b68820b 100644 --- a/src/ansys/mapdl/core/mapdl_grpc.py +++ b/src/ansys/mapdl/core/mapdl_grpc.py @@ -326,8 +326,8 @@ class MapdlGrpc(MapdlBase): """ # Required by `_name` method to be defined before __init__ be - _ip = None - _port = None + _ip: Optional[str] = None + _port: Optional[int] = None def __init__( self, @@ -369,7 +369,7 @@ def __init__( self._hostname: str = hostname check_valid_ip(ip) - self._ip: str = ip + self._ip = ip # type: ignore[misc] # port and ip are needed to setup the log if port is None: @@ -377,7 +377,7 @@ def __init__( port = MAPDL_DEFAULT_PORT - self._port: int = int(port) + self._port = int(port) # type: ignore[misc] start_parm["port"] = self._port # type: ignore[assignment] # store for `open_gui` super().__init__( @@ -408,6 +408,7 @@ def __init__( ) self._busy: bool = False # used to check if running a command on the server self._local: bool = start_parm.get("local", True) # type: ignore[assignment] + self._xpl = None # ansXpl instance, initialized on first access self._launched: bool = start_parm.get("launched", False) # type: ignore[assignment] self._health_response_queue: Optional["Queue"] = None self._exiting: bool = False @@ -425,10 +426,10 @@ def __init__( if channel is None: self._log.debug("Creating channel to %s:%s", ip, port) - self._channel: grpc.Channel = self._create_channel(ip, port) + self._channel = self._create_channel(ip, port) # type: ignore[misc] else: self._log.debug("Using provided channel") - self._channel: grpc.Channel = channel + self._channel = channel # type: ignore[misc] # Subscribe to channel for channel state updates self._subscribe_to_channel() @@ -977,7 +978,8 @@ def _launch( self._connect() # may need to wait for viable connection in open_gui case - tmax = time.time() + timeout + timeout_value = timeout if timeout is not None else 10 + tmax = time.time() + timeout_value success = False while time.time() < tmax: try: @@ -1179,6 +1181,8 @@ def _send_command( request = pb_types.CmdRequest(command=cmd, opt=opt) # TODO: Capture keyboard exception and place this in a thread + if self._stub is None: + raise MapdlRuntimeError("MAPDL stub not initialized") grpc_response = self._stub.SendCommand(request) resp = grpc_response.response @@ -1192,6 +1196,8 @@ def _send_command_stream(self, cmd, verbose=False) -> str: # numpydoc ignore=RT request = pb_types.CmdRequest(command=cmd) time_step = self._get_time_step_stream() metadata = [("time_step_stream", str(time_step))] + if self._stub is None: + raise MapdlRuntimeError("MAPDL stub not initialized") stream = self._stub.SendCommandS(request, metadata=metadata) response = [] for item in stream: @@ -1690,6 +1696,9 @@ def _ctrl(self, cmd: str, opt1: str = ""): # numpydoc ignore=RT01 self._log.debug(f'Issuing CtrlRequest "{cmd}" with option "{opt1}".') request = anskernel.CtrlRequest(ctrl=str(cmd), opt1=str(opt1)) + if self._stub is None: + raise MapdlRuntimeError("MAPDL stub not initialized") + # handle socket closing upon exit if cmd.lower() == "exit": try: @@ -2223,6 +2232,8 @@ def _get( # numpydoc ignore=RT01 self._get_lock = True try: + if self._stub is None: + raise MapdlRuntimeError("MAPDL stub not initialized") response = self._stub.Get(pb_types.GetRequest(getcmd=cmd)) finally: self._get_lock = False @@ -2451,7 +2462,7 @@ def _download_on_local( # numpydoc ignore=RT01 "Only strings, tuple of strings or list of strings are allowed." ) - return_list_files = [] + return_list_files: list[str] = [] for file in list_files: # file is a complete path basename = os.path.basename(file) @@ -2603,6 +2614,8 @@ def _download( ("time_step_stream", "200"), ("chunk_size", str(chunk_size)), ] + if self._stub is None: + raise MapdlRuntimeError("MAPDL stub not initialized") chunks = self._stub.DownloadFile(request, metadata=metadata) file_size = save_chunks_to_file( chunks, @@ -2645,6 +2658,8 @@ def upload(self, file_name: str, progress_bar: bool = _HAS_TQDM) -> str: self._log.debug(f"Uploading file '{file_name}' to the MAPDL instance.") chunks_generator = get_file_chunks(file_name, progress_bar=progress_bar) + if self._stub is None: + raise MapdlRuntimeError("MAPDL stub not initialized") response = self._stub.UploadFile(chunks_generator) if not response.length: @@ -2717,6 +2732,8 @@ def _download_as_raw(self, target_name: str) -> str: # numpydoc ignore=RT01 string without saving it to disk. """ request = pb_types.DownloadFileRequest(name=target_name) + if self._stub is None: + raise MapdlRuntimeError("MAPDL stub not initialized") chunks = self._stub.DownloadFile(request) return b"".join([chunk.payload for chunk in chunks]) @@ -2812,6 +2829,8 @@ def scalar_param(self, pname: str) -> float: parameter does not exist. """ request = pb_types.ParameterRequest(name=pname, array=False) + if self._stub is None: + raise MapdlRuntimeError("MAPDL stub not initialized") presponse = self._stub.GetParameter(request) if presponse.val: return float(presponse.val[0]) From d85ee0f74d1d87741e1572b25c165f2b43589469 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 10:59:08 +0100 Subject: [PATCH 12/33] Fix common_grpc.py: replace None with empty string in list items --- src/ansys/mapdl/core/common_grpc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ansys/mapdl/core/common_grpc.py b/src/ansys/mapdl/core/common_grpc.py index 85e5a6cb580..2ff6fbebed5 100644 --- a/src/ansys/mapdl/core/common_grpc.py +++ b/src/ansys/mapdl/core/common_grpc.py @@ -72,7 +72,7 @@ "EPCR": STRESS_TYPES, "EPTH": STRESS_TYPES, "EPDI": STRESS_TYPES, - "EPSW": [None], + "EPSW": [""], "NL": ["SEPL", "SRAT", "HPRES", "EPEQ", "PSV", "PLWK"], "HS": ["X", "Y", "Z"], "BFE": ["TEMP"], @@ -84,7 +84,7 @@ "H": COMP_TYPE, "B": COMP_TYPE, "FMAG": COMP_TYPE, - "NLIST": [None], + "NLIST": [""], } From f785249b75587bee71700300b160e51aedee7e07 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 10:59:28 +0100 Subject: [PATCH 13/33] Fix database.py: add None check for environment variable --- src/ansys/mapdl/core/database/database.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ansys/mapdl/core/database/database.py b/src/ansys/mapdl/core/database/database.py index 2fbbbfe69ff..c65d26732bc 100644 --- a/src/ansys/mapdl/core/database/database.py +++ b/src/ansys/mapdl/core/database/database.py @@ -247,11 +247,13 @@ def start(self, port: Optional[int] = None, timeout: int = 10): # permit overriding db_port via env var for CI if not port: + env_port = os.environ.get("PYMAPDL_DB_PORT") if ( "PYMAPDL_DB_PORT" in os.environ - and os.environ.get("PYMAPDL_DB_PORT").isdigit() + and env_port is not None + and env_port.isdigit() ): - db_port_str = int(os.environ.get("PYMAPDL_DB_PORT")) + db_port_str = int(env_port) self._mapdl._log.debug( f"Setting DB port from 'PYMAPDL_DB_PORT' env var: {db_port_str}" ) From 6100d61853fa1e7c0424a726500a01231db20a35 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 11:01:38 +0100 Subject: [PATCH 14/33] Fix mapdl_core.py: initialize _remove_tmp as bool instead of None --- src/ansys/mapdl/core/mapdl_core.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/ansys/mapdl/core/mapdl_core.py b/src/ansys/mapdl/core/mapdl_core.py index fe43e6390de..ac4b7b16e17 100644 --- a/src/ansys/mapdl/core/mapdl_core.py +++ b/src/ansys/mapdl/core/mapdl_core.py @@ -43,6 +43,7 @@ List, Literal, Optional, + TextIO, Tuple, TypeAlias, Union, @@ -309,7 +310,7 @@ def __init__( self._query = None self._exited: bool = False self._ignore_errors: bool = False - self._apdl_log = None + self._apdl_log: Optional[TextIO] = None self._store_commands: bool = False self._stored_commands: list[str] = [] self._response = None @@ -317,6 +318,8 @@ def __init__( self._mapdl_process = None self._launched: bool = start_parm.get("launched", False) # type: ignore[assignment] self._stderr = None + self._archive_cache = None # type: ignore[var-annotated] + self._remove_tmp: bool = False self._stdout = None self._file_type_for_plots = file_type_for_plots self._default_file_type_for_plots = file_type_for_plots @@ -2008,6 +2011,7 @@ def __enter__(self) -> None: ]: parent.show(parent.default_file_type_for_plots) + @requires_graphics def __exit__(self, *args) -> None: parent = self._parent() assert parent is not None, "Parent reference is None" @@ -2020,7 +2024,8 @@ def __exit__(self, *args) -> None: parent.show("PNG", mute=True) parent.gfile(self._pixel_res, mute=True) - self._parent().file_type_for_plots = self.previous_device + assert parent is not None # already checked above + parent.file_type_for_plots = self.previous_device def set_log_level(self, loglevel: DEBUG_LEVELS) -> None: """Sets log level @@ -3358,11 +3363,14 @@ def screenshot( file_name = self._get_plot_name(out_) if savefig: - return self._download_plot(file_name, savefig, default_name=default_name) + self._download_plot(file_name, savefig, default_name=default_name) + return None elif self._has_matplotlib: - return self._display_plot(file_name) + self._display_plot(file_name) + return None else: self._log.debug("Since matplolib is not installed, images are not shown.") + return None def _create_session(self): """Generate a session ID.""" From 7697ac1a9a8b93f757d9880ada8aa493d9ee70be Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 11:02:25 +0100 Subject: [PATCH 15/33] Fix pool.py: handle Optional timeout parameter --- src/ansys/mapdl/core/pool.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ansys/mapdl/core/pool.py b/src/ansys/mapdl/core/pool.py index f7870509f2e..f44bfd8fc46 100755 --- a/src/ansys/mapdl/core/pool.py +++ b/src/ansys/mapdl/core/pool.py @@ -398,14 +398,15 @@ def ready(self) -> bool: def wait_for_ready(self, timeout: Optional[int] = 180) -> bool: """Wait until pool is ready.""" - timeout_ = time.time() + timeout + timeout_value = timeout if timeout is not None else 180 + timeout_ = time.time() + timeout_value while time.time() < timeout_: if self.ready: break time.sleep(0.1) else: raise TimeoutError( - f"MapdlPool is not ready after waiting {timeout} seconds." + f"MapdlPool is not ready after waiting {timeout_value} seconds." ) def _verify_unique_ports(self) -> None: From 72ebf9a80d702113e0a77a000e51f4c0740760eb Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 11:02:46 +0100 Subject: [PATCH 16/33] Fix mesh_grpc.py: cast float to int for list assignment --- src/ansys/mapdl/core/mesh_grpc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/mapdl/core/mesh_grpc.py b/src/ansys/mapdl/core/mesh_grpc.py index d43209c6309..f3b845b0d9c 100644 --- a/src/ansys/mapdl/core/mesh_grpc.py +++ b/src/ansys/mapdl/core/mesh_grpc.py @@ -887,7 +887,7 @@ def _parse_rlist(self) -> Dict[int, float]: const_[set_] = values for i, jlimit in enumerate(range(limits[0] - 1, limits[1])): - const_[set_][jlimit] = values_[i] + const_[set_][jlimit] = int(values_[i]) return const_ From 93fe786c42794e41dcd4fb9c8dd5cd137da7a8c3 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 11:03:08 +0100 Subject: [PATCH 17/33] Fix verif_files.py: add None check for inspect.currentframe() --- src/ansys/mapdl/core/examples/verif_files.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ansys/mapdl/core/examples/verif_files.py b/src/ansys/mapdl/core/examples/verif_files.py index 39dfda35ca9..3a0d291d019 100755 --- a/src/ansys/mapdl/core/examples/verif_files.py +++ b/src/ansys/mapdl/core/examples/verif_files.py @@ -26,7 +26,10 @@ import os from typing import Dict -module_path: str = os.path.dirname(inspect.getfile(inspect.currentframe())) +current_frame = inspect.currentframe() +if current_frame is None: + raise RuntimeError("Cannot get current frame") +module_path: str = os.path.dirname(inspect.getfile(current_frame)) def load_vmfiles() -> Dict[str, str]: From d44cb5d79c1896e520385e3b70ed1d2285fe9c79 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 11:03:29 +0100 Subject: [PATCH 18/33] Fix commands.py: add value parameter to property setter --- src/ansys/mapdl/core/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/mapdl/core/commands.py b/src/ansys/mapdl/core/commands.py index 54ac3314a10..725840464ce 100644 --- a/src/ansys/mapdl/core/commands.py +++ b/src/ansys/mapdl/core/commands.py @@ -566,7 +566,7 @@ def command(self): return self._cmd @command.setter - def command(self): + def command(self, value): """Not allowed to change the value of ``command``.""" pass From 4e669772d71185f080b8b7f30405005d0c60f10f Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 11:04:28 +0100 Subject: [PATCH 19/33] Fix helpers.py: remove unused namedtuple import --- src/ansys/mapdl/core/helpers.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ansys/mapdl/core/helpers.py b/src/ansys/mapdl/core/helpers.py index e66ac221ebb..c65f4c31db5 100644 --- a/src/ansys/mapdl/core/helpers.py +++ b/src/ansys/mapdl/core/helpers.py @@ -22,7 +22,6 @@ """Module for helper functions""" -from collections import namedtuple import importlib.util import os import sys @@ -45,7 +44,7 @@ def is_installed(package_name: str) -> bool: return True -def get_python_version() -> namedtuple: +def get_python_version(): # type: ignore[misc] return sys.version_info From e015e536484479fe06b82d9f66f1fbfee52e14b2 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 11:05:36 +0100 Subject: [PATCH 20/33] Fix parameters.py: move type ignore to individual dict entries --- src/ansys/mapdl/core/parameters.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ansys/mapdl/core/parameters.py b/src/ansys/mapdl/core/parameters.py index 31e1292e552..e5db766ec00 100644 --- a/src/ansys/mapdl/core/parameters.py +++ b/src/ansys/mapdl/core/parameters.py @@ -810,9 +810,9 @@ def interp_star_status(status: str) -> dict[str, str]: myarray_size: NDArray[np.float64] = np.array( [each.split() for each in lines] ).astype(float) - idim = int(myarray[:, 0].max()) - jdim = int(myarray[:, 1].max()) - kdim = int(myarray[:, 2].max()) + idim = int(myarray_size[:, 0].max()) # type: ignore[used-before-def] + jdim = int(myarray_size[:, 1].max()) # type: ignore[used-before-def] + kdim = int(myarray_size[:, 2].max()) # type: ignore[used-before-def] myarray: NDArray[np.float64] = np.zeros((idim, jdim, kdim)) for line in lines: @@ -833,7 +833,7 @@ def interp_star_status(status: str) -> dict[str, str]: value = float(items[1]) else: value = items[1] - parameters[name] = {"type": items[2], "value": value} + parameters[name] = {"type": items[2], "value": value} # type: ignore[dict-item] elif len(items) == 4: # it is an array or string array if is_array_listing(status): @@ -852,32 +852,32 @@ def interp_star_status(status: str) -> dict[str, str]: if items[1] in ["DMAT", "VEC", "SMAT"]: parameters[name] = { "type": items[1], - "MemoryMB": float(items[2]), - "dimensions": get_apdl_math_dimensions(items[3]), - "workspace": int(items[4]), + "MemoryMB": float(items[2]), # type: ignore[dict-item] + "dimensions": get_apdl_math_dimensions(items[3]), # type: ignore[dict-item] + "workspace": int(items[4]), # type: ignore[dict-item] } elif items[1] in ["LSENGINE"]: parameters[name] = { "type": items[1], - "workspace": int(items[4]), + "workspace": int(items[4]), # type: ignore[dict-item] } elif items[1] in ["C_FullFile"]: parameters[name] = {"type": items[1]} else: shape = (int(items[2]), int(items[3]), int(items[4])) - parameters[name] = {"type": items[1], "shape": shape} + parameters[name] = {"type": items[1], "shape": shape} # type: ignore[dict-item] if is_array_listing(status): dims = [ind for ind, each in enumerate([idim, jdim, kdim]) if each == 1] if dims: try: - return {name_: {"type": "ARRAY", "value": myarray.squeeze(tuple(dims))}} + return {name_: {"type": "ARRAY", "value": myarray.squeeze(tuple(dims))}} # type: ignore[dict-item] except ValueError: - return {name_: {"type": "ARRAY", "value": myarray}} + return {name_: {"type": "ARRAY", "value": myarray}} # type: ignore[dict-item] else: - return {name_: {"type": "ARRAY", "value": myarray}} + return {name_: {"type": "ARRAY", "value": myarray}} # type: ignore[dict-item] elif is_string_array: - return {name_: {"type": "STRING_ARRAY", "value": elements}} + return {name_: {"type": "STRING_ARRAY", "value": elements}} # type: ignore[dict-item] else: return parameters From 587f2f23d8820ae31f6de986f655374f3d792dc3 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 11:06:41 +0100 Subject: [PATCH 21/33] Fix krylov.py: add type ignore for operator issues with dynamic types --- src/ansys/mapdl/core/krylov.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ansys/mapdl/core/krylov.py b/src/ansys/mapdl/core/krylov.py index 00b6fd0cf22..0897e7d748f 100644 --- a/src/ansys/mapdl/core/krylov.py +++ b/src/ansys/mapdl/core/krylov.py @@ -496,14 +496,14 @@ def solve( # Loop over frequency range omega = self.freq_start * 2 * np.pi - self.intV = (self.freq_end - self.freq_start) / self.freq_steps + self.intV = (self.freq_end - self.freq_start) / self.freq_steps # type: ignore[operator] - for iFreq in range(1, self.freq_steps + 1): + for iFreq in range(1, self.freq_steps + 1): # type: ignore[operator] # form RHS at the i-th frequency point self.iRHS.zeros() if self.ramped_load == 0: # apply ramped loading - ratio = 2 * iFreq / self.freq_steps + ratio = 2 * iFreq / self.freq_steps # type: ignore[operator] if self.freq_steps == 1: ratio = 1.00 else: @@ -621,7 +621,7 @@ def expand( omega = self.freq_start * 2 * np.pi # circular frequency at starting point xii_usr_ordered = [] - for iFreq in range(1, self.freq_steps + 1): + for iFreq in range(1, self.freq_steps + 1): # type: ignore[operator] self._mapdl.vec(self.iY.id, "Z", "LINK", self.Yz.id, iFreq) # vector of solution in solver space self._mapdl.vec("Xi", "Z", "LINK", self.DzV.id, iFreq) @@ -652,7 +652,7 @@ def expand( "off", ] ): - norm_rz, norm_fz = self.compute_residuals(iFreq, RzV, Xi, omega) + norm_rz, norm_fz = self.compute_residuals(iFreq, RzV, Xi, omega) # type: ignore[misc] if self.residuals is None: self.residuals = [] # type: ignore[assignment] @@ -676,7 +676,7 @@ def compute_residuals( self.iRHS.zeros() if self.ramped_load: # apply ramped loading - ratio = 2 * iFreq / self.freq_steps + ratio = 2 * iFreq / self.freq_steps # type: ignore[operator] if self.freq_steps == 1: ratio = 1.0 else: From 085026b0f42f7a72405269db50a521f038373153 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 11:08:11 +0100 Subject: [PATCH 22/33] Fix .ci/pytest_summary.py: add index type ignore comments --- .ci/pytest_summary.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.ci/pytest_summary.py b/.ci/pytest_summary.py index d49100819ef..5ff1db3c1a0 100644 --- a/.ci/pytest_summary.py +++ b/.ci/pytest_summary.py @@ -79,15 +79,15 @@ def compute_statistics( test_stats: dict[str, TEST_STATS_TYPE] = {} for test in tests: - test_id: str = test["id"] + test_id = test["id"] # type: ignore[assignment] if test_id not in test_stats: - test_stats[test_id] = { + test_stats[test_id] = { # type: ignore[index] "durations": [], "n_tests": 0, } - test_stats[test_id]["durations"].append(test["duration"]) - test_stats[test_id]["n_tests"] += 1 + test_stats[test_id]["durations"].append(test["duration"]) # type: ignore[arg-type,index] + test_stats[test_id]["n_tests"] += 1 # type: ignore[index] summary: list[dict[str, Any]] = [] @@ -170,10 +170,10 @@ def make_bold(s: str) -> str: for i, each_key in enumerate(keys): if i == 0: - id_: str = test[each_key] + id_ = test[each_key] # type: ignore[assignment] id_ = ( - id_.replace("(", r"(") + id_.replace("(", r"(") # type: ignore[union-attr] .replace(")", r")") .replace("[", r"[") .replace("]", r"]") @@ -197,8 +197,8 @@ def make_bold(s: str) -> str: def print_summary(summary: list[dict[str, str | float]], num: int = 10): """Print the top N longest tests and the top N most variable tests.""" - longest_tests = sorted(summary, key=lambda x: -x["average_duration"])[:num] - most_variable_tests = sorted(summary, key=lambda x: -x["std_dev"])[:num] + longest_tests = sorted(summary, key=lambda x: -x["average_duration"])[:num] # type: ignore[operator] + most_variable_tests = sorted(summary, key=lambda x: -x["std_dev"])[:num] # type: ignore[operator] print(f"\n## Top {num} Longest Running Tests\n") print_table( From a84260e398aad076ec6c2d2bb498c93545800423 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 11:14:04 +0100 Subject: [PATCH 23/33] Add doc/ and examples/ exclusions to mypy pre-commit hook --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a9fc389569a..2cddd6e2443 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,6 +24,7 @@ repos: hooks: - id: mypy args: [ --follow-imports=silent, --config-file=pyproject.toml] + exclude: ^(doc/|examples/) - repo: https://github.com/ansys/pre-commit-hooks rev: v0.5.2 From e2ea13d35488b2d7bdf021f830eae4636187185b Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Tue, 18 Nov 2025 10:16:53 +0000 Subject: [PATCH 24/33] chore: adding changelog file 4309.fixed.md [dependabot-skip] --- doc/changelog.d/4309.fixed.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changelog.d/4309.fixed.md diff --git a/doc/changelog.d/4309.fixed.md b/doc/changelog.d/4309.fixed.md new file mode 100644 index 00000000000..5816c778df8 --- /dev/null +++ b/doc/changelog.d/4309.fixed.md @@ -0,0 +1 @@ +Mypy type checking issues across core modules From 1cc8e2f1635bd258bd77344f63533e5357d57f5e Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 11:28:55 +0100 Subject: [PATCH 25/33] Delete .codacy/codacy.yaml --- .codacy/codacy.yaml | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 .codacy/codacy.yaml diff --git a/.codacy/codacy.yaml b/.codacy/codacy.yaml deleted file mode 100644 index d0b7994f625..00000000000 --- a/.codacy/codacy.yaml +++ /dev/null @@ -1,11 +0,0 @@ -runtimes: - - java@17.0.10 - - node@22.2.0 - - python@3.11.11 -tools: - - eslint@8.57.0 - - lizard@1.17.31 - - pmd@6.55.0 - - pylint@3.3.7 - - semgrep@1.78.0 - - trivy@0.65.0 From 402d57727693bc6ad6c0646f152b67f5ceeaeeaf Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Tue, 18 Nov 2025 11:55:36 +0100 Subject: [PATCH 26/33] fix (common_grpc.py): relax parse_chunks typing to Any, add numpy.typing import, and update docstring --- src/ansys/mapdl/core/common_grpc.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ansys/mapdl/core/common_grpc.py b/src/ansys/mapdl/core/common_grpc.py index 2ff6fbebed5..4e93debaf2f 100644 --- a/src/ansys/mapdl/core/common_grpc.py +++ b/src/ansys/mapdl/core/common_grpc.py @@ -22,7 +22,7 @@ """Common gRPC functions""" import time -from typing import Dict, List, Literal, Optional, get_args +from typing import Any, Dict, List, Literal, Optional, get_args import grpc import numpy as np @@ -184,15 +184,15 @@ def check_vget_input(entity: str, item: str, itnum: str) -> str: def parse_chunks( - chunks: grpc.CallIterator, # type: ignore[name-defined] + chunks: Any, # type: ignore[misc] # gRPC call iterator with custom methods dtype: Optional[np.typing.DTypeLike] = None, ) -> np.ndarray: """Deserialize gRPC chunks into a numpy array. Parameters ---------- - chunks : grpc.CallIterator - generator from grpc. Each chunk contains a bytes payload + chunks : Any + gRPC response iterator. Each chunk contains a bytes payload dtype : np.dtype Numpy data type to interpret chunks as. From 8e5c9a0d8d01e4e14a5063ae718891b9f34926c8 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:01:37 +0100 Subject: [PATCH 27/33] fix (mapdl_core.py, mesh_grpc.py, tests/test_commands.py): return plot filename from screenshot, refine rlist typing, update test commands - mapdl_core.py: change _download_plot to return the copied filename (str); update screenshot signature/return to str | None and adjust logic/docstring so providing savefig returns the saved filename. - mesh_grpc.py: tighten _parse_rlist typing to dict[int, list[int | float]] and fix parsing/assignment so real-constant values preserve numeric types. - tests/test_commands.py: include "run" in the tested command list. --- src/ansys/mapdl/core/mapdl_core.py | 13 +++++-------- src/ansys/mapdl/core/mesh_grpc.py | 10 +++++----- tests/test_commands.py | 1 + 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/ansys/mapdl/core/mapdl_core.py b/src/ansys/mapdl/core/mapdl_core.py index ac4b7b16e17..cb9b26e2186 100644 --- a/src/ansys/mapdl/core/mapdl_core.py +++ b/src/ansys/mapdl/core/mapdl_core.py @@ -2588,7 +2588,7 @@ def in_ipython(): def _download_plot( self, filename: str, plot_name: str, default_name: str = "plot" - ) -> None: + ) -> str: """Copy the temporary download plot to the working directory.""" if isinstance(plot_name, str): provided = True @@ -3335,7 +3335,7 @@ def list_files(self, refresh_cache: bool = True) -> List[str]: def screenshot( self, savefig: Optional[str] = None, default_name: str = "mapdl_screenshot" - ) -> str: + ) -> str | None: """Take an MAPDL screenshot and show it in a popup window. Parameters @@ -3346,8 +3346,8 @@ def screenshot( Returns ------- - str - File name. + str | None + Returns the file name if ``savefig`` is provided. Otherwise, it returns None. Raises ------ @@ -3363,14 +3363,11 @@ def screenshot( file_name = self._get_plot_name(out_) if savefig: - self._download_plot(file_name, savefig, default_name=default_name) - return None + return self._download_plot(file_name, savefig, default_name=default_name) elif self._has_matplotlib: self._display_plot(file_name) - return None else: self._log.debug("Since matplolib is not installed, images are not shown.") - return None def _create_session(self): """Generate a session ID.""" diff --git a/src/ansys/mapdl/core/mesh_grpc.py b/src/ansys/mapdl/core/mesh_grpc.py index f3b845b0d9c..76f479ecd53 100644 --- a/src/ansys/mapdl/core/mesh_grpc.py +++ b/src/ansys/mapdl/core/mesh_grpc.py @@ -25,7 +25,6 @@ import re import threading import time -from typing import Dict import weakref from ansys.api.mapdl.v0 import ansys_kernel_pb2 as anskernel @@ -853,7 +852,7 @@ def _parse_vtk( additional_checking, ) - def _parse_rlist(self) -> Dict[int, float]: + def _parse_rlist(self) -> dict[int, list[int | float]]: # mapdl.rmore(*list) with self._mapdl.force_output: rlist = self._mapdl.rlist() @@ -869,7 +868,7 @@ def _parse_rlist(self) -> Dict[int, float]: r"REAL CONSTANT SET.*?\n\n", rlist + "\n\n", flags=re.DOTALL ) - const_ = {} + const_: dict[int, list[int | float]] = {} for each in constants_: values = [0 for i in range(18)] set_match = re.match(r"REAL CONSTANT SET\s+(\d+)\s+", each) @@ -877,6 +876,7 @@ def _parse_rlist(self) -> Dict[int, float]: items_match = re.match(r".*ITEMS\s+(\d+)\s+", each) to_match = re.match(r".*TO\s+(\d+)\s*", each) + limits = ( int(items_match.groups()[0]) if items_match else 0, int(to_match.groups()[0]) if to_match else 0, @@ -884,10 +884,10 @@ def _parse_rlist(self) -> Dict[int, float]: values_ = [float(i) for i in each.strip().splitlines()[1].split()] if not set_ in const_: - const_[set_] = values + const_[set_] = values # type: ignore for i, jlimit in enumerate(range(limits[0] - 1, limits[1])): - const_[set_][jlimit] = int(values_[i]) + const_[set_][jlimit] = values_[i] return const_ diff --git a/tests/test_commands.py b/tests/test_commands.py index 2267b4890f2..4268a944f6f 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -614,6 +614,7 @@ class Test_MAPDL_commands(TestClass): "mpwrite", "mwrite", "nplot", + "run", "sys", "vplot", "vwrite", From 6e1f7c040e729f05022e95f4257058ee63844662 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:02:19 +0100 Subject: [PATCH 28/33] ci (.pre-commit-config.yaml): remove skip for mypy hook --- .pre-commit-config.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2cddd6e2443..f9723f050f3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,6 @@ ci: # PR name when autoupdate autoupdate_commit_msg: 'ci: pre-commit autoupdate' - skip: [mypy] repos: From ec72b1fd261bcac0e99dabe64fb244b458dcd98e Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:06:25 +0100 Subject: [PATCH 29/33] refactor (misc.py): simplify creation_time by using hasattr(stat, "st_birthtime") and return mtime fallback --- src/ansys/mapdl/core/misc.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/ansys/mapdl/core/misc.py b/src/ansys/mapdl/core/misc.py index fff9b795a53..eec4830404a 100644 --- a/src/ansys/mapdl/core/misc.py +++ b/src/ansys/mapdl/core/misc.py @@ -283,14 +283,9 @@ def creation_time(path_to_file: str) -> float: return os.path.getctime(path_to_file) else: stat = os.stat(path_to_file) - try: + if hasattr(stat, "st_birthtime"): return float(stat.st_birthtime) - except AttributeError: - LOG.debug( - "We're probably on Linux. No easy way to get creation dates here, " - "so we'll settle for when its content was last modified." - ) - return stat.st_mtime + return stat.st_mtime def last_created(filenames: List[str]) -> str: From f0114e4474ab67e7cb47ed472250e53ec2583f28 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:09:51 +0100 Subject: [PATCH 30/33] fix (misc.py): add type: ignore for stat.st_birthtime in creation_time --- src/ansys/mapdl/core/misc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/mapdl/core/misc.py b/src/ansys/mapdl/core/misc.py index eec4830404a..45be591f312 100644 --- a/src/ansys/mapdl/core/misc.py +++ b/src/ansys/mapdl/core/misc.py @@ -284,7 +284,7 @@ def creation_time(path_to_file: str) -> float: else: stat = os.stat(path_to_file) if hasattr(stat, "st_birthtime"): - return float(stat.st_birthtime) + return float(stat.st_birthtime) # type: ignore[attr-defined] return stat.st_mtime From a95eae072a055b5c7c91cfd9448056080d611b25 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:13:32 +0100 Subject: [PATCH 31/33] fix (parameters.py): initialize name_ in interp_star_status to avoid unbound local reference --- src/ansys/mapdl/core/parameters.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ansys/mapdl/core/parameters.py b/src/ansys/mapdl/core/parameters.py index e5db766ec00..e2323b9d9c3 100644 --- a/src/ansys/mapdl/core/parameters.py +++ b/src/ansys/mapdl/core/parameters.py @@ -778,6 +778,7 @@ def interp_star_status(status: str) -> dict[str, str]: parameters = {} is_string_array = False + name_ = "" if is_parameter_listing(status): # Works for one parameter or general listing header = "NAME VALUE" From 969593d9ae611002e67561d7aea5bbc0bc23e888 Mon Sep 17 00:00:00 2001 From: German <28149841+germa89@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:27:43 +0100 Subject: [PATCH 32/33] ci (.github/workflows/migrator.yml): add zizmor ignore comment to persist-credentials setting --- .github/workflows/migrator.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/migrator.yml b/.github/workflows/migrator.yml index c060305460b..001ebfd678f 100644 --- a/.github/workflows/migrator.yml +++ b/.github/workflows/migrator.yml @@ -298,7 +298,7 @@ jobs: uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: ref: main - persist-credentials: true + persist-credentials: true # zizmor: ignore[artipacked] - name: Clone head repo and checkout branch. Resolve conflicts if needed. if : ${{ env.CONTINUE == 'true' }} From 208d6b1badfa5c0311646ee8e828f9103fefc4bb Mon Sep 17 00:00:00 2001 From: germa89 <28149841+germa89@users.noreply.github.com> Date: Thu, 27 Nov 2025 13:13:11 +0100 Subject: [PATCH 33/33] fix(action): correct shell command for starting Julia in test action --- .github/actions/test-julia/action.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/actions/test-julia/action.yml b/.github/actions/test-julia/action.yml index 9e23d0aae97..c1e3f41411e 100644 --- a/.github/actions/test-julia/action.yml +++ b/.github/actions/test-julia/action.yml @@ -33,6 +33,7 @@ runs: "$PYTHON_PATH" -m pip install -e . - name: "Starting Julia" - shell: julia {0} + shell: bash run: | - using Pkg; Pkg.add("PyCall");using PyCall;pymapdl = pyimport("ansys.mapdl.core");print(pymapdl.__version__) + julia -e 'using Pkg; Pkg.add("PyCall");using PyCall;pymapdl = pyimport("ansys.mapdl.core");print(pymapdl.__version__)' +