Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
composer.py247 linesDownload Raw Back to yaml
1 2from __future__ import annotations3 4import warnings5 6from ruamel.yaml.error import MarkedYAMLError, ReusedAnchorWarning7from ruamel.yaml.compat import nprint, nprintf  # NOQA8 9from ruamel.yaml.events import (10    StreamStartEvent,11    StreamEndEvent,12    MappingStartEvent,13    MappingEndEvent,14    SequenceStartEvent,15    SequenceEndEvent,16    AliasEvent,17    ScalarEvent,18)19from ruamel.yaml.nodes import MappingNode, ScalarNode, SequenceNode20 21if False:  # MYPY22    from typing import Any, Dict, Optional, List  # NOQA23 24__all__ = ['Composer', 'ComposerError', 'MaxDepthExceededError']25 26 27class ComposerError(MarkedYAMLError):28    pass29 30 31class MaxDepthExceededError(MarkedYAMLError):32    pass33 34 35class Composer:36    def __init__(self, loader: Any = None) -> None:37        self.loader = loader38        if self.loader is not None and getattr(self.loader, '_composer', None) is None:39            self.loader._composer = self40        self.anchors: Dict[Any, Any] = {}41        self.warn_double_anchors = True42        self.depth = 043 44    @property45    def parser(self) -> Any:46        if hasattr(self.loader, 'typ'):47            self.loader.parser48        return self.loader._parser49 50    @property51    def resolver(self) -> Any:52        # assert self.loader._resolver is not None53        if hasattr(self.loader, 'typ'):54            self.loader.resolver55        return self.loader._resolver56 57    def check_node(self) -> Any:58        # Drop the STREAM-START event.59        if self.parser.check_event(StreamStartEvent):60            self.parser.get_event()61 62        # If there are more documents available?63        return not self.parser.check_event(StreamEndEvent)64 65    def get_node(self) -> Any:66        # Get the root node of the next document.67        if not self.parser.check_event(StreamEndEvent):68            return self.compose_document()69 70    def get_single_node(self) -> Any:71        # Drop the STREAM-START event.72        self.parser.get_event()73 74        # Compose a document if the stream is not empty.75        document: Any = None76        if not self.parser.check_event(StreamEndEvent):77            document = self.compose_document()78 79        # Ensure that the stream contains no more documents.80        if not self.parser.check_event(StreamEndEvent):81            event = self.parser.get_event()82            raise ComposerError(83                'expected a single document in the stream',84                document.start_mark,85                'but found another document',86                event.start_mark,87            )88 89        # Drop the STREAM-END event.90        self.parser.get_event()91 92        return document93 94    def compose_document(self: Any) -> Any:95        self.anchors = {}96        # Drop the DOCUMENT-START event.97        self.parser.get_event()98 99        # Compose the root node.100        node = self.compose_node(None, None)101 102        # Drop the DOCUMENT-END event.103        self.parser.get_event()104 105        return node106 107    def return_alias(self, a: Any) -> Any:108        return a109 110    def compose_node(self, parent: Any, index: Any) -> Any:111        if self.parser.check_event(AliasEvent):112            event = self.parser.get_event()113            alias = event.anchor114            if alias not in self.anchors:115                raise ComposerError(116                    None, None, f'found undefined alias {alias!r}', event.start_mark,117                )118            return self.return_alias(self.anchors[alias])119        self.depth += 1120        event = self.parser.peek_event()121        if self.loader.max_depth and self.depth > self.loader.max_depth:122            raise MaxDepthExceededError(123                None,124                None,125                f'maximum depth of data structure exceeded ({self.depth}), '126                'if necessary increase YAML().max_depth',127                event.start_mark,128            )129        anchor = event.anchor130        if anchor is not None:  # have an anchor131            if self.warn_double_anchors and anchor in self.anchors:132                ws = (133                    f'\nfound duplicate anchor {anchor!r}\n'134                    f'first occurrence {self.anchors[anchor].start_mark}\n'135                    f'second occurrence {event.start_mark}'136                )137                warnings.warn(ws, ReusedAnchorWarning, stacklevel=2)138        self.resolver.descend_resolver(parent, index)139        if self.parser.check_event(ScalarEvent):140            node = self.compose_scalar_node(anchor)141        elif self.parser.check_event(SequenceStartEvent):142            node = self.compose_sequence_node(anchor)143        elif self.parser.check_event(MappingStartEvent):144            node = self.compose_mapping_node(anchor)145        self.resolver.ascend_resolver()146        self.depth -= 1147        return node148 149    def compose_scalar_node(self, anchor: Any) -> Any:150        event = self.parser.get_event()151        tag = event.ctag152        if tag is None or str(tag) == '!':153            tag = self.resolver.resolve(ScalarNode, event.value, event.implicit)154            assert not isinstance(tag, str)155            # e.g tag.yaml.org,2002:str156        node = ScalarNode(157            tag,158            event.value,159            event.start_mark,160            event.end_mark,161            style=event.style,162            comment=event.comment,163            anchor=anchor,164        )165        if anchor is not None:166            self.anchors[anchor] = node167        return node168 169    def compose_sequence_node(self, anchor: Any) -> Any:170        start_event = self.parser.get_event()171        tag = start_event.ctag172        if tag is None or str(tag) == '!':173            tag = self.resolver.resolve(SequenceNode, None, start_event.implicit)174            assert not isinstance(tag, str)175        node = SequenceNode(176            tag,177            [],178            start_event.start_mark,179            None,180            flow_style=start_event.flow_style,181            comment=start_event.comment,182            anchor=anchor,183        )184        if anchor is not None:185            self.anchors[anchor] = node186        index = 0187        while not self.parser.check_event(SequenceEndEvent):188            node.value.append(self.compose_node(node, index))189            index += 1190        end_event = self.parser.get_event()191        if node.flow_style is True and end_event.comment is not None:192            if node.comment is not None:193                x = node.flow_style194                nprint(195                    f'Warning: unexpected end_event commment in sequence node {x}\n',196                    '    if possible, please report an issue with reproducable data/code',197                )198            node.comment = end_event.comment199        node.end_mark = end_event.end_mark200        self.check_end_doc_comment(end_event, node)201        return node202 203    def compose_mapping_node(self, anchor: Any) -> Any:204        start_event = self.parser.get_event()205        tag = start_event.ctag206        if tag is None or str(tag) == '!':207            tag = self.resolver.resolve(MappingNode, None, start_event.implicit)208            assert not isinstance(tag, str)209        node = MappingNode(210            tag,211            [],212            start_event.start_mark,213            None,214            flow_style=start_event.flow_style,215            comment=start_event.comment,216            anchor=anchor,217        )218        if anchor is not None:219            self.anchors[anchor] = node220        while not self.parser.check_event(MappingEndEvent):221            # key_event = self.parser.peek_event()222            item_key = self.compose_node(node, None)223            # if item_key in node.value:224            #     raise ComposerError("while composing a mapping",225            #             start_event.start_mark,226            #             "found duplicate key", key_event.start_mark)227            item_value = self.compose_node(node, item_key)228            # node.value[item_key] = item_value229            node.value.append((item_key, item_value))230        end_event = self.parser.get_event()231        if node.flow_style is True and end_event.comment is not None:232            node.comment = end_event.comment233        node.end_mark = end_event.end_mark234        self.check_end_doc_comment(end_event, node)235        return node236 237    def check_end_doc_comment(self, end_event: Any, node: Any) -> None:238        if end_event.comment and end_event.comment[1]:239            # pre comments on an end_event, no following to move to240            if node.comment is None:241                node.comment = [None, None]242            assert not isinstance(node, ScalarEvent)243            # this is a post comment on a mapping node, add as third element244            # in the list245            node.comment.append(end_event.comment[1])246            end_event.comment[1] = None247 
codekingpro/portable-devtools · Team Ai