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.
Files changed (64) hide show
  1. datahold/__init__.py +39 -18
  2. datahold/_utils/Missing.py +9 -0
  3. datahold/_utils/Slice.py +4 -0
  4. datahold/_utils/__init__.py +3 -0
  5. datahold/base/BaseDataAbstractSet.py +16 -0
  6. datahold/base/BaseDataCollection.py +49 -0
  7. datahold/base/BaseDataDict.py +76 -0
  8. datahold/base/BaseDataList.py +109 -0
  9. datahold/base/BaseDataMapping.py +41 -0
  10. datahold/base/BaseDataSequence.py +57 -0
  11. datahold/base/BaseDataSet.py +64 -0
  12. datahold/base/BaseHoldCollection.py +11 -0
  13. datahold/base/__init__.py +3 -0
  14. datahold/core/DataDict.py +50 -89
  15. datahold/core/DataList.py +87 -127
  16. datahold/core/DataSet.py +70 -136
  17. datahold/core/HoldDict.py +23 -15
  18. datahold/core/HoldList.py +18 -13
  19. datahold/core/HoldSet.py +19 -12
  20. datahold/core/__init__.py +3 -0
  21. datahold/frozen/FrozenDataDict.py +23 -0
  22. datahold/frozen/FrozenDataList.py +23 -0
  23. datahold/frozen/FrozenDataSet.py +20 -0
  24. datahold/frozen/FrozenHoldDict.py +45 -0
  25. datahold/frozen/FrozenHoldList.py +33 -0
  26. datahold/frozen/FrozenHoldSet.py +34 -0
  27. datahold/frozen/__init__.py +3 -0
  28. datahold/py.typed +0 -0
  29. {datahold-4.0.0.dev1.dist-info → datahold-4.0.0.dev2.dist-info}/METADATA +9 -8
  30. datahold-4.0.0.dev2.dist-info/RECORD +33 -0
  31. {datahold-4.0.0.dev1.dist-info → datahold-4.0.0.dev2.dist-info}/WHEEL +1 -1
  32. {datahold-4.0.0.dev1.dist-info → datahold-4.0.0.dev2.dist-info}/licenses/LICENSE.txt +1 -1
  33. datahold/_utils/wrapping.py +0 -91
  34. datahold/core/BaseDataDict.py +0 -113
  35. datahold/core/BaseDataList.py +0 -100
  36. datahold/core/BaseDataObject.py +0 -24
  37. datahold/core/BaseDataSet.py +0 -140
  38. datahold/core/BaseHoldDict.py +0 -15
  39. datahold/core/BaseHoldList.py +0 -13
  40. datahold/core/BaseHoldObject.py +0 -10
  41. datahold/core/BaseHoldSet.py +0 -13
  42. datahold/core/DataObject.py +0 -18
  43. datahold/core/FrozenDataDict.py +0 -15
  44. datahold/core/FrozenDataList.py +0 -13
  45. datahold/core/FrozenDataObject.py +0 -18
  46. datahold/core/FrozenDataSet.py +0 -13
  47. datahold/core/FrozenHoldDict.py +0 -22
  48. datahold/core/FrozenHoldList.py +0 -20
  49. datahold/core/FrozenHoldObject.py +0 -15
  50. datahold/core/FrozenHoldSet.py +0 -20
  51. datahold/core/HoldObject.py +0 -11
  52. datahold/tests/__init__.py +0 -16
  53. datahold/tests/test_0.py +0 -62
  54. datahold/tests/test_datahold_TestAbstractness.py +0 -52
  55. datahold/tests/test_datahold_TestCopy.py +0 -83
  56. datahold/tests/test_datahold_TestDataAttribute.py +0 -54
  57. datahold/tests/test_datahold_TestFrozenMutability.py +0 -36
  58. datahold/tests/test_datahold_TestInheritance.py +0 -60
  59. datahold/tests/test_datahold_TestMutableBehavior.py +0 -33
  60. datahold/tests/test_datahold_TestProtocols.py +0 -64
  61. datahold/tests/test_generic.py +0 -86
  62. datahold/tests/test_object.py +0 -41
  63. datahold-4.0.0.dev1.dist-info/RECORD +0 -44
  64. {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
- from datahold.core.BaseDataDict import BaseDataDict
2
- from datahold.core.BaseDataList import BaseDataList
3
- from datahold.core.BaseDataObject import BaseDataObject
4
- from datahold.core.BaseDataSet import BaseDataSet
5
- from datahold.core.BaseHoldDict import BaseHoldDict
6
- from datahold.core.BaseHoldList import BaseHoldList
7
- from datahold.core.BaseHoldObject import BaseHoldObject
8
- from datahold.core.BaseHoldSet import BaseHoldSet
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
@@ -0,0 +1,9 @@
1
+ """Provide Missing."""
2
+
3
+ __all__: list[str] = []
4
+
5
+ import enum
6
+
7
+
8
+ class Missing(enum.Enum):
9
+ missing = None
@@ -0,0 +1,4 @@
1
+ __all__: list[str] = ["Slice"]
2
+ from typing import Optional
3
+
4
+ type Slice[Index] = slice[Optional[Index], Optional[Index], Optional[Index]]
@@ -0,0 +1,3 @@
1
+ """Provide _utils."""
2
+
3
+ __all__: list[str] = []
@@ -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",)
@@ -0,0 +1,3 @@
1
+ """Provide base holder types."""
2
+
3
+ __all__: list[str] = []
datahold/core/DataDict.py CHANGED
@@ -1,106 +1,67 @@
1
- import collections
2
- from types import MappingProxyType
3
- from typing import *
1
+ """Provide DataDict."""
4
2
 
5
- import setdoc
3
+ from __future__ import annotations
6
4
 
7
- from datahold._utils.wrapping import wraps
5
+ __all__: list[str] = ["DataDict"]
8
6
 
9
- from .BaseDataDict import BaseDataDict
10
- from .DataObject import DataObject
7
+ from abc import abstractmethod
8
+ from collections import abc
9
+ from typing import Optional, Self
11
10
 
12
- __all__ = ["DataDict"]
11
+ import setdoc
12
+ from frozendict import frozendict
13
13
 
14
- Key = TypeVar("Key")
15
- Value = TypeVar("Value")
14
+ from ..base.BaseDataDict import BaseDataDict
16
15
 
17
16
 
18
- class DataDict(
19
- DataObject, BaseDataDict[Key, Value], collections.abc.MutableMapping[Key, Value]
17
+ class DataDict[Key: abc.Hashable, Value](
18
+ BaseDataDict[Key, Value],
19
+ abc.MutableMapping[Key | str, Optional[Value]],
20
20
  ):
21
- data: MappingProxyType[Key, Value]
22
- __slots__ = ()
21
+ """Provide easy abc for custom mutable dict-like."""
23
22
 
24
- @wraps(dict[Key, Value])
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 __init__(self: Self, data: Any = (), /, **kwargs: Any) -> None:
36
- self.data = MappingProxyType[Key, Value](dict[Key, Value](data, **kwargs))
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
- @wraps(dict[Key, Value])
49
- def __setitem__(self: Self, *args: Any, **kwargs: Any) -> Any:
50
- "This doc string is overwritten together with the signature to match the original as closely as possible."
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
- @wraps(dict[Key, Value])
59
- def clear(self: Self, *args: Any, **kwargs: Any) -> Any:
60
- "This doc string is overwritten together with the signature to match the original as closely as possible."
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
- @wraps(dict[Key, Value])
69
- def pop(self: Self, *args: Any, **kwargs: Any) -> Any:
70
- "This doc string is overwritten together with the signature to match the original as closely as possible."
71
- ans: Any
72
- data: dict[Key, Value]
73
- data = dict[Key, Value](self.data)
74
- ans = data.pop(*args, **kwargs)
75
- self.data = MappingProxyType[Key, Value](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
- @wraps(dict[Key, Value])
79
- def popitem(self: Self, *args: Any, **kwargs: Any) -> Any:
80
- "This doc string is overwritten together with the signature to match the original as closely as possible."
81
- ans: Any
82
- data: dict[Key, Value]
83
- data = dict[Key, Value](self.data)
84
- ans = data.popitem(*args, **kwargs)
85
- self.data = MappingProxyType[Key, Value](data)
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
- @wraps(dict[Key, Value])
89
- def setdefault(self: Self, *args: Any, **kwargs: Any) -> Any:
90
- "This doc string is overwritten together with the signature to match the original as closely as possible."
91
- ans: Any
92
- data: dict[Key, Value]
93
- data = dict[Key, Value](self.data)
94
- ans = data.setdefault(*args, **kwargs)
95
- self.data = MappingProxyType[Key, Value](data)
96
- return ans
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
- @wraps(dict[Key, Value])
99
- def update(self: Self, *args: Any, **kwargs: Any) -> Any:
100
- "This doc string is overwritten together with the signature to match the original as closely as possible."
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)