Repository: strictdoc-project/strictdoc
Pull request #2253: code-climate: mypy address some no-any-return
Author: login: thseiler
Labels: name: Code climate
Created: 2025-05-16T12:14:03Z | Merged: 2025-05-16T14:02:58Z

This PR addresses the bullet point "mypy: fix remaining no-any-return issues" of #2068.




Diff:
diff --git a/strictdoc/backend/sdoc/models/section.py b/strictdoc/backend/sdoc/models/section.py
index d730b1e19..760daab45 100644
--- a/strictdoc/backend/sdoc/models/section.py
+++ b/strictdoc/backend/sdoc/models/section.py
@@ -115,16 +115,16 @@ def parent_or_including_document(self) -> SDocDocumentIF:
     def document_is_included(self):
         return self.ng_including_document_reference.get_document() is not None
 
-    def is_requirement(self):
+    def is_requirement(self) -> bool:
         return False
 
-    def is_composite_requirement(self):
+    def is_composite_requirement(self) -> bool:
         return False
 
-    def is_section(self):
+    def is_section(self) -> bool:
         return True
 
-    def has_any_text_nodes(self):
+    def has_any_text_nodes(self) -> bool:
         return any(
             node_.__class__.__name__ == "SDocNode" and node_.node_type == "TEXT"
             for node_ in self.section_contents
diff --git a/strictdoc/backend/sdoc/reader.py b/strictdoc/backend/sdoc/reader.py
index 8a7dd6e7e..363ba52f7 100644
--- a/strictdoc/backend/sdoc/reader.py
+++ b/strictdoc/backend/sdoc/reader.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="no-any-return,no-untyped-call,no-untyped-def"
+# mypy: disable-error-code="no-untyped-call,no-untyped-def"
 import sys
 import traceback
 from copy import copy
diff --git a/strictdoc/core/environment.py b/strictdoc/core/environment.py
index 23af9a5a9..ed44fcd1e 100644
--- a/strictdoc/core/environment.py
+++ b/strictdoc/core/environment.py
@@ -46,14 +46,14 @@ def __init__(self, path_to_init: str):
             f"{self.path_to_strictdoc}"
         )
 
-    def get_static_files_path(self):
+    def get_static_files_path(self) -> str:
         if self.is_binary_dist:  # pragma: no cover
             return os.path.join(self.path_to_strictdoc, "_static")
         return os.path.join(
             self.path_to_strictdoc, "strictdoc/export/html/_static"
         )
 
