Skip to content

Commit 5d9aedf

Browse files
authored
feat: Unstable settings warning (#2590)
* feat: Unstable settings warning * test: fix * feat: runtime query * feat: runtime query
1 parent fad4210 commit 5d9aedf

File tree

5 files changed

+69
-34
lines changed

5 files changed

+69
-34
lines changed

codegen/settingsgen.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,13 +455,13 @@ def _populate_classes(parent_dir):
455455
f.write(f"{istr1}child_object_type of {cls_name}.")
456456
f.write(f'\n{istr1}"""\n')
457457
if stubf:
458-
stubf.write(f"{istr1}{child_object_type} = ...\n")
458+
stubf.write(f"{istr1}child_object_type = ...\n")
459459

460460
return_type = getattr(cls, "return_type", None)
461461
if return_type:
462462
f.write(f'{istr1}return_type = "{return_type}"\n')
463463
if stubf:
464-
stubf.write(f"{istr1}{return_type} = ...\n")
464+
stubf.write(f"{istr1}return_type = ...\n")
465465

466466

467467
def _populate_init(parent_dir, sinfo):

src/ansys/fluent/core/session_solver.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def _import_settings_root(root):
6060
api_keys = root.child_names
6161

6262
for root_item in api_keys:
63-
_class_dict[root_item] = getattr(root, root_item)
63+
_class_dict[root_item] = root.__dict__[root_item]
6464

6565
settings_api_root = type("SettingsRoot", (object,), _class_dict)
6666
return settings_api_root()

src/ansys/fluent/core/solver/flobject.py

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -329,20 +329,19 @@ def is_active(self) -> bool:
329329
attr = self.get_attr(_InlineConstants.is_active)
330330
return False if attr is False else True
331331

332-
def _is_stable(self) -> bool:
332+
def _check_stable(self) -> None:
333333
"""Whether the object is stable."""
334-
if self.is_active():
335-
attr = self.get_attr(_InlineConstants.is_stable)
336-
else:
337-
attr = True
338-
attr = False if attr is False else True
339-
if attr is False:
334+
if not self.is_active():
335+
return
336+
attr = self.get_attr(_InlineConstants.is_stable)
337+
attr = True if attr is None else attr
338+
if not attr:
340339
warnings.warn(
341-
f"The API feature at {self.path} is not stable. "
340+
f"The API feature at '{self.path}' is not stable. "
342341
f"It is not guaranteed that it is fully validated and "
343-
f"there is no commitment to its backwards compatibility."
342+
f"there is no commitment to its backwards compatibility.",
343+
UnstableSettingWarning,
344344
)
345-
return attr
346345

347346
def is_read_only(self) -> bool:
348347
"""Whether the object is read-only."""
@@ -520,6 +519,12 @@ class DeprecatedSettingWarning(FutureWarning):
520519
pass
521520

522521

522+
class UnstableSettingWarning(UserWarning):
523+
"""Provides unstable settings warning."""
524+
525+
pass
526+
527+
523528
_show_warning_orig = warnings.showwarning
524529

525530

@@ -991,24 +996,26 @@ def get_completer_info(self, prefix="", excluded=None) -> List[List[str]]:
991996
return ret
992997

993998
def _get_parent_of_active_child_names(self, name):
994-
parents = ""
995-
path_list = []
996-
for parent in self.get_active_child_names():
997-
try:
998-
if hasattr(getattr(self, parent), str(name)):
999-
path_list.append(f" {self.python_path}.{parent}.{str(name)}")
1000-
if len(parents) != 0:
1001-
parents += ", " + parent
1002-
else:
1003-
parents += parent
1004-
except AttributeError:
1005-
pass
1006-
if len(path_list):
1007-
print(f"\n {str(name)} can be accessed from the following paths: \n")
1008-
for path in path_list:
1009-
print(path)
1010-
if len(parents):
1011-
return f"\n {name} is a child of {parents} \n"
999+
with warnings.catch_warnings():
1000+
warnings.filterwarnings(action="ignore", category=UnstableSettingWarning)
1001+
parents = ""
1002+
path_list = []
1003+
for parent in self.get_active_child_names():
1004+
try:
1005+
if hasattr(getattr(self, parent), str(name)):
1006+
path_list.append(f" {self.python_path}.{parent}.{str(name)}")
1007+
if len(parents) != 0:
1008+
parents += ", " + parent
1009+
else:
1010+
parents += parent
1011+
except AttributeError:
1012+
pass
1013+
if len(path_list):
1014+
print(f"\n {str(name)} can be accessed from the following paths: \n")
1015+
for path in path_list:
1016+
print(path)
1017+
if len(parents):
1018+
return f"\n {name} is a child of {parents} \n"
10121019

10131020
def __getattribute__(self, name):
10141021
if name in super().__getattribute__("child_names"):
@@ -1024,7 +1031,10 @@ def __getattribute__(self, name):
10241031
)
10251032
return alias_obj
10261033
try:
1027-
return super().__getattribute__(name)
1034+
attr = super().__getattribute__(name)
1035+
if name in super().__getattribute__("_child_classes"):
1036+
attr._check_stable()
1037+
return attr
10281038
except AttributeError as ex:
10291039
self._get_parent_of_active_child_names(name)
10301040
error_msg = allowed_name_error_message(

tests/test_flobject.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def get_attrs(self, attrs):
3838

3939
attrs = {
4040
"active?": lambda self: True,
41+
"webui-release-active?": lambda self: True,
4142
}
4243

4344

@@ -294,6 +295,7 @@ class S1(String):
294295
attrs = {
295296
"active?": lambda self: not self.parent.objs["b-3"].get_state(),
296297
"allowed-values": lambda self: ["foo", "bar"],
298+
"webui-release-active?": lambda self: True,
297299
}
298300

299301
children = {
@@ -365,7 +367,10 @@ def get_obj(self, path):
365367
return self.r
366368
obj = self.r
367369
for c in path.split("/"):
368-
obj = obj.get_child(c)
370+
try:
371+
obj = obj.get_child(c)
372+
except KeyError:
373+
obj = obj.get_command(c)
369374
return obj
370375

371376
def get_var(self, path):

tests/test_settings_api.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22
from util.solver_workflow import new_solver_session # noqa: F401
33

44
from ansys.fluent.core.examples import download_file
5-
from ansys.fluent.core.solver.flobject import DeprecatedSettingWarning, _Alias
5+
from ansys.fluent.core.solver.flobject import (
6+
DeprecatedSettingWarning,
7+
UnstableSettingWarning,
8+
_Alias,
9+
)
610
from ansys.fluent.core.utils.fluent_version import FluentVersion
711

812

@@ -275,3 +279,19 @@ def test_command_return_type(new_solver_session):
275279
)
276280
ret = solver.solution.report_definitions.compute(report_defs=["surface-1"])
277281
assert ret is not None
282+
283+
284+
@pytest.mark.fluent_version(">=24.2")
285+
def test_unstable_settings_warning(new_solver_session, recwarn):
286+
solver = new_solver_session
287+
solver.file.export
288+
assert len(recwarn) == 1
289+
assert recwarn.pop().category == UnstableSettingWarning
290+
try:
291+
solver.file.exp
292+
except AttributeError:
293+
pass
294+
assert len(recwarn) == 0
295+
solver.file.export
296+
assert len(recwarn) == 1
297+
assert recwarn.pop().category == UnstableSettingWarning

0 commit comments

Comments
 (0)