From beab30c66cf496cb0c6b93569bcceeddc2136d7f Mon Sep 17 00:00:00 2001 From: Stanislav Pankevich Date: Sat, 20 Jul 2024 22:43:35 +0200 Subject: [PATCH] Code climate: document_iterator: add SDocAnyNode type hint --- .../reqif/p01_sdoc/sdoc_to_reqif_converter.py | 28 ++++---- strictdoc/backend/sdoc/models/any_node.py | 12 ++++ .../backend/sdoc/models/document_config.py | 2 +- strictdoc/core/document_iterator.py | 69 +++++++++++-------- strictdoc/core/traceability_index_builder.py | 8 ++- tests/end2end/__init__.py | 2 +- 6 files changed, 73 insertions(+), 48 deletions(-) create mode 100644 strictdoc/backend/sdoc/models/any_node.py diff --git a/strictdoc/backend/reqif/p01_sdoc/sdoc_to_reqif_converter.py b/strictdoc/backend/reqif/p01_sdoc/sdoc_to_reqif_converter.py index 4c7e0d56d..57a4e0234 100644 --- a/strictdoc/backend/reqif/p01_sdoc/sdoc_to_reqif_converter.py +++ b/strictdoc/backend/reqif/p01_sdoc/sdoc_to_reqif_converter.py @@ -235,21 +235,22 @@ def convert_document_tree( current_hierarchy = root_hierarchy # FIXME: ReqIF must export complete documents including fragments. - for node in document_iterator.all_content( + for node_ in document_iterator.all_content( print_fragments=False, print_fragments_from_files=False ): - if node.is_composite_requirement: + if node_.is_composite_requirement: raise NotImplementedError( "Exporting composite requirements is not " "supported yet.", - node, + node_, ) - if node.is_section: + if node_.is_section: + section: SDocSection = assert_cast(node_, SDocSection) # fmt: off spec_object = ( P01_SDocToReqIFObjectConverter ._convert_section_to_spec_object( - section=node, + section=section, context=context, ) ) @@ -264,14 +265,14 @@ def convert_document_tree( spec_object=spec_object.identifier, children=[], ref_then_children_order=True, - level=node.ng_level, + level=section.ng_level, ) - if node.ng_level > current_hierarchy.level: + if section.ng_level > current_hierarchy.level: parents[hierarchy] = current_hierarchy current_hierarchy.add_child(hierarchy) - elif node.ng_level < current_hierarchy.level: + elif section.ng_level < current_hierarchy.level: for _ in range( - 0, (current_hierarchy.level - node.ng_level + 1) + 0, (current_hierarchy.level - section.ng_level + 1) ): current_hierarchy = parents[current_hierarchy] current_hierarchy.add_child(hierarchy) @@ -282,9 +283,10 @@ def convert_document_tree( parents[hierarchy] = current_hierarchy_parent current_hierarchy = hierarchy - elif node.is_requirement: + elif node_.is_requirement: + requirement = assert_cast(node_, SDocNode) spec_object = cls._convert_requirement_to_spec_object( - requirement=node, + requirement=requirement, grammar=assert_cast(document.grammar, DocumentGrammar), context=context, data_types=data_types, @@ -302,10 +304,10 @@ def convert_document_tree( spec_object=spec_object.identifier, children=None, ref_then_children_order=True, - level=node.ng_level, + level=requirement.ng_level, ) for _ in range( - 0, (current_hierarchy.level - node.ng_level + 1) + 0, (current_hierarchy.level - requirement.ng_level + 1) ): current_hierarchy = parents[current_hierarchy] parents[hierarchy] = current_hierarchy diff --git a/strictdoc/backend/sdoc/models/any_node.py b/strictdoc/backend/sdoc/models/any_node.py new file mode 100644 index 000000000..fdfb615df --- /dev/null +++ b/strictdoc/backend/sdoc/models/any_node.py @@ -0,0 +1,12 @@ +from typing import Union + +from strictdoc.backend.sdoc.models.document import SDocDocument +from strictdoc.backend.sdoc.models.node import SDocCompositeNode, SDocNode +from strictdoc.backend.sdoc.models.section import SDocSection + +SDocAnyNode = Union[ + SDocCompositeNode, + SDocSection, + SDocNode, + SDocDocument, +] diff --git a/strictdoc/backend/sdoc/models/document_config.py b/strictdoc/backend/sdoc/models/document_config.py index 8816c2d67..3c05c5bc5 100644 --- a/strictdoc/backend/sdoc/models/document_config.py +++ b/strictdoc/backend/sdoc/models/document_config.py @@ -98,7 +98,7 @@ def get_requirement_style_mode(self) -> str: return "zebra" raise NotImplementedError(self.requirement_style) - def is_requirement_in_toc(self): + def is_requirement_in_toc(self) -> bool: return ( self.requirement_in_toc is None or self.requirement_in_toc == "True" ) diff --git a/strictdoc/core/document_iterator.py b/strictdoc/core/document_iterator.py index c3cb3d4d7..6ff0d6ad8 100644 --- a/strictdoc/core/document_iterator.py +++ b/strictdoc/core/document_iterator.py @@ -1,26 +1,28 @@ -# mypy: disable-error-code="arg-type,attr-defined,no-any-return,no-untyped-call,no-untyped-def,operator,type-arg" -from typing import Optional, Tuple +# mypy: disable-error-code="attr-defined" +from typing import Iterator, Tuple, Union +from strictdoc.backend.sdoc.models.any_node import SDocAnyNode from strictdoc.backend.sdoc.models.document import SDocDocument from strictdoc.backend.sdoc.models.document_from_file import DocumentFromFile from strictdoc.backend.sdoc.models.node import ( SDocCompositeNode, SDocNode, ) -from strictdoc.backend.sdoc.models.section import FreeText, SDocSection +from strictdoc.backend.sdoc.models.section import SDocSection +from strictdoc.helpers.cast import assert_cast class DocumentCachingIterator: - def __init__(self, document): + def __init__(self, document: SDocDocument) -> None: assert isinstance(document, SDocDocument) - self.document = document + self.document: SDocDocument = document - def table_of_contents(self): + def table_of_contents(self) -> Iterator[SDocAnyNode]: nodes_to_skip = ( - (FreeText, SDocNode) + (SDocNode,) if not self.document.config.is_requirement_in_toc() - else FreeText + else () ) for node in self.all_content( @@ -37,7 +39,7 @@ def all_content( self, print_fragments: bool = False, print_fragments_from_files: bool = False, - ): + ) -> Iterator[SDocAnyNode]: root_node = self.document yield from self._all_content( @@ -48,30 +50,17 @@ def all_content( custom_level=not root_node.config.auto_levels, ) - def all_content_from_node( - self, - node, - print_fragments: bool = False, - print_fragments_from_files: bool = False, - ): - document = node if isinstance(node, SDocDocument) else node.document - yield from self._all_content( - node, - print_fragments=print_fragments, - print_fragments_from_files=print_fragments_from_files, - level_stack=(), - custom_level=not document.config.auto_levels, - ) - def _all_content( self, - node, + node: Union[SDocAnyNode, DocumentFromFile], print_fragments: bool = False, print_fragments_from_files: bool = False, - level_stack: Optional[Tuple] = (), + level_stack: Tuple[int, ...] = (), custom_level: bool = False, - ): - def get_level_string_(node_) -> str: + ) -> Iterator[SDocAnyNode]: + def get_level_string_( + node_: Union[SDocSection, SDocNode, SDocCompositeNode], + ) -> str: if isinstance(node_, SDocNode) and node_.requirement_type == "TEXT": return "" @@ -108,7 +97,17 @@ def get_level_string_(node_) -> str: current_number += 1 yield from self._all_content( - subnode_, + # FIXME: sections_contents(SDocObject) shall be changed to SDocAnyNode. + assert_cast( + subnode_, + ( + SDocNode, + SDocCompositeNode, + SDocSection, + SDocDocument, + DocumentFromFile, + ), + ), print_fragments=print_fragments, print_fragments_from_files=print_fragments_from_files, level_stack=level_stack + (current_number,), @@ -181,7 +180,17 @@ def get_level_string_(node_) -> str: ): current_number += 1 yield from self._all_content( - subnode_, + # FIXME: sections_contents(SDocObject) shall be changed to SDocAnyNode. + assert_cast( + subnode_, + ( + SDocNode, + SDocCompositeNode, + SDocSection, + SDocDocument, + DocumentFromFile, + ), + ), print_fragments=print_fragments, print_fragments_from_files=print_fragments_from_files, level_stack=level_stack + (current_number,), diff --git a/strictdoc/core/traceability_index_builder.py b/strictdoc/core/traceability_index_builder.py index 363adcfae..55afad643 100644 --- a/strictdoc/core/traceability_index_builder.py +++ b/strictdoc/core/traceability_index_builder.py @@ -12,7 +12,7 @@ from strictdoc.backend.sdoc.models.document_from_file import DocumentFromFile from strictdoc.backend.sdoc.models.document_grammar import DocumentGrammar from strictdoc.backend.sdoc.models.inline_link import InlineLink -from strictdoc.backend.sdoc.models.node import SDocNode +from strictdoc.backend.sdoc.models.node import SDocCompositeNode, SDocNode from strictdoc.backend.sdoc.models.reference import ( ChildReqReference, ParentReqReference, @@ -465,7 +465,7 @@ def create_from_document_tree( ), ) if node.is_requirement: - requirement: SDocNode = node + requirement: SDocNode = assert_cast(node, SDocNode) if requirement.reserved_tags is not None: for tag in requirement.reserved_tags: document_tags.setdefault(tag, 0) @@ -671,7 +671,9 @@ def create_from_document_tree( ): if not node.is_requirement: continue - requirement = node + requirement: Union[SDocNode, SDocCompositeNode] = assert_cast( + node, (SDocNode, SDocCompositeNode) + ) if requirement.reserved_uid is None: continue diff --git a/tests/end2end/__init__.py b/tests/end2end/__init__.py index 1df4b49af..4e2048858 100644 --- a/tests/end2end/__init__.py +++ b/tests/end2end/__init__.py @@ -1 +1 @@ -# Dummy comment to trigger CI +# Dummy comment to trigger CI.