Skip to content
1 change: 1 addition & 0 deletions doc/changelog.d/4932.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Call .name if it's a SettingsBase + Path support
Comment thread
Copilot marked this conversation as resolved.
Outdated
5 changes: 3 additions & 2 deletions src/ansys/fluent/core/codegen/settingsgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,13 @@ def _get_unique_name(name):
"Integer": "int",
"Real": "float | str",
"String": "str",
"Filename": "str",
"Filename": "PathType",
"BooleanList": "list[bool]",
"IntegerList": "list[int]",
"RealVector": "tuple[float | str, float | str, float | str]",
"RealList": "list[float | str]",
"StringList": "list[str]",
"FilenameList": "list[str]",
"FilenameList": "list[PathType]",
}


Expand Down Expand Up @@ -385,6 +385,7 @@ def generate(version: str, static_infos: dict, verbose: bool = False) -> None:
header.write("# This is an auto-generated file. DO NOT EDIT!\n")
header.write("#\n")
header.write("\n")
header.write("from ansys.fluent.core._types import PathType\n")
header.write("from ansys.fluent.core.solver.flobject import *\n\n")
header.write("from ansys.fluent.core.solver.flobject import (\n")
header.write(" ExposureLevel,\n")
Expand Down
56 changes: 52 additions & 4 deletions src/ansys/fluent/core/solver/flobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
from __future__ import annotations

import collections
import collections.abc
from collections.abc import Sequence
from contextlib import contextmanager, nullcontext, suppress
from enum import Enum
import fnmatch
Expand All @@ -63,6 +65,7 @@
Generic,
List,
NewType,
Protocol,
Tuple,
TypeVar,
Union,
Expand All @@ -73,6 +76,9 @@
import warnings
import weakref

from typing_extensions import override

from ansys.fluent.core._types import PathType
from ansys.fluent.core.pyfluent_warnings import (
PyFluentDeprecationWarning,
PyFluentUserWarning,
Expand Down Expand Up @@ -696,24 +702,36 @@ def units(self) -> str | None:
return get_si_unit_for_fluent_quantity(quantity)


class SettingsBaseWithName(Protocol): # pylint: disable=missing-class-docstring
__class__: type["SettingsBase"] # pyright: ignore[reportIncompatibleMethodOverride]
name: Callable[[], str]


class Textual(Property):
"""Exposes attribute accessor on settings object - specific to string objects."""

def set_state(self, state: StateT | None = None, **kwargs):
def set_state(
self,
state: str | VariableDescriptor | SettingsBaseWithName | None = None,
**kwargs,
):
"""Set the state of the object.

Parameters
----------
state
Either str or VariableDescriptor.
Either str, settings object with a ``name()`` method or VariableDescriptor.
kwargs : Any
Keyword arguments.

Raises
------
TypeError
If state is not a string.
If state is not an appropriate type.
"""
Comment thread
Gobot1234 marked this conversation as resolved.
if isinstance(state, SettingsBase) and hasattr(state, "name"):
state = state.name()
Comment thread
Gobot1234 marked this conversation as resolved.
Comment thread
Gobot1234 marked this conversation as resolved.
Comment thread
Gobot1234 marked this conversation as resolved.

allowed_types = (str, VariableDescriptor)

if not isinstance(state, allowed_types):
Expand Down Expand Up @@ -966,11 +984,17 @@ class String(SettingsBase[str], Textual):
set_state = Textual.set_state


class Filename(SettingsBase[str], Textual):
class Filename(SettingsBase[PathType], Textual):
Comment thread
Gobot1234 marked this conversation as resolved.
Outdated
"""A ``Filename`` object representing a file name."""

_state_type = str

@override
def set_state(self, state: PathType | None = None, **kwargs):
if state is not None:
state = os.fspath(state)
return super().set_state(state, **kwargs)
Comment thread
Gobot1234 marked this conversation as resolved.
Comment on lines +1108 to +1111

def file_purpose(self):
"""Specifies whether this file is used as input or output by Fluent."""
return self.get_attr(_InlineConstants.file_purpose)
Expand All @@ -981,6 +1005,12 @@ class FilenameList(SettingsBase[StringListType], Textual):

_state_type = StringListType

@override
def set_state(self, state: Sequence[PathType] | None = None, **kwargs):
if state is not None:
state = [os.fspath(path) for path in state]
Comment thread
Gobot1234 marked this conversation as resolved.
Outdated
return super().set_state(state, **kwargs)
Comment thread
Gobot1234 marked this conversation as resolved.
Comment thread
Gobot1234 marked this conversation as resolved.

Comment thread
Gobot1234 marked this conversation as resolved.
def file_purpose(self):
"""Specifies whether this file is used as input or output by Fluent."""
return self.get_attr(_InlineConstants.file_purpose)
Expand Down Expand Up @@ -1054,6 +1084,24 @@ class StringList(SettingsBase[StringListType], Textual):

_state_type = StringListType

@override
def set_state(
self,
state: Sequence[str | SettingsBaseWithName | VariableDescriptor] | None = None,
**kwargs,
):
if isinstance(state, Sequence):
state = [
(
entry.name()
if isinstance(entry, SettingsBase) and hasattr(entry, "name")
else entry
)
for entry in state
]
Comment on lines +1207 to +1219

return super().set_state(state, **kwargs)


class BooleanList(SettingsBase[BoolListType], Property):
"""A ``BooleanList`` object representing a Boolean list setting."""
Expand Down
48 changes: 47 additions & 1 deletion tests/test_settings_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from pathlib import Path
import tempfile
import warnings

from conftest import SKIP_INVESTIGATING
Expand Down Expand Up @@ -842,7 +844,7 @@ def test_named_object_commands(mixing_elbow_settings_session):
solver = mixing_elbow_settings_session
inlets = VelocityInlets(solver)
inlets.list()
inlets.list_properties(object_name="hot-inlet")
inlets.list_properties(object_name="hot-i nlet")
Comment thread
Gobot1234 marked this conversation as resolved.
Outdated
if solver.get_fluent_version() >= FluentVersion.v261:
NamedObject.list(inlets)
NamedObject.list_properties(inlets, object_name="hot-inlet")
Expand Down Expand Up @@ -903,3 +905,47 @@ def test_read_only_command_execution(mixing_elbow_case_session):
assert contour.display.is_read_only() is True
with pytest.raises(ReadOnlyActionError):
contour.display()


def test_setting_base_with_name(mixing_elbow_settings_session):
solver = mixing_elbow_settings_session

with solver:
report_def = solver.settings.solution.report_definitions.surface.create(
"test-report-def"
)
report_def.report_type = "surface-areaavg"
report_def.field = "temperature"
report_def.surface_names = ["hot-inlet"]

report_file_obj = solver.settings.solution.monitor.report_files.create(
"test-file"
)
report_file_obj.report_defs = [report_def]

assert report_file_obj.report_defs() == [report_def.name()]


def test_filename_with_pathlib_path(mixing_elbow_settings_session):
solver = mixing_elbow_settings_session

with tempfile.TemporaryDirectory() as tmpdir, solver:
path_obj = Path(tmpdir) / "test_output.dat"
path_str = str(path_obj)

report_def = solver.settings.solution.report_definitions.surface.create(
"test-path-report"
)
report_def.report_type = "surface-areaavg"
report_def.field = "pressure"
report_def.surface_names = ["cold-inlet"]

report_file = solver.settings.solution.monitor.report_files.create(
"test-path-file"
)
report_file.report_defs = "test-path-report"

report_file.file_name = path_obj

result_path = report_file.file_name()
assert result_path == path_str
Loading