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
|