datahold 1.2.1__tar.gz → 1.3.0.dev0__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-1.2.1/src/datahold.egg-info → datahold-1.3.0.dev0}/PKG-INFO +3 -2
- {datahold-1.2.1 → datahold-1.3.0.dev0}/pyproject.toml +3 -2
- datahold-1.3.0.dev0/src/datahold/_utils/deco/__init__.py +3 -0
- datahold-1.3.0.dev0/src/datahold/_utils/deco/dataDeco.py +46 -0
- datahold-1.3.0.dev0/src/datahold/_utils/deco/funcDeco.py +62 -0
- datahold-1.3.0.dev0/src/datahold/_utils/deco/initDeco.py +45 -0
- datahold-1.2.1/src/datahold/_utils/deco/util.py → datahold-1.3.0.dev0/src/datahold/_utils/deco/wrapping.py +19 -23
- datahold-1.3.0.dev0/src/datahold/core/DataABC.py +26 -0
- datahold-1.3.0.dev0/src/datahold/core/DataDict.py +47 -0
- datahold-1.3.0.dev0/src/datahold/core/DataList.py +50 -0
- datahold-1.3.0.dev0/src/datahold/core/DataSet.py +59 -0
- datahold-1.3.0.dev0/src/datahold/core/HoldABC.py +9 -0
- datahold-1.3.0.dev0/src/datahold/core/HoldDict.py +17 -0
- datahold-1.3.0.dev0/src/datahold/core/HoldList.py +15 -0
- datahold-1.3.0.dev0/src/datahold/core/HoldSet.py +15 -0
- datahold-1.3.0.dev0/src/datahold/core/OkayABC.py +84 -0
- datahold-1.3.0.dev0/src/datahold/core/OkayDict.py +47 -0
- datahold-1.3.0.dev0/src/datahold/core/OkayList.py +39 -0
- datahold-1.3.0.dev0/src/datahold/core/OkaySet.py +63 -0
- datahold-1.3.0.dev0/src/datahold/core/__init__.py +12 -0
- {datahold-1.2.1 → datahold-1.3.0.dev0}/src/datahold/tests/test_okay.py +22 -11
- {datahold-1.2.1 → datahold-1.3.0.dev0/src/datahold.egg-info}/PKG-INFO +3 -2
- datahold-1.3.0.dev0/src/datahold.egg-info/SOURCES.txt +32 -0
- {datahold-1.2.1 → datahold-1.3.0.dev0}/src/datahold.egg-info/requires.txt +1 -0
- datahold-1.2.1/src/datahold/_utils/deco/ClassDataDecorator.py +0 -37
- datahold-1.2.1/src/datahold/_utils/deco/ClassFuncDecorator.py +0 -42
- datahold-1.2.1/src/datahold/_utils/deco/ClassInitDecorator.py +0 -33
- datahold-1.2.1/src/datahold/_utils/deco/__init__.py +0 -3
- datahold-1.2.1/src/datahold/core/__init__.py +0 -379
- datahold-1.2.1/src/datahold.egg-info/SOURCES.txt +0 -20
- {datahold-1.2.1 → datahold-1.3.0.dev0}/LICENSE.txt +0 -0
- {datahold-1.2.1 → datahold-1.3.0.dev0}/MANIFEST.in +0 -0
- {datahold-1.2.1 → datahold-1.3.0.dev0}/README.rst +0 -0
- {datahold-1.2.1 → datahold-1.3.0.dev0}/setup.cfg +0 -0
- {datahold-1.2.1 → datahold-1.3.0.dev0}/src/datahold/__init__.py +0 -0
- {datahold-1.2.1 → datahold-1.3.0.dev0}/src/datahold/_utils/__init__.py +0 -0
- {datahold-1.2.1 → datahold-1.3.0.dev0}/src/datahold/tests/__init__.py +0 -0
- {datahold-1.2.1 → datahold-1.3.0.dev0}/src/datahold.egg-info/dependency_links.txt +0 -0
- {datahold-1.2.1 → datahold-1.3.0.dev0}/src/datahold.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datahold
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0.dev0
|
|
4
4
|
Summary: This project wraps common mutable datastructures for inheritance with modification.
|
|
5
5
|
Author-email: Johannes <johannes.programming@gmail.com>
|
|
6
6
|
License: The MIT License (MIT)
|
|
@@ -28,7 +28,7 @@ Project-URL: Download, https://pypi.org/project/datahold/#files
|
|
|
28
28
|
Project-URL: Index, https://pypi.org/project/datahold/
|
|
29
29
|
Project-URL: Source, https://github.com/johannes-programming/datahold/
|
|
30
30
|
Project-URL: Website, http://datahold.johannes-programming.online/
|
|
31
|
-
Classifier: Development Status ::
|
|
31
|
+
Classifier: Development Status :: 3 - Alpha
|
|
32
32
|
Classifier: Intended Audience :: Developers
|
|
33
33
|
Classifier: License :: OSI Approved :: MIT License
|
|
34
34
|
Classifier: Natural Language :: English
|
|
@@ -41,6 +41,7 @@ Requires-Python: >=3.11
|
|
|
41
41
|
Description-Content-Type: text/x-rst
|
|
42
42
|
License-File: LICENSE.txt
|
|
43
43
|
Requires-Dist: datarepr<2,>=1.0
|
|
44
|
+
Requires-Dist: frozendict<3,>=2.4.6
|
|
44
45
|
Requires-Dist: scaevola<2,>=1.0.11
|
|
45
46
|
Requires-Dist: setdoc<2,>=1.2
|
|
46
47
|
Requires-Dist: unhash<2,>=1.0
|
|
@@ -9,7 +9,7 @@ authors = [
|
|
|
9
9
|
{ email = "johannes.programming@gmail.com", name = "Johannes" },
|
|
10
10
|
]
|
|
11
11
|
classifiers = [
|
|
12
|
-
"Development Status ::
|
|
12
|
+
"Development Status :: 3 - Alpha",
|
|
13
13
|
"Intended Audience :: Developers",
|
|
14
14
|
"License :: OSI Approved :: MIT License",
|
|
15
15
|
"Natural Language :: English",
|
|
@@ -21,6 +21,7 @@ classifiers = [
|
|
|
21
21
|
]
|
|
22
22
|
dependencies = [
|
|
23
23
|
"datarepr>=1.0,<2",
|
|
24
|
+
"frozendict>=2.4.6,<3",
|
|
24
25
|
"scaevola>=1.0.11,<2",
|
|
25
26
|
"setdoc>=1.2,<2",
|
|
26
27
|
"unhash>=1.0,<2",
|
|
@@ -30,7 +31,7 @@ keywords = []
|
|
|
30
31
|
name = "datahold"
|
|
31
32
|
readme = "README.rst"
|
|
32
33
|
requires-python = ">=3.11"
|
|
33
|
-
version = "1.
|
|
34
|
+
version = "1.3.0.dev0"
|
|
34
35
|
|
|
35
36
|
[project.license]
|
|
36
37
|
file = "LICENSE.txt"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
from functools import partial
|
|
3
|
+
from typing import *
|
|
4
|
+
|
|
5
|
+
import setdoc
|
|
6
|
+
|
|
7
|
+
__all__ = ["dataDeco"]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def dataDeco() -> partial:
|
|
11
|
+
return update
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def update(
|
|
15
|
+
Target: type,
|
|
16
|
+
) -> type:
|
|
17
|
+
Target.data = makeData(Target)
|
|
18
|
+
abc.update_abstractmethods(Target)
|
|
19
|
+
return Target
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def makeData(Target: type) -> property:
|
|
23
|
+
Frozen: type = Target.__annotations__["data"]
|
|
24
|
+
|
|
25
|
+
def fget(self: Self) -> Any:
|
|
26
|
+
return self._data
|
|
27
|
+
|
|
28
|
+
adapt(fget, Target=Target)
|
|
29
|
+
|
|
30
|
+
def fset(self: Self, value: Any) -> None:
|
|
31
|
+
self._data = Frozen(value)
|
|
32
|
+
|
|
33
|
+
adapt(fset, Target=Target)
|
|
34
|
+
|
|
35
|
+
ans: property = property(
|
|
36
|
+
fget=fget,
|
|
37
|
+
fset=fset,
|
|
38
|
+
doc=setdoc.getbasicdoc("data"),
|
|
39
|
+
)
|
|
40
|
+
return ans
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def adapt(func: Callable, *, Target: type) -> None:
|
|
44
|
+
func.__module__ = Target.__module__
|
|
45
|
+
func.__qualname__ = Target.__qualname__ + ".data." + func.__name__
|
|
46
|
+
func.__name__ = "data"
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
from functools import partial
|
|
3
|
+
from types import FunctionType
|
|
4
|
+
from typing import *
|
|
5
|
+
|
|
6
|
+
from datahold._utils.deco.wrapping import wrap
|
|
7
|
+
|
|
8
|
+
__all__ = ["funcDeco"]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def funcDeco(*args: str, **kwargs: type) -> partial:
|
|
12
|
+
return partial(update, funcnames=args, **kwargs)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def update(
|
|
16
|
+
Target: type,
|
|
17
|
+
*,
|
|
18
|
+
funcnames: str,
|
|
19
|
+
Frozen: type,
|
|
20
|
+
NonFrozen: type,
|
|
21
|
+
) -> type:
|
|
22
|
+
name: str
|
|
23
|
+
for name in funcnames:
|
|
24
|
+
setupFunc(
|
|
25
|
+
Target=Target,
|
|
26
|
+
name=name,
|
|
27
|
+
Frozen=Frozen,
|
|
28
|
+
NonFrozen=NonFrozen,
|
|
29
|
+
)
|
|
30
|
+
abc.update_abstractmethods(Target)
|
|
31
|
+
return Target
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def setupFunc(
|
|
35
|
+
*,
|
|
36
|
+
Target: type,
|
|
37
|
+
NonFrozen: type,
|
|
38
|
+
Frozen: type,
|
|
39
|
+
name: str,
|
|
40
|
+
) -> None:
|
|
41
|
+
old: Callable = getattr(NonFrozen, name)
|
|
42
|
+
new: FunctionType = makeFunc(
|
|
43
|
+
old=old,
|
|
44
|
+
NonFrozen=NonFrozen,
|
|
45
|
+
Frozen=Frozen,
|
|
46
|
+
)
|
|
47
|
+
new.__module__ = Target.__module__
|
|
48
|
+
new.__name__ = name
|
|
49
|
+
new.__qualname__ = Target.__qualname__ + "." + name
|
|
50
|
+
setattr(Target, name, new)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def makeFunc(*, old: FunctionType, NonFrozen: type, Frozen: type) -> Any:
|
|
54
|
+
def new(self: Self, *args: Any, **kwargs: Any) -> Any:
|
|
55
|
+
data: Any = NonFrozen(self.data)
|
|
56
|
+
ans: Any = old(data, *args, **kwargs)
|
|
57
|
+
self.data = Frozen(data)
|
|
58
|
+
return ans
|
|
59
|
+
|
|
60
|
+
wrap(new=new, old=old)
|
|
61
|
+
|
|
62
|
+
return new
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
from functools import partial
|
|
3
|
+
from types import FunctionType
|
|
4
|
+
from typing import *
|
|
5
|
+
|
|
6
|
+
from datahold._utils.deco.wrapping import wrap
|
|
7
|
+
|
|
8
|
+
__all__ = ["initDeco"]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def initDeco(**kwargs: type) -> partial:
|
|
12
|
+
return partial(update, **kwargs)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def update(
|
|
16
|
+
Target: type,
|
|
17
|
+
*,
|
|
18
|
+
Frozen: type,
|
|
19
|
+
NonFrozen: type,
|
|
20
|
+
) -> type:
|
|
21
|
+
setupInit(
|
|
22
|
+
Target=Target,
|
|
23
|
+
Frozen=Frozen,
|
|
24
|
+
NonFrozen=NonFrozen,
|
|
25
|
+
)
|
|
26
|
+
Target.__annotations__ = dict(data=Frozen)
|
|
27
|
+
abc.update_abstractmethods(Target)
|
|
28
|
+
return Target
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def setupInit(*, Target: type, **kwargs: type) -> None:
|
|
32
|
+
new: FunctionType = makeInit(**kwargs)
|
|
33
|
+
new.__module__ = Target.__module__
|
|
34
|
+
new.__name__ = "__init__"
|
|
35
|
+
new.__qualname__ = Target.__qualname__ + ".__init__"
|
|
36
|
+
Target.__init__ = new
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def makeInit(*, Frozen: type, NonFrozen: type) -> FunctionType:
|
|
40
|
+
def new(self: Self, *args: Any, **kwargs: Any) -> None:
|
|
41
|
+
self.data = Frozen(*args, **kwargs)
|
|
42
|
+
|
|
43
|
+
wrap(new=new, old=NonFrozen.__init__)
|
|
44
|
+
|
|
45
|
+
return new
|
|
@@ -2,35 +2,15 @@ import inspect as ins
|
|
|
2
2
|
from types import FunctionType
|
|
3
3
|
from typing import *
|
|
4
4
|
|
|
5
|
-
__all__ = [
|
|
6
|
-
"getAnnotationsDict",
|
|
7
|
-
"getNonEmpty",
|
|
8
|
-
"wrap",
|
|
9
|
-
]
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def getAnnotationsDict(sig: ins.Signature) -> dict:
|
|
13
|
-
ans: dict = dict()
|
|
14
|
-
p: ins.Parameter
|
|
15
|
-
for p in sig.parameters.values():
|
|
16
|
-
ans[p.name] = p.annotation
|
|
17
|
-
ans["return"] = sig.return_annotation
|
|
18
|
-
return ans
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def getNonEmpty(value: Any, backup: Any = Any) -> Any:
|
|
22
|
-
if value is ins.Parameter.empty:
|
|
23
|
-
return backup
|
|
24
|
-
else:
|
|
25
|
-
return value
|
|
5
|
+
__all__ = ["wrap"]
|
|
26
6
|
|
|
27
7
|
|
|
28
8
|
def wrap(
|
|
29
9
|
*,
|
|
30
10
|
old: Callable,
|
|
31
11
|
new: FunctionType,
|
|
32
|
-
isinit: bool,
|
|
33
12
|
) -> ins.Signature:
|
|
13
|
+
new.__doc__ = old.__doc__
|
|
34
14
|
try:
|
|
35
15
|
oldsig: ins.Signature = ins.signature(old)
|
|
36
16
|
except ValueError:
|
|
@@ -47,7 +27,23 @@ def wrap(
|
|
|
47
27
|
a = getNonEmpty(p.annotation)
|
|
48
28
|
q = p.replace(annotation=a)
|
|
49
29
|
params.append(q)
|
|
50
|
-
a =
|
|
30
|
+
a = ins.signature(new).return_annotation
|
|
51
31
|
a = getNonEmpty(oldsig.return_annotation, backup=a)
|
|
52
32
|
new.__signature__ = ins.Signature(params, return_annotation=a)
|
|
53
33
|
new.__annotations__ = getAnnotationsDict(new.__signature__)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def getAnnotationsDict(sig: ins.Signature) -> dict:
|
|
37
|
+
ans: dict = dict()
|
|
38
|
+
p: ins.Parameter
|
|
39
|
+
for p in sig.parameters.values():
|
|
40
|
+
ans[p.name] = p.annotation
|
|
41
|
+
ans["return"] = sig.return_annotation
|
|
42
|
+
return ans
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def getNonEmpty(value: Any, backup: Any = Any) -> Any:
|
|
46
|
+
if value is ins.Parameter.empty:
|
|
47
|
+
return backup
|
|
48
|
+
else:
|
|
49
|
+
return value
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from abc import ABCMeta, abstractmethod
|
|
2
|
+
from typing import *
|
|
3
|
+
|
|
4
|
+
import setdoc
|
|
5
|
+
from unhash import unhash
|
|
6
|
+
|
|
7
|
+
__all__ = ["DataABC"]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class DataABC(metaclass=ABCMeta):
|
|
11
|
+
__slots__ = ()
|
|
12
|
+
|
|
13
|
+
__hash__ = unhash
|
|
14
|
+
|
|
15
|
+
@abstractmethod
|
|
16
|
+
@setdoc.basic
|
|
17
|
+
def __init__(self: Self, *args: Any, **kwargs: Any) -> None: ...
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def __subclasshook__(cls: type, other: type, /) -> bool:
|
|
21
|
+
"This magic classmethod can be overwritten for a custom subclass check."
|
|
22
|
+
return NotImplemented
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
@abstractmethod
|
|
26
|
+
def data(self: Self) -> Any: ...
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import collections
|
|
2
|
+
from typing import *
|
|
3
|
+
|
|
4
|
+
from frozendict import frozendict
|
|
5
|
+
|
|
6
|
+
from datahold._utils import deco
|
|
7
|
+
from datahold.core.DataABC import DataABC
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@deco.funcDeco(
|
|
11
|
+
"__contains__",
|
|
12
|
+
"__delitem__",
|
|
13
|
+
"__eq__",
|
|
14
|
+
"__format__",
|
|
15
|
+
"__ge__",
|
|
16
|
+
"__getitem__",
|
|
17
|
+
"__gt__",
|
|
18
|
+
"__ior__",
|
|
19
|
+
"__iter__",
|
|
20
|
+
"__le__",
|
|
21
|
+
"__len__",
|
|
22
|
+
"__lt__",
|
|
23
|
+
"__or__",
|
|
24
|
+
"__repr__",
|
|
25
|
+
"__reversed__",
|
|
26
|
+
"__ror__",
|
|
27
|
+
"__setitem__",
|
|
28
|
+
"__str__",
|
|
29
|
+
"clear",
|
|
30
|
+
"copy",
|
|
31
|
+
"get",
|
|
32
|
+
"items",
|
|
33
|
+
"keys",
|
|
34
|
+
"pop",
|
|
35
|
+
"popitem",
|
|
36
|
+
"setdefault",
|
|
37
|
+
"update",
|
|
38
|
+
"values",
|
|
39
|
+
Frozen=frozendict,
|
|
40
|
+
NonFrozen=dict,
|
|
41
|
+
)
|
|
42
|
+
@deco.initDeco(
|
|
43
|
+
Frozen=frozendict,
|
|
44
|
+
NonFrozen=dict,
|
|
45
|
+
)
|
|
46
|
+
class DataDict(DataABC, collections.abc.MutableMapping):
|
|
47
|
+
__slots__ = ()
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import collections
|
|
2
|
+
from typing import *
|
|
3
|
+
|
|
4
|
+
from datahold._utils import deco
|
|
5
|
+
from datahold.core.DataABC import DataABC
|
|
6
|
+
|
|
7
|
+
__all__ = ["DataList"]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@deco.funcDeco(
|
|
11
|
+
"__add__",
|
|
12
|
+
"__contains__",
|
|
13
|
+
"__delitem__",
|
|
14
|
+
"__eq__",
|
|
15
|
+
"__format__",
|
|
16
|
+
"__ge__",
|
|
17
|
+
"__getitem__",
|
|
18
|
+
"__gt__",
|
|
19
|
+
"__iadd__",
|
|
20
|
+
"__imul__",
|
|
21
|
+
"__iter__",
|
|
22
|
+
"__le__",
|
|
23
|
+
"__len__",
|
|
24
|
+
"__lt__",
|
|
25
|
+
"__mul__",
|
|
26
|
+
"__repr__",
|
|
27
|
+
"__reversed__",
|
|
28
|
+
"__rmul__",
|
|
29
|
+
"__setitem__",
|
|
30
|
+
"__str__",
|
|
31
|
+
"append",
|
|
32
|
+
"clear",
|
|
33
|
+
"copy",
|
|
34
|
+
"count",
|
|
35
|
+
"extend",
|
|
36
|
+
"index",
|
|
37
|
+
"insert",
|
|
38
|
+
"pop",
|
|
39
|
+
"remove",
|
|
40
|
+
"reverse",
|
|
41
|
+
"sort",
|
|
42
|
+
Frozen=tuple,
|
|
43
|
+
NonFrozen=list,
|
|
44
|
+
)
|
|
45
|
+
@deco.initDeco(
|
|
46
|
+
Frozen=tuple,
|
|
47
|
+
NonFrozen=list,
|
|
48
|
+
)
|
|
49
|
+
class DataList(DataABC, collections.abc.MutableSequence):
|
|
50
|
+
__slots__ = ()
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import collections
|
|
2
|
+
from typing import *
|
|
3
|
+
|
|
4
|
+
from datahold._utils import deco
|
|
5
|
+
from datahold.core.DataABC import DataABC
|
|
6
|
+
|
|
7
|
+
__all__ = ["DataSet"]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@deco.funcDeco(
|
|
11
|
+
"__and__",
|
|
12
|
+
"__contains__",
|
|
13
|
+
"__eq__",
|
|
14
|
+
"__format__",
|
|
15
|
+
"__ge__",
|
|
16
|
+
"__gt__",
|
|
17
|
+
"__iand__",
|
|
18
|
+
"__ior__",
|
|
19
|
+
"__isub__",
|
|
20
|
+
"__iter__",
|
|
21
|
+
"__ixor__",
|
|
22
|
+
"__le__",
|
|
23
|
+
"__len__",
|
|
24
|
+
"__lt__",
|
|
25
|
+
"__or__",
|
|
26
|
+
"__rand__",
|
|
27
|
+
"__repr__",
|
|
28
|
+
"__ror__",
|
|
29
|
+
"__rsub__",
|
|
30
|
+
"__rxor__",
|
|
31
|
+
"__str__",
|
|
32
|
+
"__sub__",
|
|
33
|
+
"__xor__",
|
|
34
|
+
"add",
|
|
35
|
+
"clear",
|
|
36
|
+
"copy",
|
|
37
|
+
"difference",
|
|
38
|
+
"difference_update",
|
|
39
|
+
"discard",
|
|
40
|
+
"intersection",
|
|
41
|
+
"intersection_update",
|
|
42
|
+
"isdisjoint",
|
|
43
|
+
"issubset",
|
|
44
|
+
"issuperset",
|
|
45
|
+
"pop",
|
|
46
|
+
"remove",
|
|
47
|
+
"symmetric_difference",
|
|
48
|
+
"symmetric_difference_update",
|
|
49
|
+
"union",
|
|
50
|
+
"update",
|
|
51
|
+
Frozen=frozenset,
|
|
52
|
+
NonFrozen=set,
|
|
53
|
+
)
|
|
54
|
+
@deco.initDeco(
|
|
55
|
+
Frozen=frozenset,
|
|
56
|
+
NonFrozen=set,
|
|
57
|
+
)
|
|
58
|
+
class DataSet(DataABC, collections.abc.MutableSet):
|
|
59
|
+
__slots__ = ()
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from typing import *
|
|
2
|
+
|
|
3
|
+
from frozendict import frozendict
|
|
4
|
+
|
|
5
|
+
from datahold._utils import deco
|
|
6
|
+
from datahold.core.DataDict import DataDict
|
|
7
|
+
from datahold.core.HoldABC import HoldABC
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"HoldDict",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@deco.dataDeco()
|
|
15
|
+
class HoldDict(DataDict, HoldABC):
|
|
16
|
+
__slots__ = ()
|
|
17
|
+
data: frozendict
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from typing import *
|
|
2
|
+
|
|
3
|
+
from datahold._utils import deco
|
|
4
|
+
from datahold.core.DataList import DataList
|
|
5
|
+
from datahold.core.HoldABC import HoldABC
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"HoldList",
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@deco.dataDeco()
|
|
13
|
+
class HoldList(DataList, HoldABC):
|
|
14
|
+
__slots__ = ()
|
|
15
|
+
data: tuple
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from typing import *
|
|
2
|
+
|
|
3
|
+
from datahold._utils import deco
|
|
4
|
+
from datahold.core.DataSet import DataSet
|
|
5
|
+
from datahold.core.HoldABC import HoldABC
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"HoldSet",
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@deco.dataDeco()
|
|
13
|
+
class HoldSet(DataSet, HoldABC):
|
|
14
|
+
__slots__ = ()
|
|
15
|
+
data: frozenset
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import collections
|
|
2
|
+
from abc import ABCMeta, abstractmethod
|
|
3
|
+
from typing import *
|
|
4
|
+
|
|
5
|
+
import setdoc
|
|
6
|
+
from datarepr import datarepr
|
|
7
|
+
from scaevola import Scaevola
|
|
8
|
+
|
|
9
|
+
from datahold.core.HoldABC import HoldABC
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"OkayABC",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class OkayABC(Scaevola, HoldABC):
|
|
17
|
+
__slots__ = ()
|
|
18
|
+
|
|
19
|
+
@setdoc.basic
|
|
20
|
+
def __bool__(self: Self, /) -> bool:
|
|
21
|
+
return bool(self._data)
|
|
22
|
+
|
|
23
|
+
@setdoc.basic
|
|
24
|
+
def __contains__(self: Self, other: Any, /) -> bool:
|
|
25
|
+
return other in self._data
|
|
26
|
+
|
|
27
|
+
@setdoc.basic
|
|
28
|
+
def __eq__(self: Self, other: Any, /) -> bool:
|
|
29
|
+
if type(self) is type(other):
|
|
30
|
+
return self._data == other._data
|
|
31
|
+
try:
|
|
32
|
+
opp: Self = type(self)(other)
|
|
33
|
+
except:
|
|
34
|
+
return False
|
|
35
|
+
else:
|
|
36
|
+
return self._data == opp._data
|
|
37
|
+
|
|
38
|
+
@setdoc.basic
|
|
39
|
+
def __format__(self: Self, format_spec: Any = "", /) -> str:
|
|
40
|
+
return format(self._data, str(format_spec))
|
|
41
|
+
|
|
42
|
+
@setdoc.basic
|
|
43
|
+
def __getitem__(self: Self, key: Any, /) -> Any:
|
|
44
|
+
return self._data[key]
|
|
45
|
+
|
|
46
|
+
@setdoc.basic
|
|
47
|
+
def __gt__(self: Self, other: Any, /) -> bool:
|
|
48
|
+
return not (self == other) and (self >= other)
|
|
49
|
+
|
|
50
|
+
@setdoc.basic
|
|
51
|
+
def __iter__(self: Self, /) -> Iterator:
|
|
52
|
+
return iter(self._data)
|
|
53
|
+
|
|
54
|
+
@setdoc.basic
|
|
55
|
+
def __le__(self: Self, other: Any, /) -> bool:
|
|
56
|
+
return self._data <= type(self._data)(other)
|
|
57
|
+
|
|
58
|
+
@setdoc.basic
|
|
59
|
+
def __len__(self: Self, /) -> int:
|
|
60
|
+
return len(self._data)
|
|
61
|
+
|
|
62
|
+
@setdoc.basic
|
|
63
|
+
def __lt__(self: Self, other: Any, /) -> bool:
|
|
64
|
+
return not (self == other) and (self <= other)
|
|
65
|
+
|
|
66
|
+
@setdoc.basic
|
|
67
|
+
def __ne__(self: Self, other: Any, /) -> bool:
|
|
68
|
+
return not (self == other)
|
|
69
|
+
|
|
70
|
+
@setdoc.basic
|
|
71
|
+
def __repr__(self: Self, /) -> str:
|
|
72
|
+
return datarepr(type(self).__name__, self._data)
|
|
73
|
+
|
|
74
|
+
@setdoc.basic
|
|
75
|
+
def __reversed__(self: Self, /) -> reversed:
|
|
76
|
+
return reversed(self._data)
|
|
77
|
+
|
|
78
|
+
@setdoc.basic
|
|
79
|
+
def __str__(self: Self, /) -> str:
|
|
80
|
+
return repr(self)
|
|
81
|
+
|
|
82
|
+
@setdoc.basic
|
|
83
|
+
def copy(self: Self, /) -> Self:
|
|
84
|
+
return type(self)(self.data)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import collections
|
|
2
|
+
from typing import *
|
|
3
|
+
|
|
4
|
+
import setdoc
|
|
5
|
+
from frozendict import frozendict
|
|
6
|
+
|
|
7
|
+
from datahold.core.HoldDict import HoldDict
|
|
8
|
+
from datahold.core.OkayABC import OkayABC
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"OkayDict",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class OkayDict(OkayABC, HoldDict):
|
|
16
|
+
__slots__ = ()
|
|
17
|
+
|
|
18
|
+
data: frozendict
|
|
19
|
+
|
|
20
|
+
@setdoc.basic
|
|
21
|
+
def __init__(self: Self, data: Iterable = (), /, **kwargs: Any) -> None:
|
|
22
|
+
self.data = dict(data, **kwargs)
|
|
23
|
+
|
|
24
|
+
@setdoc.basic
|
|
25
|
+
def __or__(self: Self, other: Any, /) -> Self:
|
|
26
|
+
return type(self)(self._data | dict(other))
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
def fromkeys(cls: type, iterable: Iterable, value: Any = None, /) -> Self:
|
|
30
|
+
"This classmethod creates a new instance with keys from iterable and values set to value."
|
|
31
|
+
return cls(dict.fromkeys(iterable, value))
|
|
32
|
+
|
|
33
|
+
def get(self: Self, /, *args: Any) -> Any:
|
|
34
|
+
"This method returns self[key] if key is in the dictionary, and default otherwise."
|
|
35
|
+
return self._data.get(*args)
|
|
36
|
+
|
|
37
|
+
def items(self: Self, /) -> collections.abc.ItemsView:
|
|
38
|
+
"This method returns a view of the items of the current instance."
|
|
39
|
+
return self._data.items()
|
|
40
|
+
|
|
41
|
+
def keys(self: Self, /) -> collections.abc.KeysView:
|
|
42
|
+
"This method returns a view of the keys of the current instance."
|
|
43
|
+
return self._data.keys()
|
|
44
|
+
|
|
45
|
+
def values(self: Self, /) -> collections.abc.ValuesView:
|
|
46
|
+
"This method returns a view of the values of the current instance."
|
|
47
|
+
return self._data.values()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from typing import *
|
|
2
|
+
|
|
3
|
+
import setdoc
|
|
4
|
+
|
|
5
|
+
from datahold.core.HoldList import HoldList
|
|
6
|
+
from datahold.core.OkayABC import OkayABC
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"OkayList",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class OkayList(OkayABC, HoldList):
|
|
14
|
+
__slots__ = ()
|
|
15
|
+
data: tuple
|
|
16
|
+
|
|
17
|
+
@setdoc.basic
|
|
18
|
+
def __add__(self: Self, other: Any, /) -> Self:
|
|
19
|
+
return type(self)(self._data + list(other))
|
|
20
|
+
|
|
21
|
+
@setdoc.basic
|
|
22
|
+
def __init__(self: Self, data: Iterable = ()) -> None:
|
|
23
|
+
self.data = data
|
|
24
|
+
|
|
25
|
+
@setdoc.basic
|
|
26
|
+
def __mul__(self: Self, value: SupportsIndex, /) -> Self:
|
|
27
|
+
return type(self)(self.data * value)
|
|
28
|
+
|
|
29
|
+
@setdoc.basic
|
|
30
|
+
def __rmul__(self: Self, value: SupportsIndex, /) -> Self:
|
|
31
|
+
return self * value
|
|
32
|
+
|
|
33
|
+
def count(self: Self, value: Any, /) -> int:
|
|
34
|
+
"This method returns the number of occurences of value."
|
|
35
|
+
return self._data.count(value)
|
|
36
|
+
|
|
37
|
+
def index(self: Self, /, *args: Any) -> int:
|
|
38
|
+
"This method returns the index of the first occurence of value, or raises a ValueError if value is not present."
|
|
39
|
+
return self._data.index(*args)
|