From d14b18bbcdf05ed0e4bf8205df9f951f3f21250c Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Tue, 18 Jun 2024 15:30:40 -0500 Subject: [PATCH 1/8] add new funtion to print project tree --- src/ansys/mechanical/core/embedding/app.py | 50 ++++++++++++++++++++++ tests/embedding/test_app.py | 13 ++++++ 2 files changed, 63 insertions(+) diff --git a/src/ansys/mechanical/core/embedding/app.py b/src/ansys/mechanical/core/embedding/app.py index de9901148..4cf84f173 100644 --- a/src/ansys/mechanical/core/embedding/app.py +++ b/src/ansys/mechanical/core/embedding/app.py @@ -249,6 +249,56 @@ def plot(self) -> None: plot_model(self) + def print_tree(self, node, indentation=""): + """ + Recursively prints a tree structure starting from the given node. + + Each object in the tree is expected to have the following attributes: + - Name: The name of the object. + - Suppressed : Print as suppressed, if object is suppressed. + - Children: Checks if object have children. + Each child node is expected to have the all these attributes. + + Parameters + ---------- + node: ExtAPI object + The starting object of the tree. + + Raises + ------ + AttributeError + If the node does not have the required attributes. + + Examples + -------- + >>> import ansys.mechanical.core as mech + >>> app = mech.App() + >>> app.update_globals(globals()) + >>> app.print_tree(DataModel.Project) + ... ├── Project + ... | ├── Model + ... | | ├── Geometry Imports + ... | | ├── Geometry + ... | | ├── Materials + ... | | ├── Coordinate Systems + ... | | | ├── Global Coordinate System + ... | | ├── Remote Points + ... | | ├── Mesh + + Prints a hierarchical tree representation of the Mechanical project structure. + """ + if not hasattr(node, "Name"): + raise AttributeError("Object must have a 'Name' attribute") + + if hasattr(node, "Suppressed") and node.Suppressed is True: + print(f"{indentation}├── {node.Name} (Suppressed)") + else: + print(f"{indentation}├── {node.Name}") + + if hasattr(node, "Children") and node.Children is not None and node.Children.Count > 0: + for child in node.Children: + self.print_tree(child, indentation + "| ") + @property def poster(self) -> Poster: """Returns an instance of Poster.""" diff --git a/tests/embedding/test_app.py b/tests/embedding/test_app.py index f38eef1f9..62a5d03e7 100644 --- a/tests/embedding/test_app.py +++ b/tests/embedding/test_app.py @@ -103,6 +103,19 @@ def test_nonblock_sleep(embedded_app): assert (t2 - t1) >= 1 +@pytest.mark.embedding +def test_app_print_tree(embedded_app, capsys): + """Test printing hierarchical tree of Mechanical ExtAPI object""" + embedded_app.update_globals(globals()) + embedded_app.print_tree(DataModel.Project) + captured = capsys.readouterr() + printed_output = captured.out.strip() + assert "├── Project" in printed_output + + with pytest.raises(AttributeError): + embedded_app.print_tree(DataModel) + + @pytest.mark.embedding def test_app_poster(embedded_app): """The getters of app should be usable after a new(). From 1f3b6b4267fd5653e66ee9db84a3656623b0d119 Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot Date: Tue, 18 Jun 2024 20:44:32 +0000 Subject: [PATCH 2/8] Adding changelog entry: 779.added.md --- doc/changelog.d/779.added.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changelog.d/779.added.md diff --git a/doc/changelog.d/779.added.md b/doc/changelog.d/779.added.md new file mode 100644 index 000000000..76ea89a46 --- /dev/null +++ b/doc/changelog.d/779.added.md @@ -0,0 +1 @@ +FEAT: Add an App() method to print project tree for embedding scenario \ No newline at end of file From 9e8717d2dfedcdb7c0de4e34f4b740b6f54b60cc Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot Date: Tue, 18 Jun 2024 21:28:42 +0000 Subject: [PATCH 3/8] Adding changelog entry: 779.added.md --- doc/changelog.d/779.added.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/changelog.d/779.added.md b/doc/changelog.d/779.added.md index 76ea89a46..a8ca1810e 100644 --- a/doc/changelog.d/779.added.md +++ b/doc/changelog.d/779.added.md @@ -1 +1 @@ -FEAT: Add an App() method to print project tree for embedding scenario \ No newline at end of file +FEAT: Add an App method to print project tree for embedding scenario \ No newline at end of file From 33fb63b12c5b6660d75c29b6bb81b8e8188b4df2 Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Tue, 18 Jun 2024 21:11:41 -0500 Subject: [PATCH 4/8] cover suppressed case --- tests/embedding/test_app.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/embedding/test_app.py b/tests/embedding/test_app.py index 62a5d03e7..ab0cee1c7 100644 --- a/tests/embedding/test_app.py +++ b/tests/embedding/test_app.py @@ -104,9 +104,14 @@ def test_nonblock_sleep(embedded_app): @pytest.mark.embedding -def test_app_print_tree(embedded_app, capsys): +def test_app_print_tree(embedded_app, capsys, assets): """Test printing hierarchical tree of Mechanical ExtAPI object""" embedded_app.update_globals(globals()) + geometry_file = os.path.join(assets, "Eng157.x_t") + geometry_import = Model.GeometryImportGroup.AddGeometryImport() + geometry_import.Import(geometry_file) + allbodies = Model.GetChildren(DataModelObjectCategory.Body, True) + allbodies[0].Suppressed = True embedded_app.print_tree(DataModel.Project) captured = capsys.readouterr() printed_output = captured.out.strip() From 83bee75a0cca21969d2cb829f67f33af54edb528 Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Wed, 19 Jun 2024 10:23:14 -0500 Subject: [PATCH 5/8] max lines limit --- .pre-commit-config.yaml | 12 +-- src/ansys/mechanical/core/embedding/app.py | 120 ++++++++++++--------- tests/embedding/test_app.py | 8 +- 3 files changed, 82 insertions(+), 58 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 558711f8a..fed22fd72 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,12 +33,12 @@ repos: - id: codespell args: ["--ignore-words", "doc/styles/config/vocabularies/ANSYS/accept.txt", "-w"] -- repo: https://github.com/ansys/pre-commit-hooks - rev: v0.3.1 - hooks: - - id: add-license-headers - args: - - --start_year=2022 +# - repo: https://github.com/ansys/pre-commit-hooks +# rev: v0.3.1 +# hooks: +# - id: add-license-headers +# args: +# - --start_year=2022 - repo: https://github.com/pycqa/pydocstyle rev: 6.3.0 diff --git a/src/ansys/mechanical/core/embedding/app.py b/src/ansys/mechanical/core/embedding/app.py index 4cf84f173..5125985d5 100644 --- a/src/ansys/mechanical/core/embedding/app.py +++ b/src/ansys/mechanical/core/embedding/app.py @@ -249,56 +249,6 @@ def plot(self) -> None: plot_model(self) - def print_tree(self, node, indentation=""): - """ - Recursively prints a tree structure starting from the given node. - - Each object in the tree is expected to have the following attributes: - - Name: The name of the object. - - Suppressed : Print as suppressed, if object is suppressed. - - Children: Checks if object have children. - Each child node is expected to have the all these attributes. - - Parameters - ---------- - node: ExtAPI object - The starting object of the tree. - - Raises - ------ - AttributeError - If the node does not have the required attributes. - - Examples - -------- - >>> import ansys.mechanical.core as mech - >>> app = mech.App() - >>> app.update_globals(globals()) - >>> app.print_tree(DataModel.Project) - ... ├── Project - ... | ├── Model - ... | | ├── Geometry Imports - ... | | ├── Geometry - ... | | ├── Materials - ... | | ├── Coordinate Systems - ... | | | ├── Global Coordinate System - ... | | ├── Remote Points - ... | | ├── Mesh - - Prints a hierarchical tree representation of the Mechanical project structure. - """ - if not hasattr(node, "Name"): - raise AttributeError("Object must have a 'Name' attribute") - - if hasattr(node, "Suppressed") and node.Suppressed is True: - print(f"{indentation}├── {node.Name} (Suppressed)") - else: - print(f"{indentation}├── {node.Name}") - - if hasattr(node, "Children") and node.Children is not None and node.Children.Count > 0: - for child in node.Children: - self.print_tree(child, indentation + "| ") - @property def poster(self) -> Poster: """Returns an instance of Poster.""" @@ -380,3 +330,73 @@ def update_globals( def _update_all_globals(self) -> None: for scope in self._updated_scopes: scope.update(global_entry_points(self)) + + def _print_tree(self, node, max_lines=80, lines_count=0, indentation=""): + if lines_count >= max_lines and max_lines != -1: + return lines_count + + if not hasattr(node, "Name"): + raise AttributeError("Object must have a 'Name' attribute") + + node_name = node.Name + if hasattr(node, "Suppressed") and node.Suppressed is True: + node_name += " (Suppressed)" + print(f"{indentation}├── {node.Name}") + lines_count += 1 + + if hasattr(node, "Children") and node.Children is not None and node.Children.Count > 0: + for child in node.Children: + _lines_count = self._print_tree(child, max_lines, lines_count, indentation + "| ") + if _lines_count >= max_lines and max_lines != -1: + break + + return lines_count + + def print_tree(self, node, max_lines=80, lines_count=0, indentation=""): + """ + Recursively prints a tree structure starting from the given node. + + Each object in the tree is expected to have the following attributes: + - Name: The name of the object. + - Suppressed : Print as suppressed, if object is suppressed. + - Children: Checks if object have children. + Each child node is expected to have the all these attributes. + + Parameters + ---------- + node: ExtAPI object + The starting object of the tree. + max_lines: int, optional + The maximum number of lines to print. Default is 80. If set to -1, no limit is applied. + lines_count: int, optional + The current count of lines printed. Default is 0. + indentation: str, optional + The indentation string used for printing the tree structure. Default is "". + + Raises + ------ + AttributeError + If the node does not have the required attributes. + + Examples + -------- + >>> import ansys.mechanical.core as mech + >>> app = mech.App() + >>> app.update_globals(globals()) + >>> app.print_tree(DataModel.Project) + ... ├── Project + ... | ├── Model + ... | | ├── Geometry Imports + ... | | ├── Geometry + ... | | ├── Materials + ... | | ├── Coordinate Systems + ... | | | ├── Global Coordinate System + ... | | ├── Remote Points + ... | | ├── Mesh + + >>> app.print_tree(DataModel.Project, 1) + ... ├── Project + + Prints a hierarchical tree representation of the Mechanical project structure. + """ + self._print_tree(node, max_lines, lines_count, indentation) diff --git a/tests/embedding/test_app.py b/tests/embedding/test_app.py index ab0cee1c7..490619b86 100644 --- a/tests/embedding/test_app.py +++ b/tests/embedding/test_app.py @@ -112,10 +112,14 @@ def test_app_print_tree(embedded_app, capsys, assets): geometry_import.Import(geometry_file) allbodies = Model.GetChildren(DataModelObjectCategory.Body, True) allbodies[0].Suppressed = True - embedded_app.print_tree(DataModel.Project) + embedded_app.print_tree(DataModel.Project, 1) captured = capsys.readouterr() printed_output = captured.out.strip() - assert "├── Project" in printed_output + assert "Project" in printed_output + embedded_app.print_tree(DataModel.Project, 2) + captured = capsys.readouterr() + printed_output = captured.out.strip() + assert "Model" in printed_output with pytest.raises(AttributeError): embedded_app.print_tree(DataModel) From caccea9f4f7b167d973024262bc9ad0317e569d2 Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Wed, 19 Jun 2024 10:24:53 -0500 Subject: [PATCH 6/8] revert pre-commit config change --- .pre-commit-config.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fed22fd72..558711f8a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,12 +33,12 @@ repos: - id: codespell args: ["--ignore-words", "doc/styles/config/vocabularies/ANSYS/accept.txt", "-w"] -# - repo: https://github.com/ansys/pre-commit-hooks -# rev: v0.3.1 -# hooks: -# - id: add-license-headers -# args: -# - --start_year=2022 +- repo: https://github.com/ansys/pre-commit-hooks + rev: v0.3.1 + hooks: + - id: add-license-headers + args: + - --start_year=2022 - repo: https://github.com/pycqa/pydocstyle rev: 6.3.0 From 0fcfc4f72507fd74a6381fa4ffc3f77c9c1d17aa Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Wed, 19 Jun 2024 11:07:53 -0500 Subject: [PATCH 7/8] add truncate message at the end --- src/ansys/mechanical/core/embedding/app.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/ansys/mechanical/core/embedding/app.py b/src/ansys/mechanical/core/embedding/app.py index 5125985d5..15992bb7c 100644 --- a/src/ansys/mechanical/core/embedding/app.py +++ b/src/ansys/mechanical/core/embedding/app.py @@ -331,8 +331,18 @@ def _update_all_globals(self) -> None: for scope in self._updated_scopes: scope.update(global_entry_points(self)) - def _print_tree(self, node, max_lines=80, lines_count=0, indentation=""): + def _print_tree(self, node, max_lines, lines_count, indentation): + """Recursively print till provided maximum lines limit. + + Parameters + ---------- + lines_count: int, optional + The current count of lines printed. Default is 0. + indentation: str, optional + The indentation string used for printing the tree structure. Default is "". + """ if lines_count >= max_lines and max_lines != -1: + print(f"... truncating after {max_lines} lines") return lines_count if not hasattr(node, "Name"): @@ -354,7 +364,7 @@ def _print_tree(self, node, max_lines=80, lines_count=0, indentation=""): def print_tree(self, node, max_lines=80, lines_count=0, indentation=""): """ - Recursively prints a tree structure starting from the given node. + Print the hierarchical tree representation of the Mechanical project structure. Each object in the tree is expected to have the following attributes: - Name: The name of the object. @@ -368,10 +378,6 @@ def print_tree(self, node, max_lines=80, lines_count=0, indentation=""): The starting object of the tree. max_lines: int, optional The maximum number of lines to print. Default is 80. If set to -1, no limit is applied. - lines_count: int, optional - The current count of lines printed. Default is 0. - indentation: str, optional - The indentation string used for printing the tree structure. Default is "". Raises ------ @@ -396,7 +402,6 @@ def print_tree(self, node, max_lines=80, lines_count=0, indentation=""): >>> app.print_tree(DataModel.Project, 1) ... ├── Project - - Prints a hierarchical tree representation of the Mechanical project structure. + ... ... truncating after 2 line """ self._print_tree(node, max_lines, lines_count, indentation) From 4a4a239484ae42acdf87e3a1c17509088bbec44f Mon Sep 17 00:00:00 2001 From: dkunhamb Date: Wed, 19 Jun 2024 11:32:22 -0500 Subject: [PATCH 8/8] doc string fix --- src/ansys/mechanical/core/embedding/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/mechanical/core/embedding/app.py b/src/ansys/mechanical/core/embedding/app.py index 15992bb7c..3fe0d019a 100644 --- a/src/ansys/mechanical/core/embedding/app.py +++ b/src/ansys/mechanical/core/embedding/app.py @@ -402,6 +402,6 @@ def print_tree(self, node, max_lines=80, lines_count=0, indentation=""): >>> app.print_tree(DataModel.Project, 1) ... ├── Project - ... ... truncating after 2 line + ... ... truncating after 1 lines """ self._print_tree(node, max_lines, lines_count, indentation)