v440 2.0.0.dev60__tar.gz → 2.0.0.dev61__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {v440-2.0.0.dev60/src/v440.egg-info → v440-2.0.0.dev61}/PKG-INFO +1 -1
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/pyproject.toml +1 -1
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/_utils/BaseList.py +18 -45
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/_utils/SlotList.py +12 -5
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/_utils/VList.py +95 -1
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/_utils/qualparse.py +0 -45
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/_utils/utils.py +3 -16
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/core/Base.py +39 -42
- v440-2.0.0.dev61/src/v440/core/Local.py +45 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/core/Public.py +35 -41
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/core/Qual.py +44 -19
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/core/Release.py +7 -17
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/core/Version.py +34 -40
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/tests/test_testdata.py +1 -1
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/tests/test_version.py +3 -3
- {v440-2.0.0.dev60 → v440-2.0.0.dev61/src/v440.egg-info}/PKG-INFO +1 -1
- v440-2.0.0.dev60/src/v440/core/Local.py +0 -84
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/LICENSE.txt +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/MANIFEST.in +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/README.rst +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/setup.cfg +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/__init__.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/_utils/Cfg.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/_utils/Digest.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/_utils/Pattern.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/_utils/__init__.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/_utils/cfg.toml +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/core/VersionError.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/core/__init__.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/tests/__init__.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440/tests/testdata.toml +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440.egg-info/SOURCES.txt +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440.egg-info/dependency_links.txt +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440.egg-info/requires.txt +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev61}/src/v440.egg-info/top_level.txt +0 -0
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import collections
|
|
2
|
-
from abc import abstractmethod
|
|
2
|
+
from abc import ABCMeta, abstractmethod
|
|
3
3
|
from typing import *
|
|
4
4
|
|
|
5
5
|
import scaevola
|
|
6
6
|
import setdoc
|
|
7
7
|
import unhash
|
|
8
|
-
from datarepr import datarepr
|
|
9
8
|
|
|
10
9
|
from v440._utils.utils import guard
|
|
11
10
|
from v440.core.VersionError import VersionError
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
@scaevola.auto
|
|
15
|
-
class BaseList(
|
|
14
|
+
class BaseList(metaclass=ABCMeta):
|
|
16
15
|
__slots__ = ()
|
|
17
16
|
|
|
18
17
|
string: str
|
|
@@ -21,17 +20,13 @@ class BaseList(collections.abc.Collection):
|
|
|
21
20
|
@setdoc.basic
|
|
22
21
|
def __bool__(self: Self) -> bool: ...
|
|
23
22
|
|
|
24
|
-
@setdoc.basic
|
|
25
|
-
def __contains__(self: Self, other: Any) -> bool:
|
|
26
|
-
return other in self.data
|
|
27
|
-
|
|
28
23
|
@setdoc.basic
|
|
29
24
|
def __eq__(self: Self, other: Any) -> bool:
|
|
30
25
|
try:
|
|
31
26
|
alt: Self = type(self)(other)
|
|
32
27
|
except VersionError:
|
|
33
28
|
return False
|
|
34
|
-
return self.
|
|
29
|
+
return self.string == alt.string
|
|
35
30
|
|
|
36
31
|
@setdoc.basic
|
|
37
32
|
def __format__(self: Self, format_spec: Any) -> str:
|
|
@@ -40,7 +35,7 @@ class BaseList(collections.abc.Collection):
|
|
|
40
35
|
except Exception:
|
|
41
36
|
msg: str = "unsupported format string passed to %s.__format__"
|
|
42
37
|
msg %= type(self).__name__
|
|
43
|
-
raise TypeError(msg) from None
|
|
38
|
+
raise TypeError(msg) # from None
|
|
44
39
|
|
|
45
40
|
@setdoc.basic
|
|
46
41
|
def __ge__(self: Self, other: Any) -> bool:
|
|
@@ -51,10 +46,6 @@ class BaseList(collections.abc.Collection):
|
|
|
51
46
|
return NotImplemented
|
|
52
47
|
return self._cmp() >= alt._cmp()
|
|
53
48
|
|
|
54
|
-
@setdoc.basic
|
|
55
|
-
def __getitem__(self: Self, key: Any) -> Any:
|
|
56
|
-
return self.data[key]
|
|
57
|
-
|
|
58
49
|
@setdoc.basic
|
|
59
50
|
def __gt__(self: Self, other: Any) -> bool:
|
|
60
51
|
alt: Self
|
|
@@ -66,13 +57,9 @@ class BaseList(collections.abc.Collection):
|
|
|
66
57
|
|
|
67
58
|
__hash__ = unhash
|
|
68
59
|
|
|
60
|
+
@abstractmethod
|
|
69
61
|
@setdoc.basic
|
|
70
|
-
def __init__(self: Self,
|
|
71
|
-
self.data = data
|
|
72
|
-
|
|
73
|
-
@setdoc.basic
|
|
74
|
-
def __iter__(self: Self) -> Iterator:
|
|
75
|
-
return iter(self.data)
|
|
62
|
+
def __init__(self: Self, string: Any) -> None: ...
|
|
76
63
|
|
|
77
64
|
@setdoc.basic
|
|
78
65
|
def __le__(self: Self, other: Any) -> bool:
|
|
@@ -96,19 +83,9 @@ class BaseList(collections.abc.Collection):
|
|
|
96
83
|
def __ne__(self: Self, other: Any) -> bool:
|
|
97
84
|
return not (self == other)
|
|
98
85
|
|
|
86
|
+
@abstractmethod
|
|
99
87
|
@setdoc.basic
|
|
100
|
-
def __repr__(self: Self) -> str:
|
|
101
|
-
return datarepr(type(self).__name__, self.data)
|
|
102
|
-
|
|
103
|
-
@setdoc.basic
|
|
104
|
-
def __reversed__(self: Self) -> reversed:
|
|
105
|
-
return reversed(self.data)
|
|
106
|
-
|
|
107
|
-
@setdoc.basic
|
|
108
|
-
def __setitem__(self: Self, key: Any, value: Any) -> None:
|
|
109
|
-
data: list = list(self.data)
|
|
110
|
-
data[key] = value
|
|
111
|
-
self.data = data
|
|
88
|
+
def __repr__(self: Self) -> str: ...
|
|
112
89
|
|
|
113
90
|
@classmethod
|
|
114
91
|
def __subclasshook__(cls: type, other: type, /) -> bool:
|
|
@@ -125,26 +102,19 @@ class BaseList(collections.abc.Collection):
|
|
|
125
102
|
@abstractmethod
|
|
126
103
|
def _format(self: Self, format_spec: str) -> str: ...
|
|
127
104
|
|
|
105
|
+
@abstractmethod
|
|
106
|
+
def _set(self: Self, value: Any) -> None: ...
|
|
107
|
+
|
|
128
108
|
@abstractmethod
|
|
129
109
|
def _string_fset(self: Self, value: str) -> None: ...
|
|
130
110
|
|
|
111
|
+
@abstractmethod
|
|
112
|
+
def _todict(self: Self) -> dict: ...
|
|
113
|
+
|
|
131
114
|
@setdoc.basic
|
|
132
115
|
def copy(self: Self) -> Self:
|
|
133
116
|
return type(self)(self)
|
|
134
117
|
|
|
135
|
-
@property
|
|
136
|
-
@abstractmethod
|
|
137
|
-
@setdoc.basic
|
|
138
|
-
def data(self: Self) -> tuple: ...
|
|
139
|
-
|
|
140
|
-
def count(self: Self, value: Any) -> int:
|
|
141
|
-
"This method counts the occurences of value."
|
|
142
|
-
return self.data.count(value)
|
|
143
|
-
|
|
144
|
-
def index(self: Self, *args: Any) -> None:
|
|
145
|
-
"This method returns the index of the first occurence."
|
|
146
|
-
return self.data.index(*args)
|
|
147
|
-
|
|
148
118
|
@property
|
|
149
119
|
def string(self: Self) -> str:
|
|
150
120
|
return self._format("")
|
|
@@ -152,4 +122,7 @@ class BaseList(collections.abc.Collection):
|
|
|
152
122
|
@string.setter
|
|
153
123
|
@guard
|
|
154
124
|
def string(self: Self, value: Any) -> None:
|
|
155
|
-
|
|
125
|
+
if value is None:
|
|
126
|
+
self._string_fset("")
|
|
127
|
+
else:
|
|
128
|
+
self._string_fset(str(value))
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
1
2
|
from functools import partial
|
|
2
3
|
from typing import *
|
|
3
4
|
|
|
4
5
|
import setdoc
|
|
6
|
+
from datarepr import datarepr
|
|
5
7
|
|
|
6
8
|
from v440._utils.BaseList import BaseList
|
|
7
9
|
|
|
@@ -11,16 +13,21 @@ __all__ = ["SlotList"]
|
|
|
11
13
|
class SlotList(BaseList):
|
|
12
14
|
__slots__ = ()
|
|
13
15
|
|
|
14
|
-
data: tuple
|
|
15
16
|
string: str
|
|
16
17
|
|
|
17
|
-
@setdoc.basic
|
|
18
|
-
def __bool__(self: Self) -> bool:
|
|
19
|
-
return any(self.data)
|
|
20
|
-
|
|
21
18
|
@setdoc.basic
|
|
22
19
|
def __len__(self: Self) -> int:
|
|
23
20
|
return len(type(self).__slots__)
|
|
24
21
|
|
|
22
|
+
@setdoc.basic
|
|
23
|
+
def __repr__(self: Self) -> str:
|
|
24
|
+
return datarepr(type(self).__name__, **self._todict())
|
|
25
|
+
|
|
25
26
|
def _cmp(self: Self) -> tuple:
|
|
26
27
|
return tuple(map(partial(getattr, self), type(self).__slots__))
|
|
28
|
+
|
|
29
|
+
def _set(self: Self, value: Any) -> None:
|
|
30
|
+
if value is None:
|
|
31
|
+
self.string = ""
|
|
32
|
+
else:
|
|
33
|
+
self.string = value
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
+
import collections
|
|
1
2
|
from abc import abstractmethod
|
|
2
3
|
from typing import *
|
|
3
4
|
|
|
4
5
|
import setdoc
|
|
6
|
+
from datarepr import datarepr
|
|
7
|
+
from overloadable import Overloadable
|
|
5
8
|
|
|
6
9
|
from v440._utils.BaseList import BaseList
|
|
10
|
+
from v440._utils.utils import guard
|
|
7
11
|
|
|
8
12
|
__all__ = ["VList"]
|
|
9
13
|
|
|
10
14
|
|
|
11
|
-
class VList(BaseList):
|
|
15
|
+
class VList(BaseList, collections.abc.MutableSequence):
|
|
12
16
|
|
|
13
17
|
__slots__ = ("_data",)
|
|
14
18
|
data: tuple
|
|
@@ -57,6 +61,9 @@ class VList(BaseList):
|
|
|
57
61
|
@abstractmethod
|
|
58
62
|
def _sort(cls: type, value: Any): ...
|
|
59
63
|
|
|
64
|
+
def _todict(self: Self) -> dict:
|
|
65
|
+
return dict(data=self.data)
|
|
66
|
+
|
|
60
67
|
def append(self: Self, value: Self, /) -> None:
|
|
61
68
|
"This method appends value to self."
|
|
62
69
|
data: list = list(self.data)
|
|
@@ -110,3 +117,90 @@ class VList(BaseList):
|
|
|
110
117
|
r: bool = bool(reverse)
|
|
111
118
|
data.sort(key=k, reverse=r)
|
|
112
119
|
self.data = data
|
|
120
|
+
|
|
121
|
+
# data-associated
|
|
122
|
+
@setdoc.basic
|
|
123
|
+
def __contains__(self: Self, other: Any) -> bool:
|
|
124
|
+
return other in self.data
|
|
125
|
+
|
|
126
|
+
@setdoc.basic
|
|
127
|
+
def __getitem__(self: Self, key: Any) -> Any:
|
|
128
|
+
return self.data[key]
|
|
129
|
+
|
|
130
|
+
@Overloadable
|
|
131
|
+
@setdoc.basic
|
|
132
|
+
def __init__(self: Self, *args: Any, **kwargs: Any) -> bool:
|
|
133
|
+
if len(args) == 0 and "string" in kwargs.keys():
|
|
134
|
+
return True
|
|
135
|
+
if len(args) == 1 and len(kwargs) == 0:
|
|
136
|
+
if isinstance(args[0], str):
|
|
137
|
+
return True
|
|
138
|
+
if hasattr(args[0], "__iter__"):
|
|
139
|
+
return False
|
|
140
|
+
return True
|
|
141
|
+
return False
|
|
142
|
+
|
|
143
|
+
@__init__.overload(True)
|
|
144
|
+
@setdoc.basic
|
|
145
|
+
def __init__(self: Self, string: Any) -> None:
|
|
146
|
+
self._init_setup()
|
|
147
|
+
self.string = string
|
|
148
|
+
|
|
149
|
+
@__init__.overload(False)
|
|
150
|
+
@setdoc.basic
|
|
151
|
+
def __init__(self: Self, data: Iterable = ()) -> None:
|
|
152
|
+
self._init_setup()
|
|
153
|
+
self.data = data
|
|
154
|
+
|
|
155
|
+
@setdoc.basic
|
|
156
|
+
def __iter__(self: Self) -> Iterator:
|
|
157
|
+
return iter(self.data)
|
|
158
|
+
|
|
159
|
+
@setdoc.basic
|
|
160
|
+
def __repr__(self: Self) -> str:
|
|
161
|
+
return datarepr(type(self).__name__, *self.data)
|
|
162
|
+
|
|
163
|
+
@setdoc.basic
|
|
164
|
+
def __reversed__(self: Self) -> reversed:
|
|
165
|
+
return reversed(self.data)
|
|
166
|
+
|
|
167
|
+
@setdoc.basic
|
|
168
|
+
def __setitem__(self: Self, key: Any, value: Any) -> None:
|
|
169
|
+
data: list = list(self.data)
|
|
170
|
+
data[key] = value
|
|
171
|
+
self.data = data
|
|
172
|
+
|
|
173
|
+
@classmethod
|
|
174
|
+
@abstractmethod
|
|
175
|
+
def _data_parse(cls: type, value: list) -> Iterable: ...
|
|
176
|
+
|
|
177
|
+
def _init_setup(self: Self) -> None:
|
|
178
|
+
self._data = ()
|
|
179
|
+
|
|
180
|
+
def _set(self: Self, value: Any) -> None:
|
|
181
|
+
if value is None:
|
|
182
|
+
self.data = ()
|
|
183
|
+
elif isinstance(value, str):
|
|
184
|
+
self.string = value
|
|
185
|
+
elif hasattr(value, "__iter__"):
|
|
186
|
+
self.data = value
|
|
187
|
+
else:
|
|
188
|
+
self.string = value
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
@setdoc.basic
|
|
192
|
+
def data(self: Self) -> tuple:
|
|
193
|
+
return self._data
|
|
194
|
+
|
|
195
|
+
@data.setter
|
|
196
|
+
@guard
|
|
197
|
+
def data(self: Self, value: Iterable) -> None:
|
|
198
|
+
self._data = tuple(self._data_parse(list(value)))
|
|
199
|
+
|
|
200
|
+
def count(self: Self, value: Any) -> int:
|
|
201
|
+
"This method counts the occurences of value."
|
|
202
|
+
return self.data.count(value)
|
|
203
|
+
|
|
204
|
+
def index(self: Self, *args: Any) -> None:
|
|
205
|
+
"This method returns the index of the first occurence."
|
|
206
|
+
return self.data.index(*args)
|
|
@@ -7,51 +7,6 @@ from v440._utils.Cfg import Cfg
|
|
|
7
7
|
from v440._utils.Digest import Digest
|
|
8
8
|
from v440._utils.Pattern import Pattern
|
|
9
9
|
|
|
10
|
-
parse_leg: Digest = Digest("parse_leg")
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@parse_leg.overload()
|
|
14
|
-
def parse_leg() -> tuple:
|
|
15
|
-
return None, None, None
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@parse_leg.overload(int)
|
|
19
|
-
def parse_leg(value: int) -> tuple:
|
|
20
|
-
return None, abs(value), None
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@parse_leg.overload(list)
|
|
24
|
-
def parse_leg(value: list) -> tuple:
|
|
25
|
-
return tuple([value[:2]] + value[2:])
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
@parse_leg.overload(str)
|
|
29
|
-
def parse_leg(value: str) -> tuple:
|
|
30
|
-
v = value
|
|
31
|
-
pre: tuple = None, None
|
|
32
|
-
post: Optional[str] = None
|
|
33
|
-
dev: Optional[str] = None
|
|
34
|
-
m: Any
|
|
35
|
-
x: Any
|
|
36
|
-
y: Any
|
|
37
|
-
while v:
|
|
38
|
-
m = Pattern.QUALIFIERS.leftbound.search(v)
|
|
39
|
-
v = v[m.end() :]
|
|
40
|
-
if m.group("N"):
|
|
41
|
-
post = m.group("N")
|
|
42
|
-
continue
|
|
43
|
-
x = m.group("l")
|
|
44
|
-
y = m.group("n")
|
|
45
|
-
if x == "dev":
|
|
46
|
-
dev = y
|
|
47
|
-
continue
|
|
48
|
-
if x in ("post", "r", "rev"):
|
|
49
|
-
post = y
|
|
50
|
-
continue
|
|
51
|
-
pre = x, y
|
|
52
|
-
return pre, post, dev
|
|
53
|
-
|
|
54
|
-
|
|
55
10
|
parse_dev: Digest = Digest("parse_dev")
|
|
56
11
|
|
|
57
12
|
|
|
@@ -74,30 +74,17 @@ def ishashable(value: Any) -> bool:
|
|
|
74
74
|
def guard(old: Any) -> Any:
|
|
75
75
|
@functools.wraps(old)
|
|
76
76
|
def new(self: Self, value: Any) -> None:
|
|
77
|
-
backup:
|
|
78
|
-
x: Any
|
|
79
|
-
y: Any
|
|
80
|
-
for x in type(self).__slots__:
|
|
81
|
-
y = getattr(self, x)
|
|
82
|
-
backup[x] = y if ishashable(y) else y.copy()
|
|
77
|
+
backup: str = str(getattr(self, old.__name__))
|
|
83
78
|
try:
|
|
84
79
|
old(self, value)
|
|
85
80
|
except VersionError:
|
|
86
|
-
|
|
81
|
+
setattr(self, old.__name__, backup)
|
|
87
82
|
raise
|
|
88
83
|
except Exception:
|
|
89
|
-
|
|
84
|
+
setattr(self, old.__name__, backup)
|
|
90
85
|
msg: str = "%r is an invalid value for %r"
|
|
91
86
|
target: str = type(self).__name__ + "." + old.__name__
|
|
92
87
|
msg %= (value, target)
|
|
93
88
|
raise VersionError(msg)
|
|
94
89
|
|
|
95
90
|
return new
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
def restore(obj: Any, backup: dict) -> None:
|
|
99
|
-
for x in type(obj).__slots__:
|
|
100
|
-
if ishashable(backup[x]):
|
|
101
|
-
setattr(obj, x, backup[x])
|
|
102
|
-
else:
|
|
103
|
-
getattr(obj, x).data = backup[x]
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import *
|
|
4
4
|
|
|
5
5
|
import setdoc
|
|
6
|
+
from overloadable import Overloadable
|
|
6
7
|
|
|
7
8
|
from v440._utils.Digest import Digest
|
|
8
9
|
from v440._utils.SlotList import SlotList
|
|
@@ -12,32 +13,6 @@ from v440.core.Release import Release
|
|
|
12
13
|
__all__ = ["Base"]
|
|
13
14
|
|
|
14
15
|
|
|
15
|
-
parse_data: Digest = Digest("parse_data")
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@parse_data.overload()
|
|
19
|
-
def parse_data() -> tuple:
|
|
20
|
-
return None, None
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@parse_data.overload(int)
|
|
24
|
-
def parse_data(value: int) -> tuple:
|
|
25
|
-
return None, value
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
@parse_data.overload(list)
|
|
29
|
-
def parse_data(value: list) -> tuple:
|
|
30
|
-
return tuple(value)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
@parse_data.overload(str)
|
|
34
|
-
def parse_data(value: str) -> tuple:
|
|
35
|
-
if "!" in value:
|
|
36
|
-
return tuple(value.split("!"))
|
|
37
|
-
else:
|
|
38
|
-
return 0, value
|
|
39
|
-
|
|
40
|
-
|
|
41
16
|
parse_epoch: Digest = Digest("parse_epoch")
|
|
42
17
|
|
|
43
18
|
|
|
@@ -70,16 +45,42 @@ class Base(SlotList):
|
|
|
70
45
|
|
|
71
46
|
__slots__ = ("_epoch", "_release")
|
|
72
47
|
|
|
73
|
-
data: tuple
|
|
74
48
|
string: str
|
|
75
49
|
epoch: int
|
|
76
50
|
release: Release
|
|
77
51
|
|
|
52
|
+
def __bool__(self: Self) -> bool:
|
|
53
|
+
return bool(self.epoch or self.release)
|
|
54
|
+
|
|
55
|
+
@Overloadable
|
|
56
|
+
@setdoc.basic
|
|
57
|
+
def __init__(self: Self, *args: Any, **kwargs: Any) -> bool:
|
|
58
|
+
if len(args) == 0 and "string" in kwargs.keys():
|
|
59
|
+
return True
|
|
60
|
+
if len(args) == 1 and len(kwargs) == 0:
|
|
61
|
+
return True
|
|
62
|
+
return False
|
|
63
|
+
|
|
64
|
+
@__init__.overload(True)
|
|
65
|
+
@setdoc.basic
|
|
66
|
+
def __init__(self: Self, string: Any) -> None:
|
|
67
|
+
self._init_setup()
|
|
68
|
+
self.string = string
|
|
69
|
+
|
|
70
|
+
@__init__.overload(False)
|
|
78
71
|
@setdoc.basic
|
|
79
|
-
def __init__(
|
|
72
|
+
def __init__(
|
|
73
|
+
self: Self,
|
|
74
|
+
epoch: Any = "0",
|
|
75
|
+
release: Any = "0",
|
|
76
|
+
) -> None:
|
|
77
|
+
self._init_setup()
|
|
78
|
+
self.epoch = epoch
|
|
79
|
+
self.release = release
|
|
80
|
+
|
|
81
|
+
def _init_setup(self: Self) -> None:
|
|
80
82
|
self._epoch = 0
|
|
81
83
|
self._release = Release()
|
|
82
|
-
self.data = data
|
|
83
84
|
|
|
84
85
|
def _format(self: Self, format_spec: str) -> str:
|
|
85
86
|
ans: str = ""
|
|
@@ -89,22 +90,18 @@ class Base(SlotList):
|
|
|
89
90
|
return ans
|
|
90
91
|
|
|
91
92
|
def _string_fset(self: Self, value: str) -> None:
|
|
93
|
+
v: str = value
|
|
94
|
+
if v.startswith("v"):
|
|
95
|
+
v = v[1:]
|
|
92
96
|
parsed: Iterable
|
|
93
|
-
if "!" in
|
|
94
|
-
parsed =
|
|
97
|
+
if "!" in v:
|
|
98
|
+
parsed = v.split("!")
|
|
95
99
|
else:
|
|
96
|
-
parsed = 0,
|
|
100
|
+
parsed = 0, v
|
|
97
101
|
self.epoch, self.release.string = parsed
|
|
98
102
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def data(self: Self) -> tuple:
|
|
102
|
-
return self.epoch, self.release
|
|
103
|
-
|
|
104
|
-
@data.setter
|
|
105
|
-
@guard
|
|
106
|
-
def data(self: Self, value: Any) -> None:
|
|
107
|
-
self.epoch, self.release = parse_data(value)
|
|
103
|
+
def _todict(self: Self) -> dict:
|
|
104
|
+
return dict(epoch=self.epoch, release=self.release)
|
|
108
105
|
|
|
109
106
|
@property
|
|
110
107
|
def epoch(self: Self) -> int:
|
|
@@ -124,4 +121,4 @@ class Base(SlotList):
|
|
|
124
121
|
@release.setter
|
|
125
122
|
@guard
|
|
126
123
|
def release(self: Self, value: Any) -> None:
|
|
127
|
-
self.
|
|
124
|
+
self.release._set(value)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import *
|
|
4
|
+
|
|
5
|
+
import setdoc
|
|
6
|
+
|
|
7
|
+
from v440._utils import utils
|
|
8
|
+
from v440._utils.Digest import Digest
|
|
9
|
+
from v440._utils.utils import guard
|
|
10
|
+
from v440._utils.VList import VList
|
|
11
|
+
|
|
12
|
+
__all__ = ["Local"]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Local(VList):
|
|
16
|
+
__slots__ = ()
|
|
17
|
+
|
|
18
|
+
data: tuple[int | str]
|
|
19
|
+
string: str
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def _data_parse(cls: type, value: list) -> Iterable:
|
|
23
|
+
ans: tuple = tuple(map(utils.segment, value))
|
|
24
|
+
if None in ans:
|
|
25
|
+
raise ValueError
|
|
26
|
+
return ans
|
|
27
|
+
|
|
28
|
+
def _format(self: Self, format_spec: str) -> str:
|
|
29
|
+
if format_spec:
|
|
30
|
+
raise ValueError
|
|
31
|
+
return ".".join(map(str, self))
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def _sort(cls: type, value: Any) -> tuple[bool, int | str]:
|
|
35
|
+
return type(value) is int, value
|
|
36
|
+
|
|
37
|
+
def _string_fset(self: Self, value: str) -> None:
|
|
38
|
+
if value == "":
|
|
39
|
+
return ()
|
|
40
|
+
v: str = value
|
|
41
|
+
if v.startswith("+"):
|
|
42
|
+
v = v[1:]
|
|
43
|
+
v = v.replace("_", ".")
|
|
44
|
+
v = v.replace("-", ".")
|
|
45
|
+
self.data = v.split(".")
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import *
|
|
4
4
|
|
|
5
5
|
import setdoc
|
|
6
|
+
from overloadable import Overloadable
|
|
6
7
|
|
|
7
8
|
from v440._utils.Digest import Digest
|
|
8
9
|
from v440._utils.Pattern import Pattern
|
|
@@ -14,44 +15,46 @@ from v440.core.Qual import Qual
|
|
|
14
15
|
__all__ = ["Public"]
|
|
15
16
|
|
|
16
17
|
|
|
17
|
-
parse_data: Digest = Digest("parse_data")
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@parse_data.overload()
|
|
21
|
-
def parse_data() -> tuple:
|
|
22
|
-
return None, None
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@parse_data.overload(int)
|
|
26
|
-
def parse_data(value: int) -> tuple:
|
|
27
|
-
return value, None
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@parse_data.overload(list)
|
|
31
|
-
def parse_data(value: list) -> tuple:
|
|
32
|
-
return tuple(value)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@parse_data.overload(str)
|
|
36
|
-
def parse_data(value: str) -> tuple:
|
|
37
|
-
match: Any = Pattern.PUBLIC.leftbound.search(value)
|
|
38
|
-
return value[: match.end()], value[match.end() :]
|
|
39
|
-
|
|
40
|
-
|
|
41
18
|
class Public(SlotList):
|
|
42
19
|
|
|
43
20
|
__slots__ = ("_base", "_qual")
|
|
44
21
|
|
|
45
|
-
data: tuple
|
|
46
22
|
string: str
|
|
47
23
|
base: Base
|
|
48
24
|
qual: Qual
|
|
49
25
|
|
|
26
|
+
def __bool__(self: Self) -> bool:
|
|
27
|
+
return bool(self.base or self.qual)
|
|
28
|
+
|
|
29
|
+
@Overloadable
|
|
30
|
+
@setdoc.basic
|
|
31
|
+
def __init__(self: Self, *args: Any, **kwargs: Any) -> bool:
|
|
32
|
+
if len(args) == 0 and "string" in kwargs.keys():
|
|
33
|
+
return True
|
|
34
|
+
if len(args) == 1 and len(kwargs) == 0:
|
|
35
|
+
return True
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
@__init__.overload(True)
|
|
50
39
|
@setdoc.basic
|
|
51
|
-
def __init__(self: Self,
|
|
40
|
+
def __init__(self: Self, string: Any) -> None:
|
|
41
|
+
self._init_setup()
|
|
42
|
+
self.string = string
|
|
43
|
+
|
|
44
|
+
@__init__.overload(False)
|
|
45
|
+
@setdoc.basic
|
|
46
|
+
def __init__(
|
|
47
|
+
self: Self,
|
|
48
|
+
base: Any = "0",
|
|
49
|
+
qual: Any = "",
|
|
50
|
+
) -> None:
|
|
51
|
+
self._init_setup()
|
|
52
|
+
self.base = base
|
|
53
|
+
self.qual = qual
|
|
54
|
+
|
|
55
|
+
def _init_setup(self: Self) -> None:
|
|
52
56
|
self._base = Base()
|
|
53
57
|
self._qual = Qual()
|
|
54
|
-
self.data = data
|
|
55
58
|
|
|
56
59
|
def _format(self: Self, format_spec: str) -> str:
|
|
57
60
|
return format(self.base, format_spec) + format(self.qual)
|
|
@@ -61,25 +64,17 @@ class Public(SlotList):
|
|
|
61
64
|
self.base.string = value[: match.end()]
|
|
62
65
|
self.qual.string = value[match.end() :]
|
|
63
66
|
|
|
67
|
+
def _todict(self: Self) -> dict:
|
|
68
|
+
return dict(base=self.base, qual=self.qual)
|
|
69
|
+
|
|
64
70
|
@property
|
|
65
71
|
def base(self: Self) -> Base:
|
|
66
72
|
"This property represents the version base."
|
|
67
73
|
return self._base
|
|
68
74
|
|
|
69
75
|
@base.setter
|
|
70
|
-
@guard
|
|
71
76
|
def base(self: Self, value: Any) -> None:
|
|
72
|
-
self.base.
|
|
73
|
-
|
|
74
|
-
@property
|
|
75
|
-
@setdoc.basic
|
|
76
|
-
def data(self: Self) -> list:
|
|
77
|
-
return self.base, self.qual
|
|
78
|
-
|
|
79
|
-
@data.setter
|
|
80
|
-
@guard
|
|
81
|
-
def data(self: Self, value: Any) -> None:
|
|
82
|
-
self.base, self.qual = parse_data(value)
|
|
77
|
+
self.base._set(value)
|
|
83
78
|
|
|
84
79
|
@property
|
|
85
80
|
def qual(self: Self) -> Qual:
|
|
@@ -87,6 +82,5 @@ class Public(SlotList):
|
|
|
87
82
|
return self._qual
|
|
88
83
|
|
|
89
84
|
@qual.setter
|
|
90
|
-
@guard
|
|
91
85
|
def qual(self: Self, value: Any) -> None:
|
|
92
|
-
self.qual.
|
|
86
|
+
self.qual._set(value)
|
|
@@ -3,8 +3,10 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import *
|
|
4
4
|
|
|
5
5
|
import setdoc
|
|
6
|
+
from overloadable import Overloadable
|
|
6
7
|
|
|
7
|
-
from v440._utils import qualparse
|
|
8
|
+
from v440._utils import qualparse, utils
|
|
9
|
+
from v440._utils.Pattern import Pattern
|
|
8
10
|
from v440._utils.SlotList import SlotList
|
|
9
11
|
from v440._utils.utils import guard
|
|
10
12
|
|
|
@@ -15,7 +17,6 @@ class Qual(SlotList):
|
|
|
15
17
|
|
|
16
18
|
__slots__ = ("_prephase", "_presubphase", "_post", "_dev")
|
|
17
19
|
|
|
18
|
-
data: tuple
|
|
19
20
|
string: str
|
|
20
21
|
pre: tuple
|
|
21
22
|
prephase: Optional[str]
|
|
@@ -23,17 +24,42 @@ class Qual(SlotList):
|
|
|
23
24
|
post: Optional[int]
|
|
24
25
|
dev: Optional[int]
|
|
25
26
|
|
|
26
|
-
@setdoc.basic
|
|
27
27
|
def __bool__(self: Self) -> bool:
|
|
28
|
-
return
|
|
28
|
+
return self.string == ""
|
|
29
|
+
|
|
30
|
+
@Overloadable
|
|
31
|
+
@setdoc.basic
|
|
32
|
+
def __init__(self: Self, *args: Any, **kwargs: Any) -> bool:
|
|
33
|
+
if len(args) == 0 and "string" in kwargs.keys():
|
|
34
|
+
return True
|
|
35
|
+
if len(args) == 1 and len(kwargs) == 0:
|
|
36
|
+
return True
|
|
37
|
+
return False
|
|
38
|
+
|
|
39
|
+
@__init__.overload(True)
|
|
40
|
+
@setdoc.basic
|
|
41
|
+
def __init__(self: Self, string: Any) -> None:
|
|
42
|
+
self._init_setup()
|
|
43
|
+
self.string = string
|
|
29
44
|
|
|
45
|
+
@__init__.overload(False)
|
|
30
46
|
@setdoc.basic
|
|
31
|
-
def __init__(
|
|
47
|
+
def __init__(
|
|
48
|
+
self: Self,
|
|
49
|
+
pre: Any = None,
|
|
50
|
+
post: Any = None,
|
|
51
|
+
dev: Any = None,
|
|
52
|
+
) -> None:
|
|
53
|
+
self._init_setup()
|
|
54
|
+
self.pre = pre
|
|
55
|
+
self.post = post
|
|
56
|
+
self.dev = dev
|
|
57
|
+
|
|
58
|
+
def _init_setup(self: Self) -> None:
|
|
32
59
|
self._prephase = None
|
|
33
60
|
self._presubphase = None
|
|
34
61
|
self._post = None
|
|
35
62
|
self._dev = None
|
|
36
|
-
self.data = data
|
|
37
63
|
|
|
38
64
|
def _cmp(self: Self) -> list:
|
|
39
65
|
ans: list = list()
|
|
@@ -68,31 +94,30 @@ class Qual(SlotList):
|
|
|
68
94
|
m: Any
|
|
69
95
|
x: Any
|
|
70
96
|
y: Any
|
|
97
|
+
pre: Any = (None, None)
|
|
98
|
+
post: Any = None
|
|
99
|
+
dev: Any = None
|
|
71
100
|
while v:
|
|
72
101
|
m = Pattern.QUALIFIERS.leftbound.search(v)
|
|
73
102
|
v = v[m.end() :]
|
|
74
103
|
if m.group("N"):
|
|
75
|
-
|
|
104
|
+
post = m.group("N")
|
|
76
105
|
continue
|
|
77
106
|
x = m.group("l")
|
|
78
107
|
y = m.group("n")
|
|
79
108
|
if x == "dev":
|
|
80
|
-
|
|
109
|
+
dev = y
|
|
81
110
|
continue
|
|
82
111
|
if x in ("post", "r", "rev"):
|
|
83
|
-
|
|
112
|
+
post = y
|
|
84
113
|
continue
|
|
85
|
-
|
|
114
|
+
pre = x, y
|
|
115
|
+
self.pre = pre
|
|
116
|
+
self.post = post
|
|
117
|
+
self.dev = dev
|
|
86
118
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def data(self: Self) -> tuple:
|
|
90
|
-
return self.prephase, self.presubphase, self.post, self.dev
|
|
91
|
-
|
|
92
|
-
@data.setter
|
|
93
|
-
@guard
|
|
94
|
-
def data(self: Self, value: Any) -> None:
|
|
95
|
-
self.pre, self.post, self.dev = qualparse.parse_leg(value)
|
|
119
|
+
def _todict(self: Self) -> dict:
|
|
120
|
+
return dict(pre=self.pre, post=self.post, dev=self.dev)
|
|
96
121
|
|
|
97
122
|
@property
|
|
98
123
|
def dev(self: Self) -> Optional[int]:
|
|
@@ -157,10 +157,6 @@ class Release(VList):
|
|
|
157
157
|
ans: list = list(m)
|
|
158
158
|
return ans
|
|
159
159
|
|
|
160
|
-
@setdoc.basic
|
|
161
|
-
def __init__(self: Any, data: Any = None) -> None:
|
|
162
|
-
self.data = data
|
|
163
|
-
|
|
164
160
|
@Overloadable
|
|
165
161
|
@setdoc.basic
|
|
166
162
|
def __setitem__(self: Self, key: Any, value: Any) -> bool:
|
|
@@ -178,6 +174,13 @@ class Release(VList):
|
|
|
178
174
|
k: range = torange(key, len(self))
|
|
179
175
|
self._setitem_range(k, value)
|
|
180
176
|
|
|
177
|
+
@classmethod
|
|
178
|
+
def _data_parse(cls: type, value: list) -> Iterable:
|
|
179
|
+
v: list = tolist(value, slicing="always")
|
|
180
|
+
while v and v[-1] == 0:
|
|
181
|
+
v.pop()
|
|
182
|
+
return v
|
|
183
|
+
|
|
181
184
|
def _format(self: Self, format_spec: str) -> str:
|
|
182
185
|
i: Optional[int]
|
|
183
186
|
if format_spec:
|
|
@@ -254,16 +257,3 @@ class Release(VList):
|
|
|
254
257
|
self._setitem_int(i, x)
|
|
255
258
|
if i != -1:
|
|
256
259
|
self.data = self.data[: i + 1]
|
|
257
|
-
|
|
258
|
-
@property
|
|
259
|
-
@setdoc.basic
|
|
260
|
-
def data(self: Self) -> tuple:
|
|
261
|
-
return self._data
|
|
262
|
-
|
|
263
|
-
@data.setter
|
|
264
|
-
@guard
|
|
265
|
-
def data(self: Self, value: Any) -> None:
|
|
266
|
-
v: list = tolist(value, slicing="always")
|
|
267
|
-
while v and v[-1] == 0:
|
|
268
|
-
v.pop()
|
|
269
|
-
self._data = tuple(v)
|
|
@@ -4,8 +4,8 @@ from typing import *
|
|
|
4
4
|
|
|
5
5
|
import packaging.version
|
|
6
6
|
import setdoc
|
|
7
|
+
from overloadable import Overloadable
|
|
7
8
|
|
|
8
|
-
from v440._utils.Digest import Digest
|
|
9
9
|
from v440._utils.SlotList import SlotList
|
|
10
10
|
from v440._utils.utils import guard
|
|
11
11
|
from v440.core.Local import Local
|
|
@@ -13,45 +13,46 @@ from v440.core.Public import Public
|
|
|
13
13
|
|
|
14
14
|
__all__ = ["Version"]
|
|
15
15
|
|
|
16
|
-
parse_data: Digest = Digest("parse_data")
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@parse_data.overload()
|
|
20
|
-
def parse_data() -> tuple:
|
|
21
|
-
return None, None
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
@parse_data.overload(int)
|
|
25
|
-
def parse_data(value: int) -> tuple:
|
|
26
|
-
return value, None
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@parse_data.overload(list)
|
|
30
|
-
def parse_data(value: list) -> tuple:
|
|
31
|
-
return tuple(value)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
@parse_data.overload(str)
|
|
35
|
-
def parse_data(value: str) -> tuple:
|
|
36
|
-
if "+" in value:
|
|
37
|
-
return tuple(value.split("+"))
|
|
38
|
-
else:
|
|
39
|
-
return value, None
|
|
40
|
-
|
|
41
16
|
|
|
42
17
|
class Version(SlotList):
|
|
43
18
|
__slots__ = ("_public", "_local")
|
|
44
19
|
|
|
45
|
-
data: tuple
|
|
46
20
|
string: str
|
|
47
21
|
local: Local
|
|
48
22
|
public: Public
|
|
49
23
|
|
|
24
|
+
def __bool__(self: Self) -> bool:
|
|
25
|
+
return bool(self.local or self.public)
|
|
26
|
+
|
|
27
|
+
@Overloadable
|
|
28
|
+
@setdoc.basic
|
|
29
|
+
def __init__(self: Self, *args: Any, **kwargs: Any) -> bool:
|
|
30
|
+
if len(args) == 0 and "string" in kwargs.keys():
|
|
31
|
+
return True
|
|
32
|
+
if len(args) == 1 and len(kwargs) == 0:
|
|
33
|
+
return True
|
|
34
|
+
return False
|
|
35
|
+
|
|
36
|
+
@__init__.overload(True)
|
|
37
|
+
@setdoc.basic
|
|
38
|
+
def __init__(self: Self, string: Any) -> None:
|
|
39
|
+
self._init_setup()
|
|
40
|
+
self.string = string
|
|
41
|
+
|
|
42
|
+
@__init__.overload(False)
|
|
50
43
|
@setdoc.basic
|
|
51
|
-
def __init__(
|
|
44
|
+
def __init__(
|
|
45
|
+
self: Self,
|
|
46
|
+
public: Any = "0",
|
|
47
|
+
local: Any = "",
|
|
48
|
+
) -> None:
|
|
49
|
+
self._init_setup()
|
|
50
|
+
self.public = public
|
|
51
|
+
self.local = local
|
|
52
|
+
|
|
53
|
+
def _init_setup(self: Self) -> None:
|
|
52
54
|
self._public = Public()
|
|
53
55
|
self._local = Local()
|
|
54
|
-
self.data = data
|
|
55
56
|
|
|
56
57
|
def _format(self: Self, format_spec: str) -> str:
|
|
57
58
|
ans: str = format(self.public, format_spec)
|
|
@@ -67,15 +68,8 @@ class Version(SlotList):
|
|
|
67
68
|
parsed = value, ""
|
|
68
69
|
self.public.string, self.local.string = parsed
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def data(self: Self) -> tuple:
|
|
73
|
-
return self.public, self.local
|
|
74
|
-
|
|
75
|
-
@data.setter
|
|
76
|
-
@guard
|
|
77
|
-
def data(self: Self, value: Any) -> None:
|
|
78
|
-
self.public, self.local = parse_data(value)
|
|
71
|
+
def _todict(self: Self) -> dict:
|
|
72
|
+
return dict(public=self.public, local=self.local)
|
|
79
73
|
|
|
80
74
|
@property
|
|
81
75
|
def local(self: Self) -> Local:
|
|
@@ -85,7 +79,7 @@ class Version(SlotList):
|
|
|
85
79
|
@local.setter
|
|
86
80
|
@guard
|
|
87
81
|
def local(self: Self, value: Any) -> None:
|
|
88
|
-
self.local.
|
|
82
|
+
self.local._set(value)
|
|
89
83
|
|
|
90
84
|
def packaging(self: Self) -> packaging.version.Version:
|
|
91
85
|
"This method returns an eqivalent packaging.version.Version object."
|
|
@@ -99,4 +93,4 @@ class Version(SlotList):
|
|
|
99
93
|
@public.setter
|
|
100
94
|
@guard
|
|
101
95
|
def public(self: Self, value: Any) -> None:
|
|
102
|
-
self.public.
|
|
96
|
+
self.public._set(value)
|
|
@@ -59,7 +59,7 @@ class TestPre(unittest.TestCase):
|
|
|
59
59
|
|
|
60
60
|
# Initial version, no pre-release version
|
|
61
61
|
self.assertEqual(str(v), "1.2.3")
|
|
62
|
-
self.assertEqual(v.public.qual,
|
|
62
|
+
self.assertEqual(v.public.qual.string, "")
|
|
63
63
|
|
|
64
64
|
# Set pre-release version to "a1"
|
|
65
65
|
v.public.qual = "a1"
|
|
@@ -88,7 +88,7 @@ class TestPre(unittest.TestCase):
|
|
|
88
88
|
# Set pre-release to None
|
|
89
89
|
v.public.qual = None
|
|
90
90
|
self.assertEqual(str(v), "1.2.3")
|
|
91
|
-
self.assertEqual(v.public.qual,
|
|
91
|
+
self.assertEqual(str(v.public.qual), "")
|
|
92
92
|
|
|
93
93
|
|
|
94
94
|
class TestExample(unittest.TestCase):
|
|
@@ -179,7 +179,7 @@ class TestExample(unittest.TestCase):
|
|
|
179
179
|
def test_example_7(self: Self) -> None:
|
|
180
180
|
v: Version = Version("5.0.0")
|
|
181
181
|
self.assertEqual(str(v), "5") # Original version
|
|
182
|
-
v.
|
|
182
|
+
v.string = ""
|
|
183
183
|
self.assertEqual(str(v), "0") # After reset
|
|
184
184
|
v.public.base = "4!5.0.1"
|
|
185
185
|
self.assertEqual(str(v), "4!5.0.1") # Before error
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import *
|
|
4
|
-
|
|
5
|
-
import setdoc
|
|
6
|
-
|
|
7
|
-
from v440._utils import utils
|
|
8
|
-
from v440._utils.Digest import Digest
|
|
9
|
-
from v440._utils.utils import guard
|
|
10
|
-
from v440._utils.VList import VList
|
|
11
|
-
|
|
12
|
-
__all__ = ["Local"]
|
|
13
|
-
|
|
14
|
-
parse_data: Digest = Digest("parse_data")
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@parse_data.overload()
|
|
18
|
-
def parse_data() -> tuple:
|
|
19
|
-
return ()
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@parse_data.overload(int)
|
|
23
|
-
def parse_data(value: int) -> list:
|
|
24
|
-
return (value,)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@parse_data.overload(list)
|
|
28
|
-
def parse_data(value: list) -> list:
|
|
29
|
-
ans: tuple = tuple(map(utils.segment, value))
|
|
30
|
-
if None in ans:
|
|
31
|
-
raise ValueError
|
|
32
|
-
return ans
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@parse_data.overload(str)
|
|
36
|
-
def parse_data(value: str) -> tuple:
|
|
37
|
-
v: str = value
|
|
38
|
-
if v.startswith("+"):
|
|
39
|
-
v = v[1:]
|
|
40
|
-
v = v.replace("_", ".")
|
|
41
|
-
v = v.replace("-", ".")
|
|
42
|
-
ans: tuple = v.split(".")
|
|
43
|
-
ans = tuple(map(utils.segment, ans))
|
|
44
|
-
if None in ans:
|
|
45
|
-
raise ValueError
|
|
46
|
-
return ans
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
class Local(VList):
|
|
50
|
-
__slots__ = ()
|
|
51
|
-
|
|
52
|
-
data: tuple[int | str]
|
|
53
|
-
string: str
|
|
54
|
-
|
|
55
|
-
@setdoc.basic
|
|
56
|
-
def __init__(self: Any, data: Any = None) -> None:
|
|
57
|
-
self.data = data
|
|
58
|
-
|
|
59
|
-
def _format(self: Self, format_spec: str) -> str:
|
|
60
|
-
if format_spec:
|
|
61
|
-
raise ValueError
|
|
62
|
-
return ".".join(map(str, self))
|
|
63
|
-
|
|
64
|
-
@classmethod
|
|
65
|
-
def _sort(cls: type, value: Any) -> tuple[bool, int | str]:
|
|
66
|
-
return type(value) is int, value
|
|
67
|
-
|
|
68
|
-
def _string_fset(self: Self, value: str) -> None:
|
|
69
|
-
v: str = value
|
|
70
|
-
if v.startswith("+"):
|
|
71
|
-
v = v[1:]
|
|
72
|
-
v = v.replace("_", ".")
|
|
73
|
-
v = v.replace("-", ".")
|
|
74
|
-
self.data = v.split(".")
|
|
75
|
-
|
|
76
|
-
@property
|
|
77
|
-
@setdoc.basic
|
|
78
|
-
def data(self: Self) -> tuple[int | str]:
|
|
79
|
-
return self._data
|
|
80
|
-
|
|
81
|
-
@data.setter
|
|
82
|
-
@guard
|
|
83
|
-
def data(self: Self, value: Any) -> None:
|
|
84
|
-
self._data = parse_data(value)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|