diff --git a/src/ansys/fluent/core/examples/downloads.py b/src/ansys/fluent/core/examples/downloads.py index f41527e71ccd..2a766df9858c 100644 --- a/src/ansys/fluent/core/examples/downloads.py +++ b/src/ansys/fluent/core/examples/downloads.py @@ -30,6 +30,7 @@ import zipfile import ansys.fluent.core as pyfluent +from ansys.fluent.core.types import PathType from ansys.fluent.core.utils.networking import check_url_exists, get_url_content logger = logging.getLogger("pyfluent.networking") @@ -74,7 +75,7 @@ def _get_file_url(file_name: str, directory: str | None = None) -> str: def _retrieve_file( url: str, file_name: str, - save_path: str | None = None, + save_path: "PathType | None" = None, return_without_path: bool | None = False, ) -> str: """Download specified file from specified URL.""" @@ -121,7 +122,7 @@ def _retrieve_file( def download_file( file_name: str, directory: str | None = None, - save_path: str | None = None, + save_path: "PathType | None" = None, return_without_path: bool | None = None, ) -> str: """Download specified example file from the Ansys example data repository. diff --git a/src/ansys/fluent/core/filereader/case_file.py b/src/ansys/fluent/core/filereader/case_file.py index 6150307632ee..b67418637553 100644 --- a/src/ansys/fluent/core/filereader/case_file.py +++ b/src/ansys/fluent/core/filereader/case_file.py @@ -49,6 +49,7 @@ import numpy as np from ansys.fluent.core.solver.error_message import allowed_name_error_message +from ansys.fluent.core.types import PathType from . import lispy from .pre_processor import remove_unsupported_xml_chars @@ -616,17 +617,17 @@ class CaseFile(RPVarProcessor): def __init__( self, - case_file_name: str | None = None, - project_file_name: str | None = None, + case_file_name: "PathType | None" = None, + project_file_name: "PathType | None" = None, ) -> None: """Initialize a CaseFile object. Exactly one file path argument must be specified. Parameters ---------- - case_file_name : str + case_file_name : :class:`os.PathLike` | str | None The path of a case file. - project_file_name : str + project_file_name : :class:`os.PathLike` | str | None The path of a project file from which the case file is selected. """ self._is_case_file = False diff --git a/src/ansys/fluent/core/launcher/launcher.py b/src/ansys/fluent/core/launcher/launcher.py index e7b7c8754ddf..38a20e5bfab6 100644 --- a/src/ansys/fluent/core/launcher/launcher.py +++ b/src/ansys/fluent/core/launcher/launcher.py @@ -58,6 +58,7 @@ from ansys.fluent.core.session_pure_meshing import PureMeshing from ansys.fluent.core.session_solver import Solver from ansys.fluent.core.session_solver_icing import SolverIcing +from ansys.fluent.core.types import PathType from ansys.fluent.core.utils.deprecate import all_deprecators from ansys.fluent.core.utils.fluent_version import FluentVersion @@ -162,14 +163,14 @@ def launch_fluent( graphics_driver: ( FluentWindowsGraphicsDriver | FluentLinuxGraphicsDriver | str | None ) = None, - case_file_name: str | None = None, - case_data_file_name: str | None = None, + case_file_name: "PathType | None" = None, + case_data_file_name: "PathType | None" = None, lightweight_mode: bool | None = None, mode: FluentMode | str | None = None, py: bool | None = None, gpu: bool | list[int] | None = None, - cwd: str | None = None, - fluent_path: str | None = None, + cwd: "PathType | None" = None, + fluent_path: "PathType | None" = None, topy: str | list | None = None, start_watchdog: bool | None = None, scheduler_options: dict | None = None, @@ -254,9 +255,9 @@ def launch_fluent( ``"null"``, ``"x11"``, ``"opengl2"``, ``"opengl"`` or ``"auto"``. The default is ``FluentWindowsGraphicsDriver.AUTO`` in Windows and ``FluentLinuxGraphicsDriver.AUTO`` in Linux. - case_file_name : str, optional + case_file_name : :class:`os.PathLike` or str, optional If provided, the case file at ``case_file_name`` is read into the Fluent session. - case_data_file_name : str, optional + case_data_file_name : :class:`os.PathLike` or str, optional If provided, the case and data files at ``case_data_file_name`` are read into the Fluent session. lightweight_mode : bool, optional Whether to run in lightweight mode. In lightweight mode, the lightweight settings are read into the @@ -278,9 +279,9 @@ def launch_fluent( clamped to the value of ``processor_count``. Please refer to *Starting the Fluent GPU Solver* section in *Fluent's User Guide* for more information like how to determine the GPU IDs. - cwd : str, Optional + cwd : :class:`os.PathLike` or str, optional Working directory for the Fluent client. - fluent_path: str, Optional + fluent_path: :class:`os.PathLike` or str, optional User provided Fluent installation path. topy : bool or str, optional A boolean flag to write the equivalent Python journal(s) from the journal(s) passed. diff --git a/src/ansys/fluent/core/launcher/slurm_launcher.py b/src/ansys/fluent/core/launcher/slurm_launcher.py index 75ae43556bf7..aaf9bbee5c4d 100644 --- a/src/ansys/fluent/core/launcher/slurm_launcher.py +++ b/src/ansys/fluent/core/launcher/slurm_launcher.py @@ -91,6 +91,7 @@ from ansys.fluent.core.session_pure_meshing import PureMeshing from ansys.fluent.core.session_solver import Solver from ansys.fluent.core.session_solver_icing import SolverIcing +from ansys.fluent.core.types import PathType from ansys.fluent.core.utils.fluent_version import FluentVersion logger = logging.getLogger("pyfluent.launcher") @@ -298,13 +299,13 @@ def __init__( env: Dict[str, Any] | None = None, cleanup_on_exit: bool = True, start_transcript: bool = True, - case_file_name: str | None = None, - case_data_file_name: str | None = None, + case_file_name: "PathType | None" = None, + case_data_file_name: "PathType | None" = None, lightweight_mode: bool | None = None, py: bool | None = None, gpu: bool | None = None, - cwd: str | None = None, - fluent_path: str | None = None, + cwd: "PathType | None" = None, + fluent_path: "PathType | None" = None, topy: str | list | None = None, start_watchdog: bool | None = None, scheduler_options: dict | None = None, @@ -359,10 +360,10 @@ def __init__( default is ``True``. You can stop and start the streaming of the Fluent transcript subsequently via the method calls, ``transcript.start()`` and ``transcript.stop()`` on the session object. - case_file_name : str, optional + case_file_name : :class:`os.PathLike` or str, optional Name of the case file to read into the Fluent session. The default is ``None``. - case_data_file_name : str, optional + case_data_file_name : :class:`os.PathLike` or str, optional Name of the case data file. If names of both a case file and case data file are provided, they are read into the Fluent session. lightweight_mode : bool, optional Whether to run in lightweight mode. In lightweight mode, the lightweight settings are read into the @@ -375,9 +376,9 @@ def __init__( If True, Fluent will run in Python mode. Default is None. gpu : bool, optional If True, Fluent will start with GPU Solver. - cwd : str, Optional + cwd : :class:`os.PathLike` or str, optional Working directory for the Fluent client. - fluent_path: str, Optional + fluent_path: :class:`os.PathLike` or str, optional User provided Fluent installation path. topy : bool or str, optional A boolean flag to write the equivalent Python journal(s) from the journal(s) passed. diff --git a/src/ansys/fluent/core/launcher/standalone_launcher.py b/src/ansys/fluent/core/launcher/standalone_launcher.py index 10e2fd4573e7..4dd015347eeb 100644 --- a/src/ansys/fluent/core/launcher/standalone_launcher.py +++ b/src/ansys/fluent/core/launcher/standalone_launcher.py @@ -69,6 +69,7 @@ _get_server_info_file_names, ) import ansys.fluent.core.launcher.watchdog as watchdog +from ansys.fluent.core.types import PathType from ansys.fluent.core.utils.fluent_version import FluentVersion logger = logging.getLogger("pyfluent.launcher") @@ -95,13 +96,13 @@ def __init__( cleanup_on_exit: bool = True, dry_run: bool = False, start_transcript: bool = True, - case_file_name: str | None = None, - case_data_file_name: str | None = None, + case_file_name: "PathType | None" = None, + case_data_file_name: "PathType | None" = None, lightweight_mode: bool | None = None, py: bool | None = None, gpu: bool | None = None, - cwd: str | None = None, - fluent_path: str | None = None, + cwd: "PathType | None" = None, + fluent_path: "PathType | None" = None, topy: str | list | None = None, start_watchdog: bool | None = None, file_transfer_service: Any | None = None, @@ -150,9 +151,9 @@ def __init__( start_transcript : bool, optional Indicates whether to start streaming the Fluent transcript in the client. Defaults to True; streaming can be controlled via `transcript.start()` and `transcript.stop()` methods on the session object. - case_file_name : str, optional + case_file_name : :class:`os.PathLike` or str, optional Name of the case file to read into the Fluent session. Defaults to None. - case_data_file_name : str, optional + case_data_file_name : :class:`os.PathLike` or str, optional Name of the case data file. If both case and data files are provided, they are read into the session. lightweight_mode : bool, optional If True, runs in lightweight mode where mesh settings are read into a background solver session, @@ -161,9 +162,9 @@ def __init__( If True, runs Fluent in Python mode. Defaults to None. gpu : bool, optional If True, starts Fluent with GPU Solver enabled. - cwd : str, optional + cwd : :class:`os.PathLike` or str, optional Working directory for the Fluent client. - fluent_path: str, optional + fluent_path: :class:`os.PathLike` or str, optional User-specified path for Fluent installation. topy : bool or str, optional A flag indicating whether to write equivalent Python journals from provided journal files; can also specify diff --git a/src/ansys/fluent/core/meshing/meshing_workflow.py b/src/ansys/fluent/core/meshing/meshing_workflow.py index 2996c37a5231..139aef009087 100644 --- a/src/ansys/fluent/core/meshing/meshing_workflow.py +++ b/src/ansys/fluent/core/meshing/meshing_workflow.py @@ -26,8 +26,10 @@ from __future__ import annotations from enum import Enum +import os from ansys.fluent.core.services.datamodel_se import PyMenuGeneric +from ansys.fluent.core.types import PathType from ansys.fluent.core.utils.fluent_version import FluentVersion from ansys.fluent.core.workflow import Workflow @@ -272,7 +274,7 @@ def __init__( self, workflow: PyMenuGeneric, meshing: PyMenuGeneric, - file_path: str, + file_path: PathType, fluent_version: FluentVersion, ) -> None: """Initialize a ``LoadWorkflow`` instance. @@ -283,8 +285,8 @@ def __init__( Underlying workflow object. meshing : PyMenuGeneric Meshing object. - file_path: str - Path to the saved workflow. + file_path: os.PathLike[str | bytes] | str | bytes + Path to the saved workflow file. fluent_version: FluentVersion Version of Fluent in this session. """ @@ -293,7 +295,7 @@ def __init__( ) self._meshing = meshing self._unsubscribe_root_affected_callback() - self._load_workflow(file_path=file_path) + self._load_workflow(file_path=os.fspath(file_path)) class CreateWorkflow(Workflow): diff --git a/src/ansys/fluent/core/parametric.py b/src/ansys/fluent/core/parametric.py index fb5c9ae19e79..e5437a681f9d 100644 --- a/src/ansys/fluent/core/parametric.py +++ b/src/ansys/fluent/core/parametric.py @@ -51,9 +51,11 @@ """ from math import ceil +import os from typing import Any, Dict from ansys.fluent.core.launcher.launcher import launch_fluent +from ansys.fluent.core.types import PathType from ansys.fluent.core.utils.execution import asynchronous BASE_DP_NAME = "Base DP" @@ -293,11 +295,13 @@ class LocalParametricStudy: If the design point is not found. """ - def __init__(self, case_filepath: str, base_design_point_name: str = "Base DP"): + def __init__( + self, case_filepath: PathType, base_design_point_name: str = "Base DP" + ): """Initialize LocalParametricStudy.""" from ansys.fluent.core.filereader.casereader import CaseReader - self.case_filepath = case_filepath + self.case_filepath = os.fspath(case_filepath) base_design_point = LocalDesignPoint(base_design_point_name) case_reader = CaseReader(case_file_name=case_filepath) diff --git a/src/ansys/fluent/core/services/app_utilities.py b/src/ansys/fluent/core/services/app_utilities.py index 3f24675a2fac..2e0cbfb19d65 100644 --- a/src/ansys/fluent/core/services/app_utilities.py +++ b/src/ansys/fluent/core/services/app_utilities.py @@ -24,6 +24,7 @@ from dataclasses import dataclass from enum import Enum +import os from typing import List, Tuple import grpc @@ -37,6 +38,7 @@ TracingInterceptor, ) from ansys.fluent.core.streaming_services.events_streaming import SolverEvent +from ansys.fluent.core.types import PathType class AppUtilitiesService: @@ -328,9 +330,9 @@ def exit(self) -> None: """Exit.""" self.scheme.exec(("(exit-server)",)) - def set_working_directory(self, path: str) -> None: + def set_working_directory(self, path: PathType) -> None: """Change client cortex dir.""" - self.scheme.eval(f'(syncdir "{path}")') + self.scheme.eval(f'(syncdir "{os.fspath(path)}")') class AppUtilities: @@ -474,10 +476,10 @@ def exit(self) -> None: request = AppUtilitiesProtoModule.ExitRequest() self.service.exit(request) - def set_working_directory(self, path: str) -> None: + def set_working_directory(self, path: PathType) -> None: """Change client cortex dir.""" request = AppUtilitiesProtoModule.SetWorkingDirectoryRequest() - request.path = path + request.path = os.fspath(path) self.service.set_working_directory(request) diff --git a/src/ansys/fluent/core/session.py b/src/ansys/fluent/core/session.py index 67439b2d6c46..7717de18002d 100644 --- a/src/ansys/fluent/core/session.py +++ b/src/ansys/fluent/core/session.py @@ -25,6 +25,7 @@ from enum import Enum import json import logging +import os from typing import Any, Callable, Dict import warnings import weakref @@ -46,6 +47,7 @@ ) from ansys.fluent.core.streaming_services.events_streaming import EventsManager from ansys.fluent.core.streaming_services.transcript_streaming import Transcript +from ansys.fluent.core.types import PathType from ansys.fluent.core.utils.fluent_version import FluentVersion from .rpvars import RPVars @@ -452,15 +454,15 @@ def download(self, file_name: str, local_directory: str | None = None): if self._file_transfer_service: return self._file_transfer_service.download(file_name, local_directory) - def chdir(self, path: str) -> None: + def chdir(self, path: PathType) -> None: """Change Fluent working directory. Parameters ---------- - path : str + path : os.PathLike[str | bytes] | str | bytes Path of the directory to change. """ - self._app_utilities.set_working_directory(path) + self._app_utilities.set_working_directory(os.fspath(path)) def __enter__(self): return self diff --git a/src/ansys/fluent/core/session_base_meshing.py b/src/ansys/fluent/core/session_base_meshing.py index fe9c87ed6643..37612b1bd835 100644 --- a/src/ansys/fluent/core/session_base_meshing.py +++ b/src/ansys/fluent/core/session_base_meshing.py @@ -23,6 +23,7 @@ """Provides a module to get base Meshing session.""" import logging +import os from ansys.fluent.core.fluent_connection import FluentConnection from ansys.fluent.core.meshing.meshing_workflow import ( @@ -35,6 +36,7 @@ _make_datamodel_module, _make_tui_module, ) +from ansys.fluent.core.types import PathType from ansys.fluent.core.utils.fluent_version import ( FluentVersion, get_version_for_file_name, @@ -169,12 +171,12 @@ def topology_based_meshing_workflow(self, initialize: bool = True): ) return self._current_workflow - def load_workflow(self, file_path: str): + def load_workflow(self, file_path: PathType): """Datamodel root of workflow.""" self._current_workflow = LoadWorkflow( _make_datamodel_module(self, "workflow"), self.meshing, - file_path, + os.fspath(file_path), self.get_fluent_version(), ) return self._current_workflow diff --git a/src/ansys/fluent/core/session_pure_meshing.py b/src/ansys/fluent/core/session_pure_meshing.py index fd4c9b9e249e..c30f59ad92e8 100644 --- a/src/ansys/fluent/core/session_pure_meshing.py +++ b/src/ansys/fluent/core/session_pure_meshing.py @@ -23,6 +23,7 @@ """Module containing class encapsulating Fluent connection.""" import functools +import os from typing import Any, Dict import ansys.fluent.core as pyfluent @@ -34,6 +35,7 @@ from ansys.fluent.core.session_base_meshing import BaseMeshing from ansys.fluent.core.streaming_services.datamodel_streaming import DatamodelStream from ansys.fluent.core.streaming_services.events_streaming import MeshingEvent +from ansys.fluent.core.types import PathType from ansys.fluent.core.utils.data_transfer import transfer_case from ansys.fluent.core.utils.fluent_version import FluentVersion @@ -158,9 +160,9 @@ def two_dimensional_meshing(self): """Get a new 2D meshing workflow.""" return self._base_meshing.two_dimensional_meshing_workflow() - def load_workflow(self, file_path: str): + def load_workflow(self, file_path: PathType): """Load a saved workflow.""" - return self._base_meshing.load_workflow(file_path=file_path) + return self._base_meshing.load_workflow(file_path=os.fspath(file_path)) def create_workflow(self): """Create a meshing workflow.""" diff --git a/src/ansys/fluent/core/session_utilities.py b/src/ansys/fluent/core/session_utilities.py index e3a16c654ee0..9ba404588886 100644 --- a/src/ansys/fluent/core/session_utilities.py +++ b/src/ansys/fluent/core/session_utilities.py @@ -36,6 +36,7 @@ ) from ansys.fluent.core.launcher.pim_launcher import PIMLauncher from ansys.fluent.core.launcher.standalone_launcher import StandaloneLauncher +from ansys.fluent.core.types import PathType from ansys.fluent.core.utils.fluent_version import FluentVersion @@ -74,13 +75,13 @@ def from_install( cleanup_on_exit: bool = True, dry_run: bool = False, start_transcript: bool = True, - case_file_name: str | None = None, - case_data_file_name: str | None = None, + case_file_name: "PathType | None" = None, + case_data_file_name: "PathType | None" = None, lightweight_mode: bool | None = None, py: bool | None = None, gpu: bool | None = None, - cwd: str | None = None, - fluent_path: str | None = None, + cwd: "PathType | None" = None, + fluent_path: "PathType | None" = None, topy: str | list | None = None, start_watchdog: bool | None = None, file_transfer_service: Any | None = None, @@ -127,9 +128,9 @@ def from_install( start_transcript : bool, optional Indicates whether to start streaming the Fluent transcript in the client. Defaults to True; streaming can be controlled via `transcript.start()` and `transcript.stop()` methods on the session object. - case_file_name : str, optional + case_file_name : :class:`os.PathLike` or str, optional Name of the case file to read into the Fluent session. Defaults to None. - case_data_file_name : str, optional + case_data_file_name : :class:`os.PathLike` or str, optional Name of the case data file. If both case and data files are provided, they are read into the session. lightweight_mode : bool, optional If True, runs in lightweight mode where mesh settings are read into a background solver session, @@ -138,9 +139,9 @@ def from_install( If True, runs Fluent in Python mode. Defaults to None. gpu : bool, optional If True, starts Fluent with GPU Solver enabled. - cwd : str, optional + cwd : :class:`os.PathLike` or str, optional Working directory for the Fluent client. - fluent_path: str, optional + fluent_path: :class:`os.PathLike` or str, optional User-specified path for Fluent installation. topy : bool or str, optional A flag indicating whether to write equivalent Python journals from provided journal files; can also specify diff --git a/src/ansys/fluent/core/types.py b/src/ansys/fluent/core/types.py new file mode 100644 index 000000000000..c949db4f5a35 --- /dev/null +++ b/src/ansys/fluent/core/types.py @@ -0,0 +1,35 @@ +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# 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. + + +"""Common type aliases for PyFluent. + +This module centralizes reusable typing constructs +""" + +from __future__ import annotations + +import os +from typing import TypeAlias + +PathType: TypeAlias = "os.PathLike[str | bytes] | str | bytes" +"""Type alias for file system paths."""