From 5086a5b68e56866b1ac8eb474ccdfe0564e818dd Mon Sep 17 00:00:00 2001 From: Antoine Karcher Date: Tue, 11 Mar 2025 10:28:27 +0100 Subject: [PATCH 1/4] implement op version getter, inprocess only --- src/ansys/dpf/core/operator_specification.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/ansys/dpf/core/operator_specification.py b/src/ansys/dpf/core/operator_specification.py index 1bbe5aaaad..1f1896a03c 100644 --- a/src/ansys/dpf/core/operator_specification.py +++ b/src/ansys/dpf/core/operator_specification.py @@ -37,8 +37,9 @@ integral_types, operator_specification_capi, operator_specification_grpcapi, + semantic_version_capi ) - +import ctypes class PinSpecification: """Documents an input or output pin of an Operator. @@ -496,6 +497,22 @@ def config_specification(self) -> ConfigSpecification: document=option_doc, ) return self._config_specification + + @property + def version(self) -> str: + semver_obj = lambda: None + semver_obj._internal_obj = self._api.operator_specification_get_version(self) + + semver_api = self._server.get_api_for_type( + capi=semantic_version_capi.SemanticVersionCAPI, grpcapi=None + ) + + size = ctypes.c_uint64(0) + semver_api.semantic_version_to_string(semver_obj, None, ctypes.byref(size)) + buf = integral_types.MutableString(size.value) + semver_api.semantic_version_to_string(semver_obj, buf, ctypes.byref(size)) + return str(buf) + class CustomConfigOptionSpec(ConfigOptionSpec): From cf4f107e6a48848b0bfb2f0a37f418cb476f5ff7 Mon Sep 17 00:00:00 2001 From: Antoine Karcher Date: Tue, 11 Mar 2025 18:07:55 +0100 Subject: [PATCH 2/4] untested custom spec version setter --- src/ansys/dpf/core/operator_specification.py | 30 +++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/ansys/dpf/core/operator_specification.py b/src/ansys/dpf/core/operator_specification.py index 1f1896a03c..e330ff5198 100644 --- a/src/ansys/dpf/core/operator_specification.py +++ b/src/ansys/dpf/core/operator_specification.py @@ -29,7 +29,7 @@ from __future__ import annotations import abc -from typing import Union +from typing import Union, Tuple from ansys.dpf.core import common, mapping_types, server as server_module from ansys.dpf.core.check_version import server_meet_version, version_requires @@ -883,3 +883,31 @@ def properties(self, val: SpecificationProperties): for key, value in val.items(): if value is not None: self._api.operator_specification_set_property(self, key, value) + + @property + def version(self) -> str: + return super().version + + @version.setter + def version(self, ver_obj: Union[Tuple[int], Tuple[int, int], Tuple[int, int, int]]): + major = 0 + minor = 0 + patch = 0 + if isinstance(ver_obj, tuple): + if len(ver_obj) > 0 : + major = ver_obj[0] + if len(ver_obj) > 1: + minor = ver_obj[1] + if len(ver_obj) > 2: + patch = ver_obj[2] + + semver_api: semantic_version_capi.semantic_version_abstract_api.SemanticVersionAbstractAPI = self._server.get_api_for_type( + capi=semantic_version_capi.SemanticVersionCAPI, + grpcapi=None + ) + + # proxy obj + semver_obj = lambda: None + semver_obj._internal_obj = semver_api.semantic_version_new(major, minor, patch) + + self._api.operator_specification_set_version(self, semver_obj) From 164289b366825611bac66b296283268942c3d19d Mon Sep 17 00:00:00 2001 From: Antoine Karcher Date: Wed, 12 Mar 2025 11:01:56 +0100 Subject: [PATCH 3/4] added tests for custom operators --- tests/test_python_plugins.py | 24 +++++++++++++++++++ .../pythonPlugins/operator_with_spec.py | 18 ++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/tests/test_python_plugins.py b/tests/test_python_plugins.py index a13892612f..f38e1f411b 100644 --- a/tests/test_python_plugins.py +++ b/tests/test_python_plugins.py @@ -35,6 +35,7 @@ CustomSpecification, PinSpecification, SpecificationProperties, + Specification ) import conftest from conftest import ( @@ -408,3 +409,26 @@ def test_custom_op_with_spec(server_type_remote_process, testfiles_dir): outf = op.outputs.field() expected = np.ones((3, 3), dtype=np.float64) + 4.0 assert np.allclose(outf.data, expected) + + +def test_custom_op_without_version(testfiles_dir): + dpf.load_library( + dpf.path_utilities.to_server_os( + Path(testfiles_dir) / "pythonPlugins" + ), + "py_operator_with_spec", + "load_operators", + ) + spec = Specification("custom_add_to_field") + assert spec.version == "0.0.0" + +def test_custom_op_with_version(testfiles_dir): + dpf.load_library( + dpf.path_utilities.to_server_os( + Path(testfiles_dir) / "pythonPlugins", + ), + "py_operator_with_spec", + "load_operators" + ) + spec = Specification("__op_with_version") + assert spec.version == "2.3.1" \ No newline at end of file diff --git a/tests/testfiles/pythonPlugins/operator_with_spec.py b/tests/testfiles/pythonPlugins/operator_with_spec.py index 4743ff0ae4..4f8b1219e4 100644 --- a/tests/testfiles/pythonPlugins/operator_with_spec.py +++ b/tests/testfiles/pythonPlugins/operator_with_spec.py @@ -56,6 +56,24 @@ def specification(self): def name(self): return "custom_add_to_field" +class OpWithVersion(CustomOperatorBase): + def run(self): + self.set_output("The brown fox jumps over the lazy dog.") + self.set_succeeded() + + @property + def specification(self): + spec = CustomSpecification() + spec.description = "Outputs a string" + spec.outputs = { + 0: PinSpecification("message", [str], "Important message") + } + spec.version = (2, 3, 1) + return spec + @property + def name(self): + return "__op_with_version" def load_operators(*args): record_operator(AddFloatToFieldData, *args) + record_operator(OpWithVersion, *args) From a41e2acfa22c161c5ae8193cd087753687e7ca83 Mon Sep 17 00:00:00 2001 From: Antoine Karcher Date: Mon, 17 Mar 2025 17:32:27 +0100 Subject: [PATCH 4/4] use get_components directly --- src/ansys/dpf/core/operator_specification.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ansys/dpf/core/operator_specification.py b/src/ansys/dpf/core/operator_specification.py index e330ff5198..60da80eee2 100644 --- a/src/ansys/dpf/core/operator_specification.py +++ b/src/ansys/dpf/core/operator_specification.py @@ -506,12 +506,13 @@ def version(self) -> str: semver_api = self._server.get_api_for_type( capi=semantic_version_capi.SemanticVersionCAPI, grpcapi=None ) + + major = ctypes.c_uint16(0) + minor = ctypes.c_uint16(0) + patch = ctypes.c_uint16(0) + semver_api.semantic_vesion_get_components(semver_obj, ctypes.byref(major), ctypes.byref(minor), ctypes.byref(patch)) - size = ctypes.c_uint64(0) - semver_api.semantic_version_to_string(semver_obj, None, ctypes.byref(size)) - buf = integral_types.MutableString(size.value) - semver_api.semantic_version_to_string(semver_obj, buf, ctypes.byref(size)) - return str(buf) + return f"{major}.{minor}.{patch}"