datahold 4.0.0.dev10__tar.gz → 4.0.0.dev21__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.
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/PKG-INFO +1 -1
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/pyproject.toml +1 -1
- datahold-4.0.0.dev21/src/datahold/__init__.py +649 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/src/datahold.egg-info/PKG-INFO +1 -1
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/src/datahold.egg-info/SOURCES.txt +1 -0
- datahold-4.0.0.dev21/tests/test_prefix.py +41 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/tests/testdata.toml +83 -15
- datahold-4.0.0.dev10/src/datahold/__init__.py +0 -258
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/LICENSE.txt +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/MANIFEST.in +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/README.rst +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/docs/v1.1.rst +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/docs/v1.2.rst +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/docs/v2.0.rst +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/docs/v2.1.rst +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/docs/v2.2.rst +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/docs/v2.3.rst +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/docs/v3.0.rst +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/docs/v4.0.rst +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/run_tests.py +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/setup.cfg +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/src/datahold/py.typed +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/src/datahold.egg-info/dependency_links.txt +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/src/datahold.egg-info/requires.txt +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/src/datahold.egg-info/top_level.txt +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/tests/test_FrozenListSlot.py +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/tests/test_MutableListHold.py +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/tests/test_abstractmethods.py +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/tests/test_all.py +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/tests/test_attributes.py +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/tests/test_docs.py +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/tests/test_generic.py +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/tests/test_internal_comparison.py +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/tests/test_issubclass.py +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/tests/test_nested.py +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/tests/test_sorted.py +0 -0
- {datahold-4.0.0.dev10 → datahold-4.0.0.dev21}/tests/test_variance.py +0 -0
|
@@ -0,0 +1,649 @@
|
|
|
1
|
+
"""Provide provides base classes for customized collections."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__: list[str] = [
|
|
6
|
+
"Collection",
|
|
7
|
+
"FrozenListLike",
|
|
8
|
+
"FrozenListSlot",
|
|
9
|
+
"FrozenSetLike",
|
|
10
|
+
"FrozenSetSlot",
|
|
11
|
+
"ListLike",
|
|
12
|
+
"ListSlot",
|
|
13
|
+
"MutableListLike",
|
|
14
|
+
"MutableListSlot",
|
|
15
|
+
"MutableSequence",
|
|
16
|
+
"MutableSet",
|
|
17
|
+
"MutableSetLike",
|
|
18
|
+
"MutableSetSlot",
|
|
19
|
+
"Sequence",
|
|
20
|
+
"Set",
|
|
21
|
+
"SetLike",
|
|
22
|
+
"SetSlot",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
from abc import abstractmethod
|
|
26
|
+
from collections import abc
|
|
27
|
+
from contextlib import contextmanager
|
|
28
|
+
from types import NotImplementedType, TracebackType
|
|
29
|
+
from typing import (
|
|
30
|
+
Any,
|
|
31
|
+
Never,
|
|
32
|
+
Optional,
|
|
33
|
+
Protocol,
|
|
34
|
+
Self,
|
|
35
|
+
SupportsIndex,
|
|
36
|
+
overload,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
import setdoc
|
|
40
|
+
|
|
41
|
+
### UTILS ###
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class ContextManager[Enter](Protocol):
|
|
45
|
+
"""Provide context manager protocol."""
|
|
46
|
+
|
|
47
|
+
@setdoc.basic
|
|
48
|
+
def __enter__(self: Self, /) -> Enter: ...
|
|
49
|
+
|
|
50
|
+
@setdoc.basic
|
|
51
|
+
def __exit__(
|
|
52
|
+
self: Self,
|
|
53
|
+
exc_type: type[BaseException] | None,
|
|
54
|
+
exc_value: BaseException | None,
|
|
55
|
+
traceback: TracebackType | None,
|
|
56
|
+
/,
|
|
57
|
+
) -> object: ...
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
type Slice[Index] = slice[Optional[Index], Optional[Index], Optional[Index]]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
### COLLECTION ###
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class Collection[Item](
|
|
67
|
+
abc.Sized,
|
|
68
|
+
abc.Iterable[Item],
|
|
69
|
+
abc.Container[object],
|
|
70
|
+
):
|
|
71
|
+
"""Provide abc for custom collections."""
|
|
72
|
+
|
|
73
|
+
@setdoc.basic
|
|
74
|
+
class __Frozen__[FrozenItem](
|
|
75
|
+
abc.Sized,
|
|
76
|
+
abc.Iterable[FrozenItem],
|
|
77
|
+
Protocol,
|
|
78
|
+
):
|
|
79
|
+
@setdoc.basic
|
|
80
|
+
def __contains__(self: Self, other: Never, /) -> bool: ...
|
|
81
|
+
|
|
82
|
+
@setdoc.basic
|
|
83
|
+
def __contains__(self: Self, other: object, /) -> bool:
|
|
84
|
+
try:
|
|
85
|
+
return other in self.__frozen__() # type: ignore[operator]
|
|
86
|
+
except TypeError:
|
|
87
|
+
return other in (x for x in self) # type: ignore[operator]
|
|
88
|
+
|
|
89
|
+
@abstractmethod
|
|
90
|
+
@setdoc.basic
|
|
91
|
+
def __frozen__(self: Self, /) -> __Frozen__[Item]: ...
|
|
92
|
+
|
|
93
|
+
@setdoc.basic
|
|
94
|
+
def __iter__(self: Self) -> abc.Iterator[Item]:
|
|
95
|
+
return iter(self.__frozen__())
|
|
96
|
+
|
|
97
|
+
@setdoc.basic
|
|
98
|
+
def __len__(self: Self, /) -> int:
|
|
99
|
+
return len(self.__frozen__())
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
### SET ###
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class Set[Item: abc.Hashable](Collection[Item], abc.Set[Item]):
|
|
106
|
+
"""Provide abc for custom set."""
|
|
107
|
+
|
|
108
|
+
__slots__ = ()
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class MutableSet[Item: abc.Hashable](Set[Item], abc.MutableSet[Item]):
|
|
112
|
+
"""Provide abc for custom mutable set."""
|
|
113
|
+
|
|
114
|
+
__slots__ = ()
|
|
115
|
+
|
|
116
|
+
@setdoc.basic
|
|
117
|
+
class __Mutable__[MutableItem: abc.Hashable](Protocol):
|
|
118
|
+
@setdoc.basic
|
|
119
|
+
def add(self: Self, item: MutableItem, /) -> object: ...
|
|
120
|
+
@setdoc.basic
|
|
121
|
+
def discard(self: Self, item: abc.Hashable, /) -> object: ...
|
|
122
|
+
@abstractmethod
|
|
123
|
+
@setdoc.basic
|
|
124
|
+
def __mutate__(self: Self) -> ContextManager[__Mutable__[Item]]: ...
|
|
125
|
+
@setdoc.basic
|
|
126
|
+
def add(self: Self, item: Item, /) -> None:
|
|
127
|
+
with self.__mutate__() as mutable:
|
|
128
|
+
mutable.add(item)
|
|
129
|
+
|
|
130
|
+
@setdoc.basic
|
|
131
|
+
def discard(self: Self, item: abc.Hashable, /) -> None:
|
|
132
|
+
with self.__mutate__() as mutable:
|
|
133
|
+
mutable.discard(item)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
### SET-LIKE ###
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class SetLike[Item: abc.Hashable](Set[Item]):
|
|
140
|
+
"""Provide abc for custom set-like."""
|
|
141
|
+
|
|
142
|
+
__slots__ = ()
|
|
143
|
+
type __Frozen__[FrozenItem] = frozenset[FrozenItem]
|
|
144
|
+
type Init[FrozenItem] = abc.Iterable[FrozenItem]
|
|
145
|
+
|
|
146
|
+
@abstractmethod
|
|
147
|
+
@setdoc.basic
|
|
148
|
+
def __frozen__(self: Self, /) -> __Frozen__[Item]: ...
|
|
149
|
+
@abstractmethod
|
|
150
|
+
@setdoc.basic
|
|
151
|
+
def __init__(self: Self, data: Init[Item] = (), /) -> None: ...
|
|
152
|
+
@setdoc.basic
|
|
153
|
+
def difference(self: Self, /, *others: abc.Iterable[abc.Hashable]) -> Self:
|
|
154
|
+
return type(self)(self.__frozen__().difference(*others))
|
|
155
|
+
|
|
156
|
+
@setdoc.basic
|
|
157
|
+
def intersection(
|
|
158
|
+
self: Self, /, *others: abc.Iterable[abc.Hashable]
|
|
159
|
+
) -> Self:
|
|
160
|
+
return type(self)(self.__frozen__().intersection(*others))
|
|
161
|
+
|
|
162
|
+
@setdoc.basic
|
|
163
|
+
def issubset(self: Self, other: abc.Iterable[abc.Hashable], /) -> Self:
|
|
164
|
+
return type(self)(self.__frozen__().issubset(other)) # type: ignore
|
|
165
|
+
|
|
166
|
+
@setdoc.basic
|
|
167
|
+
def issuperset(self: Self, other: abc.Iterable[abc.Hashable], /) -> Self:
|
|
168
|
+
return type(self)(self.__frozen__().issuperset(other)) # type: ignore
|
|
169
|
+
|
|
170
|
+
@setdoc.basic
|
|
171
|
+
def symmetric_difference(self: Self, other: abc.Iterable[Item], /) -> Self:
|
|
172
|
+
return type(self)(self.__frozen__().symmetric_difference(other))
|
|
173
|
+
|
|
174
|
+
@setdoc.basic
|
|
175
|
+
def union(self: Self, /, *others: abc.Iterable[Item]) -> Self:
|
|
176
|
+
return type(self)(self.__frozen__().union(others)) # type: ignore
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class FrozenSetLike[Item: abc.Hashable](SetLike[Item], abc.Hashable):
|
|
180
|
+
"""Provide abc for custom frozen set-like."""
|
|
181
|
+
|
|
182
|
+
__slots__ = ()
|
|
183
|
+
|
|
184
|
+
@setdoc.basic
|
|
185
|
+
def __hash__(self: Self) -> int:
|
|
186
|
+
return hash(self.__frozen__())
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class MutableSetLike[Item: abc.Hashable](SetLike[Item], MutableSet[Item]):
|
|
190
|
+
"""Provide abc for custom mutable set-like."""
|
|
191
|
+
|
|
192
|
+
__slots__ = ()
|
|
193
|
+
|
|
194
|
+
type __Mutable__[MutableItem] = set[MutableItem]
|
|
195
|
+
|
|
196
|
+
@setdoc.basic
|
|
197
|
+
def __frozen__(self: Self, /) -> MutableSetLike.__Frozen__[Item]:
|
|
198
|
+
with self.__mutate__() as mutable:
|
|
199
|
+
return frozenset(mutable)
|
|
200
|
+
|
|
201
|
+
@abstractmethod
|
|
202
|
+
@setdoc.basic
|
|
203
|
+
def __init__(self: Self, data: MutableSetLike.Init[Item] = (), /) -> None:
|
|
204
|
+
with self.__mutate__() as mutable:
|
|
205
|
+
mutable.update(data)
|
|
206
|
+
|
|
207
|
+
@abstractmethod
|
|
208
|
+
@setdoc.basic
|
|
209
|
+
def __mutate__(self: Self) -> ContextManager[__Mutable__[Item]]: ...
|
|
210
|
+
@setdoc.basic
|
|
211
|
+
def difference_update(
|
|
212
|
+
self: Self, /, *others: abc.Iterable[abc.Hashable]
|
|
213
|
+
) -> None:
|
|
214
|
+
with self.__mutate__() as mutable:
|
|
215
|
+
mutable.difference_update(*others)
|
|
216
|
+
|
|
217
|
+
@setdoc.basic
|
|
218
|
+
def intersection_update(
|
|
219
|
+
self: Self, /, *others: abc.Iterable[abc.Hashable]
|
|
220
|
+
) -> None:
|
|
221
|
+
with self.__mutate__() as mutable:
|
|
222
|
+
mutable.intersection_update(*others)
|
|
223
|
+
|
|
224
|
+
@setdoc.basic
|
|
225
|
+
def symmetric_difference_update(
|
|
226
|
+
self: Self, other: abc.Iterable[Item], /
|
|
227
|
+
) -> None:
|
|
228
|
+
with self.__mutate__() as mutable:
|
|
229
|
+
mutable.symmetric_difference_update(other)
|
|
230
|
+
|
|
231
|
+
@setdoc.basic
|
|
232
|
+
def update(self: Self, /, *others: abc.Iterable[Item]) -> None:
|
|
233
|
+
with self.__mutate__() as mutable:
|
|
234
|
+
mutable.update(*others)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
### SET-SLOT ###
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
class SetSlot[Item: abc.Hashable](SetLike[Item]):
|
|
241
|
+
"""Provide slotted set-like."""
|
|
242
|
+
|
|
243
|
+
__slots__ = ("_slot",)
|
|
244
|
+
|
|
245
|
+
_slot: SetSlot.__Frozen__[Item]
|
|
246
|
+
|
|
247
|
+
@setdoc.basic
|
|
248
|
+
def __frozen__(self: Self) -> SetSlot.__Frozen__[Item]:
|
|
249
|
+
return self._slot
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
class FrozenSetSlot[Item](SetSlot[Item], FrozenSetLike[Item]):
|
|
253
|
+
"""Provide slotted frozen set-like."""
|
|
254
|
+
|
|
255
|
+
__slots__ = ()
|
|
256
|
+
|
|
257
|
+
@setdoc.basic
|
|
258
|
+
def __init__(self: Self, data: FrozenSetSlot.Init[Item] = (), /) -> None:
|
|
259
|
+
self._slot = frozenset(data)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class MutableSetSlot[Item](SetSlot[Item], MutableSetLike[Item]):
|
|
263
|
+
"""Provide slotted mutable set-like."""
|
|
264
|
+
|
|
265
|
+
__slots__ = ()
|
|
266
|
+
|
|
267
|
+
@contextmanager
|
|
268
|
+
@setdoc.basic
|
|
269
|
+
def __mutate__(self: Self, /) -> abc.Generator[set[Item], None, None]:
|
|
270
|
+
slot = set(getattr(self, "_slot", ()))
|
|
271
|
+
yield slot
|
|
272
|
+
self._slot = frozenset(slot)
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
### SEQUENCE ###
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
class Sequence[Item](Collection[Item], abc.Sequence[Item]):
|
|
279
|
+
"""Provide a base class for customized sequence."""
|
|
280
|
+
|
|
281
|
+
__slots__ = ()
|
|
282
|
+
|
|
283
|
+
@setdoc.basic
|
|
284
|
+
class __Frozen__[FrozenItem](
|
|
285
|
+
Collection.__Frozen__[FrozenItem],
|
|
286
|
+
Protocol,
|
|
287
|
+
):
|
|
288
|
+
@overload
|
|
289
|
+
@setdoc.basic
|
|
290
|
+
def __getitem__(self: Self, key: int, /) -> FrozenItem: ...
|
|
291
|
+
@overload
|
|
292
|
+
@setdoc.basic
|
|
293
|
+
def __getitem__(
|
|
294
|
+
self: Self, key: Slice[int], /
|
|
295
|
+
) -> abc.Sequence[FrozenItem]: ...
|
|
296
|
+
@setdoc.basic
|
|
297
|
+
def __getitem__(
|
|
298
|
+
self: Self,
|
|
299
|
+
key: int | Slice[int],
|
|
300
|
+
/,
|
|
301
|
+
) -> FrozenItem | abc.Sequence[FrozenItem]: ...
|
|
302
|
+
|
|
303
|
+
@abstractmethod
|
|
304
|
+
@setdoc.basic
|
|
305
|
+
def __frozen__(self: Self, /) -> __Frozen__[Item]: ...
|
|
306
|
+
|
|
307
|
+
@overload
|
|
308
|
+
@setdoc.basic
|
|
309
|
+
def __getitem__(self: Self, key: int, /) -> Item: ...
|
|
310
|
+
@overload
|
|
311
|
+
@setdoc.basic
|
|
312
|
+
def __getitem__(self: Self, key: Slice[int], /) -> abc.Sequence[Item]: ...
|
|
313
|
+
@setdoc.basic
|
|
314
|
+
def __getitem__(
|
|
315
|
+
self: Self, key: int | Slice[int], /
|
|
316
|
+
) -> Item | abc.Sequence[Item]:
|
|
317
|
+
return self.__frozen__()[key]
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
class MutableSequence[Item](Sequence[Item], abc.MutableSequence[Item]):
|
|
321
|
+
"""Provide a base class for customized mutable list-likes."""
|
|
322
|
+
|
|
323
|
+
__slots__ = ()
|
|
324
|
+
|
|
325
|
+
@setdoc.basic
|
|
326
|
+
class __Mutable__[MutableItem](Protocol):
|
|
327
|
+
|
|
328
|
+
@overload
|
|
329
|
+
@setdoc.basic
|
|
330
|
+
def __delitem__(self: Self, key: SupportsIndex, /) -> None: ...
|
|
331
|
+
@overload
|
|
332
|
+
@setdoc.basic
|
|
333
|
+
def __delitem__(self: Self, key: Slice[SupportsIndex], /) -> None: ...
|
|
334
|
+
@setdoc.basic
|
|
335
|
+
def __delitem__(
|
|
336
|
+
self: Self, key: SupportsIndex | Slice[SupportsIndex], /
|
|
337
|
+
) -> None: ...
|
|
338
|
+
|
|
339
|
+
@overload
|
|
340
|
+
@setdoc.basic
|
|
341
|
+
def __getitem__(self: Self, key: int, /) -> MutableItem: ...
|
|
342
|
+
@overload
|
|
343
|
+
@setdoc.basic
|
|
344
|
+
def __getitem__(
|
|
345
|
+
self: Self, key: Slice[int], /
|
|
346
|
+
) -> abc.MutableSequence[MutableItem]: ...
|
|
347
|
+
@setdoc.basic
|
|
348
|
+
def __getitem__(
|
|
349
|
+
self: Self,
|
|
350
|
+
key: int | Slice[int],
|
|
351
|
+
/,
|
|
352
|
+
) -> MutableItem | abc.MutableSequence[MutableItem]: ...
|
|
353
|
+
|
|
354
|
+
@overload
|
|
355
|
+
@setdoc.basic
|
|
356
|
+
def __setitem__(
|
|
357
|
+
self: Self, key: int, value: MutableItem, /
|
|
358
|
+
) -> None: ...
|
|
359
|
+
@overload
|
|
360
|
+
@setdoc.basic
|
|
361
|
+
def __setitem__(
|
|
362
|
+
self: Self, key: Slice[int], value: abc.Iterable[MutableItem], /
|
|
363
|
+
) -> None: ...
|
|
364
|
+
@setdoc.basic
|
|
365
|
+
def __setitem__(
|
|
366
|
+
self: Self,
|
|
367
|
+
key: int | Slice[int],
|
|
368
|
+
value: MutableItem | abc.Iterable[MutableItem],
|
|
369
|
+
/,
|
|
370
|
+
) -> None: ...
|
|
371
|
+
|
|
372
|
+
@setdoc.basic
|
|
373
|
+
def insert(self: Self, index: int, item: MutableItem, /) -> None: ...
|
|
374
|
+
|
|
375
|
+
@overload
|
|
376
|
+
@setdoc.basic
|
|
377
|
+
def __delitem__(self: Self, key: int, /) -> None: ...
|
|
378
|
+
@overload
|
|
379
|
+
@setdoc.basic
|
|
380
|
+
def __delitem__(self: Self, key: Slice[int], /) -> None: ...
|
|
381
|
+
@setdoc.basic
|
|
382
|
+
def __delitem__(self: Self, key: int | Slice[int], /) -> None:
|
|
383
|
+
with self.__mutate__() as mutable:
|
|
384
|
+
del mutable[key]
|
|
385
|
+
|
|
386
|
+
@overload
|
|
387
|
+
@setdoc.basic
|
|
388
|
+
def __getitem__(self: Self, key: int, /) -> Item: ...
|
|
389
|
+
@overload
|
|
390
|
+
@setdoc.basic
|
|
391
|
+
def __getitem__(
|
|
392
|
+
self: Self, key: Slice[int], /
|
|
393
|
+
) -> abc.MutableSequence[Item]: ...
|
|
394
|
+
@setdoc.basic
|
|
395
|
+
def __getitem__(
|
|
396
|
+
self: Self, key: int | Slice[int], /
|
|
397
|
+
) -> Item | abc.MutableSequence[Item]:
|
|
398
|
+
with self.__mutate__() as mutable:
|
|
399
|
+
return mutable[key]
|
|
400
|
+
|
|
401
|
+
@abstractmethod
|
|
402
|
+
@setdoc.basic
|
|
403
|
+
def __mutate__(self: Self, /) -> ContextManager[__Mutable__[Item]]: ...
|
|
404
|
+
|
|
405
|
+
@overload
|
|
406
|
+
@setdoc.basic
|
|
407
|
+
def __setitem__(self: Self, key: int, value: Item, /) -> None: ...
|
|
408
|
+
@overload
|
|
409
|
+
@setdoc.basic
|
|
410
|
+
def __setitem__(
|
|
411
|
+
self: Self, key: Slice[int], value: abc.Iterable[Item], /
|
|
412
|
+
) -> None: ...
|
|
413
|
+
@setdoc.basic
|
|
414
|
+
def __setitem__(
|
|
415
|
+
self: Self,
|
|
416
|
+
key: int | Slice[int],
|
|
417
|
+
value: Item | abc.Iterable[Item],
|
|
418
|
+
/,
|
|
419
|
+
) -> None:
|
|
420
|
+
with self.__mutate__() as mutable:
|
|
421
|
+
mutable[key] = value # type: ignore
|
|
422
|
+
|
|
423
|
+
@setdoc.basic
|
|
424
|
+
def insert(self: Self, index: int, item: Item, /) -> None:
|
|
425
|
+
with self.__mutate__() as mutable:
|
|
426
|
+
mutable.insert(index, item)
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
### LIST-LIKE ###
|
|
430
|
+
class ListLike[Item](Sequence[Item]):
|
|
431
|
+
"""Provide a base class for customized list-likes."""
|
|
432
|
+
|
|
433
|
+
__slots__ = ()
|
|
434
|
+
|
|
435
|
+
type __Frozen__[FrozenItem] = tuple[FrozenItem, ...]
|
|
436
|
+
# Frozen has to be tuple to allow covariance
|
|
437
|
+
|
|
438
|
+
type Init[InitItem] = abc.Iterable[InitItem]
|
|
439
|
+
|
|
440
|
+
@setdoc.basic
|
|
441
|
+
def __add__[Item_](
|
|
442
|
+
self: Self, other: ListLike[Item_], /
|
|
443
|
+
) -> ListLike[Item | Item_]:
|
|
444
|
+
if isinstance(other, ListLike):
|
|
445
|
+
return type(self)(self.__frozen__() + other.__frozen__()) # type: ignore[operator]
|
|
446
|
+
else:
|
|
447
|
+
raise TypeError
|
|
448
|
+
|
|
449
|
+
@setdoc.basic
|
|
450
|
+
def __eq__(self: Self, other: object, /) -> NotImplementedType | bool:
|
|
451
|
+
if isinstance(other, ListLike):
|
|
452
|
+
return self.__frozen__() == other.__frozen__()
|
|
453
|
+
else:
|
|
454
|
+
return NotImplemented
|
|
455
|
+
|
|
456
|
+
@abstractmethod
|
|
457
|
+
@setdoc.basic
|
|
458
|
+
def __frozen__(self: Self, /) -> __Frozen__[Item]: ...
|
|
459
|
+
|
|
460
|
+
@setdoc.basic
|
|
461
|
+
def __ge__(self: Self, other: ListLike[Any], /) -> bool:
|
|
462
|
+
if isinstance(other, ListLike):
|
|
463
|
+
return self.__frozen__() >= other.__frozen__()
|
|
464
|
+
else:
|
|
465
|
+
return NotImplemented
|
|
466
|
+
|
|
467
|
+
@overload
|
|
468
|
+
@setdoc.basic
|
|
469
|
+
def __getitem__(self: Self, key: SupportsIndex, /) -> Item: ...
|
|
470
|
+
|
|
471
|
+
@overload
|
|
472
|
+
@setdoc.basic
|
|
473
|
+
def __getitem__(self: Self, key: Slice[SupportsIndex], /) -> Self: ...
|
|
474
|
+
|
|
475
|
+
@setdoc.basic
|
|
476
|
+
def __getitem__(
|
|
477
|
+
self: Self,
|
|
478
|
+
key: SupportsIndex | Slice[SupportsIndex],
|
|
479
|
+
/,
|
|
480
|
+
) -> Item | Self:
|
|
481
|
+
if isinstance(key, SupportsIndex):
|
|
482
|
+
return self.__frozen__()[key]
|
|
483
|
+
else:
|
|
484
|
+
return type(self)(self.__frozen__()[key])
|
|
485
|
+
|
|
486
|
+
@setdoc.basic
|
|
487
|
+
def __gt__(self: Self, other: ListLike[Any], /) -> bool:
|
|
488
|
+
if isinstance(other, ListLike):
|
|
489
|
+
return self.__frozen__() > other.__frozen__()
|
|
490
|
+
else:
|
|
491
|
+
return NotImplemented
|
|
492
|
+
|
|
493
|
+
@abstractmethod
|
|
494
|
+
@setdoc.basic
|
|
495
|
+
def __init__(self: Self, data: Init[Item] = (), /) -> None: ...
|
|
496
|
+
|
|
497
|
+
@setdoc.basic
|
|
498
|
+
def __le__(self: Self, other: ListLike[Any], /) -> bool:
|
|
499
|
+
if isinstance(other, ListLike):
|
|
500
|
+
return self.__frozen__() <= other.__frozen__()
|
|
501
|
+
else:
|
|
502
|
+
return NotImplemented
|
|
503
|
+
|
|
504
|
+
@setdoc.basic
|
|
505
|
+
def __lt__(self: Self, other: ListLike[Any], /) -> bool:
|
|
506
|
+
if isinstance(other, ListLike):
|
|
507
|
+
return self.__frozen__() < other.__frozen__()
|
|
508
|
+
else:
|
|
509
|
+
return NotImplemented
|
|
510
|
+
|
|
511
|
+
@setdoc.basic
|
|
512
|
+
def __mul__(self: Self, other: SupportsIndex, /) -> Self:
|
|
513
|
+
if isinstance(other, SupportsIndex):
|
|
514
|
+
return type(self)(self.__frozen__() * other)
|
|
515
|
+
else:
|
|
516
|
+
raise TypeError
|
|
517
|
+
|
|
518
|
+
__rmul__ = __mul__
|
|
519
|
+
|
|
520
|
+
@setdoc.basic
|
|
521
|
+
def __repr__(self: Self, /) -> str:
|
|
522
|
+
return f"{type(self).__name__}({list(self)!r})"
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
class FrozenListLike[Item](ListLike[Item], abc.Hashable):
|
|
526
|
+
"""Provide a base class for customized frozen list-likes."""
|
|
527
|
+
|
|
528
|
+
__slots__ = ()
|
|
529
|
+
|
|
530
|
+
@setdoc.basic
|
|
531
|
+
def __hash__(self: Self) -> int:
|
|
532
|
+
return hash(self.__frozen__())
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
class MutableListLike[Item](ListLike[Item], MutableSequence[Item]):
|
|
536
|
+
"""Provide a base class for customized mutable list-likes."""
|
|
537
|
+
|
|
538
|
+
__slots__ = ()
|
|
539
|
+
|
|
540
|
+
type __Mutable__[MutableItem] = list[MutableItem]
|
|
541
|
+
|
|
542
|
+
@overload
|
|
543
|
+
@setdoc.basic
|
|
544
|
+
def __delitem__(self: Self, key: SupportsIndex, /) -> None: ...
|
|
545
|
+
@overload
|
|
546
|
+
@setdoc.basic
|
|
547
|
+
def __delitem__(self: Self, key: Slice[SupportsIndex], /) -> None: ...
|
|
548
|
+
@setdoc.basic
|
|
549
|
+
def __delitem__(
|
|
550
|
+
self: Self, key: SupportsIndex | Slice[SupportsIndex], /
|
|
551
|
+
) -> None:
|
|
552
|
+
with self.__mutate__() as mutable:
|
|
553
|
+
del mutable[key]
|
|
554
|
+
|
|
555
|
+
@setdoc.basic
|
|
556
|
+
def __frozen__(self: Self) -> MutableListLike.__Frozen__[Item]:
|
|
557
|
+
with self.__mutate__() as mutable:
|
|
558
|
+
return tuple(mutable)
|
|
559
|
+
|
|
560
|
+
@setdoc.basic
|
|
561
|
+
def __imul__(self: Self, other: SupportsIndex, /) -> Self:
|
|
562
|
+
with self.__mutate__() as mutable:
|
|
563
|
+
mutable *= other
|
|
564
|
+
return self
|
|
565
|
+
|
|
566
|
+
@setdoc.basic
|
|
567
|
+
def __init__(self: Self, data: abc.Iterable[Item] = (), /) -> None:
|
|
568
|
+
with self.__mutate__() as mutable:
|
|
569
|
+
mutable.extend(data)
|
|
570
|
+
|
|
571
|
+
@abstractmethod
|
|
572
|
+
@setdoc.basic
|
|
573
|
+
def __mutate__(self: Self, /) -> ContextManager[__Mutable__[Item]]: ...
|
|
574
|
+
|
|
575
|
+
@overload
|
|
576
|
+
@setdoc.basic
|
|
577
|
+
def __setitem__(
|
|
578
|
+
self: Self, key: SupportsIndex, value: Item, /
|
|
579
|
+
) -> None: ...
|
|
580
|
+
@overload
|
|
581
|
+
@setdoc.basic
|
|
582
|
+
def __setitem__(
|
|
583
|
+
self: Self, key: Slice[SupportsIndex], value: abc.Iterable[Item], /
|
|
584
|
+
) -> None: ...
|
|
585
|
+
@setdoc.basic
|
|
586
|
+
def __setitem__(
|
|
587
|
+
self: Self,
|
|
588
|
+
key: SupportsIndex | Slice[SupportsIndex],
|
|
589
|
+
value: Item | abc.Iterable[Item],
|
|
590
|
+
/,
|
|
591
|
+
) -> None:
|
|
592
|
+
with self.__mutate__() as mutable:
|
|
593
|
+
mutable[key] = value # type: ignore
|
|
594
|
+
|
|
595
|
+
@setdoc.basic
|
|
596
|
+
def copy(self: Self) -> Self:
|
|
597
|
+
return type(self)(self)
|
|
598
|
+
|
|
599
|
+
@setdoc.basic
|
|
600
|
+
def insert(self: Self, index: SupportsIndex, item: Item, /) -> None:
|
|
601
|
+
with self.__mutate__() as mutable:
|
|
602
|
+
mutable.insert(index, item)
|
|
603
|
+
|
|
604
|
+
@setdoc.basic
|
|
605
|
+
def sort(self: Self, /, *, key: Any = None, reverse: bool = False) -> None:
|
|
606
|
+
# list.sort reveals Overload(
|
|
607
|
+
# def [_T, SupportsRichComparisonT <: _typeshed.SupportsDunderLT[Any] | _typeshed.SupportsDunderGT[Any]] (self: list[SupportsRichComparisonT], *, key: None =, reverse: bool =),
|
|
608
|
+
# def [_T] (self: list[_T], *, key: def (_T) -> _typeshed.SupportsDunderLT[Any] | _typeshed.SupportsDunderGT[Any], reverse: bool =),
|
|
609
|
+
# )
|
|
610
|
+
with self.__mutate__() as mutable:
|
|
611
|
+
mutable.sort(key=key, reverse=reverse)
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
### LIST-SLOT ###
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
class ListSlot[Item](ListLike[Item]):
|
|
618
|
+
"""Provide slotted list-like class."""
|
|
619
|
+
|
|
620
|
+
__slots__ = ("_slot",)
|
|
621
|
+
|
|
622
|
+
_slot: ListSlot.__Frozen__[Item]
|
|
623
|
+
|
|
624
|
+
@setdoc.basic
|
|
625
|
+
def __frozen__(self: Self) -> ListSlot.__Frozen__[Item]:
|
|
626
|
+
return self._slot
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
class FrozenListSlot[Item](ListSlot[Item], FrozenListLike[Item]):
|
|
630
|
+
"""Provide a base class for customized frozen data-holds."""
|
|
631
|
+
|
|
632
|
+
__slots__ = ()
|
|
633
|
+
|
|
634
|
+
@setdoc.basic
|
|
635
|
+
def __init__(self: Self, data: abc.Iterable[Item] = (), /) -> None:
|
|
636
|
+
self._slot = tuple(data)
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
class MutableListSlot[Item](ListSlot[Item], MutableListLike[Item]):
|
|
640
|
+
"""Provide slotted mutable list-like class."""
|
|
641
|
+
|
|
642
|
+
__slots__ = ()
|
|
643
|
+
|
|
644
|
+
@contextmanager
|
|
645
|
+
@setdoc.basic
|
|
646
|
+
def __mutate__(self: Self, /) -> abc.Generator[list[Item], None, None]:
|
|
647
|
+
slot = list(getattr(self, "_slot", ()))
|
|
648
|
+
yield slot
|
|
649
|
+
self._slot = tuple(slot)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
__all__: list[str] = ["TestPrefix"]
|
|
4
|
+
|
|
5
|
+
import unittest
|
|
6
|
+
from collections import abc
|
|
7
|
+
from typing import Self
|
|
8
|
+
|
|
9
|
+
from Lazy import Lazy
|
|
10
|
+
|
|
11
|
+
import datahold
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TestPrefix(unittest.TestCase):
|
|
15
|
+
def _test_prefix(self: Self, name: str, /) -> None:
|
|
16
|
+
datatype = getattr(datahold, name)
|
|
17
|
+
self.assertEqual(datatype.__name__, name)
|
|
18
|
+
self.assertTrue(hasattr(datatype, "__Frozen__"))
|
|
19
|
+
self.assertTrue(hasattr(datatype, "__frozen__"))
|
|
20
|
+
if name.startswith("Frozen"):
|
|
21
|
+
self.assertIsNot(datatype.__hash__, object.__hash__)
|
|
22
|
+
self.assertTrue(issubclass(datatype, abc.Hashable))
|
|
23
|
+
self.assertFalse(hasattr(datatype, "__Mutable__"))
|
|
24
|
+
self.assertFalse(hasattr(datatype, "__mutate__"))
|
|
25
|
+
return
|
|
26
|
+
self.assertIn(datatype.__hash__, [None, object.__hash__])
|
|
27
|
+
if name.startswith("Mutable"):
|
|
28
|
+
self.assertTrue(hasattr(datatype, "__Mutable__"))
|
|
29
|
+
self.assertTrue(hasattr(datatype, "__mutate__"))
|
|
30
|
+
return
|
|
31
|
+
self.assertFalse(hasattr(datatype, "__Mutable__"))
|
|
32
|
+
self.assertFalse(hasattr(datatype, "__mutate__"))
|
|
33
|
+
|
|
34
|
+
def test_prefix(self: Self, /) -> None:
|
|
35
|
+
for name in Lazy.lazy.datatypes.keys():
|
|
36
|
+
with self.subTest(datatype=name):
|
|
37
|
+
self._test_prefix(name)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
unittest.main(verbosity=2)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
[datatypes.Collection]
|
|
2
|
+
|
|
1
3
|
[datatypes.FrozenListLike]
|
|
2
4
|
abstractmethods = [
|
|
3
5
|
"__frozen__",
|
|
@@ -16,9 +18,9 @@ __init__ = "datahold.ListLike"
|
|
|
16
18
|
"collections.abc.Sequence" = true
|
|
17
19
|
|
|
18
20
|
[datatypes.FrozenListLike.nested]
|
|
19
|
-
Frozen = "builtins.tuple"
|
|
20
21
|
Init = "collections.abc.Iterable"
|
|
21
|
-
|
|
22
|
+
__Frozen__ = "builtins.tuple"
|
|
23
|
+
__Mutable__ = ""
|
|
22
24
|
|
|
23
25
|
[datatypes.FrozenListLike.varia]
|
|
24
26
|
generic = 1
|
|
@@ -131,13 +133,25 @@ args = [
|
|
|
131
133
|
]
|
|
132
134
|
|
|
133
135
|
[datatypes.FrozenListSlot.nested]
|
|
134
|
-
Frozen = "builtins.tuple"
|
|
135
136
|
Init = "collections.abc.Iterable"
|
|
136
|
-
|
|
137
|
+
__Frozen__ = "builtins.tuple"
|
|
138
|
+
__Mutable__ = ""
|
|
137
139
|
|
|
138
140
|
[datatypes.FrozenListSlot.varia]
|
|
139
141
|
generic = 1
|
|
140
142
|
|
|
143
|
+
[datatypes.FrozenSetLike.issubclass]
|
|
144
|
+
"collections.abc.Hashable" = true
|
|
145
|
+
"collections.abc.Set" = true
|
|
146
|
+
"datahold.Collection" = true
|
|
147
|
+
"datahold.SetLike" = true
|
|
148
|
+
|
|
149
|
+
[datatypes.FrozenSetSlot.issubclass]
|
|
150
|
+
"collections.abc.Collection" = true
|
|
151
|
+
"collections.abc.MutableSet" = false
|
|
152
|
+
"collections.abc.Set" = true
|
|
153
|
+
"datahold.Collection" = true
|
|
154
|
+
|
|
141
155
|
[datatypes.ListLike]
|
|
142
156
|
abstractmethods = [
|
|
143
157
|
"__frozen__",
|
|
@@ -147,7 +161,7 @@ abstractmethods = [
|
|
|
147
161
|
[datatypes.ListLike.attributes]
|
|
148
162
|
__frozen__ = "datahold.ListLike"
|
|
149
163
|
__init__ = "datahold.ListLike"
|
|
150
|
-
|
|
164
|
+
__mutate__ = ""
|
|
151
165
|
__reversed__ = "collections.abc.Sequence"
|
|
152
166
|
count = "collections.abc.Sequence"
|
|
153
167
|
index = "collections.abc.Sequence"
|
|
@@ -157,11 +171,12 @@ index = "collections.abc.Sequence"
|
|
|
157
171
|
"collections.abc.MutableSequence" = false
|
|
158
172
|
"collections.abc.Sequence" = true
|
|
159
173
|
"datahold.ListLike" = true
|
|
174
|
+
"datahold.MutableSequence" = false
|
|
160
175
|
|
|
161
176
|
[datatypes.ListLike.nested]
|
|
162
|
-
Frozen = "builtins.tuple"
|
|
163
177
|
Init = "collections.abc.Iterable"
|
|
164
|
-
|
|
178
|
+
__Frozen__ = "builtins.tuple"
|
|
179
|
+
__Mutable__ = ""
|
|
165
180
|
|
|
166
181
|
[datatypes.ListLike.varia]
|
|
167
182
|
generic = 1
|
|
@@ -172,26 +187,25 @@ abstractmethods = [
|
|
|
172
187
|
]
|
|
173
188
|
|
|
174
189
|
[datatypes.ListSlot.nested]
|
|
175
|
-
Frozen = "builtins.tuple"
|
|
176
190
|
Init = "collections.abc.Iterable"
|
|
177
|
-
|
|
191
|
+
__Frozen__ = "builtins.tuple"
|
|
192
|
+
__Mutable__ = ""
|
|
178
193
|
|
|
179
194
|
[datatypes.ListSlot.varia]
|
|
180
195
|
generic = 1
|
|
181
196
|
|
|
182
197
|
[datatypes.MutableListLike]
|
|
183
198
|
abstractmethods = [
|
|
184
|
-
"
|
|
185
|
-
"__mutable__",
|
|
199
|
+
"__mutate__",
|
|
186
200
|
]
|
|
187
201
|
|
|
188
202
|
[datatypes.MutableListLike.attributes]
|
|
189
203
|
__add__ = "datahold.MutableListLike"
|
|
190
|
-
__frozen__ = "datahold.
|
|
204
|
+
__frozen__ = "datahold.MutableListLike"
|
|
191
205
|
__iadd__ = "collections.abc.MutableSequence"
|
|
192
206
|
__imul__ = "datahold.MutableListLike"
|
|
193
207
|
__init__ = "datahold.MutableListLike"
|
|
194
|
-
|
|
208
|
+
__mutate__ = "datahold.MutableListLike"
|
|
195
209
|
__reversed__ = "collections.abc.Sequence"
|
|
196
210
|
append = "collections.abc.MutableSequence"
|
|
197
211
|
clear = "collections.abc.MutableSequence"
|
|
@@ -199,6 +213,7 @@ count = "collections.abc.Sequence"
|
|
|
199
213
|
extend = "collections.abc.MutableSequence"
|
|
200
214
|
foo = ""
|
|
201
215
|
index = "collections.abc.Sequence"
|
|
216
|
+
insert = "datahold.MutableListLike"
|
|
202
217
|
pop = "collections.abc.MutableSequence"
|
|
203
218
|
remove = "collections.abc.MutableSequence"
|
|
204
219
|
reverse = "collections.abc.MutableSequence"
|
|
@@ -208,10 +223,11 @@ reverse = "collections.abc.MutableSequence"
|
|
|
208
223
|
"collections.abc.Hashable" = false
|
|
209
224
|
"collections.abc.MutableMapping" = false
|
|
210
225
|
"collections.abc.MutableSequence" = true
|
|
226
|
+
"datahold.MutableSequence" = true
|
|
211
227
|
|
|
212
228
|
[datatypes.MutableListLike.nested]
|
|
213
|
-
Frozen = "builtins.tuple"
|
|
214
229
|
Init = "collections.abc.Iterable"
|
|
230
|
+
__Frozen__ = "builtins.tuple"
|
|
215
231
|
__hash__ = ""
|
|
216
232
|
|
|
217
233
|
[datatypes.MutableListLike.varia]
|
|
@@ -227,11 +243,63 @@ abstractmethods = []
|
|
|
227
243
|
"datahold.MutableListSlot" = true
|
|
228
244
|
|
|
229
245
|
[datatypes.MutableListSlot.nested]
|
|
230
|
-
Frozen = "builtins.tuple"
|
|
231
246
|
Init = "collections.abc.Iterable"
|
|
247
|
+
__Frozen__ = "builtins.tuple"
|
|
232
248
|
__hash__ = ""
|
|
233
249
|
|
|
234
250
|
[datatypes.MutableListSlot.varia]
|
|
235
251
|
generic = 1
|
|
236
252
|
|
|
253
|
+
[datatypes.MutableSequence.attributes]
|
|
254
|
+
__Frozen__ = "datahold.Sequence"
|
|
255
|
+
__Mutable__ = "datahold.MutableSequence"
|
|
256
|
+
__delitem__ = "datahold.MutableSequence"
|
|
257
|
+
__frozen__ = "datahold.Sequence"
|
|
258
|
+
__getitem__ = "datahold.MutableSequence"
|
|
259
|
+
__mutate__ = "datahold.MutableSequence"
|
|
260
|
+
__setitem__ = "datahold.MutableSequence"
|
|
261
|
+
insert = "datahold.MutableSequence"
|
|
262
|
+
sort = ""
|
|
263
|
+
|
|
264
|
+
[datatypes.MutableSet.issubclass]
|
|
265
|
+
"collections.abc.MutableSet" = true
|
|
266
|
+
"collections.abc.Set" = true
|
|
267
|
+
"datahold.Collection" = true
|
|
268
|
+
|
|
269
|
+
[datatypes.MutableSetLike.issubclass]
|
|
270
|
+
"collections.abc.Hashable" = false
|
|
271
|
+
"collections.abc.MutableSet" = true
|
|
272
|
+
"collections.abc.Set" = true
|
|
273
|
+
"datahold.Collection" = true
|
|
274
|
+
"datahold.MutableSet" = true
|
|
275
|
+
"datahold.SetLike" = true
|
|
276
|
+
|
|
277
|
+
[datatypes.MutableSetSlot.issubclass]
|
|
278
|
+
"collections.abc.MutableSet" = true
|
|
279
|
+
"collections.abc.Set" = true
|
|
280
|
+
"datahold.Collection" = true
|
|
281
|
+
"datahold.MutableSet" = true
|
|
282
|
+
"datahold.MutableSetLike" = true
|
|
283
|
+
"datahold.SetSlot" = true
|
|
284
|
+
|
|
285
|
+
[datatypes.Sequence]
|
|
286
|
+
abstractmethods = [
|
|
287
|
+
"__frozen__",
|
|
288
|
+
]
|
|
289
|
+
|
|
290
|
+
[datatypes.Set.issubclass]
|
|
291
|
+
"collections.abc.Set" = true
|
|
292
|
+
"datahold.Collection" = true
|
|
293
|
+
|
|
294
|
+
[datatypes.SetLike.issubclass]
|
|
295
|
+
"collections.abc.Set" = true
|
|
296
|
+
"datahold.Collection" = true
|
|
297
|
+
"datahold.Set" = true
|
|
298
|
+
"datahold.SetLike" = true
|
|
299
|
+
|
|
300
|
+
[datatypes.SetSlot.issubclass]
|
|
301
|
+
"collections.abc.Set" = true
|
|
302
|
+
"datahold.Collection" = true
|
|
303
|
+
"datahold.SetLike" = true
|
|
304
|
+
|
|
237
305
|
[non_datatypes]
|
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
"""Provide provides base classes for customized collections."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
__all__: list[str] = [
|
|
6
|
-
"FrozenListLike",
|
|
7
|
-
"FrozenListSlot",
|
|
8
|
-
"ListLike",
|
|
9
|
-
"ListSlot",
|
|
10
|
-
"MutableListLike",
|
|
11
|
-
"MutableListSlot",
|
|
12
|
-
]
|
|
13
|
-
|
|
14
|
-
from abc import abstractmethod
|
|
15
|
-
from collections import abc
|
|
16
|
-
from contextlib import contextmanager
|
|
17
|
-
from types import NotImplementedType, TracebackType
|
|
18
|
-
from typing import Any, Optional, Protocol, Self, SupportsIndex, overload
|
|
19
|
-
|
|
20
|
-
import setdoc
|
|
21
|
-
|
|
22
|
-
### UTILS ###
|
|
23
|
-
|
|
24
|
-
type Slice[Index] = slice[Optional[Index], Optional[Index], Optional[Index]]
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
### LIST-LIKE ###
|
|
28
|
-
class ListLike[Item](abc.Sequence[Item]):
|
|
29
|
-
"""Provide a base class for customized list-likes."""
|
|
30
|
-
|
|
31
|
-
__slots__ = ()
|
|
32
|
-
|
|
33
|
-
type Frozen[FrozenItem] = tuple[FrozenItem, ...]
|
|
34
|
-
# Frozen has to be tuple to allow covariance
|
|
35
|
-
|
|
36
|
-
type Init[InitItem] = abc.Iterable[InitItem]
|
|
37
|
-
|
|
38
|
-
@setdoc.basic
|
|
39
|
-
def __add__[Item_](
|
|
40
|
-
self: Self, other: ListLike[Item_], /
|
|
41
|
-
) -> ListLike[Item | Item_]:
|
|
42
|
-
if isinstance(other, ListLike):
|
|
43
|
-
return type(self)(self.__frozen__() + other.__frozen__()) # type: ignore[operator]
|
|
44
|
-
else:
|
|
45
|
-
raise TypeError
|
|
46
|
-
|
|
47
|
-
@setdoc.basic
|
|
48
|
-
def __contains__(self: Self, other: object, /) -> bool:
|
|
49
|
-
return other in self.__frozen__()
|
|
50
|
-
|
|
51
|
-
@setdoc.basic
|
|
52
|
-
def __eq__(self: Self, other: object, /) -> NotImplementedType | bool:
|
|
53
|
-
if isinstance(other, ListLike):
|
|
54
|
-
return self.__frozen__() == other.__frozen__()
|
|
55
|
-
else:
|
|
56
|
-
return NotImplemented
|
|
57
|
-
|
|
58
|
-
@abstractmethod
|
|
59
|
-
@setdoc.basic
|
|
60
|
-
def __frozen__(self: Self, /) -> Frozen[Item]: ...
|
|
61
|
-
|
|
62
|
-
@setdoc.basic
|
|
63
|
-
def __ge__(self: Self, other: ListLike[Any], /) -> bool:
|
|
64
|
-
if isinstance(other, ListLike):
|
|
65
|
-
return self.__frozen__() >= other.__frozen__()
|
|
66
|
-
else:
|
|
67
|
-
return NotImplemented
|
|
68
|
-
|
|
69
|
-
@overload
|
|
70
|
-
@setdoc.basic
|
|
71
|
-
def __getitem__(self: Self, key: SupportsIndex, /) -> Item: ...
|
|
72
|
-
|
|
73
|
-
@overload
|
|
74
|
-
@setdoc.basic
|
|
75
|
-
def __getitem__(self: Self, key: Slice[SupportsIndex], /) -> Self: ...
|
|
76
|
-
|
|
77
|
-
@setdoc.basic
|
|
78
|
-
def __getitem__(
|
|
79
|
-
self: Self,
|
|
80
|
-
key: SupportsIndex | Slice[SupportsIndex],
|
|
81
|
-
/,
|
|
82
|
-
) -> Item | Self:
|
|
83
|
-
if isinstance(key, SupportsIndex):
|
|
84
|
-
return self.__frozen__()[key]
|
|
85
|
-
else:
|
|
86
|
-
return type(self)(self.__frozen__()[key])
|
|
87
|
-
|
|
88
|
-
@setdoc.basic
|
|
89
|
-
def __gt__(self: Self, other: ListLike[Any], /) -> bool:
|
|
90
|
-
if isinstance(other, ListLike):
|
|
91
|
-
return self.__frozen__() > other.__frozen__()
|
|
92
|
-
else:
|
|
93
|
-
return NotImplemented
|
|
94
|
-
|
|
95
|
-
@abstractmethod
|
|
96
|
-
@setdoc.basic
|
|
97
|
-
def __init__(self: Self, data: Init[Item] = (), /) -> None: ...
|
|
98
|
-
|
|
99
|
-
@setdoc.basic
|
|
100
|
-
def __le__(self: Self, other: ListLike[Any], /) -> bool:
|
|
101
|
-
if isinstance(other, ListLike):
|
|
102
|
-
return self.__frozen__() <= other.__frozen__()
|
|
103
|
-
else:
|
|
104
|
-
return NotImplemented
|
|
105
|
-
|
|
106
|
-
@setdoc.basic
|
|
107
|
-
def __len__(self: Self, /) -> int:
|
|
108
|
-
return len(self.__frozen__())
|
|
109
|
-
|
|
110
|
-
@setdoc.basic
|
|
111
|
-
def __lt__(self: Self, other: ListLike[Any], /) -> bool:
|
|
112
|
-
if isinstance(other, ListLike):
|
|
113
|
-
return self.__frozen__() < other.__frozen__()
|
|
114
|
-
else:
|
|
115
|
-
return NotImplemented
|
|
116
|
-
|
|
117
|
-
@setdoc.basic
|
|
118
|
-
def __mul__(self: Self, other: SupportsIndex, /) -> Self:
|
|
119
|
-
if isinstance(other, SupportsIndex):
|
|
120
|
-
return type(self)(self.__frozen__() * other)
|
|
121
|
-
else:
|
|
122
|
-
raise TypeError
|
|
123
|
-
|
|
124
|
-
__rmul__ = __mul__
|
|
125
|
-
|
|
126
|
-
@setdoc.basic
|
|
127
|
-
def __repr__(self: Self, /) -> str:
|
|
128
|
-
return f"{type(self).__name__}({list(self)!r})"
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
class ListSlot[Item](ListLike[Item]):
|
|
132
|
-
"""Provide slotted list-like class."""
|
|
133
|
-
|
|
134
|
-
__slots__ = ("_slot",)
|
|
135
|
-
|
|
136
|
-
_slot: ListSlot.Frozen[Item]
|
|
137
|
-
|
|
138
|
-
@setdoc.basic
|
|
139
|
-
def __frozen__(self: Self) -> ListSlot.Frozen[Item]:
|
|
140
|
-
return self._slot
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
class FrozenListLike[Item](ListLike[Item], abc.Hashable):
|
|
144
|
-
"""Provide a base class for customized frozen list-likes."""
|
|
145
|
-
|
|
146
|
-
__slots__ = ()
|
|
147
|
-
|
|
148
|
-
@setdoc.basic
|
|
149
|
-
def __hash__(self: Self) -> int:
|
|
150
|
-
return hash(self.__frozen__())
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
class FrozenListSlot[Item](ListSlot[Item], FrozenListLike[Item]):
|
|
154
|
-
"""Provide a base class for customized frozen data-holds."""
|
|
155
|
-
|
|
156
|
-
__slots__ = ()
|
|
157
|
-
|
|
158
|
-
@setdoc.basic
|
|
159
|
-
def __init__(self: Self, data: abc.Iterable[Item] = (), /) -> None:
|
|
160
|
-
self._slot = tuple(data)
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
class MutableListLike[Item](ListLike[Item], abc.MutableSequence[Item]):
|
|
164
|
-
"""Provide a base class for customized mutable list-likes."""
|
|
165
|
-
|
|
166
|
-
__slots__ = ()
|
|
167
|
-
|
|
168
|
-
@setdoc.basic
|
|
169
|
-
class Mutable[MutableItem](Protocol):
|
|
170
|
-
@setdoc.basic
|
|
171
|
-
def __enter__(self: Self, /) -> list[MutableItem]: ...
|
|
172
|
-
@setdoc.basic
|
|
173
|
-
def __exit__(
|
|
174
|
-
self,
|
|
175
|
-
exc_type: type[BaseException] | None,
|
|
176
|
-
exc_value: BaseException | None,
|
|
177
|
-
traceback: TracebackType | None,
|
|
178
|
-
/,
|
|
179
|
-
) -> object: ...
|
|
180
|
-
|
|
181
|
-
@overload
|
|
182
|
-
@setdoc.basic
|
|
183
|
-
def __delitem__(self: Self, key: SupportsIndex, /) -> None: ...
|
|
184
|
-
@overload
|
|
185
|
-
@setdoc.basic
|
|
186
|
-
def __delitem__(self: Self, key: Slice[SupportsIndex], /) -> None: ...
|
|
187
|
-
@setdoc.basic
|
|
188
|
-
def __delitem__(
|
|
189
|
-
self: Self, key: SupportsIndex | Slice[SupportsIndex], /
|
|
190
|
-
) -> None:
|
|
191
|
-
with self.__mutable__() as mutable:
|
|
192
|
-
del mutable[key]
|
|
193
|
-
|
|
194
|
-
@setdoc.basic
|
|
195
|
-
def __imul__(self: Self, other: SupportsIndex, /) -> Self:
|
|
196
|
-
with self.__mutable__() as mutable:
|
|
197
|
-
mutable *= other
|
|
198
|
-
return self
|
|
199
|
-
|
|
200
|
-
@setdoc.basic
|
|
201
|
-
def __init__(self: Self, data: abc.Iterable[Item] = (), /) -> None:
|
|
202
|
-
with self.__mutable__() as mutable:
|
|
203
|
-
mutable.extend(data)
|
|
204
|
-
|
|
205
|
-
@abstractmethod
|
|
206
|
-
@setdoc.basic
|
|
207
|
-
def __mutable__(self: Self, /) -> Mutable[Item]: ...
|
|
208
|
-
|
|
209
|
-
@overload
|
|
210
|
-
@setdoc.basic
|
|
211
|
-
def __setitem__(
|
|
212
|
-
self: Self, key: SupportsIndex, value: Item, /
|
|
213
|
-
) -> None: ...
|
|
214
|
-
@overload
|
|
215
|
-
@setdoc.basic
|
|
216
|
-
def __setitem__(
|
|
217
|
-
self: Self, key: Slice[SupportsIndex], value: abc.Iterable[Item], /
|
|
218
|
-
) -> None: ...
|
|
219
|
-
@setdoc.basic
|
|
220
|
-
def __setitem__(
|
|
221
|
-
self: Self,
|
|
222
|
-
key: SupportsIndex | Slice[SupportsIndex],
|
|
223
|
-
value: Item | abc.Iterable[Item],
|
|
224
|
-
/,
|
|
225
|
-
) -> None:
|
|
226
|
-
with self.__mutable__() as mutable:
|
|
227
|
-
mutable[key] = value # type: ignore
|
|
228
|
-
|
|
229
|
-
@setdoc.basic
|
|
230
|
-
def copy(self: Self) -> Self:
|
|
231
|
-
return type(self)(self.__frozen__())
|
|
232
|
-
|
|
233
|
-
@setdoc.basic
|
|
234
|
-
def insert(self: Self, index: SupportsIndex, item: Item, /) -> None:
|
|
235
|
-
with self.__mutable__() as mutable:
|
|
236
|
-
mutable.insert(index, item)
|
|
237
|
-
|
|
238
|
-
@setdoc.basic
|
|
239
|
-
def sort(self: Self, /, *, key: Any = None, reverse: bool = False) -> None:
|
|
240
|
-
# list.sort reveals Overload(
|
|
241
|
-
# def [_T, SupportsRichComparisonT <: _typeshed.SupportsDunderLT[Any] | _typeshed.SupportsDunderGT[Any]] (self: list[SupportsRichComparisonT], *, key: None =, reverse: bool =),
|
|
242
|
-
# def [_T] (self: list[_T], *, key: def (_T) -> _typeshed.SupportsDunderLT[Any] | _typeshed.SupportsDunderGT[Any], reverse: bool =),
|
|
243
|
-
# )
|
|
244
|
-
with self.__mutable__() as mutable:
|
|
245
|
-
mutable.sort(key=key, reverse=reverse)
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
class MutableListSlot[Item](ListSlot[Item], MutableListLike[Item]):
|
|
249
|
-
"""Provide slotted mutable list-like class."""
|
|
250
|
-
|
|
251
|
-
__slots__ = ()
|
|
252
|
-
|
|
253
|
-
@contextmanager
|
|
254
|
-
@setdoc.basic
|
|
255
|
-
def __mutable__(self: Self, /) -> abc.Generator[list[Item], None, None]:
|
|
256
|
-
slot = list(getattr(self, "_slot", ()))
|
|
257
|
-
yield slot
|
|
258
|
-
self._slot = tuple(slot)
|
|
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
|
|
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
|