Skip to content
64 changes: 25 additions & 39 deletions src/ansys/fluent/core/services/datamodel_se.py
Original file line number Diff line number Diff line change
Expand Up @@ -704,15 +704,6 @@ def __init__(
self.path = path
self.parent_arg = parent_arg

def __getattr__(self, attr):
arg = self.parent_arg.info.parameters[attr]

mode = AccessorModes.get_mode(arg.type)
py_class = mode.value[1]
return MakeReadOnly(
py_class(self, attr, self.service, self.rules, self.path, arg)
)

def get_state(self) -> Any:
parent_state = self.parent.get_state()
try:
Expand Down Expand Up @@ -766,9 +757,7 @@ def __getattr__(self, attr):
if arg.name == attr:
mode = AccessorModes.get_mode(arg.type)
py_class = mode.value[1]
return MakeReadOnly(
py_class(self, attr, self.service, self.rules, self.path, arg)
)
return py_class(self, attr, self.service, self.rules, self.path, arg)


class PyTextualCommandArgumentsSubItem(PyCommandArgumentsSubItem, PyTextual):
Expand Down Expand Up @@ -835,6 +824,28 @@ def __init__(
PyParameter.__init__(self, service, rules, path)


class PySingletonCommandArgumentsSubItem(PyCommandArgumentsSubItem):
def __init__(
self,
parent,
attr,
service: DatamodelService,
rules: str,
path: Path,
arg,
):
PyCommandArgumentsSubItem.__init__(
self, parent, attr, service, rules, path, arg
)

def __getattr__(self, attr):
arg = self.parent_arg.info.parameters[attr]

mode = AccessorModes.get_mode(arg.type)
py_class = mode.value[1]
return py_class(self, attr, self.service, self.rules, self.path, arg)


class AccessorModes(Enum):
"""Provides the standard Fluent launch modes."""

Expand All @@ -849,7 +860,7 @@ class AccessorModes(Enum):
["Bool", "Logical", "Logical List"],
PyParameterCommandArgumentsSubItem,
)
GENERIC = ([], PyCommandArgumentsSubItem)
MODELOBJECT = (["ModelObject"], PySingletonCommandArgumentsSubItem)

@staticmethod
def get_mode(mode: str) -> "AccessorModes":
Expand All @@ -858,32 +869,7 @@ def get_mode(mode: str) -> "AccessorModes":
if mode in m.value[0]:
return m
else:
return AccessorModes.GENERIC


class MakeReadOnly:
"""Removes 'set_state()' attribute to implement read-only behaviour."""

_unwanted_attr = ["set_state", "setState"]

def __init__(self, cmd):
self._cmd = cmd

def __getattr__(self, attr):
if attr in MakeReadOnly._unwanted_attr:
raise AttributeError("Command Arguments are read-only.")
return getattr(self._cmd, attr)

def __dir__(self):
returned_list = sorted(
set(list(self.__dict__.keys()) + dir(type(self)) + dir(self._cmd))
)
for attr in MakeReadOnly._unwanted_attr:
returned_list.remove(attr)
return returned_list

def __call__(self):
return self._cmd()
raise TypeError(f"The specified mode: {mode} was not found.")


class PyMenuGeneric(PyMenu):
Expand Down
39 changes: 37 additions & 2 deletions src/ansys/fluent/core/workflow.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from ansys.fluent.core.services.datamodel_se import MakeReadOnly, PyCallableStateObject
from ansys.fluent.core.services.datamodel_se import PyCallableStateObject


def _new_command_for_task(task, session):
Expand Down Expand Up @@ -56,7 +56,16 @@ def _refreshed_command(self):
cmd = self._command()
if task_arg_state:
cmd.set_state(task_arg_state)
return MakeReadOnly(cmd)
return _MakeReadOnly(self._cmd_sub_items_read_only(cmd))

def _cmd_sub_items_read_only(self, cmd):
for item in cmd():
if type(getattr(cmd, item).get_state()) == dict:
setattr(
cmd, item, self._cmd_sub_items_read_only(getattr(cmd, item))
)
setattr(cmd, item, _MakeReadOnly(getattr(cmd, item)))
return cmd

def _command(self):
if not self._cmd:
Expand Down Expand Up @@ -98,3 +107,29 @@ def __dir__(self):

def __call__(self):
return self._workflow()


class _MakeReadOnly:
"""Removes 'set_state()' attribute to implement read-only behaviour."""

_unwanted_attr = ["set_state", "setState"]

def __init__(self, cmd):
self._cmd = cmd

def __getattr__(self, attr):
if attr in _MakeReadOnly._unwanted_attr:
raise AttributeError("Command Arguments are read-only.")
return getattr(self._cmd, attr)

def __dir__(self):
returned_list = sorted(
set(list(self.__dict__.keys()) + dir(type(self)) + dir(self._cmd))
)
for attr in _MakeReadOnly._unwanted_attr:
if attr in returned_list:
returned_list.remove(attr)
return returned_list

def __call__(self):
return self._cmd()
35 changes: 34 additions & 1 deletion tests/test_meshing_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,10 +287,30 @@ def test_accessors_for_argument_sub_items(new_mesh_session):
)

# Test intended to fail in numerical type (allowed_values() only available in string types)
with pytest.raises(AttributeError):
with pytest.raises(AttributeError) as msg:
assert w.task(
"Import Geometry"
).CommandArguments.CadImportOptions.FeatureAngle.allowed_values()
assert (
msg.value.args[0]
== "'PyNumericalCommandArgumentsSubItem' object has no attribute 'allowed_values'"
)

# Test intended to fail in numerical type (allowed_values() only available in string types)
with pytest.raises(AttributeError) as msg:
assert w.task("Import Geometry").CommandArguments.NumParts.allowed_values()
assert (
msg.value.args[0]
== "'PyNumericalCommandArgumentsSubItem' object has no attribute 'allowed_values'"
)

# Test intended to fail in string type (min() only available in numerical types)
with pytest.raises(AttributeError) as msg:
assert w.task("Import Geometry").CommandArguments.LengthUnit.min()
assert (
msg.value.args[0]
== "'PyTextualCommandArgumentsSubItem' object has no attribute 'min'"
)


@pytest.mark.dev
Expand All @@ -303,12 +323,25 @@ def test_read_only_behaviour_of_command_arguments(new_mesh_session):

assert "set_state" not in dir(w.task("Import Geometry").CommandArguments)
assert "set_state" not in dir(w.task("Import Geometry").CommandArguments.LengthUnit)
assert "set_state" not in dir(
w.task("Import Geometry").CommandArguments.CadImportOptions
)
assert "set_state" not in dir(
w.task("Import Geometry").CommandArguments.CadImportOptions.OneZonePer
)

with pytest.raises(AttributeError) as msg:
w.task("Import Geometry").CommandArguments.MeshUnit.set_state("in")
assert msg.value.args[0] == "Command Arguments are read-only."

with pytest.raises(AttributeError) as msg:
w.task(
"Import Geometry"
).CommandArguments.CadImportOptions.OneZonePer.set_state(None)
assert msg.value.args[0] == "Command Arguments are read-only."

assert "set_state" in dir(m.ImportGeometry.new())
assert "set_state" in dir(m.ImportGeometry.new().NumParts)


@pytest.mark.dev
Expand Down