From 2d7f9cc5a1ecdfd2f5a0ef2d9b48f74d20b93619 Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Wed, 22 Jan 2025 14:27:33 -0600 Subject: [PATCH 1/9] add explicit interface support --- src/ansys/mechanical/core/embedding/app.py | 2 +- src/ansys/mechanical/core/embedding/runtime.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/ansys/mechanical/core/embedding/app.py b/src/ansys/mechanical/core/embedding/app.py index 708b3151a..e1f743457 100644 --- a/src/ansys/mechanical/core/embedding/app.py +++ b/src/ansys/mechanical/core/embedding/app.py @@ -181,8 +181,8 @@ def __init__(self, db_file=None, private_appdata=False, **kwargs): profile.update_environment(os.environ) atexit.register(_cleanup_private_appdata, profile) - self._app = _start_application(configuration, self._version, db_file) runtime.initialize(self._version) + self._app = _start_application(configuration, self._version, db_file) connect_warnings(self) self._poster = None diff --git a/src/ansys/mechanical/core/embedding/runtime.py b/src/ansys/mechanical/core/embedding/runtime.py index f609808c7..a4b619277 100644 --- a/src/ansys/mechanical/core/embedding/runtime.py +++ b/src/ansys/mechanical/core/embedding/runtime.py @@ -44,6 +44,18 @@ def __register_function_codec(): Ansys.Mechanical.CPython.Codecs.FunctionCodec.Register() +def _bind_assembly_for_explicit_interface(assembly_name: str): + """Bind the assembly for explicit interface implementation.""" + import clr + + assembly = clr.AddReference(assembly_name) + from Python.Runtime import BindingManager, BindingOptions + + binding_options = BindingOptions() + binding_options.AllowExplicitInterfaceImplementation = True + BindingManager.SetBindingOptions(assembly, binding_options) + + def initialize(version: int) -> None: """Initialize the runtime. @@ -59,3 +71,5 @@ def initialize(version: int) -> None: # function codec is distributed with pymechanical on linux only # at version 242 or later __register_function_codec() + + _bind_assembly_for_explicit_interface("Ansys.ACT.WB1") From 39fa0295bbc971476c481c9b0ee4084469c11c6f Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Wed, 22 Jan 2025 21:06:53 +0000 Subject: [PATCH 2/9] chore: adding changelog file 1058.fixed.md [dependabot-skip] --- doc/changelog.d/1058.fixed.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changelog.d/1058.fixed.md diff --git a/doc/changelog.d/1058.fixed.md b/doc/changelog.d/1058.fixed.md new file mode 100644 index 000000000..da84df383 --- /dev/null +++ b/doc/changelog.d/1058.fixed.md @@ -0,0 +1 @@ +Add explicit interface support \ No newline at end of file From 4cdb51198c5273609b362bfcc86214c466bae43e Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Thu, 23 Jan 2025 13:20:28 -0600 Subject: [PATCH 3/9] review suggestion --- src/ansys/mechanical/core/embedding/runtime.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/ansys/mechanical/core/embedding/runtime.py b/src/ansys/mechanical/core/embedding/runtime.py index a4b619277..0d06af011 100644 --- a/src/ansys/mechanical/core/embedding/runtime.py +++ b/src/ansys/mechanical/core/embedding/runtime.py @@ -22,7 +22,9 @@ """Runtime initialize for pythonnet in embedding.""" +from importlib.metadata import distribution import os +import warnings from ansys.mechanical.core.embedding.logger import Logger @@ -71,5 +73,16 @@ def initialize(version: int) -> None: # function codec is distributed with pymechanical on linux only # at version 242 or later __register_function_codec() - - _bind_assembly_for_explicit_interface("Ansys.ACT.WB1") + try: + distribution("pythonnet") + warnings.warn( + "Explicit interface binding is not supported with pythonnet." + "Some of the Mechanical API may not work as expected." + "For using PyMechanical, we recommend you do the following:\n" + "1. Uninstall your existing pythonnet package: pip uninstall pythonnet\n" + "2. Install the ansys-pythonnet package: pip install --upgrade " + "--force-reinstall ansys-pythonnet\n", + stacklevel=2, + ) + except: + _bind_assembly_for_explicit_interface("Ansys.ACT.WB1") From 51459269bb5d6f5c4523a9ed11ee2b1d65bc97be Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Fri, 24 Jan 2025 09:41:21 -0600 Subject: [PATCH 4/9] review suggestion --- .../mechanical/core/embedding/initializer.py | 26 +++++++++++-------- .../mechanical/core/embedding/runtime.py | 14 ++-------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/ansys/mechanical/core/embedding/initializer.py b/src/ansys/mechanical/core/embedding/initializer.py index bf5160dc1..77ef00467 100644 --- a/src/ansys/mechanical/core/embedding/initializer.py +++ b/src/ansys/mechanical/core/embedding/initializer.py @@ -165,6 +165,20 @@ def __check_loaded_libs(version: int = None): # pragma: no cover ) +def __check_and_issue_pythonnet_warning(): + distribution("pythonnet") + warnings.warn( + "The pythonnet package was found in your environment " + "which interferes with the ansys-pythonnet package. " + "Some APIs may not work due to pythonnet being installed.\n\n" + "For using PyMechanical, we recommend you do the following:\n" + "1. Uninstall your existing pythonnet package: pip uninstall pythonnet\n" + "2. Install the ansys-pythonnet package: pip install --upgrade " + "--force-reinstall ansys-pythonnet\n", + stacklevel=2, + ) + + def initialize(version: int = None): """Initialize Mechanical embedding.""" global INITIALIZED_VERSION @@ -195,17 +209,7 @@ def initialize(version: int = None): # Check if 'pythonnet' is installed... and if so, throw warning try: - distribution("pythonnet") - warnings.warn( - "The pythonnet package was found in your environment " - "which interferes with the ansys-pythonnet package. " - "Some APIs may not work due to pythonnet being installed.\n\n" - "For using PyMechanical, we recommend you do the following:\n" - "1. Uninstall your existing pythonnet package: pip uninstall pythonnet\n" - "2. Install the ansys-pythonnet package: pip install --upgrade " - "--force-reinstall ansys-pythonnet\n", - stacklevel=2, - ) + __check_and_issue_pythonnet_warning() except ModuleNotFoundError: pass diff --git a/src/ansys/mechanical/core/embedding/runtime.py b/src/ansys/mechanical/core/embedding/runtime.py index 0d06af011..6059e68ba 100644 --- a/src/ansys/mechanical/core/embedding/runtime.py +++ b/src/ansys/mechanical/core/embedding/runtime.py @@ -22,10 +22,9 @@ """Runtime initialize for pythonnet in embedding.""" -from importlib.metadata import distribution import os -import warnings +from ansys.mechanical.core.embedding.initializer import __check_and_issue_pythonnet_warning from ansys.mechanical.core.embedding.logger import Logger @@ -74,15 +73,6 @@ def initialize(version: int) -> None: # at version 242 or later __register_function_codec() try: - distribution("pythonnet") - warnings.warn( - "Explicit interface binding is not supported with pythonnet." - "Some of the Mechanical API may not work as expected." - "For using PyMechanical, we recommend you do the following:\n" - "1. Uninstall your existing pythonnet package: pip uninstall pythonnet\n" - "2. Install the ansys-pythonnet package: pip install --upgrade " - "--force-reinstall ansys-pythonnet\n", - stacklevel=2, - ) + __check_and_issue_pythonnet_warning() except: _bind_assembly_for_explicit_interface("Ansys.ACT.WB1") From 3394c1720a1ce352bc1ef376b853da08c322b7b4 Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Fri, 24 Jan 2025 09:57:17 -0600 Subject: [PATCH 5/9] fix not throwing exception --- src/ansys/mechanical/core/embedding/initializer.py | 6 +++--- src/ansys/mechanical/core/embedding/runtime.py | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/ansys/mechanical/core/embedding/initializer.py b/src/ansys/mechanical/core/embedding/initializer.py index 77ef00467..c8aa9ec5e 100644 --- a/src/ansys/mechanical/core/embedding/initializer.py +++ b/src/ansys/mechanical/core/embedding/initializer.py @@ -165,8 +165,7 @@ def __check_loaded_libs(version: int = None): # pragma: no cover ) -def __check_and_issue_pythonnet_warning(): - distribution("pythonnet") +def __issue_pythonnet_warning(): warnings.warn( "The pythonnet package was found in your environment " "which interferes with the ansys-pythonnet package. " @@ -209,7 +208,8 @@ def initialize(version: int = None): # Check if 'pythonnet' is installed... and if so, throw warning try: - __check_and_issue_pythonnet_warning() + distribution("pythonnet") + __issue_pythonnet_warning() except ModuleNotFoundError: pass diff --git a/src/ansys/mechanical/core/embedding/runtime.py b/src/ansys/mechanical/core/embedding/runtime.py index 6059e68ba..01642f74c 100644 --- a/src/ansys/mechanical/core/embedding/runtime.py +++ b/src/ansys/mechanical/core/embedding/runtime.py @@ -22,9 +22,10 @@ """Runtime initialize for pythonnet in embedding.""" +from importlib.metadata import distribution import os -from ansys.mechanical.core.embedding.initializer import __check_and_issue_pythonnet_warning +from ansys.mechanical.core.embedding.initializer import __issue_pythonnet_warning from ansys.mechanical.core.embedding.logger import Logger @@ -73,6 +74,7 @@ def initialize(version: int) -> None: # at version 242 or later __register_function_codec() try: - __check_and_issue_pythonnet_warning() + distribution("pythonnet") + __issue_pythonnet_warning() except: _bind_assembly_for_explicit_interface("Ansys.ACT.WB1") From 563418d4f02d96d25eec7e678385469e65391d5e Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Fri, 24 Jan 2025 14:11:57 -0600 Subject: [PATCH 6/9] update conditions --- src/ansys/mechanical/core/embedding/runtime.py | 15 +++++++++------ tests/embedding/test_app.py | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/ansys/mechanical/core/embedding/runtime.py b/src/ansys/mechanical/core/embedding/runtime.py index 01642f74c..89b8a14cb 100644 --- a/src/ansys/mechanical/core/embedding/runtime.py +++ b/src/ansys/mechanical/core/embedding/runtime.py @@ -25,7 +25,6 @@ from importlib.metadata import distribution import os -from ansys.mechanical.core.embedding.initializer import __issue_pythonnet_warning from ansys.mechanical.core.embedding.logger import Logger @@ -48,6 +47,13 @@ def __register_function_codec(): def _bind_assembly_for_explicit_interface(assembly_name: str): """Bind the assembly for explicit interface implementation.""" + # if pythonnet is not installed, we can't bind the assembly + try: + distribution("pythonnet") + return + except ModuleNotFoundError: + pass + import clr assembly = clr.AddReference(assembly_name) @@ -73,8 +79,5 @@ def initialize(version: int) -> None: # function codec is distributed with pymechanical on linux only # at version 242 or later __register_function_codec() - try: - distribution("pythonnet") - __issue_pythonnet_warning() - except: - _bind_assembly_for_explicit_interface("Ansys.ACT.WB1") + + _bind_assembly_for_explicit_interface("Ansys.ACT.WB1") diff --git a/tests/embedding/test_app.py b/tests/embedding/test_app.py index 910d83c8d..0f6a83549 100644 --- a/tests/embedding/test_app.py +++ b/tests/embedding/test_app.py @@ -96,6 +96,21 @@ def test_app_update_globals_after_open(embedded_app, assets): Model.AddNamedSelection() +@pytest.mark.embedding +def test_explicit_interface(embedded_app): + """Test save and open of the Application class.""" + embedded_app.update_globals(globals()) + try: + namedselection = Model.AddNamedSelection() + ids = list(namedselection.Ids) + assert not ids, f"Expected an empty Ids list, but got {ids}." + except AttributeError as e: + pytest.fail( + f"{str(e)}. This might be related to pythonnet." + "Unisntall pythonnet and install ansys-pythonnet." + ) + + @pytest.mark.embedding def test_app_version(embedded_app): """Test version of the Application class.""" From d1c26c176e6991eb9c57eef186e124bbb6656125 Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Fri, 24 Jan 2025 14:29:44 -0600 Subject: [PATCH 7/9] revert intializer change --- .../mechanical/core/embedding/initializer.py | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/ansys/mechanical/core/embedding/initializer.py b/src/ansys/mechanical/core/embedding/initializer.py index c8aa9ec5e..bf5160dc1 100644 --- a/src/ansys/mechanical/core/embedding/initializer.py +++ b/src/ansys/mechanical/core/embedding/initializer.py @@ -165,19 +165,6 @@ def __check_loaded_libs(version: int = None): # pragma: no cover ) -def __issue_pythonnet_warning(): - warnings.warn( - "The pythonnet package was found in your environment " - "which interferes with the ansys-pythonnet package. " - "Some APIs may not work due to pythonnet being installed.\n\n" - "For using PyMechanical, we recommend you do the following:\n" - "1. Uninstall your existing pythonnet package: pip uninstall pythonnet\n" - "2. Install the ansys-pythonnet package: pip install --upgrade " - "--force-reinstall ansys-pythonnet\n", - stacklevel=2, - ) - - def initialize(version: int = None): """Initialize Mechanical embedding.""" global INITIALIZED_VERSION @@ -209,7 +196,16 @@ def initialize(version: int = None): # Check if 'pythonnet' is installed... and if so, throw warning try: distribution("pythonnet") - __issue_pythonnet_warning() + warnings.warn( + "The pythonnet package was found in your environment " + "which interferes with the ansys-pythonnet package. " + "Some APIs may not work due to pythonnet being installed.\n\n" + "For using PyMechanical, we recommend you do the following:\n" + "1. Uninstall your existing pythonnet package: pip uninstall pythonnet\n" + "2. Install the ansys-pythonnet package: pip install --upgrade " + "--force-reinstall ansys-pythonnet\n", + stacklevel=2, + ) except ModuleNotFoundError: pass From e5ae420ad62f38afafb3cd9a81c77b3edc8eca6a Mon Sep 17 00:00:00 2001 From: Dipin <26918585+dipinknair@users.noreply.github.com> Date: Fri, 24 Jan 2025 14:31:22 -0600 Subject: [PATCH 8/9] Update tests/embedding/test_app.py --- tests/embedding/test_app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/embedding/test_app.py b/tests/embedding/test_app.py index 0f6a83549..b7b33db31 100644 --- a/tests/embedding/test_app.py +++ b/tests/embedding/test_app.py @@ -107,7 +107,7 @@ def test_explicit_interface(embedded_app): except AttributeError as e: pytest.fail( f"{str(e)}. This might be related to pythonnet." - "Unisntall pythonnet and install ansys-pythonnet." + "Uninstall pythonnet and install ansys-pythonnet." ) From b51379110efe1d2b4f058325a409c14e26fb0732 Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Mon, 27 Jan 2025 11:15:10 -0600 Subject: [PATCH 9/9] review suggestion --- tests/embedding/test_app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/embedding/test_app.py b/tests/embedding/test_app.py index b7b33db31..8a442b324 100644 --- a/tests/embedding/test_app.py +++ b/tests/embedding/test_app.py @@ -103,7 +103,7 @@ def test_explicit_interface(embedded_app): try: namedselection = Model.AddNamedSelection() ids = list(namedselection.Ids) - assert not ids, f"Expected an empty Ids list, but got {ids}." + assert len(ids) == 0, f"Expected an empty Ids list, but got {ids}." except AttributeError as e: pytest.fail( f"{str(e)}. This might be related to pythonnet."