summaryrefslogtreecommitdiffstats
path: root/docinfo.py
blob: 1c9254bc14eca594005c39b78524c5a689c4ca96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
from __future__ import annotations

"""
DocInfo

Although it was possible to read tag directives before this, all handle/prefix
pairs for all documents in all streams were stored in one dictionary per
YAML instance, making it impossible to distinguish where such a pair came
from without sublassing the scanner.

ToDo:
DocInfo can be used by a yaml dumper to dump a class
- if connected to the root of a data structure
- if provided to the dumper?
"""

if False:  # MYPY
    from typing import Optional, Tuple, Any

# from dataclasses import dataclass, field, MISSING  # NOQA


# @dataclass(order=True, frozen=True)
class Version:
    # major: int
    # minor: int
    def __init__(self, major: int, minor: int) -> None:
        self._major = major
        self._minor = minor

    @property
    def major(self) -> int:
        return self._major

    @property
    def minor(self) -> int:
        return self._minor

    def __eq__(self, v: Any) -> bool:
        if not isinstance(v, Version):
            return False
        return self._major == v._major and self._minor == v._minor

    def __lt__(self, v: Version) -> bool:
        if self._major < v._major:
            return True
        if self._major > v._major:
            return False
        return self._minor < v._minor

    def __le__(self, v: Version) -> bool:
        if self._major < v._major:
            return True
        if self._major > v._major:
            return False
        return self._minor <= v._minor

    def __gt__(self, v: Version) -> bool:
        if self._major > v._major:
            return True
        if self._major < v._major:
            return False
        return self._minor > v._minor

    def __ge__(self, v: Version) -> bool:
        if self._major > v._major:
            return True
        if self._major < v._major:
            return False
        return self._minor >= v._minor


def version(
    major: int | str | Tuple[int, int] | None,
    minor: Optional[int] = None,
) -> Optional[Version]:
    if major is None:
        assert minor is None
        return None
    if isinstance(major, str):
        assert minor is None
        parts = major.split('.')
        assert len(parts) == 2
        return Version(int(parts[0]), int(parts[1]))
    elif isinstance(major, tuple):
        assert minor is None
        assert len(major) == 2
        major, minor = major
    assert minor is not None
    return Version(major, minor)


# @dataclass(frozen=True)
class Tag:
    # handle: str
    # prefix: str
    def __init__(self, handle: str, prefix: str) -> None:
        self._handle = handle
        self._prefix = prefix

    @property
    def handle(self) -> str:
        return self._handle

    @property
    def prefix(self) -> str:
        return self._prefix


# @dataclass
class DocInfo:
    """
    Store document information, can be used for analysis of a loaded YAML document
    requested_version: if explicitly set before load
    doc_version: from %YAML directive
    tags: from %TAG directives in scanned order
    """
    # requested_version: Optional[Version] = None
    # doc_version: Optional[Version] = None
    # tags: list[Tag] = field(default_factory=list)
    def __init__(
        self,
        requested_version: Optional[Version] = None,
        doc_version: Optional[Version] = None,
        tags: Optional[list[Tag]] = None,
    ):
        self.requested_version = requested_version
        self.doc_version = doc_version
        self.tags = [] if tags is None else tags