v440 2.0.0.dev60__tar.gz → 2.0.0.dev62__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.dev62}/PKG-INFO +1 -1
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/pyproject.toml +1 -1
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/_utils/BaseList.py +14 -44
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/_utils/SlotList.py +12 -5
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/_utils/VList.py +95 -1
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/_utils/qualparse.py +0 -45
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/_utils/utils.py +3 -16
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/core/Base.py +39 -42
- v440-2.0.0.dev62/src/v440/core/Local.py +45 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/core/Public.py +35 -41
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/core/Qual.py +44 -19
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/core/Release.py +7 -17
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/core/Version.py +34 -40
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/tests/test_testdata.py +5 -4
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/tests/test_version.py +3 -3
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/tests/testdata.toml +7 -3
- {v440-2.0.0.dev60 → v440-2.0.0.dev62/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.dev62}/LICENSE.txt +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/MANIFEST.in +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/README.rst +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/setup.cfg +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/__init__.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/_utils/Cfg.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/_utils/Digest.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/_utils/Pattern.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/_utils/__init__.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/_utils/cfg.toml +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/core/VersionError.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/core/__init__.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440/tests/__init__.py +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440.egg-info/SOURCES.txt +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440.egg-info/dependency_links.txt +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/src/v440.egg-info/requires.txt +0 -0
- {v440-2.0.0.dev60 → v440-2.0.0.dev62}/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("")
|
|
@@ -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)
|
|
@@ -167,7 +167,8 @@ class TestSlicingGo(unittest.TestCase):
|
|
|
167
167
|
class TestDataProperty(unittest.TestCase):
|
|
168
168
|
def test_data(self: Self) -> None:
|
|
169
169
|
for k, v in Util.util.data["data-property"].items():
|
|
170
|
-
self.
|
|
170
|
+
with self.subTest(key=k):
|
|
171
|
+
self.go(**v, key=k)
|
|
171
172
|
|
|
172
173
|
def go(
|
|
173
174
|
self: Self,
|
|
@@ -177,7 +178,7 @@ class TestDataProperty(unittest.TestCase):
|
|
|
177
178
|
) -> None:
|
|
178
179
|
msg: str = "data-property %r" % key
|
|
179
180
|
version: Version = Version()
|
|
180
|
-
version.
|
|
181
|
+
version.string = query
|
|
181
182
|
self.assertEqual(solution, str(version), msg=msg)
|
|
182
183
|
|
|
183
184
|
|
|
@@ -384,7 +385,7 @@ class TestSlots(unittest.TestCase):
|
|
|
384
385
|
clsname: str,
|
|
385
386
|
attrname: str,
|
|
386
387
|
attrvalue: Any,
|
|
387
|
-
|
|
388
|
+
string: Any = None,
|
|
388
389
|
isimported: Optional[bool] = False,
|
|
389
390
|
) -> None:
|
|
390
391
|
cls: type
|
|
@@ -392,7 +393,7 @@ class TestSlots(unittest.TestCase):
|
|
|
392
393
|
cls = getattr(core, clsname)
|
|
393
394
|
else:
|
|
394
395
|
cls = getattr(getattr(core, clsname), clsname)
|
|
395
|
-
obj: Any = cls(
|
|
396
|
+
obj: Any = cls(string=string)
|
|
396
397
|
with self.assertRaises(AttributeError):
|
|
397
398
|
setattr(obj, attrname, attrvalue)
|
|
398
399
|
|
|
@@ -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
|
|
@@ -961,9 +961,6 @@ solution = "9001"
|
|
|
961
961
|
query = "1701!4.5.6.rc255+reset"
|
|
962
962
|
solution = "1701!4.5.6rc255+reset"
|
|
963
963
|
|
|
964
|
-
[data-property.none]
|
|
965
|
-
solution = "0"
|
|
966
|
-
|
|
967
964
|
[slicingmethod.test_slicing_1]
|
|
968
965
|
query = "1.2.3.4.5.6.7.8.9.10"
|
|
969
966
|
start = -8
|
|
@@ -1030,36 +1027,43 @@ full = "1.2.3"
|
|
|
1030
1027
|
part = 0
|
|
1031
1028
|
|
|
1032
1029
|
[core-non-attributes.test-0000]
|
|
1030
|
+
string = ""
|
|
1033
1031
|
clsname = "Base"
|
|
1034
1032
|
attrname = "fdsfvdsff"
|
|
1035
1033
|
attrvalue = 42
|
|
1036
1034
|
|
|
1037
1035
|
[core-non-attributes.test-0100]
|
|
1036
|
+
string = ""
|
|
1038
1037
|
clsname = "Local"
|
|
1039
1038
|
attrname = "fdsfvdsff"
|
|
1040
1039
|
attrvalue = 42
|
|
1041
1040
|
|
|
1042
1041
|
[core-non-attributes.test-0200]
|
|
1042
|
+
string = ""
|
|
1043
1043
|
clsname = "Public"
|
|
1044
1044
|
attrname = "fdsfvdsff"
|
|
1045
1045
|
attrvalue = 42
|
|
1046
1046
|
|
|
1047
1047
|
[core-non-attributes.test-0300]
|
|
1048
|
+
string = ""
|
|
1048
1049
|
clsname = "Qual"
|
|
1049
1050
|
attrname = "fdsfvdsff"
|
|
1050
1051
|
attrvalue = 42
|
|
1051
1052
|
|
|
1052
1053
|
[core-non-attributes.test-0400]
|
|
1054
|
+
string = ""
|
|
1053
1055
|
clsname = "Release"
|
|
1054
1056
|
attrname = "fdsfvdsff"
|
|
1055
1057
|
attrvalue = 42
|
|
1056
1058
|
|
|
1057
1059
|
[core-non-attributes.test-0500]
|
|
1060
|
+
string = ""
|
|
1058
1061
|
clsname = "Public"
|
|
1059
1062
|
attrname = "fdsfvdsff"
|
|
1060
1063
|
attrvalue = 42
|
|
1061
1064
|
|
|
1062
1065
|
[core-non-attributes.test-0600]
|
|
1066
|
+
string = ""
|
|
1063
1067
|
clsname = "Version"
|
|
1064
1068
|
attrname = "fdsfvdsff"
|
|
1065
1069
|
attrvalue = 42
|
|
@@ -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
|