datahold 4.0.0.dev1__py3-none-any.whl → 4.0.0.dev2__py3-none-any.whl
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/__init__.py +39 -18
- datahold/_utils/Missing.py +9 -0
- datahold/_utils/Slice.py +4 -0
- datahold/_utils/__init__.py +3 -0
- datahold/base/BaseDataAbstractSet.py +16 -0
- datahold/base/BaseDataCollection.py +49 -0
- datahold/base/BaseDataDict.py +76 -0
- datahold/base/BaseDataList.py +109 -0
- datahold/base/BaseDataMapping.py +41 -0
- datahold/base/BaseDataSequence.py +57 -0
- datahold/base/BaseDataSet.py +64 -0
- datahold/base/BaseHoldCollection.py +11 -0
- datahold/base/__init__.py +3 -0
- datahold/core/DataDict.py +50 -89
- datahold/core/DataList.py +87 -127
- datahold/core/DataSet.py +70 -136
- datahold/core/HoldDict.py +23 -15
- datahold/core/HoldList.py +18 -13
- datahold/core/HoldSet.py +19 -12
- datahold/core/__init__.py +3 -0
- datahold/frozen/FrozenDataDict.py +23 -0
- datahold/frozen/FrozenDataList.py +23 -0
- datahold/frozen/FrozenDataSet.py +20 -0
- datahold/frozen/FrozenHoldDict.py +45 -0
- datahold/frozen/FrozenHoldList.py +33 -0
- datahold/frozen/FrozenHoldSet.py +34 -0
- datahold/frozen/__init__.py +3 -0
- datahold/py.typed +0 -0
- {datahold-4.0.0.dev1.dist-info → datahold-4.0.0.dev2.dist-info}/METADATA +9 -8
- datahold-4.0.0.dev2.dist-info/RECORD +33 -0
- {datahold-4.0.0.dev1.dist-info → datahold-4.0.0.dev2.dist-info}/WHEEL +1 -1
- {datahold-4.0.0.dev1.dist-info → datahold-4.0.0.dev2.dist-info}/licenses/LICENSE.txt +1 -1
- datahold/_utils/wrapping.py +0 -91
- datahold/core/BaseDataDict.py +0 -113
- datahold/core/BaseDataList.py +0 -100
- datahold/core/BaseDataObject.py +0 -24
- datahold/core/BaseDataSet.py +0 -140
- datahold/core/BaseHoldDict.py +0 -15
- datahold/core/BaseHoldList.py +0 -13
- datahold/core/BaseHoldObject.py +0 -10
- datahold/core/BaseHoldSet.py +0 -13
- datahold/core/DataObject.py +0 -18
- datahold/core/FrozenDataDict.py +0 -15
- datahold/core/FrozenDataList.py +0 -13
- datahold/core/FrozenDataObject.py +0 -18
- datahold/core/FrozenDataSet.py +0 -13
- datahold/core/FrozenHoldDict.py +0 -22
- datahold/core/FrozenHoldList.py +0 -20
- datahold/core/FrozenHoldObject.py +0 -15
- datahold/core/FrozenHoldSet.py +0 -20
- datahold/core/HoldObject.py +0 -11
- datahold/tests/__init__.py +0 -16
- datahold/tests/test_0.py +0 -62
- datahold/tests/test_datahold_TestAbstractness.py +0 -52
- datahold/tests/test_datahold_TestCopy.py +0 -83
- datahold/tests/test_datahold_TestDataAttribute.py +0 -54
- datahold/tests/test_datahold_TestFrozenMutability.py +0 -36
- datahold/tests/test_datahold_TestInheritance.py +0 -60
- datahold/tests/test_datahold_TestMutableBehavior.py +0 -33
- datahold/tests/test_datahold_TestProtocols.py +0 -64
- datahold/tests/test_generic.py +0 -86
- datahold/tests/test_object.py +0 -41
- datahold-4.0.0.dev1.dist-info/RECORD +0 -44
- {datahold-4.0.0.dev1.dist-info → datahold-4.0.0.dev2.dist-info}/top_level.txt +0 -0
datahold/__init__.py
CHANGED
|
@@ -1,24 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
"""Provide __init__."""
|
|
2
|
+
|
|
3
|
+
__all__ = [
|
|
4
|
+
"BaseDataAbstractSet",
|
|
5
|
+
"BaseDataCollection",
|
|
6
|
+
"BaseDataDict",
|
|
7
|
+
"BaseDataList",
|
|
8
|
+
"BaseDataMapping",
|
|
9
|
+
"BaseDataSequence",
|
|
10
|
+
"BaseDataSet",
|
|
11
|
+
"BaseHoldCollection",
|
|
12
|
+
"DataDict",
|
|
13
|
+
"DataList",
|
|
14
|
+
"DataSet",
|
|
15
|
+
"FrozenDataDict",
|
|
16
|
+
"FrozenDataList",
|
|
17
|
+
"FrozenDataSet",
|
|
18
|
+
"FrozenHoldDict",
|
|
19
|
+
"FrozenHoldList",
|
|
20
|
+
"FrozenHoldSet",
|
|
21
|
+
"HoldDict",
|
|
22
|
+
"HoldList",
|
|
23
|
+
"HoldSet",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
from datahold.base.BaseDataAbstractSet import BaseDataAbstractSet
|
|
27
|
+
from datahold.base.BaseDataCollection import BaseDataCollection
|
|
28
|
+
from datahold.base.BaseDataDict import BaseDataDict
|
|
29
|
+
from datahold.base.BaseDataList import BaseDataList
|
|
30
|
+
from datahold.base.BaseDataMapping import BaseDataMapping
|
|
31
|
+
from datahold.base.BaseDataSequence import BaseDataSequence
|
|
32
|
+
from datahold.base.BaseDataSet import BaseDataSet
|
|
33
|
+
from datahold.base.BaseHoldCollection import BaseHoldCollection
|
|
9
34
|
from datahold.core.DataDict import DataDict
|
|
10
35
|
from datahold.core.DataList import DataList
|
|
11
|
-
from datahold.core.DataObject import DataObject
|
|
12
36
|
from datahold.core.DataSet import DataSet
|
|
13
|
-
from datahold.core.FrozenDataDict import FrozenDataDict
|
|
14
|
-
from datahold.core.FrozenDataList import FrozenDataList
|
|
15
|
-
from datahold.core.FrozenDataObject import FrozenDataObject
|
|
16
|
-
from datahold.core.FrozenDataSet import FrozenDataSet
|
|
17
|
-
from datahold.core.FrozenHoldDict import FrozenHoldDict
|
|
18
|
-
from datahold.core.FrozenHoldList import FrozenHoldList
|
|
19
|
-
from datahold.core.FrozenHoldObject import FrozenHoldObject
|
|
20
|
-
from datahold.core.FrozenHoldSet import FrozenHoldSet
|
|
21
37
|
from datahold.core.HoldDict import HoldDict
|
|
22
38
|
from datahold.core.HoldList import HoldList
|
|
23
|
-
from datahold.core.HoldObject import HoldObject
|
|
24
39
|
from datahold.core.HoldSet import HoldSet
|
|
40
|
+
from datahold.frozen.FrozenDataDict import FrozenDataDict
|
|
41
|
+
from datahold.frozen.FrozenDataList import FrozenDataList
|
|
42
|
+
from datahold.frozen.FrozenDataSet import FrozenDataSet
|
|
43
|
+
from datahold.frozen.FrozenHoldDict import FrozenHoldDict
|
|
44
|
+
from datahold.frozen.FrozenHoldList import FrozenHoldList
|
|
45
|
+
from datahold.frozen.FrozenHoldSet import FrozenHoldSet
|
datahold/_utils/Slice.py
ADDED
datahold/_utils/__init__.py
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Provide BaseDataAbstractSet."""
|
|
2
|
+
|
|
3
|
+
__all__: list[str] = ["BaseDataAbstractSet"]
|
|
4
|
+
|
|
5
|
+
from collections import abc
|
|
6
|
+
|
|
7
|
+
from .BaseDataCollection import BaseDataCollection
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class BaseDataAbstractSet[Item](
|
|
11
|
+
BaseDataCollection[Item],
|
|
12
|
+
abc.Set[Item],
|
|
13
|
+
):
|
|
14
|
+
"""Provide an easy abc for a custom (abstract) set."""
|
|
15
|
+
|
|
16
|
+
__slots__ = ()
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Provide BaseDataCollection."""
|
|
2
|
+
|
|
3
|
+
__all__: list[str] = ["BaseDataCollection"]
|
|
4
|
+
|
|
5
|
+
from abc import ABCMeta, abstractmethod
|
|
6
|
+
from collections import abc
|
|
7
|
+
from typing import Never, Protocol, Self
|
|
8
|
+
|
|
9
|
+
import setdoc
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BaseDataCollection[Item](
|
|
13
|
+
abc.Sized,
|
|
14
|
+
abc.Iterable[Item],
|
|
15
|
+
abc.Container[object],
|
|
16
|
+
metaclass=ABCMeta,
|
|
17
|
+
):
|
|
18
|
+
"""Provide an easy abc for a custom collection."""
|
|
19
|
+
|
|
20
|
+
__slots__ = ()
|
|
21
|
+
|
|
22
|
+
@setdoc.basic
|
|
23
|
+
class Data[DataItem](
|
|
24
|
+
abc.Sized,
|
|
25
|
+
abc.Iterable[DataItem],
|
|
26
|
+
abc.Container[Never],
|
|
27
|
+
abc.Hashable,
|
|
28
|
+
Protocol,
|
|
29
|
+
):
|
|
30
|
+
"""Provide collection data protocol."""
|
|
31
|
+
|
|
32
|
+
@setdoc.basic
|
|
33
|
+
def __contains__(self: Self, other: object, /) -> bool:
|
|
34
|
+
try:
|
|
35
|
+
return other in self.__fget__()
|
|
36
|
+
except TypeError:
|
|
37
|
+
return other in (x for x in self.__fget__()) # type: ignore[operator]
|
|
38
|
+
|
|
39
|
+
@setdoc.basic
|
|
40
|
+
def __iter__(self: Self, /) -> abc.Iterator[Item]:
|
|
41
|
+
return iter(self.__fget__())
|
|
42
|
+
|
|
43
|
+
@setdoc.basic
|
|
44
|
+
def __len__(self: Self, /) -> int:
|
|
45
|
+
return len(self.__fget__())
|
|
46
|
+
|
|
47
|
+
@abstractmethod
|
|
48
|
+
@setdoc.basic
|
|
49
|
+
def __fget__(self: Self) -> Data[Item]: ...
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Provide BaseDataDict."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__: list[str] = ["BaseDataDict"]
|
|
6
|
+
|
|
7
|
+
from abc import abstractmethod
|
|
8
|
+
from collections import abc
|
|
9
|
+
from typing import Never, Optional, Protocol, Self
|
|
10
|
+
|
|
11
|
+
import setdoc
|
|
12
|
+
from frozendict import frozendict
|
|
13
|
+
|
|
14
|
+
from .BaseDataMapping import BaseDataMapping
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SupportsKeysAndGetitem[Key, Value](Protocol):
|
|
18
|
+
|
|
19
|
+
@setdoc.basic
|
|
20
|
+
def __getitem__(self: Self, key: Never, /) -> Value: ...
|
|
21
|
+
|
|
22
|
+
@setdoc.basic
|
|
23
|
+
def keys(self: Self) -> abc.Iterable[Key]: ...
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class BaseDataDict[Key: abc.Hashable, Value](
|
|
27
|
+
BaseDataMapping[Key | str, Optional[Value]],
|
|
28
|
+
):
|
|
29
|
+
"""Provide an easy abc for custom dict-like."""
|
|
30
|
+
|
|
31
|
+
__slots__ = ()
|
|
32
|
+
|
|
33
|
+
type Data[DataKey, DataValue] = frozendict[
|
|
34
|
+
DataKey | str, Optional[DataValue]
|
|
35
|
+
]
|
|
36
|
+
type Init[DataKey, DataValue] = (
|
|
37
|
+
SupportsKeysAndGetitem[DataKey | str, Optional[DataValue]]
|
|
38
|
+
| abc.Iterable[tuple[DataKey | str, Optional[DataValue]]]
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
@abstractmethod
|
|
42
|
+
@setdoc.basic
|
|
43
|
+
def __init__(
|
|
44
|
+
self: Self,
|
|
45
|
+
data: Init[Key, Value] = (),
|
|
46
|
+
/,
|
|
47
|
+
**kwargs: Optional[Value],
|
|
48
|
+
) -> None: ...
|
|
49
|
+
|
|
50
|
+
@setdoc.basic
|
|
51
|
+
def __or__(
|
|
52
|
+
self: Self,
|
|
53
|
+
other: BaseDataDict[Key, Value],
|
|
54
|
+
/,
|
|
55
|
+
) -> Self:
|
|
56
|
+
return type(self)(self.__fget__() | other.__fget__())
|
|
57
|
+
|
|
58
|
+
@setdoc.basic
|
|
59
|
+
def __repr__(self: Self, /) -> str:
|
|
60
|
+
return f"{type(self).__name__}({dict(self)!r})"
|
|
61
|
+
|
|
62
|
+
# __ror__ is unnecessary because of how __or__ is defined
|
|
63
|
+
|
|
64
|
+
@abstractmethod
|
|
65
|
+
@setdoc.basic
|
|
66
|
+
def __fget__(self: Self) -> Data[Key, Value]: ...
|
|
67
|
+
|
|
68
|
+
@classmethod
|
|
69
|
+
@setdoc.basic
|
|
70
|
+
def fromkeys(
|
|
71
|
+
cls: type[Self],
|
|
72
|
+
iterable: abc.Iterable[Key | str],
|
|
73
|
+
value: Optional[Value] = None,
|
|
74
|
+
/,
|
|
75
|
+
) -> Self:
|
|
76
|
+
return cls(dict.fromkeys(iterable, value))
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""Provide BaseDataList."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__: list[str] = ["BaseDataList"]
|
|
6
|
+
|
|
7
|
+
from abc import abstractmethod
|
|
8
|
+
from collections import abc
|
|
9
|
+
from types import NotImplementedType
|
|
10
|
+
from typing import Self, SupportsIndex, overload
|
|
11
|
+
|
|
12
|
+
import setdoc
|
|
13
|
+
|
|
14
|
+
from .._utils.Slice import Slice
|
|
15
|
+
from .BaseDataSequence import BaseDataSequence
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class BaseDataList[Item](BaseDataSequence[Item]):
|
|
19
|
+
"""Provide an easy abc for custom list-like."""
|
|
20
|
+
|
|
21
|
+
__slots__ = ()
|
|
22
|
+
|
|
23
|
+
type Data[DataItem] = tuple[DataItem, ...]
|
|
24
|
+
type Init[InitItem] = abc.Iterable[InitItem]
|
|
25
|
+
|
|
26
|
+
@setdoc.basic
|
|
27
|
+
def __add__(self: Self, other: BaseDataList[Item], /) -> Self:
|
|
28
|
+
# list.__add__ reveals Overload(
|
|
29
|
+
# def [_T] (list[_T], list[_T]) -> list[_T],
|
|
30
|
+
# def [_T, _S] (list[_T], list[_S]) -> list[_S | _T],
|
|
31
|
+
# )
|
|
32
|
+
# tuple.__add__ reveals Overload(
|
|
33
|
+
# def [_T_co] (tuple[_T_co, ...], tuple[_T_co, ...]) -> tuple[_T_co, ...],
|
|
34
|
+
# def [_T_co, _T] (tuple[_T_co, ...], tuple[_T, ...]) -> tuple[_T_co | _T, ...],
|
|
35
|
+
# )
|
|
36
|
+
if isinstance(other, BaseDataList):
|
|
37
|
+
return type(self)(self.__fget__() + other.__fget__())
|
|
38
|
+
else:
|
|
39
|
+
return NotImplemented
|
|
40
|
+
|
|
41
|
+
@setdoc.basic
|
|
42
|
+
def __eq__(self: Self, other: object, /) -> NotImplementedType | bool:
|
|
43
|
+
if isinstance(other, BaseDataList):
|
|
44
|
+
return self.__fget__() == other.__fget__()
|
|
45
|
+
else:
|
|
46
|
+
return NotImplemented
|
|
47
|
+
|
|
48
|
+
@setdoc.basic
|
|
49
|
+
def __ge__(self: Self, other: object, /) -> NotImplementedType | bool:
|
|
50
|
+
if isinstance(other, BaseDataList):
|
|
51
|
+
return self.__fget__() >= other.__fget__()
|
|
52
|
+
else:
|
|
53
|
+
return NotImplemented
|
|
54
|
+
|
|
55
|
+
@overload
|
|
56
|
+
@setdoc.basic
|
|
57
|
+
def __getitem__(self: Self, index: SupportsIndex, /) -> Item: ...
|
|
58
|
+
|
|
59
|
+
@overload
|
|
60
|
+
@setdoc.basic
|
|
61
|
+
def __getitem__(self: Self, index: Slice[SupportsIndex], /) -> Self: ...
|
|
62
|
+
|
|
63
|
+
@setdoc.basic
|
|
64
|
+
def __getitem__(
|
|
65
|
+
self: Self, index: SupportsIndex | Slice[SupportsIndex], /
|
|
66
|
+
) -> Item | Self:
|
|
67
|
+
if isinstance(index, SupportsIndex):
|
|
68
|
+
return self.__fget__()[index]
|
|
69
|
+
else:
|
|
70
|
+
return type(self)(self.__fget__()[index])
|
|
71
|
+
|
|
72
|
+
@setdoc.basic
|
|
73
|
+
def __gt__(self: Self, other: object, /) -> NotImplementedType | bool:
|
|
74
|
+
if isinstance(other, BaseDataList):
|
|
75
|
+
return self.__fget__() > other.__fget__()
|
|
76
|
+
else:
|
|
77
|
+
return NotImplemented
|
|
78
|
+
|
|
79
|
+
@abstractmethod
|
|
80
|
+
@setdoc.basic
|
|
81
|
+
def __init__(self: Self, data: Init[Item] = (), /) -> None: ...
|
|
82
|
+
|
|
83
|
+
@setdoc.basic
|
|
84
|
+
def __le__(self: Self, other: object, /) -> NotImplementedType | bool:
|
|
85
|
+
if isinstance(other, BaseDataList):
|
|
86
|
+
return self.__fget__() <= other.__fget__()
|
|
87
|
+
else:
|
|
88
|
+
return NotImplemented
|
|
89
|
+
|
|
90
|
+
@setdoc.basic
|
|
91
|
+
def __lt__(self: Self, other: object, /) -> NotImplementedType | bool:
|
|
92
|
+
if isinstance(other, BaseDataList):
|
|
93
|
+
return self.__fget__() < other.__fget__()
|
|
94
|
+
else:
|
|
95
|
+
return NotImplemented
|
|
96
|
+
|
|
97
|
+
@setdoc.basic
|
|
98
|
+
def __mul__(self: Self, other: SupportsIndex, /) -> Self:
|
|
99
|
+
return type(self)(self.__fget__() * other)
|
|
100
|
+
|
|
101
|
+
@setdoc.basic
|
|
102
|
+
def __repr__(self: Self, /) -> str:
|
|
103
|
+
return f"{type(self).__name__}({list(self.__fget__())!r})"
|
|
104
|
+
|
|
105
|
+
__rmul__ = __mul__
|
|
106
|
+
|
|
107
|
+
@abstractmethod
|
|
108
|
+
@setdoc.basic
|
|
109
|
+
def __fget__(self: Self) -> Data[Item]: ...
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Provide BaseDataMapping."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__: list[str] = ["BaseDataMapping"]
|
|
6
|
+
|
|
7
|
+
from abc import abstractmethod
|
|
8
|
+
from collections import abc
|
|
9
|
+
from typing import Never, Protocol, Self
|
|
10
|
+
|
|
11
|
+
import setdoc
|
|
12
|
+
|
|
13
|
+
from .BaseDataCollection import BaseDataCollection
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class BaseDataMapping[Key, Value](
|
|
17
|
+
BaseDataCollection[Key], abc.Mapping[Key, Value]
|
|
18
|
+
):
|
|
19
|
+
"""Provide an easy abc for a custom mapping."""
|
|
20
|
+
|
|
21
|
+
__slots__ = ()
|
|
22
|
+
|
|
23
|
+
@setdoc.basic
|
|
24
|
+
class Data[DataKey, DataValue](
|
|
25
|
+
BaseDataCollection.Data[DataKey],
|
|
26
|
+
Protocol,
|
|
27
|
+
):
|
|
28
|
+
@setdoc.basic
|
|
29
|
+
def __getitem__(self: Self, key: Never, /) -> DataValue:
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
@setdoc.basic
|
|
33
|
+
def __getitem__(self: Self, key: object, /) -> Value:
|
|
34
|
+
try:
|
|
35
|
+
return self.__fget__()[key] # type: ignore[index]
|
|
36
|
+
except TypeError:
|
|
37
|
+
raise KeyError(key) from None
|
|
38
|
+
|
|
39
|
+
@abstractmethod
|
|
40
|
+
@setdoc.basic
|
|
41
|
+
def __fget__(self: Self) -> Data[Key, Value]: ...
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Provide BaseDataSequence."""
|
|
2
|
+
|
|
3
|
+
__all__: list[str] = ["BaseDataSequence"]
|
|
4
|
+
|
|
5
|
+
from abc import abstractmethod
|
|
6
|
+
from collections import abc
|
|
7
|
+
from typing import Protocol, Self, overload
|
|
8
|
+
|
|
9
|
+
import setdoc
|
|
10
|
+
|
|
11
|
+
from .._utils.Slice import Slice
|
|
12
|
+
from .BaseDataCollection import BaseDataCollection
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BaseDataSequence[Item](
|
|
16
|
+
BaseDataCollection[Item],
|
|
17
|
+
abc.Sequence[Item],
|
|
18
|
+
):
|
|
19
|
+
"""Provide an easy abc for a custom sequence."""
|
|
20
|
+
|
|
21
|
+
__slots__ = ()
|
|
22
|
+
|
|
23
|
+
@setdoc.basic
|
|
24
|
+
class Data[DataItem](
|
|
25
|
+
BaseDataCollection.Data[DataItem],
|
|
26
|
+
Protocol,
|
|
27
|
+
):
|
|
28
|
+
"""Provide sequence data protocol."""
|
|
29
|
+
|
|
30
|
+
@overload
|
|
31
|
+
@setdoc.basic
|
|
32
|
+
def __getitem__(self: Self, key: int, /) -> DataItem: ...
|
|
33
|
+
@overload
|
|
34
|
+
@setdoc.basic
|
|
35
|
+
def __getitem__(
|
|
36
|
+
self: Self, key: Slice[int], /
|
|
37
|
+
) -> abc.Sequence[DataItem]: ...
|
|
38
|
+
@setdoc.basic
|
|
39
|
+
def __getitem__(
|
|
40
|
+
self: Self, key: int | Slice[int], /
|
|
41
|
+
) -> DataItem | abc.Sequence[DataItem]: ...
|
|
42
|
+
|
|
43
|
+
@overload
|
|
44
|
+
@setdoc.basic
|
|
45
|
+
def __getitem__(self: Self, key: int, /) -> Item: ...
|
|
46
|
+
@overload
|
|
47
|
+
@setdoc.basic
|
|
48
|
+
def __getitem__(self: Self, key: Slice[int], /) -> abc.Sequence[Item]: ...
|
|
49
|
+
@setdoc.basic
|
|
50
|
+
def __getitem__(
|
|
51
|
+
self: Self, key: int | Slice[int], /
|
|
52
|
+
) -> Item | abc.Sequence[Item]:
|
|
53
|
+
return self.__fget__()[key]
|
|
54
|
+
|
|
55
|
+
@abstractmethod
|
|
56
|
+
@setdoc.basic
|
|
57
|
+
def __fget__(self: Self) -> Data[Item]: ...
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Provide BaseDataSet."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__: list[str] = ["BaseDataSet"]
|
|
6
|
+
|
|
7
|
+
from abc import abstractmethod
|
|
8
|
+
from collections import abc
|
|
9
|
+
from typing import Self
|
|
10
|
+
|
|
11
|
+
import setdoc
|
|
12
|
+
|
|
13
|
+
from .BaseDataAbstractSet import BaseDataAbstractSet
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class BaseDataSet[Item: abc.Hashable](BaseDataAbstractSet[Item]):
|
|
17
|
+
"""Provide an easy abc for custom set-like."""
|
|
18
|
+
|
|
19
|
+
__slots__ = ()
|
|
20
|
+
|
|
21
|
+
type Data[DataItem] = frozenset[DataItem]
|
|
22
|
+
type Init[InitItem] = abc.Iterable[InitItem]
|
|
23
|
+
|
|
24
|
+
@abstractmethod
|
|
25
|
+
@setdoc.basic
|
|
26
|
+
def __init__(self: Self, data: Init[Item] = (), /) -> None: ...
|
|
27
|
+
|
|
28
|
+
@setdoc.basic
|
|
29
|
+
def __repr__(self: Self, /) -> str:
|
|
30
|
+
return f"{type(self).__name__}({set(self.__fget__())!r})"
|
|
31
|
+
|
|
32
|
+
@abstractmethod
|
|
33
|
+
@setdoc.basic
|
|
34
|
+
def __fget__(self: Self) -> frozenset[Item]: ...
|
|
35
|
+
|
|
36
|
+
@setdoc.basic
|
|
37
|
+
def difference(self: Self, /, *others: abc.Iterable[abc.Hashable]) -> Self:
|
|
38
|
+
return type(self)(self.__fget__().difference(*others))
|
|
39
|
+
|
|
40
|
+
@setdoc.basic
|
|
41
|
+
def intersection(
|
|
42
|
+
self: Self, /, *others: abc.Iterable[abc.Hashable]
|
|
43
|
+
) -> Self:
|
|
44
|
+
return type(self)(self.__fget__().intersection(*others))
|
|
45
|
+
|
|
46
|
+
@setdoc.basic
|
|
47
|
+
def issubset(self: Self, other: abc.Iterable[abc.Hashable], /) -> bool:
|
|
48
|
+
return self.__fget__().issubset(other)
|
|
49
|
+
|
|
50
|
+
@setdoc.basic
|
|
51
|
+
def issuperset(self: Self, other: abc.Iterable[abc.Hashable], /) -> bool:
|
|
52
|
+
return self.__fget__().issuperset(other)
|
|
53
|
+
|
|
54
|
+
@setdoc.basic
|
|
55
|
+
def symmetric_difference(
|
|
56
|
+
self: Self,
|
|
57
|
+
other: abc.Iterable[Item],
|
|
58
|
+
/,
|
|
59
|
+
) -> Self:
|
|
60
|
+
return type(self)(self.__fget__().symmetric_difference(other))
|
|
61
|
+
|
|
62
|
+
@setdoc.basic
|
|
63
|
+
def union(self: Self, /, *others: abc.Iterable[Item]) -> Self:
|
|
64
|
+
return type(self)(self.__fget__().union(*others))
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Provide BaseHoldCollection."""
|
|
2
|
+
|
|
3
|
+
__all__: list[str] = ["BaseHoldCollection"]
|
|
4
|
+
|
|
5
|
+
from .BaseDataCollection import BaseDataCollection
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BaseHoldCollection[Item](BaseDataCollection[Item]):
|
|
9
|
+
"""Provide abc for usable classes with slots."""
|
|
10
|
+
|
|
11
|
+
__slots__ = ("_data",)
|
datahold/core/DataDict.py
CHANGED
|
@@ -1,106 +1,67 @@
|
|
|
1
|
-
|
|
2
|
-
from types import MappingProxyType
|
|
3
|
-
from typing import *
|
|
1
|
+
"""Provide DataDict."""
|
|
4
2
|
|
|
5
|
-
import
|
|
3
|
+
from __future__ import annotations
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
__all__: list[str] = ["DataDict"]
|
|
8
6
|
|
|
9
|
-
from
|
|
10
|
-
from
|
|
7
|
+
from abc import abstractmethod
|
|
8
|
+
from collections import abc
|
|
9
|
+
from typing import Optional, Self
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
import setdoc
|
|
12
|
+
from frozendict import frozendict
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
Value = TypeVar("Value")
|
|
14
|
+
from ..base.BaseDataDict import BaseDataDict
|
|
16
15
|
|
|
17
16
|
|
|
18
|
-
class DataDict(
|
|
19
|
-
|
|
17
|
+
class DataDict[Key: abc.Hashable, Value](
|
|
18
|
+
BaseDataDict[Key, Value],
|
|
19
|
+
abc.MutableMapping[Key | str, Optional[Value]],
|
|
20
20
|
):
|
|
21
|
-
|
|
22
|
-
__slots__ = ()
|
|
21
|
+
"""Provide easy abc for custom mutable dict-like."""
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
def __delitem__(self: Self, *args: Any, **kwargs: Any) -> Any:
|
|
26
|
-
"This doc string is overwritten together with the signature to match the original as closely as possible."
|
|
27
|
-
ans: Any
|
|
28
|
-
data: dict[Key, Value]
|
|
29
|
-
data = dict[Key, Value](self.data)
|
|
30
|
-
ans = data.__delitem__(*args, **kwargs)
|
|
31
|
-
self.data = MappingProxyType[Key, Value](data)
|
|
32
|
-
return ans
|
|
23
|
+
__slots__ = ()
|
|
33
24
|
|
|
34
25
|
@setdoc.basic
|
|
35
|
-
def
|
|
36
|
-
self.
|
|
37
|
-
|
|
38
|
-
@wraps(dict[Key, Value])
|
|
39
|
-
def __ior__(self: Self, *args: Any, **kwargs: Any) -> Any:
|
|
40
|
-
"This doc string is overwritten together with the signature to match the original as closely as possible."
|
|
41
|
-
ans: Any
|
|
42
|
-
data: dict[Key, Value]
|
|
43
|
-
data = dict[Key, Value](self.data)
|
|
44
|
-
ans = data.__ior__(*args, **kwargs)
|
|
45
|
-
self.data = MappingProxyType[Key, Value](data)
|
|
46
|
-
return ans
|
|
26
|
+
def __delitem__(self: Self, key: Key | str, /) -> None:
|
|
27
|
+
self.__fset__(self.__fget__().delete(key))
|
|
47
28
|
|
|
48
|
-
@
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
ans: Any
|
|
52
|
-
data: dict[Key, Value]
|
|
53
|
-
data = dict[Key, Value](self.data)
|
|
54
|
-
ans = data.__setitem__(*args, **kwargs)
|
|
55
|
-
self.data = MappingProxyType[Key, Value](data)
|
|
56
|
-
return ans
|
|
29
|
+
@abstractmethod
|
|
30
|
+
@setdoc.basic
|
|
31
|
+
def __fget__(self: Self) -> DataDict.Data[Key, Value]: ...
|
|
57
32
|
|
|
58
|
-
@
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
ans: Any
|
|
62
|
-
data: dict[Key, Value]
|
|
63
|
-
data = dict[Key, Value](self.data)
|
|
64
|
-
ans = data.clear(*args, **kwargs)
|
|
65
|
-
self.data = MappingProxyType[Key, Value](data)
|
|
66
|
-
return ans
|
|
33
|
+
@abstractmethod
|
|
34
|
+
@setdoc.basic
|
|
35
|
+
def __fset__(self: Self, data: DataDict.Data[Key, Value], /) -> None: ...
|
|
67
36
|
|
|
68
|
-
@
|
|
69
|
-
def
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
self.data
|
|
76
|
-
return ans
|
|
37
|
+
@setdoc.basic
|
|
38
|
+
def __init__(
|
|
39
|
+
self: Self,
|
|
40
|
+
data: BaseDataDict.Init[Key, Value] = (),
|
|
41
|
+
/,
|
|
42
|
+
**kwargs: Optional[Value],
|
|
43
|
+
) -> None:
|
|
44
|
+
self.__fset__(frozendict(data, **kwargs)) # type: ignore[arg-type]
|
|
77
45
|
|
|
78
|
-
@
|
|
79
|
-
def
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
self
|
|
86
|
-
return ans
|
|
46
|
+
@setdoc.basic
|
|
47
|
+
def __ior__(
|
|
48
|
+
self: Self,
|
|
49
|
+
other: BaseDataDict[Key, Value],
|
|
50
|
+
/,
|
|
51
|
+
) -> Self:
|
|
52
|
+
self.__fset__(self.__fget__() | other.__fget__())
|
|
53
|
+
return self
|
|
87
54
|
|
|
88
|
-
@
|
|
89
|
-
def
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
55
|
+
@setdoc.basic
|
|
56
|
+
def __setitem__(
|
|
57
|
+
self: Self,
|
|
58
|
+
key: Key | str,
|
|
59
|
+
value: Optional[Value],
|
|
60
|
+
/,
|
|
61
|
+
) -> None:
|
|
62
|
+
# what to do if Key includes unhashable types?
|
|
63
|
+
self.__fset__(self.__fget__().set(key, value))
|
|
97
64
|
|
|
98
|
-
@
|
|
99
|
-
def
|
|
100
|
-
|
|
101
|
-
ans: Any
|
|
102
|
-
data: dict[Key, Value]
|
|
103
|
-
data = dict[Key, Value](self.data)
|
|
104
|
-
ans = data.update(*args, **kwargs)
|
|
105
|
-
self.data = MappingProxyType[Key, Value](data)
|
|
106
|
-
return ans
|
|
65
|
+
@setdoc.basic
|
|
66
|
+
def copy(self: Self) -> Self:
|
|
67
|
+
return type(self)(self)
|