-    def get_extra_static_files_path(self):
+    def get_extra_static_files_path(self) -> str:
         if self.is_binary_dist:  # pragma: no cover
             return os.path.join(self.path_to_strictdoc, "_static_extra")
         return os.path.join(
diff --git a/strictdoc/core/file_traceability_index.py b/strictdoc/core/file_traceability_index.py
index a9ada0242..1f4f10038 100644
--- a/strictdoc/core/file_traceability_index.py
+++ b/strictdoc/core/file_traceability_index.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="arg-type,attr-defined,no-any-return,no-untyped-def"
+# mypy: disable-error-code="arg-type,attr-defined,no-untyped-def"
 from copy import copy
 from typing import Any, Dict, Iterator, List, Optional, Set, Tuple, Union
 
diff --git a/strictdoc/core/file_tree.py b/strictdoc/core/file_tree.py
index 6b8da73c7..2d162b1a2 100644
--- a/strictdoc/core/file_tree.py
+++ b/strictdoc/core/file_tree.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="no-any-return,no-untyped-call,no-untyped-def"
+# mypy: disable-error-code="no-untyped-call,no-untyped-def"
 import collections
 import functools
 import os
@@ -24,16 +24,16 @@ def mount_folder(self):
 
 
 class File(FileOrFolderEntry):
-    def __init__(self, level, full_path, rel_path: SDocRelativePath):
+    def __init__(self, level: int, full_path: str, rel_path: SDocRelativePath):
         assert os.path.isfile(full_path)
         assert os.path.isabs(full_path)
         assert isinstance(rel_path, SDocRelativePath)
 
-        self.level = level
-        self.full_path = full_path
-        self.root_path = full_path
+        self.level: int = level
+        self.full_path: str = full_path
+        self.root_path: str = full_path
         self.rel_path: SDocRelativePath = rel_path
-        self.file_name = os.path.basename(self.full_path)
+        self.file_name: str = os.path.basename(self.full_path)
         self.files = [self]
         self.subfolder_trees: List[Folder] = []
 
diff --git a/strictdoc/core/graph/abstract_bucket.py b/strictdoc/core/graph/abstract_bucket.py
index 13e710566..c5556c39b 100644
--- a/strictdoc/core/graph/abstract_bucket.py
+++ b/strictdoc/core/graph/abstract_bucket.py
@@ -2,6 +2,8 @@
 from abc import ABC, abstractmethod
 from typing import Any, List, Optional, Tuple
 
+from strictdoc.helpers.ordered_set import OrderedSet
+
 ALL_EDGES = ".all"
 
 
@@ -26,7 +28,7 @@ def get_link_value_weak(self, *, lhs_node: Any) -> Optional[Any]:
 
     def get_link_values(
         self, *, lhs_node: Any, edge: Optional[str] = None
-    ) -> Any:
+    ) -> OrderedSet[Any]:
         raise NotImplementedError  # pragma: no cover
 
     def get_link_values_with_edges(
diff --git a/strictdoc/core/graph_database.py b/strictdoc/core/graph_database.py
index 42f018638..4aa912fa0 100644
--- a/strictdoc/core/graph_database.py
+++ b/strictdoc/core/graph_database.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="no-any-return,no-untyped-def,type-arg"
+# mypy: disable-error-code="no-untyped-def,type-arg"
 from typing import Any, Dict, Hashable, List, Optional, Tuple
 
 from strictdoc.core.graph.abstract_bucket import AbstractBucket
diff --git a/strictdoc/core/project_config.py b/strictdoc/core/project_config.py
index efb6f2551..0dcb96a9a 100644
--- a/strictdoc/core/project_config.py
+++ b/strictdoc/core/project_config.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="arg-type,attr-defined,no-any-return,no-untyped-call,no-untyped-def,type-arg"
+# mypy: disable-error-code="arg-type,attr-defined,no-untyped-call,no-untyped-def,type-arg"
 import datetime
 import os
 import re
@@ -195,7 +195,7 @@ def __init__(
         self.chromedriver: Optional[str] = chromedriver
 
     @staticmethod
-    def default_config(environment: SDocRuntimeEnvironment):
+    def default_config(environment: SDocRuntimeEnvironment) -> "ProjectConfig":
         assert isinstance(environment, SDocRuntimeEnvironment)
         return ProjectConfig(
             environment=environment,
diff --git a/strictdoc/core/query_engine/query_object.py b/strictdoc/core/query_engine/query_object.py
index c3cef9523..249540d30 100644
--- a/strictdoc/core/query_engine/query_object.py
+++ b/strictdoc/core/query_engine/query_object.py
@@ -227,7 +227,7 @@ def _evaluate_node_field_expression(
         else:
             raise NotImplementedError  # pragma: no cover
 
-    def _evaluate_node_has_parent_requirements(self, node):
+    def _evaluate_node_has_parent_requirements(self, node) -> bool:
         if not isinstance(node, SDocNode):
             raise TypeError(
                 f"node.has_parent_requirements can be only called on "
@@ -236,7 +236,7 @@ def _evaluate_node_has_parent_requirements(self, node):
             )
         return self.traceability_index.has_parent_requirements(node)
 
-    def _evaluate_node_has_child_requirements(self, node):
+    def _evaluate_node_has_child_requirements(self, node) -> bool:
         if not isinstance(node, SDocNode):
             raise TypeError(
                 f"node.has_child_requirements can be only called on "
@@ -262,7 +262,7 @@ def _evaluate_node_contains(
             return False
         raise NotImplementedError  # pragma: no cover
 
-    def _evaluate_node_contains_any_text(self, node):
+    def _evaluate_node_contains_any_text(self, node) -> bool:
         if not isinstance(node, SDocSection):
             raise TypeError(
                 f"node.contains_any_text can be only called on "
diff --git a/strictdoc/core/traceability_index.py b/strictdoc/core/traceability_index.py
index f7b361f41..509c57bab 100644
--- a/strictdoc/core/traceability_index.py
+++ b/strictdoc/core/traceability_index.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="arg-type,attr-defined,no-any-return,no-untyped-call,no-untyped-def,union-attr,type-arg"
+# mypy: disable-error-code="arg-type,attr-defined,no-untyped-call,no-untyped-def,union-attr,type-arg"
 import datetime
 from copy import deepcopy
 from typing import Any, Dict, Generator, List, Optional, Tuple, Union
@@ -64,7 +64,7 @@ def __init__(
         )
 
     @property
-    def document_iterators(self):
+    def document_iterators(self) -> Dict[SDocDocument, DocumentCachingIterator]:
         return self._document_iterators
 
     def is_small_project(self):
@@ -106,7 +106,7 @@ def has_parent_requirements(self, requirement: SDocNode) -> bool:
         )
         return len(parent_requirements) > 0
 
-    def has_children_requirements(self, requirement: SDocNode):
+    def has_children_requirements(self, requirement: SDocNode) -> bool:
         assert isinstance(requirement, SDocNode)
         if not isinstance(requirement.reserved_uid, str):
             return False
diff --git a/strictdoc/export/html/document_type.py b/strictdoc/export/html/document_type.py
index 1e2e4c76c..283080d8e 100644
--- a/strictdoc/export/html/document_type.py
+++ b/strictdoc/export/html/document_type.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="no-any-return,no-untyped-call,no-untyped-def"
+# mypy: disable-error-code="no-untyped-call,no-untyped-def"
 # FIXME: Migrate this to a proper Enum.
 class DocumentType:
     DOCUMENT = "document"
@@ -41,20 +41,20 @@ def pdf():
         return DocumentType(DocumentType.PDF)
 
     @property
-    def is_document(self):
+    def is_document(self) -> bool:
         return self.document_type == DocumentType.DOCUMENT
 
-    def is_table(self):
+    def is_table(self) -> bool:
         return self.document_type == DocumentType.TABLE
 
-    def is_trace(self):
+    def is_trace(self) -> bool:
         return self.document_type == DocumentType.TRACE
 
     @property
-    def is_deeptrace(self):
+    def is_deeptrace(self) -> bool:
         return self.document_type == DocumentType.DEEPTRACE
 
-    def is_pdf(self):
+    def is_pdf(self) -> bool:
         return self.document_type == DocumentType.PDF
 
     def get_page_title(self) -> str:
diff --git a/strictdoc/export/html/form_objects/grammar_element_form_object.py b/strictdoc/export/html/form_objects/grammar_element_form_object.py
index 69afb49a6..efba14fa2 100644
--- a/strictdoc/export/html/form_objects/grammar_element_form_object.py
+++ b/strictdoc/export/html/form_objects/grammar_element_form_object.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="arg-type,no-any-return,no-untyped-call,no-untyped-def,union-attr,type-arg"
+# mypy: disable-error-code="arg-type,no-untyped-call,no-untyped-def,union-attr,type-arg"
 from typing import Dict, List, Optional, Set, Tuple, Union
 
 from jinja2 import Template
diff --git a/strictdoc/export/html/form_objects/grammar_form_object.py b/strictdoc/export/html/form_objects/grammar_form_object.py
index aa9801b96..e5ae2b135 100644
--- a/strictdoc/export/html/form_objects/grammar_form_object.py
+++ b/strictdoc/export/html/form_objects/grammar_form_object.py
@@ -1,6 +1,7 @@
-# mypy: disable-error-code="arg-type,no-any-return,no-untyped-call,no-untyped-def,type-arg"
+# mypy: disable-error-code="arg-type,no-untyped-call,no-untyped-def,type-arg"
 from typing import Dict, List, Optional, Set
 
+from markupsafe import Markup
 from starlette.datastructures import FormData
 
 from strictdoc.backend.sdoc.models.document import SDocDocument
@@ -189,7 +190,7 @@ def render(self):
 
     def render_row_with_grammar_element(
         self, field: GrammarElementFormField
-    ) -> str:
+    ) -> Markup:
         form_object = RowWithGrammarElementFormObject(
             field=field,
             errors=self.errors,
diff --git a/strictdoc/export/html/form_objects/rows/row_with_grammar_element_form_object.py b/strictdoc/export/html/form_objects/rows/row_with_grammar_element_form_object.py
index b1aefde89..014634902 100644
--- a/strictdoc/export/html/form_objects/rows/row_with_grammar_element_form_object.py
+++ b/strictdoc/export/html/form_objects/rows/row_with_grammar_element_form_object.py
@@ -2,6 +2,8 @@
 from dataclasses import dataclass
 from typing import Any, Dict, List
 
+from markupsafe import Markup
+
 from strictdoc.export.html.html_templates import JinjaEnvironment
 
 
@@ -17,7 +19,7 @@ def __post_init__(self):
             self.jinja_environment
         )
 
-    def render(self):
+    def render(self) -> Markup:
         if self.field.is_new:
             rendered_template = self.jinja_environment.render_template_as_markup(
                 "components/grammar_form/row_with_new_grammar_element/index.jinja",
diff --git a/strictdoc/export/html/generators/view_objects/diff_screen_results_view_object.py b/strictdoc/export/html/generators/view_objects/diff_screen_results_view_object.py
index b52ddf57f..8972b6ed7 100644
--- a/strictdoc/export/html/generators/view_objects/diff_screen_results_view_object.py
+++ b/strictdoc/export/html/generators/view_objects/diff_screen_results_view_object.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="attr-defined,no-any-return,no-untyped-call,no-untyped-def"
+# mypy: disable-error-code="attr-defined,no-untyped-call,no-untyped-def"
 from dataclasses import dataclass
 from datetime import datetime
 from typing import Optional
diff --git a/strictdoc/export/html/generators/view_objects/diff_screen_view_object.py b/strictdoc/export/html/generators/view_objects/diff_screen_view_object.py
index b249d714e..713dee51d 100644
--- a/strictdoc/export/html/generators/view_objects/diff_screen_view_object.py
+++ b/strictdoc/export/html/generators/view_objects/diff_screen_view_object.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="no-any-return,no-untyped-call,no-untyped-def"
+# mypy: disable-error-code="no-untyped-call,no-untyped-def"
 from dataclasses import dataclass
 from datetime import datetime
 
diff --git a/strictdoc/export/html/generators/view_objects/document_screen_view_object.py b/strictdoc/export/html/generators/view_objects/document_screen_view_object.py
index 7c8724dbb..621a33e1c 100644
--- a/strictdoc/export/html/generators/view_objects/document_screen_view_object.py
+++ b/strictdoc/export/html/generators/view_objects/document_screen_view_object.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="no-any-return,no-redef,no-untyped-call,no-untyped-def,union-attr"
+# mypy: disable-error-code="no-redef,no-untyped-call,no-untyped-def,union-attr"
 from dataclasses import dataclass
 from datetime import datetime
 from typing import List, Optional, Union
diff --git a/strictdoc/export/html/generators/view_objects/project_statistics_view_object.py b/strictdoc/export/html/generators/view_objects/project_statistics_view_object.py
index a616d419a..1db4c6df4 100644
--- a/strictdoc/export/html/generators/view_objects/project_statistics_view_object.py
+++ b/strictdoc/export/html/generators/view_objects/project_statistics_view_object.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="no-any-return,no-untyped-call,no-untyped-def"
+# mypy: disable-error-code="no-untyped-call,no-untyped-def"
 from dataclasses import dataclass
 from datetime import datetime
 
diff --git a/strictdoc/export/html/generators/view_objects/search_screen_view_object.py b/strictdoc/export/html/generators/view_objects/search_screen_view_object.py
index d75b84888..135c19a49 100644
--- a/strictdoc/export/html/generators/view_objects/search_screen_view_object.py
+++ b/strictdoc/export/html/generators/view_objects/search_screen_view_object.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="no-any-return,no-untyped-call,no-untyped-def,union-attr"
+# mypy: disable-error-code="no-untyped-call,no-untyped-def,union-attr"
 from dataclasses import dataclass
 from datetime import datetime
 from typing import List, Optional
diff --git a/strictdoc/export/html/generators/view_objects/source_file_view_object.py b/strictdoc/export/html/generators/view_objects/source_file_view_object.py
index 86acc2aeb..4115b7e09 100644
--- a/strictdoc/export/html/generators/view_objects/source_file_view_object.py
+++ b/strictdoc/export/html/generators/view_objects/source_file_view_object.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="no-any-return,no-untyped-call,no-untyped-def,union-attr"
+# mypy: disable-error-code="no-untyped-call,no-untyped-def,union-attr"
 from dataclasses import dataclass
 from datetime import datetime
 from typing import Any, List, Optional, Union
diff --git a/strictdoc/export/html/generators/view_objects/traceability_matrix_view_object.py b/strictdoc/export/html/generators/view_objects/traceability_matrix_view_object.py
index b819f8407..c8a70f60d 100644
--- a/strictdoc/export/html/generators/view_objects/traceability_matrix_view_object.py
+++ b/strictdoc/export/html/generators/view_objects/traceability_matrix_view_object.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="arg-type,no-any-return,no-untyped-call,no-untyped-def,union-attr,type-arg"
+# mypy: disable-error-code="arg-type,no-untyped-call,no-untyped-def,union-attr,type-arg"
 from typing import Dict, List, Optional, Tuple
 
 from strictdoc import __version__
diff --git a/strictdoc/export/html/renderers/link_renderer.py b/strictdoc/export/html/renderers/link_renderer.py
index 656dedb29..72b07a771 100644
--- a/strictdoc/export/html/renderers/link_renderer.py
+++ b/strictdoc/export/html/renderers/link_renderer.py
@@ -46,12 +46,13 @@ def render_static_url_with_prefix(self, url: str) -> str:
         static_url = "/" + self.static_path + "/" + url
         return static_url
 
-    def render_local_anchor(self, node):
+    def render_local_anchor(self, node) -> str:
         if node in self.local_anchor_cache:
             return self.local_anchor_cache[node]
         if isinstance(node, Anchor):
             return f"{self._string_to_link(node.value)}"
 
+        local_anchor: str = ""
         if node.reserved_uid is not None and len(node.reserved_uid) > 0:
             # UID is unique enough.
             local_anchor = self._string_to_link(node.reserved_uid)
@@ -85,7 +86,7 @@ def render_node_link(
         context_document: Optional[SDocDocument],
         document_type: DocumentType,
         allow_local: bool = True,
-    ):
+    ) -> str:
         """
         allow_local:     used on the DTR screen where we want to ensure that only
                          full paths are used when jumping to the DOC screen.
diff --git a/strictdoc/export/json/json_generator.py b/strictdoc/export/json/json_generator.py
index eeaf7e08d..b6aa07135 100644
--- a/strictdoc/export/json/json_generator.py
+++ b/strictdoc/export/json/json_generator.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="arg-type,attr-defined,no-any-return,no-untyped-def,type-arg,union-attr,operator"
+# mypy: disable-error-code="arg-type,attr-defined,no-untyped-def,type-arg,union-attr,operator"
 import json
 import os.path
 from enum import Enum
diff --git a/strictdoc/git/project_diff_analyzer.py b/strictdoc/git/project_diff_analyzer.py
index 90a33d1bd..e272acace 100644
--- a/strictdoc/git/project_diff_analyzer.py
+++ b/strictdoc/git/project_diff_analyzer.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="arg-type,no-any-return,no-redef,no-untyped-call,no-untyped-def,type-arg,union-attr"
+# mypy: disable-error-code="arg-type,no-redef,no-untyped-call,no-untyped-def,type-arg,union-attr"
 import hashlib
 import statistics
 from dataclasses import dataclass, field
@@ -156,7 +156,10 @@ def find_requirement(self, requirement: SDocNode) -> Optional[SDocNode]:
             requirement.mid_permanent
             and requirement.reserved_mid in self.map_mid_to_nodes
         ):
-            return self.map_mid_to_nodes[requirement.reserved_mid]
+            node: SDocNode = assert_cast(
+                self.map_mid_to_nodes[requirement.reserved_mid], SDocNode
+            )
+            return node
         elif (
             requirement.reserved_uid is None
             or requirement.reserved_uid not in self.map_uid_to_nodes
diff --git a/strictdoc/server/helpers/turbo.py b/strictdoc/server/helpers/turbo.py
index 9b468c21a..cd1f22f81 100644
--- a/strictdoc/server/helpers/turbo.py
+++ b/strictdoc/server/helpers/turbo.py
@@ -2,7 +2,7 @@
 
 
 # mypy: disable-error-code="no-untyped-def"
-def render_turbo_stream(content: str, action: str, target: str):
+def render_turbo_stream(content: str, action: str, target: str) -> Markup:
     assert action in ("append", "replace", "update")
 
     turbo_stream = f"""
diff --git a/strictdoc/server/routers/main_router.py b/strictdoc/server/routers/main_router.py
index 298ee7524..d508c9cb5 100644
--- a/strictdoc/server/routers/main_router.py
+++ b/strictdoc/server/routers/main_router.py
@@ -1,4 +1,4 @@
-# mypy: disable-error-code="arg-type,attr-defined,no-any-return,no-redef,no-untyped-call,no-untyped-def,union-attr"
+# mypy: disable-error-code="arg-type,attr-defined,no-redef,no-untyped-call,no-untyped-def,union-attr"
 import copy
 import datetime
 import os
@@ -150,7 +150,7 @@ def create_main_router(project_config: ProjectConfig) -> APIRouter:
 
     is_small_project = export_action.traceability_index.is_small_project()
 
-    html_templates = HTMLTemplates.create(
+    html_templates: HTMLTemplates = HTMLTemplates.create(
         project_config=project_config,
         enable_caching=not is_small_project,
         strictdoc_last_update=export_action.traceability_index.strictdoc_last_update,


Reviews:
user: login: stanislaw
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-16T13:02:22Z
user: login: thseiler
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T13:30:55Z
user: login: thseiler
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T13:34:44Z

Review comments:
diff_hunk: @@ -62,6 +62,8 @@ def __init__(self, parent, _):
 
 
 class NodeIsRootExpression:
+    is_root: bool = True
path: strictdoc/core/query_engine/query_object.py
user: login: stanislaw
body: This doesn't seem right. Could you explain why is it added?
created_at: 2025-05-16T12:50:57Z
author_association: COLLABORATOR
diff_hunk: @@ -156,7 +156,10 @@ def find_requirement(self, requirement: SDocNode) -> Optional[SDocNode]:
             requirement.mid_permanent
             and requirement.reserved_mid in self.map_mid_to_nodes
         ):
-            return self.map_mid_to_nodes[requirement.reserved_mid]
+            node: Optional[SDocNode] = assert_optional_cast(
path: strictdoc/git/project_diff_analyzer.py
user: login: stanislaw
body: Here you would probably want just `node: SDocNode = assert_cast...` because the if condition above ensures that there is a node in the `map_mid_to_nodes` dictionary.

If the node was not there we could get a KeyError and the whole expression would throw an exception. But the if condition ensures we can safely do it.
created_at: 2025-05-16T13:01:57Z
author_association: COLLABORATOR
diff_hunk: @@ -62,6 +62,8 @@ def __init__(self, parent, _):
 
 
 class NodeIsRootExpression:
+    is_root: bool = True
path: strictdoc/core/query_engine/query_object.py
user: login: thseiler
body: https://github.com/strictdoc-project/strictdoc/blob/75c839a07ee0ca9deff378d85b966b825eccdabd/strictdoc/core/query_engine/query_object.py#L153
was flagged as no-any-return in the Visual Studio Code IDE otherwise.

I think it is not able to derive the type from the TextX grammar syntax alone.

I will remove it as the invoke check runs actually fine...
created_at: 2025-05-16T13:30:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -156,7 +156,10 @@ def find_requirement(self, requirement: SDocNode) -> Optional[SDocNode]:
             requirement.mid_permanent
             and requirement.reserved_mid in self.map_mid_to_nodes
         ):
-            return self.map_mid_to_nodes[requirement.reserved_mid]
+            node: Optional[SDocNode] = assert_optional_cast(
path: strictdoc/git/project_diff_analyzer.py
user: login: thseiler
body: true, nice catch! Thanks for reviewing!
created_at: 2025-05-16T13:34:44Z
author_association: CONTRIBUTOR

PR comments:
user: login: thseiler
created_at: 2025-05-16T15:29:13Z
body: FYI: I made a mistake earlier when checking query_object.py:

The invoke check passed because query_object.py still has the [no-arg-return] check disabled in the first line. If I remove that, I get:

```
py312-check: commands[1]> mypy strictdoc/ --show-error-codes --disable-error-code=import --disable-error-code=misc --disable-error-code=type-abstract --cache-dir=build/mypy --strict --python-version=3.8
strictdoc\core\query_engine\query_object.py:153: error: Returning Any from function declared to return "bool"  [no-any-return]
Found 1 error in 1 file (checked 222 source files)
```

So, the IDE was right after all. Unfortunately, I don't know how to fix this one cleanly.

author_association: CONTRIBUTOR
user: login: stanislaw
created_at: 2025-05-16T15:37:18Z
body: It looks like there is an implicit / undefined behavior around NodeIsRootExpression. The code does .is_root access but that property is missing on the class declaration.

The way you did it in the PR was slightly incorrect because it would have been a class-level variable, not the instance variable.

Let me double-check this closer this evening. I will cc you if I create a fix.

author_association: COLLABORATOR