omlish 0.0.0.dev143__py3-none-any.whl → 0.0.0.dev145__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.
- omlish/__about__.py +2 -2
- omlish/collections/cache/impl.py +50 -57
- omlish/defs.py +1 -1
- omlish/lite/fdio/corohttp.py +2 -2
- omlish/lite/fdio/handlers.py +2 -2
- omlish/lite/fdio/kqueue.py +8 -8
- omlish/lite/fdio/manager.py +7 -7
- omlish/lite/fdio/pollers.py +13 -13
- omlish/lite/marshal.py +73 -53
- omlish/manifests/__init__.py +2 -0
- omlish/manifests/load.py +165 -0
- omlish/manifests/types.py +17 -0
- {omlish-0.0.0.dev143.dist-info → omlish-0.0.0.dev145.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev143.dist-info → omlish-0.0.0.dev145.dist-info}/RECORD +18 -15
- {omlish-0.0.0.dev143.dist-info → omlish-0.0.0.dev145.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev143.dist-info → omlish-0.0.0.dev145.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev143.dist-info → omlish-0.0.0.dev145.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev143.dist-info → omlish-0.0.0.dev145.dist-info}/top_level.txt +0 -0
omlish/__about__.py
CHANGED
omlish/collections/cache/impl.py
CHANGED
@@ -51,63 +51,56 @@ class CacheImpl(Cache[K, V]):
|
|
51
51
|
https://google.github.io/guava/releases/16.0/api/docs/com/google/common/cache/CacheBuilder.html
|
52
52
|
"""
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
f'value={self.value!r}, '
|
105
|
-
f'weight={self.weight}, '
|
106
|
-
f'written={self.written}, '
|
107
|
-
f'accessed={self.accessed}, '
|
108
|
-
f'hits={self.hits}, '
|
109
|
-
f'unlinked={self.unlinked})'
|
110
|
-
)
|
54
|
+
class Link:
|
55
|
+
__slots__ = [
|
56
|
+
'seq',
|
57
|
+
'ins_prev',
|
58
|
+
'ins_next',
|
59
|
+
'lru_prev',
|
60
|
+
'lru_next',
|
61
|
+
'lfu_prev',
|
62
|
+
'lfu_next',
|
63
|
+
'key',
|
64
|
+
'value',
|
65
|
+
'weight',
|
66
|
+
'written',
|
67
|
+
'accessed',
|
68
|
+
'hits',
|
69
|
+
'unlinked',
|
70
|
+
]
|
71
|
+
|
72
|
+
seq: int
|
73
|
+
ins_prev: 'CacheImpl.Link'
|
74
|
+
ins_next: 'CacheImpl.Link'
|
75
|
+
lru_prev: 'CacheImpl.Link'
|
76
|
+
lru_next: 'CacheImpl.Link'
|
77
|
+
lfu_prev: 'CacheImpl.Link'
|
78
|
+
lfu_next: 'CacheImpl.Link'
|
79
|
+
key: ta.Any | weakref.ref
|
80
|
+
value: ta.Any | weakref.ref
|
81
|
+
weight: float
|
82
|
+
written: float
|
83
|
+
accessed: float
|
84
|
+
hits: int
|
85
|
+
unlinked: bool
|
86
|
+
|
87
|
+
def __repr__(self) -> str:
|
88
|
+
return (
|
89
|
+
f'Link@{self.seq!s}('
|
90
|
+
f'ins_prev={("@" + str(self.ins_prev.seq)) if self.ins_prev is not None else None}, '
|
91
|
+
f'ins_next={("@" + str(self.ins_next.seq)) if self.ins_next is not None else None}, '
|
92
|
+
f'lru_prev={("@" + str(self.lru_prev.seq)) if self.lru_prev is not None else None}, '
|
93
|
+
f'lru_next={("@" + str(self.lru_next.seq)) if self.lru_next is not None else None}, '
|
94
|
+
f'lfu_prev={("@" + str(self.lfu_prev.seq)) if self.lfu_prev is not None else None}, '
|
95
|
+
f'lfu_next={("@" + str(self.lfu_next.seq)) if self.lfu_next is not None else None}, '
|
96
|
+
f'key={self.key!r}, '
|
97
|
+
f'value={self.value!r}, '
|
98
|
+
f'weight={self.weight}, '
|
99
|
+
f'written={self.written}, '
|
100
|
+
f'accessed={self.accessed}, '
|
101
|
+
f'hits={self.hits}, '
|
102
|
+
f'unlinked={self.unlinked})'
|
103
|
+
)
|
111
104
|
|
112
105
|
_cache: ta.MutableMapping[ta.Any, Link]
|
113
106
|
|
omlish/defs.py
CHANGED
@@ -199,7 +199,7 @@ def abstract_method(cls_dct, *names):
|
|
199
199
|
|
200
200
|
@lang.cls_dct_fn()
|
201
201
|
def abstract_property(cls_dct, *names):
|
202
|
-
return not_implemented(cls_dct, *names, wrapper=abc.abstractmethod)
|
202
|
+
return not_implemented(cls_dct, *names, wrapper=lambda o: property(abc.abstractmethod(o)))
|
203
203
|
|
204
204
|
|
205
205
|
@lang.cls_dct_fn()
|
omlish/lite/fdio/corohttp.py
CHANGED
@@ -11,10 +11,10 @@ from ..http.handlers import HttpHandler
|
|
11
11
|
from ..io import IncrementalWriteBuffer
|
12
12
|
from ..io import ReadableListBuffer
|
13
13
|
from ..socket import SocketAddress
|
14
|
-
from .handlers import
|
14
|
+
from .handlers import SocketFdioHandler
|
15
15
|
|
16
16
|
|
17
|
-
class
|
17
|
+
class CoroHttpServerConnectionFdioHandler(SocketFdioHandler):
|
18
18
|
def __init__(
|
19
19
|
self,
|
20
20
|
addr: SocketAddress,
|
omlish/lite/fdio/handlers.py
CHANGED
@@ -7,7 +7,7 @@ from ..check import check_not_none
|
|
7
7
|
from ..socket import SocketAddress
|
8
8
|
|
9
9
|
|
10
|
-
class
|
10
|
+
class FdioHandler(abc.ABC):
|
11
11
|
@abc.abstractmethod
|
12
12
|
def fd(self) -> int:
|
13
13
|
raise NotImplementedError
|
@@ -43,7 +43,7 @@ class FdIoHandler(abc.ABC):
|
|
43
43
|
pass
|
44
44
|
|
45
45
|
|
46
|
-
class
|
46
|
+
class SocketFdioHandler(FdioHandler, abc.ABC):
|
47
47
|
def __init__(
|
48
48
|
self,
|
49
49
|
addr: SocketAddress,
|
omlish/lite/fdio/kqueue.py
CHANGED
@@ -4,13 +4,13 @@ import select
|
|
4
4
|
import sys
|
5
5
|
import typing as ta
|
6
6
|
|
7
|
-
from .pollers import
|
7
|
+
from .pollers import FdioPoller
|
8
8
|
|
9
9
|
|
10
|
-
|
10
|
+
KqueueFdioPoller: ta.Optional[ta.Type[FdioPoller]]
|
11
11
|
if sys.platform == 'darwin' or sys.platform.startswith('freebsd'):
|
12
12
|
|
13
|
-
class
|
13
|
+
class _KqueueFdioPoller(FdioPoller):
|
14
14
|
DEFAULT_MAX_EVENTS = 1000
|
15
15
|
|
16
16
|
def __init__(
|
@@ -98,14 +98,14 @@ if sys.platform == 'darwin' or sys.platform.startswith('freebsd'):
|
|
98
98
|
|
99
99
|
#
|
100
100
|
|
101
|
-
def poll(self, timeout: ta.Optional[float]) ->
|
101
|
+
def poll(self, timeout: ta.Optional[float]) -> FdioPoller.PollResult:
|
102
102
|
kq = self._get_kqueue()
|
103
103
|
try:
|
104
104
|
kes = kq.control(None, self._max_events, timeout)
|
105
105
|
|
106
106
|
except OSError as exc:
|
107
107
|
if exc.errno == errno.EINTR:
|
108
|
-
return
|
108
|
+
return FdioPoller.PollResult(msg='EINTR encountered in poll', exc=exc)
|
109
109
|
else:
|
110
110
|
raise
|
111
111
|
|
@@ -117,8 +117,8 @@ if sys.platform == 'darwin' or sys.platform.startswith('freebsd'):
|
|
117
117
|
if ke.filter == select.KQ_FILTER_WRITE:
|
118
118
|
w.append(ke.ident)
|
119
119
|
|
120
|
-
return
|
120
|
+
return FdioPoller.PollResult(r, w)
|
121
121
|
|
122
|
-
|
122
|
+
KqueueFdioPoller = _KqueueFdioPoller
|
123
123
|
else:
|
124
|
-
|
124
|
+
KqueueFdioPoller = None
|
omlish/lite/fdio/manager.py
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
2
|
import typing as ta
|
3
3
|
|
4
|
-
from .handlers import
|
5
|
-
from .pollers import
|
4
|
+
from .handlers import FdioHandler
|
5
|
+
from .pollers import FdioPoller
|
6
6
|
|
7
7
|
|
8
|
-
class
|
8
|
+
class FdioManager:
|
9
9
|
def __init__(
|
10
10
|
self,
|
11
|
-
poller:
|
11
|
+
poller: FdioPoller,
|
12
12
|
) -> None:
|
13
13
|
super().__init__()
|
14
14
|
|
15
15
|
self._poller = poller
|
16
16
|
|
17
|
-
self._handlers: ta.Dict[int,
|
17
|
+
self._handlers: ta.Dict[int, FdioHandler] = {} # Preserves insertion order
|
18
18
|
|
19
|
-
def register(self, h:
|
19
|
+
def register(self, h: FdioHandler) -> None:
|
20
20
|
if (hid := id(h)) in self._handlers:
|
21
21
|
raise KeyError(h)
|
22
22
|
self._handlers[hid] = h
|
23
23
|
|
24
|
-
def unregister(self, h:
|
24
|
+
def unregister(self, h: FdioHandler) -> None:
|
25
25
|
del self._handlers[id(h)]
|
26
26
|
|
27
27
|
def poll(self, *, timeout: float = 1.) -> None:
|
omlish/lite/fdio/pollers.py
CHANGED
@@ -9,7 +9,7 @@ import typing as ta
|
|
9
9
|
##
|
10
10
|
|
11
11
|
|
12
|
-
class
|
12
|
+
class FdioPoller(abc.ABC):
|
13
13
|
def __init__(self) -> None:
|
14
14
|
super().__init__()
|
15
15
|
|
@@ -120,8 +120,8 @@ class FdIoPoller(abc.ABC):
|
|
120
120
|
##
|
121
121
|
|
122
122
|
|
123
|
-
class
|
124
|
-
def poll(self, timeout: ta.Optional[float]) ->
|
123
|
+
class SelectFdioPoller(FdioPoller):
|
124
|
+
def poll(self, timeout: ta.Optional[float]) -> FdioPoller.PollResult:
|
125
125
|
try:
|
126
126
|
r, w, x = select.select(
|
127
127
|
self._readable,
|
@@ -132,22 +132,22 @@ class SelectFdIoPoller(FdIoPoller):
|
|
132
132
|
|
133
133
|
except OSError as exc:
|
134
134
|
if exc.errno == errno.EINTR:
|
135
|
-
return
|
135
|
+
return FdioPoller.PollResult(msg='EINTR encountered in poll', exc=exc)
|
136
136
|
elif exc.errno == errno.EBADF:
|
137
|
-
return
|
137
|
+
return FdioPoller.PollResult(msg='EBADF encountered in poll', exc=exc)
|
138
138
|
else:
|
139
139
|
raise
|
140
140
|
|
141
|
-
return
|
141
|
+
return FdioPoller.PollResult(r, w)
|
142
142
|
|
143
143
|
|
144
144
|
##
|
145
145
|
|
146
146
|
|
147
|
-
|
147
|
+
PollFdioPoller: ta.Optional[ta.Type[FdioPoller]]
|
148
148
|
if hasattr(select, 'poll'):
|
149
149
|
|
150
|
-
class
|
150
|
+
class _PollFdioPoller(FdioPoller):
|
151
151
|
def __init__(self) -> None:
|
152
152
|
super().__init__()
|
153
153
|
|
@@ -180,14 +180,14 @@ if hasattr(select, 'poll'):
|
|
180
180
|
|
181
181
|
#
|
182
182
|
|
183
|
-
def poll(self, timeout: ta.Optional[float]) ->
|
183
|
+
def poll(self, timeout: ta.Optional[float]) -> FdioPoller.PollResult:
|
184
184
|
polled: ta.List[ta.Tuple[int, int]]
|
185
185
|
try:
|
186
186
|
polled = self._poller.poll(timeout * 1000 if timeout is not None else None)
|
187
187
|
|
188
188
|
except OSError as exc:
|
189
189
|
if exc.errno == errno.EINTR:
|
190
|
-
return
|
190
|
+
return FdioPoller.PollResult(msg='EINTR encountered in poll', exc=exc)
|
191
191
|
else:
|
192
192
|
raise
|
193
193
|
|
@@ -205,8 +205,8 @@ if hasattr(select, 'poll'):
|
|
205
205
|
r.append(fd)
|
206
206
|
if mask & self._WRITE:
|
207
207
|
w.append(fd)
|
208
|
-
return
|
208
|
+
return FdioPoller.PollResult(r, w, inv=inv)
|
209
209
|
|
210
|
-
|
210
|
+
PollFdioPoller = _PollFdioPoller
|
211
211
|
else:
|
212
|
-
|
212
|
+
PollFdioPoller = None
|
omlish/lite/marshal.py
CHANGED
@@ -35,23 +35,24 @@ T = ta.TypeVar('T')
|
|
35
35
|
@dc.dataclass(frozen=True)
|
36
36
|
class ObjMarshalOptions:
|
37
37
|
raw_bytes: bool = False
|
38
|
+
nonstrict_dataclasses: bool = False
|
38
39
|
|
39
40
|
|
40
41
|
class ObjMarshaler(abc.ABC):
|
41
42
|
@abc.abstractmethod
|
42
|
-
def marshal(self, o: ta.Any,
|
43
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
43
44
|
raise NotImplementedError
|
44
45
|
|
45
46
|
@abc.abstractmethod
|
46
|
-
def unmarshal(self, o: ta.Any,
|
47
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
47
48
|
raise NotImplementedError
|
48
49
|
|
49
50
|
|
50
51
|
class NopObjMarshaler(ObjMarshaler):
|
51
|
-
def marshal(self, o: ta.Any,
|
52
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
52
53
|
return o
|
53
54
|
|
54
|
-
def unmarshal(self, o: ta.Any,
|
55
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
55
56
|
return o
|
56
57
|
|
57
58
|
|
@@ -59,29 +60,29 @@ class NopObjMarshaler(ObjMarshaler):
|
|
59
60
|
class ProxyObjMarshaler(ObjMarshaler):
|
60
61
|
m: ta.Optional[ObjMarshaler] = None
|
61
62
|
|
62
|
-
def marshal(self, o: ta.Any,
|
63
|
-
return check_not_none(self.m).marshal(o,
|
63
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
64
|
+
return check_not_none(self.m).marshal(o, ctx)
|
64
65
|
|
65
|
-
def unmarshal(self, o: ta.Any,
|
66
|
-
return check_not_none(self.m).unmarshal(o,
|
66
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
67
|
+
return check_not_none(self.m).unmarshal(o, ctx)
|
67
68
|
|
68
69
|
|
69
70
|
@dc.dataclass(frozen=True)
|
70
71
|
class CastObjMarshaler(ObjMarshaler):
|
71
72
|
ty: type
|
72
73
|
|
73
|
-
def marshal(self, o: ta.Any,
|
74
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
74
75
|
return o
|
75
76
|
|
76
|
-
def unmarshal(self, o: ta.Any,
|
77
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
77
78
|
return self.ty(o)
|
78
79
|
|
79
80
|
|
80
81
|
class DynamicObjMarshaler(ObjMarshaler):
|
81
|
-
def marshal(self, o: ta.Any,
|
82
|
-
return marshal_obj(o)
|
82
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
83
|
+
return ctx.manager.marshal_obj(o, opts=ctx.options)
|
83
84
|
|
84
|
-
def unmarshal(self, o: ta.Any,
|
85
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
85
86
|
return o
|
86
87
|
|
87
88
|
|
@@ -89,10 +90,10 @@ class DynamicObjMarshaler(ObjMarshaler):
|
|
89
90
|
class Base64ObjMarshaler(ObjMarshaler):
|
90
91
|
ty: type
|
91
92
|
|
92
|
-
def marshal(self, o: ta.Any,
|
93
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
93
94
|
return base64.b64encode(o).decode('ascii')
|
94
95
|
|
95
|
-
def unmarshal(self, o: ta.Any,
|
96
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
96
97
|
return self.ty(base64.b64decode(o))
|
97
98
|
|
98
99
|
|
@@ -100,25 +101,25 @@ class Base64ObjMarshaler(ObjMarshaler):
|
|
100
101
|
class BytesSwitchedObjMarshaler(ObjMarshaler):
|
101
102
|
m: ObjMarshaler
|
102
103
|
|
103
|
-
def marshal(self, o: ta.Any,
|
104
|
-
if
|
104
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
105
|
+
if ctx.options.raw_bytes:
|
105
106
|
return o
|
106
|
-
return self.m.marshal(o,
|
107
|
+
return self.m.marshal(o, ctx)
|
107
108
|
|
108
|
-
def unmarshal(self, o: ta.Any,
|
109
|
-
if
|
109
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
110
|
+
if ctx.options.raw_bytes:
|
110
111
|
return o
|
111
|
-
return self.m.unmarshal(o,
|
112
|
+
return self.m.unmarshal(o, ctx)
|
112
113
|
|
113
114
|
|
114
115
|
@dc.dataclass(frozen=True)
|
115
116
|
class EnumObjMarshaler(ObjMarshaler):
|
116
117
|
ty: type
|
117
118
|
|
118
|
-
def marshal(self, o: ta.Any,
|
119
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
119
120
|
return o.name
|
120
121
|
|
121
|
-
def unmarshal(self, o: ta.Any,
|
122
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
122
123
|
return self.ty.__members__[o] # type: ignore
|
123
124
|
|
124
125
|
|
@@ -126,15 +127,15 @@ class EnumObjMarshaler(ObjMarshaler):
|
|
126
127
|
class OptionalObjMarshaler(ObjMarshaler):
|
127
128
|
item: ObjMarshaler
|
128
129
|
|
129
|
-
def marshal(self, o: ta.Any,
|
130
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
130
131
|
if o is None:
|
131
132
|
return None
|
132
|
-
return self.item.marshal(o,
|
133
|
+
return self.item.marshal(o, ctx)
|
133
134
|
|
134
|
-
def unmarshal(self, o: ta.Any,
|
135
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
135
136
|
if o is None:
|
136
137
|
return None
|
137
|
-
return self.item.unmarshal(o,
|
138
|
+
return self.item.unmarshal(o, ctx)
|
138
139
|
|
139
140
|
|
140
141
|
@dc.dataclass(frozen=True)
|
@@ -143,11 +144,11 @@ class MappingObjMarshaler(ObjMarshaler):
|
|
143
144
|
km: ObjMarshaler
|
144
145
|
vm: ObjMarshaler
|
145
146
|
|
146
|
-
def marshal(self, o: ta.Any,
|
147
|
-
return {self.km.marshal(k,
|
147
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
148
|
+
return {self.km.marshal(k, ctx): self.vm.marshal(v, ctx) for k, v in o.items()}
|
148
149
|
|
149
|
-
def unmarshal(self, o: ta.Any,
|
150
|
-
return self.ty((self.km.unmarshal(k,
|
150
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
151
|
+
return self.ty((self.km.unmarshal(k, ctx), self.vm.unmarshal(v, ctx)) for k, v in o.items())
|
151
152
|
|
152
153
|
|
153
154
|
@dc.dataclass(frozen=True)
|
@@ -155,11 +156,11 @@ class IterableObjMarshaler(ObjMarshaler):
|
|
155
156
|
ty: type
|
156
157
|
item: ObjMarshaler
|
157
158
|
|
158
|
-
def marshal(self, o: ta.Any,
|
159
|
-
return [self.item.marshal(e,
|
159
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
160
|
+
return [self.item.marshal(e, ctx) for e in o]
|
160
161
|
|
161
|
-
def unmarshal(self, o: ta.Any,
|
162
|
-
return self.ty(self.item.unmarshal(e,
|
162
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
163
|
+
return self.ty(self.item.unmarshal(e, ctx) for e in o)
|
163
164
|
|
164
165
|
|
165
166
|
@dc.dataclass(frozen=True)
|
@@ -168,11 +169,18 @@ class DataclassObjMarshaler(ObjMarshaler):
|
|
168
169
|
fs: ta.Mapping[str, ObjMarshaler]
|
169
170
|
nonstrict: bool = False
|
170
171
|
|
171
|
-
def marshal(self, o: ta.Any,
|
172
|
-
return {
|
172
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
173
|
+
return {
|
174
|
+
k: m.marshal(getattr(o, k), ctx)
|
175
|
+
for k, m in self.fs.items()
|
176
|
+
}
|
173
177
|
|
174
|
-
def unmarshal(self, o: ta.Any,
|
175
|
-
return self.ty(**{
|
178
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
179
|
+
return self.ty(**{
|
180
|
+
k: self.fs[k].unmarshal(v, ctx)
|
181
|
+
for k, v in o.items()
|
182
|
+
if not (self.nonstrict or ctx.options.nonstrict_dataclasses) or k in self.fs
|
183
|
+
})
|
176
184
|
|
177
185
|
|
178
186
|
@dc.dataclass(frozen=True)
|
@@ -192,50 +200,50 @@ class PolymorphicObjMarshaler(ObjMarshaler):
|
|
192
200
|
{i.tag: i for i in impls},
|
193
201
|
)
|
194
202
|
|
195
|
-
def marshal(self, o: ta.Any,
|
203
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
196
204
|
impl = self.impls_by_ty[type(o)]
|
197
|
-
return {impl.tag: impl.m.marshal(o,
|
205
|
+
return {impl.tag: impl.m.marshal(o, ctx)}
|
198
206
|
|
199
|
-
def unmarshal(self, o: ta.Any,
|
207
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
200
208
|
[(t, v)] = o.items()
|
201
209
|
impl = self.impls_by_tag[t]
|
202
|
-
return impl.m.unmarshal(v,
|
210
|
+
return impl.m.unmarshal(v, ctx)
|
203
211
|
|
204
212
|
|
205
213
|
@dc.dataclass(frozen=True)
|
206
214
|
class DatetimeObjMarshaler(ObjMarshaler):
|
207
215
|
ty: type
|
208
216
|
|
209
|
-
def marshal(self, o: ta.Any,
|
217
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
210
218
|
return o.isoformat()
|
211
219
|
|
212
|
-
def unmarshal(self, o: ta.Any,
|
220
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
213
221
|
return self.ty.fromisoformat(o) # type: ignore
|
214
222
|
|
215
223
|
|
216
224
|
class DecimalObjMarshaler(ObjMarshaler):
|
217
|
-
def marshal(self, o: ta.Any,
|
225
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
218
226
|
return str(check_isinstance(o, decimal.Decimal))
|
219
227
|
|
220
|
-
def unmarshal(self, v: ta.Any,
|
228
|
+
def unmarshal(self, v: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
221
229
|
return decimal.Decimal(check_isinstance(v, str))
|
222
230
|
|
223
231
|
|
224
232
|
class FractionObjMarshaler(ObjMarshaler):
|
225
|
-
def marshal(self, o: ta.Any,
|
233
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
226
234
|
fr = check_isinstance(o, fractions.Fraction)
|
227
235
|
return [fr.numerator, fr.denominator]
|
228
236
|
|
229
|
-
def unmarshal(self, v: ta.Any,
|
237
|
+
def unmarshal(self, v: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
230
238
|
num, denom = check_isinstance(v, list)
|
231
239
|
return fractions.Fraction(num, denom)
|
232
240
|
|
233
241
|
|
234
242
|
class UuidObjMarshaler(ObjMarshaler):
|
235
|
-
def marshal(self, o: ta.Any,
|
243
|
+
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
236
244
|
return str(o)
|
237
245
|
|
238
|
-
def unmarshal(self, o: ta.Any,
|
246
|
+
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
239
247
|
return uuid.UUID(o)
|
240
248
|
|
241
249
|
|
@@ -396,6 +404,12 @@ class ObjMarshalerManager:
|
|
396
404
|
|
397
405
|
#
|
398
406
|
|
407
|
+
def _make_context(self, opts: ta.Optional[ObjMarshalOptions]) -> 'ObjMarshalContext':
|
408
|
+
return ObjMarshalContext(
|
409
|
+
options=opts or self._default_options,
|
410
|
+
manager=self,
|
411
|
+
)
|
412
|
+
|
399
413
|
def marshal_obj(
|
400
414
|
self,
|
401
415
|
o: ta.Any,
|
@@ -403,7 +417,7 @@ class ObjMarshalerManager:
|
|
403
417
|
opts: ta.Optional[ObjMarshalOptions] = None,
|
404
418
|
) -> ta.Any:
|
405
419
|
m = self.get_obj_marshaler(ty if ty is not None else type(o))
|
406
|
-
return m.marshal(o,
|
420
|
+
return m.marshal(o, self._make_context(opts))
|
407
421
|
|
408
422
|
def unmarshal_obj(
|
409
423
|
self,
|
@@ -412,7 +426,7 @@ class ObjMarshalerManager:
|
|
412
426
|
opts: ta.Optional[ObjMarshalOptions] = None,
|
413
427
|
) -> T:
|
414
428
|
m = self.get_obj_marshaler(ty)
|
415
|
-
return m.unmarshal(o,
|
429
|
+
return m.unmarshal(o, self._make_context(opts))
|
416
430
|
|
417
431
|
def roundtrip_obj(
|
418
432
|
self,
|
@@ -427,6 +441,12 @@ class ObjMarshalerManager:
|
|
427
441
|
return u
|
428
442
|
|
429
443
|
|
444
|
+
@dc.dataclass(frozen=True)
|
445
|
+
class ObjMarshalContext:
|
446
|
+
options: ObjMarshalOptions
|
447
|
+
manager: ObjMarshalerManager
|
448
|
+
|
449
|
+
|
430
450
|
##
|
431
451
|
|
432
452
|
|
omlish/manifests/load.py
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
"""
|
3
|
+
Should be kept somewhat lightweight - used in cli entrypoints.
|
4
|
+
|
5
|
+
TODO:
|
6
|
+
- persisted caching support - {pkg_name: manifests}
|
7
|
+
"""
|
8
|
+
import dataclasses as dc
|
9
|
+
import importlib.machinery
|
10
|
+
import importlib.resources
|
11
|
+
import json
|
12
|
+
import typing as ta
|
13
|
+
|
14
|
+
from .types import Manifest
|
15
|
+
|
16
|
+
|
17
|
+
##
|
18
|
+
|
19
|
+
|
20
|
+
class ManifestLoader:
|
21
|
+
def __init__(
|
22
|
+
self,
|
23
|
+
*,
|
24
|
+
module_remap: ta.Optional[ta.Mapping[str, str]] = None,
|
25
|
+
) -> None:
|
26
|
+
super().__init__()
|
27
|
+
|
28
|
+
self._module_remap = module_remap or {}
|
29
|
+
self._module_reverse_remap = {v: k for k, v in self._module_remap.items()}
|
30
|
+
|
31
|
+
self._cls_cache: ta.Dict[str, type] = {}
|
32
|
+
self._raw_cache: ta.Dict[str, ta.Optional[ta.Sequence[Manifest]]] = {}
|
33
|
+
|
34
|
+
@classmethod
|
35
|
+
def from_entry_point(
|
36
|
+
cls,
|
37
|
+
globals: ta.Mapping[str, ta.Any], # noqa
|
38
|
+
*,
|
39
|
+
module_remap: ta.Optional[ta.Mapping[str, str]] = None,
|
40
|
+
**kwargs: ta.Any,
|
41
|
+
) -> 'ManifestLoader':
|
42
|
+
rm: ta.Dict[str, str] = {}
|
43
|
+
|
44
|
+
if module_remap:
|
45
|
+
rm.update(module_remap)
|
46
|
+
|
47
|
+
if '__name__' in globals and '__spec__' in globals:
|
48
|
+
name: str = globals['__name__']
|
49
|
+
spec: importlib.machinery.ModuleSpec = globals['__spec__']
|
50
|
+
if '__main__' not in rm and name == '__main__':
|
51
|
+
rm[spec.name] = '__main__'
|
52
|
+
|
53
|
+
return cls(module_remap=rm, **kwargs)
|
54
|
+
|
55
|
+
def load_cls(self, key: str) -> type:
|
56
|
+
try:
|
57
|
+
return self._cls_cache[key]
|
58
|
+
except KeyError:
|
59
|
+
pass
|
60
|
+
|
61
|
+
if not key.startswith('$'):
|
62
|
+
raise Exception(f'Bad key: {key}')
|
63
|
+
|
64
|
+
parts = key[1:].split('.')
|
65
|
+
pos = next(i for i, p in enumerate(parts) if p[0].isupper())
|
66
|
+
|
67
|
+
mod_name = '.'.join(parts[:pos])
|
68
|
+
mod_name = self._module_remap.get(mod_name, mod_name)
|
69
|
+
mod = importlib.import_module(mod_name)
|
70
|
+
|
71
|
+
obj: ta.Any = mod
|
72
|
+
for ca in parts[pos:]:
|
73
|
+
obj = getattr(obj, ca)
|
74
|
+
|
75
|
+
cls = obj
|
76
|
+
if not isinstance(cls, type):
|
77
|
+
raise TypeError(cls)
|
78
|
+
|
79
|
+
self._cls_cache[key] = cls
|
80
|
+
return cls
|
81
|
+
|
82
|
+
def load_contents(self, obj: ta.Any, pkg_name: str) -> ta.Sequence[Manifest]:
|
83
|
+
if not isinstance(obj, (list, tuple)):
|
84
|
+
raise TypeError(obj)
|
85
|
+
|
86
|
+
lst: ta.List[Manifest] = []
|
87
|
+
for e in obj:
|
88
|
+
m = Manifest(**e)
|
89
|
+
|
90
|
+
m = dc.replace(m, module=pkg_name + m.module)
|
91
|
+
|
92
|
+
[(key, value_dct)] = m.value.items()
|
93
|
+
if not key.startswith('$'):
|
94
|
+
raise Exception(f'Bad key: {key}')
|
95
|
+
if key.startswith('$.'):
|
96
|
+
key = f'${pkg_name}{key[1:]}'
|
97
|
+
m = dc.replace(m, value={key: value_dct})
|
98
|
+
|
99
|
+
lst.append(m)
|
100
|
+
|
101
|
+
return lst
|
102
|
+
|
103
|
+
def load_raw(self, pkg_name: str) -> ta.Optional[ta.Sequence[Manifest]]:
|
104
|
+
try:
|
105
|
+
return self._raw_cache[pkg_name]
|
106
|
+
except KeyError:
|
107
|
+
pass
|
108
|
+
|
109
|
+
t = importlib.resources.files(pkg_name).joinpath('.manifests.json')
|
110
|
+
if not t.is_file():
|
111
|
+
self._raw_cache[pkg_name] = None
|
112
|
+
return None
|
113
|
+
|
114
|
+
src = t.read_text('utf-8')
|
115
|
+
obj = json.loads(src)
|
116
|
+
if not isinstance(obj, (list, tuple)):
|
117
|
+
raise TypeError(obj)
|
118
|
+
|
119
|
+
lst = self.load_contents(obj, pkg_name)
|
120
|
+
|
121
|
+
self._raw_cache[pkg_name] = lst
|
122
|
+
return lst
|
123
|
+
|
124
|
+
def load(
|
125
|
+
self,
|
126
|
+
*pkg_names: str,
|
127
|
+
only: ta.Optional[ta.Iterable[type]] = None,
|
128
|
+
) -> ta.Sequence[Manifest]:
|
129
|
+
only_keys: ta.Optional[ta.Set]
|
130
|
+
if only is not None:
|
131
|
+
only_keys = set()
|
132
|
+
for cls in only:
|
133
|
+
if not (isinstance(cls, type) and dc.is_dataclass(cls)):
|
134
|
+
raise TypeError(cls)
|
135
|
+
mod_name = cls.__module__
|
136
|
+
mod_name = self._module_reverse_remap.get(mod_name, mod_name)
|
137
|
+
only_keys.add(f'${mod_name}.{cls.__qualname__}')
|
138
|
+
else:
|
139
|
+
only_keys = None
|
140
|
+
|
141
|
+
lst: ta.List[Manifest] = []
|
142
|
+
for pn in pkg_names:
|
143
|
+
for manifest in (self.load_raw(pn) or []):
|
144
|
+
[(key, value_dct)] = manifest.value.items()
|
145
|
+
if only_keys is not None and key not in only_keys:
|
146
|
+
continue
|
147
|
+
|
148
|
+
cls = self.load_cls(key)
|
149
|
+
value = cls(**value_dct)
|
150
|
+
|
151
|
+
manifest = dc.replace(manifest, value=value)
|
152
|
+
lst.append(manifest)
|
153
|
+
|
154
|
+
return lst
|
155
|
+
|
156
|
+
ENTRY_POINT_GROUP = 'omlish.manifests'
|
157
|
+
|
158
|
+
def discover(self) -> ta.Sequence[str]:
|
159
|
+
# This is a fat dep so do it late.
|
160
|
+
import importlib.metadata
|
161
|
+
|
162
|
+
return [
|
163
|
+
ep.value
|
164
|
+
for ep in importlib.metadata.entry_points(group=self.ENTRY_POINT_GROUP)
|
165
|
+
]
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
import dataclasses as dc
|
3
|
+
import typing as ta
|
4
|
+
|
5
|
+
|
6
|
+
@dc.dataclass(frozen=True)
|
7
|
+
class ManifestOrigin:
|
8
|
+
module: str
|
9
|
+
attr: str
|
10
|
+
|
11
|
+
file: str
|
12
|
+
line: int
|
13
|
+
|
14
|
+
|
15
|
+
@dc.dataclass(frozen=True)
|
16
|
+
class Manifest(ManifestOrigin):
|
17
|
+
value: ta.Any
|
@@ -1,12 +1,12 @@
|
|
1
1
|
omlish/.manifests.json,sha256=RX24SRc6DCEg77PUVnaXOKCWa5TF_c9RQJdGIf7gl9c,1135
|
2
|
-
omlish/__about__.py,sha256=
|
2
|
+
omlish/__about__.py,sha256=ieYHGoScBfXfGD-kByEU6wmcn_lSk7Wwsk1-v6y38jg,3409
|
3
3
|
omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
|
4
4
|
omlish/argparse.py,sha256=cqKGAqcxuxv_s62z0gq29L9KAvg_3-_rFvXKjVpRJjo,8126
|
5
5
|
omlish/c3.py,sha256=ubu7lHwss5V4UznbejAI0qXhXahrU01MysuHOZI9C4U,8116
|
6
6
|
omlish/cached.py,sha256=UI-XTFBwA6YXWJJJeBn-WkwBkfzDjLBBaZf4nIJA9y0,510
|
7
7
|
omlish/check.py,sha256=CBOCfl6ANZ7CKke2bGfQfUew9m22_ke0GvfEDO4Sjug,10595
|
8
8
|
omlish/datetimes.py,sha256=HajeM1kBvwlTa-uR1TTZHmZ3zTPnnUr1uGGQhiO1XQ0,2152
|
9
|
-
omlish/defs.py,sha256=
|
9
|
+
omlish/defs.py,sha256=9uUjJuVIbCBL3g14fyzAp-9gH935MFofvlfOGwcBIaM,4913
|
10
10
|
omlish/dynamic.py,sha256=35C_cCX_Vq2HrHzGk5T-zbrMvmUdiIiwDzDNixczoDo,6541
|
11
11
|
omlish/iterators.py,sha256=GGLC7RIT86uXMjhIIIqnff_Iu5SI_b9rXYywYGFyzmo,7292
|
12
12
|
omlish/libc.py,sha256=8r7Ejyhttk9ruCfBkxNTrlzir5WPbDE2vmY7VPlceMA,15362
|
@@ -110,7 +110,7 @@ omlish/collections/unmodifiable.py,sha256=QmUEi9IBXqiM_KGgH2rqg15VmkHJo1MZ6kwq2t
|
|
110
110
|
omlish/collections/utils.py,sha256=9o9STwzAn5YjZRZ9ns1kuo7NgLXLaoVPFu6AJd-3JT8,4336
|
111
111
|
omlish/collections/cache/__init__.py,sha256=D1gO71VcwxFTZP9gAc9isHfg_TEdalwhsJcgGLvS9hg,233
|
112
112
|
omlish/collections/cache/descriptor.py,sha256=t-1Gh4DTABDuNmeDJlpoW4LV3gi_uSlBd9ZfBINfYCM,5023
|
113
|
-
omlish/collections/cache/impl.py,sha256=
|
113
|
+
omlish/collections/cache/impl.py,sha256=ySRU9UJG7jH9VPvuXdwZQ_rSqrleY-1mtie5Ml738wY,14755
|
114
114
|
omlish/collections/cache/types.py,sha256=yNjwd6CGyTJQdxN2CQxFqqBAlcs1Z7vvNV-aU1K7p8E,685
|
115
115
|
omlish/concurrent/__init__.py,sha256=9p-s8MvBEYDqHIoYU3OYoe-Nni22QdkW7nhZGEukJTM,197
|
116
116
|
omlish/concurrent/executors.py,sha256=FYKCDYYuj-OgMa8quLsA47SfFNX3KDJvRENVk8NDsrA,1292
|
@@ -320,7 +320,7 @@ omlish/lite/io.py,sha256=3ECgUXdRnXyS6pGTSoVr6oB4moI38EpWxTq08zaTM-U,5339
|
|
320
320
|
omlish/lite/journald.py,sha256=f5Y2Q6-6O3iK_7MoGiwZwoQEOcP7LfkxxQNUR9tMjJM,3882
|
321
321
|
omlish/lite/json.py,sha256=7-02Ny4fq-6YAu5ynvqoijhuYXWpLmfCI19GUeZnb1c,740
|
322
322
|
omlish/lite/logs.py,sha256=1pcGu0ekhVCcLUckLSP16VccnAoprjtl5Vkdfm7y1Wg,6184
|
323
|
-
omlish/lite/marshal.py,sha256=
|
323
|
+
omlish/lite/marshal.py,sha256=1wqZWKapZ5rFgDxSkb447Xv2ce2SFEpiB1EMg1nh2BI,13530
|
324
324
|
omlish/lite/maybes.py,sha256=7OlHJ8Q2r4wQ-aRbZSlJY7x0e8gDvufFdlohGEIJ3P4,833
|
325
325
|
omlish/lite/pidfile.py,sha256=PRSDOAXmNkNwxh-Vwif0Nrs8RAmWroiNhLKIbdjwzBc,1723
|
326
326
|
omlish/lite/pycharm.py,sha256=CUArgzaG8ZZ0evN7tdrML5WXyF-G_BvF_s3Z4SI2LA0,1164
|
@@ -333,11 +333,11 @@ omlish/lite/strings.py,sha256=QURcE4-1pKVW8eT_5VCJpXaHDWR2dW2pYOChTJnZDiQ,1504
|
|
333
333
|
omlish/lite/subprocesses.py,sha256=1we1S-YQ9kbH36hPWLoh6zKZUARRnq2__ewtX_dVdWU,3633
|
334
334
|
omlish/lite/typing.py,sha256=U3-JaEnkDSYxK4tsu_MzUn3RP6qALBe5FXQXpD-licE,1090
|
335
335
|
omlish/lite/fdio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
336
|
-
omlish/lite/fdio/corohttp.py,sha256=
|
337
|
-
omlish/lite/fdio/handlers.py,sha256=
|
338
|
-
omlish/lite/fdio/kqueue.py,sha256=
|
339
|
-
omlish/lite/fdio/manager.py,sha256
|
340
|
-
omlish/lite/fdio/pollers.py,sha256=
|
336
|
+
omlish/lite/fdio/corohttp.py,sha256=FHdakDTGI2UYbCihahuwleyailclxQMUGhpkz3suww4,4080
|
337
|
+
omlish/lite/fdio/handlers.py,sha256=Wr0O2cvIC8NuLs3yoDHj9ZG4n1g_oVEeT87B0WDsg0Y,1341
|
338
|
+
omlish/lite/fdio/kqueue.py,sha256=YgGBQibkAUYODYDiGl7Enjtx1oQsJXuDsBLBXgqlLQw,3832
|
339
|
+
omlish/lite/fdio/manager.py,sha256=q4wWf7nKrNtjx6yPEvrVnFt4UtK_BTvVlquEGw7poEo,1250
|
340
|
+
omlish/lite/fdio/pollers.py,sha256=yNadAt3W5wd90PFmd3vD77bq5QwoVb2A6SM2JjZpKRs,5507
|
341
341
|
omlish/lite/http/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
342
342
|
omlish/lite/http/coroserver.py,sha256=aBaYjP80yQHQxPxwi7PTYHub-fdRDKsMnB-tM8lBc2o,18095
|
343
343
|
omlish/lite/http/handlers.py,sha256=Yu0P3nqz-frklwCM2PbiWvoJNE-NqeTFLBvpNpqcdtA,753
|
@@ -350,6 +350,9 @@ omlish/logs/formatters.py,sha256=q79nMnR2mRIStPyGrydQHpYTXgC5HHptt8lH3W2Wwbs,671
|
|
350
350
|
omlish/logs/handlers.py,sha256=UpzUf3kWBBzWOnrtljoZsLjISw3Ix-ePz3Nsmp6lRgE,255
|
351
351
|
omlish/logs/noisy.py,sha256=Ubc-eTH6ZbGYsLfUUi69JAotwuUwzb-SJBeGo_0dIZI,348
|
352
352
|
omlish/logs/utils.py,sha256=MgGovbP0zUrZ3FGD3qYNQWn-l0jy0Y0bStcQvv5BOmQ,391
|
353
|
+
omlish/manifests/__init__.py,sha256=P2B0dpT8D7l5lJwRGPA92IcQj6oeXfd90X5-q9BJrKg,51
|
354
|
+
omlish/manifests/load.py,sha256=Wn0Orrs65rLdXneT7tlixX5Q5OXW460-zzw6IkAye7k,4788
|
355
|
+
omlish/manifests/types.py,sha256=d8bv5tknCJqclRfxCpao_8XxHo2yofhLpVHQTB-MfNw,260
|
353
356
|
omlish/marshal/__init__.py,sha256=iVA7n31L08Bdub6HKPvYOXVvDhk2CMA6rPeKDL_u1to,2298
|
354
357
|
omlish/marshal/any.py,sha256=e82OyYK3Emm1P1ClnsnxP7fIWC2iNVyW0H5nK4mLmWM,779
|
355
358
|
omlish/marshal/base.py,sha256=HEzfby-PgGzIhiRpBkFrkw5-hKacRSC5W_jwLjT8aYw,6740
|
@@ -500,9 +503,9 @@ omlish/text/glyphsplit.py,sha256=Ug-dPRO7x-OrNNr8g1y6DotSZ2KH0S-VcOmUobwa4B0,329
|
|
500
503
|
omlish/text/indent.py,sha256=6Jj6TFY9unaPa4xPzrnZemJ-fHsV53IamP93XGjSUHs,1274
|
501
504
|
omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
|
502
505
|
omlish/text/random.py,sha256=jNWpqiaKjKyTdMXC-pWAsSC10AAP-cmRRPVhm59ZWLk,194
|
503
|
-
omlish-0.0.0.
|
504
|
-
omlish-0.0.0.
|
505
|
-
omlish-0.0.0.
|
506
|
-
omlish-0.0.0.
|
507
|
-
omlish-0.0.0.
|
508
|
-
omlish-0.0.0.
|
506
|
+
omlish-0.0.0.dev145.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
507
|
+
omlish-0.0.0.dev145.dist-info/METADATA,sha256=cTjkGwAzowfyJvdka5HtKgx7n8uXvyJVJOesizuQ6_Q,4264
|
508
|
+
omlish-0.0.0.dev145.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
509
|
+
omlish-0.0.0.dev145.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
|
510
|
+
omlish-0.0.0.dev145.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
|
511
|
+
omlish-0.0.0.dev145.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|