omlish 0.0.0.dev144__py3-none-any.whl → 0.0.0.dev146__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
omlish/__about__.py CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev144'
2
- __revision__ = '4d901652b9972fb965683ca3ac965147536a9dd4'
1
+ __version__ = '0.0.0.dev146'
2
+ __revision__ = '3e5441b65738d0b3c80a43abb47b62f9ef5a6bee'
3
3
 
4
4
 
5
5
  #
@@ -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
- try:
55
- if not ta.TYPE_CHECKING:
56
- from ..._ext.cy.collections.cache import CacheLink as Link
57
- else:
58
- raise ImportError # noqa
59
-
60
- except ImportError:
61
- class Link:
62
- __slots__ = [
63
- 'seq',
64
- 'ins_prev',
65
- 'ins_next',
66
- 'lru_prev',
67
- 'lru_next',
68
- 'lfu_prev',
69
- 'lfu_next',
70
- 'key',
71
- 'value',
72
- 'weight',
73
- 'written',
74
- 'accessed',
75
- 'hits',
76
- 'unlinked',
77
- ]
78
-
79
- seq: int
80
- ins_prev: 'CacheImpl.Link'
81
- ins_next: 'CacheImpl.Link'
82
- lru_prev: 'CacheImpl.Link'
83
- lru_next: 'CacheImpl.Link'
84
- lfu_prev: 'CacheImpl.Link'
85
- lfu_next: 'CacheImpl.Link'
86
- key: ta.Any | weakref.ref
87
- value: ta.Any | weakref.ref
88
- weight: float
89
- written: float
90
- accessed: float
91
- hits: int
92
- unlinked: bool
93
-
94
- def __repr__(self) -> str:
95
- return (
96
- f'Link@{self.seq!s}('
97
- f'ins_prev={("@" + str(self.ins_prev.seq)) if self.ins_prev is not None else None}, '
98
- f'ins_next={("@" + str(self.ins_next.seq)) if self.ins_next is not None else None}, '
99
- f'lru_prev={("@" + str(self.lru_prev.seq)) if self.lru_prev is not None else None}, '
100
- f'lru_next={("@" + str(self.lru_next.seq)) if self.lru_next is not None else None}, '
101
- f'lfu_prev={("@" + str(self.lfu_prev.seq)) if self.lfu_prev is not None else None}, '
102
- f'lfu_next={("@" + str(self.lfu_next.seq)) if self.lfu_next is not None else None}, '
103
- f'key={self.key!r}, '
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()
@@ -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 SocketFdIoHandler
14
+ from .handlers import SocketFdioHandler
15
15
 
16
16
 
17
- class CoroHttpServerConnectionFdIoHandler(SocketFdIoHandler):
17
+ class CoroHttpServerConnectionFdioHandler(SocketFdioHandler):
18
18
  def __init__(
19
19
  self,
20
20
  addr: SocketAddress,
@@ -7,7 +7,7 @@ from ..check import check_not_none
7
7
  from ..socket import SocketAddress
8
8
 
9
9
 
10
- class FdIoHandler(abc.ABC):
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 SocketFdIoHandler(FdIoHandler, abc.ABC):
46
+ class SocketFdioHandler(FdioHandler, abc.ABC):
47
47
  def __init__(
48
48
  self,
49
49
  addr: SocketAddress,
@@ -4,13 +4,13 @@ import select
4
4
  import sys
5
5
  import typing as ta
6
6
 
7
- from .pollers import FdIoPoller
7
+ from .pollers import FdioPoller
8
8
 
9
9
 
10
- KqueueFdIoPoller: ta.Optional[ta.Type[FdIoPoller]]
10
+ KqueueFdioPoller: ta.Optional[ta.Type[FdioPoller]]
11
11
  if sys.platform == 'darwin' or sys.platform.startswith('freebsd'):
12
12
 
13
- class _KqueueFdIoPoller(FdIoPoller):
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]) -> FdIoPoller.PollResult:
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 FdIoPoller.PollResult(msg='EINTR encountered in poll', exc=exc)
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 FdIoPoller.PollResult(r, w)
120
+ return FdioPoller.PollResult(r, w)
121
121
 
122
- KqueueFdIoPoller = _KqueueFdIoPoller
122
+ KqueueFdioPoller = _KqueueFdioPoller
123
123
  else:
124
- KqueueFdIoPoller = None
124
+ KqueueFdioPoller = None
@@ -1,27 +1,27 @@
1
1
  # ruff: noqa: UP006 UP007
2
2
  import typing as ta
3
3
 
4
- from .handlers import FdIoHandler
5
- from .pollers import FdIoPoller
4
+ from .handlers import FdioHandler
5
+ from .pollers import FdioPoller
6
6
 
7
7
 
8
- class FdIoManager:
8
+ class FdioManager:
9
9
  def __init__(
10
10
  self,
11
- poller: FdIoPoller,
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, FdIoHandler] = {} # Preserves insertion order
17
+ self._handlers: ta.Dict[int, FdioHandler] = {} # Preserves insertion order
18
18
 
19
- def register(self, h: FdIoHandler) -> None:
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: FdIoHandler) -> None:
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:
@@ -9,7 +9,7 @@ import typing as ta
9
9
  ##
10
10
 
11
11
 
12
- class FdIoPoller(abc.ABC):
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 SelectFdIoPoller(FdIoPoller):
124
- def poll(self, timeout: ta.Optional[float]) -> FdIoPoller.PollResult:
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 FdIoPoller.PollResult(msg='EINTR encountered in poll', exc=exc)
135
+ return FdioPoller.PollResult(msg='EINTR encountered in poll', exc=exc)
136
136
  elif exc.errno == errno.EBADF:
137
- return FdIoPoller.PollResult(msg='EBADF encountered in poll', exc=exc)
137
+ return FdioPoller.PollResult(msg='EBADF encountered in poll', exc=exc)
138
138
  else:
139
139
  raise
140
140
 
141
- return FdIoPoller.PollResult(r, w)
141
+ return FdioPoller.PollResult(r, w)
142
142
 
143
143
 
144
144
  ##
145
145
 
146
146
 
147
- PollFdIoPoller: ta.Optional[ta.Type[FdIoPoller]]
147
+ PollFdioPoller: ta.Optional[ta.Type[FdioPoller]]
148
148
  if hasattr(select, 'poll'):
149
149
 
150
- class _PollFdIoPoller(FdIoPoller):
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]) -> FdIoPoller.PollResult:
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 FdIoPoller.PollResult(msg='EINTR encountered in poll', exc=exc)
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 FdIoPoller.PollResult(r, w, inv=inv)
208
+ return FdioPoller.PollResult(r, w, inv=inv)
209
209
 
210
- PollFdIoPoller = _PollFdIoPoller
210
+ PollFdioPoller = _PollFdioPoller
211
211
  else:
212
- PollFdIoPoller = None
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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> ta.Any:
63
- return check_not_none(self.m).marshal(o, opts)
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, opts: ObjMarshalOptions) -> ta.Any:
66
- return check_not_none(self.m).unmarshal(o, opts)
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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> ta.Any:
104
- if opts.raw_bytes:
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, opts)
107
+ return self.m.marshal(o, ctx)
107
108
 
108
- def unmarshal(self, o: ta.Any, opts: ObjMarshalOptions) -> ta.Any:
109
- if opts.raw_bytes:
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, opts)
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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts)
133
+ return self.item.marshal(o, ctx)
133
134
 
134
- def unmarshal(self, o: ta.Any, opts: ObjMarshalOptions) -> 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, opts)
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, opts: ObjMarshalOptions) -> ta.Any:
147
- return {self.km.marshal(k, opts): self.vm.marshal(v, opts) for k, v in o.items()}
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, opts: ObjMarshalOptions) -> ta.Any:
150
- return self.ty((self.km.unmarshal(k, opts), self.vm.unmarshal(v, opts)) for k, v in o.items())
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, opts: ObjMarshalOptions) -> ta.Any:
159
- return [self.item.marshal(e, opts) for e in o]
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, opts: ObjMarshalOptions) -> ta.Any:
162
- return self.ty(self.item.unmarshal(e, opts) for e in o)
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, opts: ObjMarshalOptions) -> ta.Any:
172
- return {k: m.marshal(getattr(o, k), opts) for k, m in self.fs.items()}
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, opts: ObjMarshalOptions) -> ta.Any:
175
- return self.ty(**{k: self.fs[k].unmarshal(v, opts) for k, v in o.items() if not self.nonstrict or k in self.fs})
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, opts: ObjMarshalOptions) -> 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, opts)}
205
+ return {impl.tag: impl.m.marshal(o, ctx)}
198
206
 
199
- def unmarshal(self, o: ta.Any, opts: ObjMarshalOptions) -> 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, opts)
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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts: ObjMarshalOptions) -> 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, opts or self._default_options)
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, opts or self._default_options)
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
 
@@ -0,0 +1,8 @@
1
+ def read_package_resource_binary(package: str, resource: str) -> bytes:
2
+ import importlib.resources
3
+ return importlib.resources.read_binary(package, resource)
4
+
5
+
6
+ def read_package_resource_text(package: str, resource: str) -> str:
7
+ import importlib.resources
8
+ return importlib.resources.read_text(package, resource)
@@ -0,0 +1,2 @@
1
+ # @omlish-lite
2
+ from .types import Manifest # noqa
@@ -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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omlish
3
- Version: 0.0.0.dev144
3
+ Version: 0.0.0.dev146
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -1,12 +1,12 @@
1
1
  omlish/.manifests.json,sha256=RX24SRc6DCEg77PUVnaXOKCWa5TF_c9RQJdGIf7gl9c,1135
2
- omlish/__about__.py,sha256=MT0BTpx7mPru-9X9bEnyKHLlujaF7_MenPp4KN78i3c,3409
2
+ omlish/__about__.py,sha256=G3zss6e134zxU5xmjngBc8mskjSdZxwZFcH8cUO87Sc,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=T3bq_7h_tO3nDB5RAFBn7DkdeQgqheXzkFColbOHZko,4890
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=nQox5kChhns9h2a5gnX-ayQGBQJ5-B1aZkLQ2Aej19g,15137
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,11 +320,12 @@ 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=a3_wuMjiCXHYngzgLhJU2C2BFznVC_VlrzRJ5_hpuRI,12989
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
327
327
  omlish/lite/reflect.py,sha256=ad_ya_zZJOQB8HoNjs9yc66R54zgflwJVPJqiBXMzqA,1681
328
+ omlish/lite/resources.py,sha256=YNSmX1Ohck1aoWRs55a-o5ChVbFJIQhtbqE-XwF55Oc,326
328
329
  omlish/lite/runtime.py,sha256=lVw5_yuQNHXZLwGf_l59u8IrAtBLZWPTml6owQ55uro,439
329
330
  omlish/lite/secrets.py,sha256=3Mz3V2jf__XU9qNHcH56sBSw95L3U2UPL24bjvobG0c,816
330
331
  omlish/lite/socket.py,sha256=7OYgkXTcQv0wq7TQuLnl9y6dJA1ZT6Vbc1JH59QlxgY,1792
@@ -333,11 +334,11 @@ omlish/lite/strings.py,sha256=QURcE4-1pKVW8eT_5VCJpXaHDWR2dW2pYOChTJnZDiQ,1504
333
334
  omlish/lite/subprocesses.py,sha256=1we1S-YQ9kbH36hPWLoh6zKZUARRnq2__ewtX_dVdWU,3633
334
335
  omlish/lite/typing.py,sha256=U3-JaEnkDSYxK4tsu_MzUn3RP6qALBe5FXQXpD-licE,1090
335
336
  omlish/lite/fdio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
336
- omlish/lite/fdio/corohttp.py,sha256=VuS4IaAluMPgtl9iQnMnKQsEMlqruN6B1BKkTV0WWKk,4080
337
- omlish/lite/fdio/handlers.py,sha256=ukUiwF8-UCr4mzTTfOaTipC0k3k7THiHnohVdYfH69o,1341
338
- omlish/lite/fdio/kqueue.py,sha256=lIWvvRpRyak0dmzE6FPtCdS02HGo0EEI0D1g8cWyLYk,3832
339
- omlish/lite/fdio/manager.py,sha256=-gMVzk4B1YTZS-d2TdM12woUme37pcNVUxNTiLe91lA,1250
340
- omlish/lite/fdio/pollers.py,sha256=d73P2ynzFdQZhmxhMKghzO6zvLwzTMSaIgBi7wQ5IQs,5507
337
+ omlish/lite/fdio/corohttp.py,sha256=FHdakDTGI2UYbCihahuwleyailclxQMUGhpkz3suww4,4080
338
+ omlish/lite/fdio/handlers.py,sha256=Wr0O2cvIC8NuLs3yoDHj9ZG4n1g_oVEeT87B0WDsg0Y,1341
339
+ omlish/lite/fdio/kqueue.py,sha256=YgGBQibkAUYODYDiGl7Enjtx1oQsJXuDsBLBXgqlLQw,3832
340
+ omlish/lite/fdio/manager.py,sha256=q4wWf7nKrNtjx6yPEvrVnFt4UtK_BTvVlquEGw7poEo,1250
341
+ omlish/lite/fdio/pollers.py,sha256=yNadAt3W5wd90PFmd3vD77bq5QwoVb2A6SM2JjZpKRs,5507
341
342
  omlish/lite/http/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
342
343
  omlish/lite/http/coroserver.py,sha256=aBaYjP80yQHQxPxwi7PTYHub-fdRDKsMnB-tM8lBc2o,18095
343
344
  omlish/lite/http/handlers.py,sha256=Yu0P3nqz-frklwCM2PbiWvoJNE-NqeTFLBvpNpqcdtA,753
@@ -350,6 +351,9 @@ omlish/logs/formatters.py,sha256=q79nMnR2mRIStPyGrydQHpYTXgC5HHptt8lH3W2Wwbs,671
350
351
  omlish/logs/handlers.py,sha256=UpzUf3kWBBzWOnrtljoZsLjISw3Ix-ePz3Nsmp6lRgE,255
351
352
  omlish/logs/noisy.py,sha256=Ubc-eTH6ZbGYsLfUUi69JAotwuUwzb-SJBeGo_0dIZI,348
352
353
  omlish/logs/utils.py,sha256=MgGovbP0zUrZ3FGD3qYNQWn-l0jy0Y0bStcQvv5BOmQ,391
354
+ omlish/manifests/__init__.py,sha256=P2B0dpT8D7l5lJwRGPA92IcQj6oeXfd90X5-q9BJrKg,51
355
+ omlish/manifests/load.py,sha256=Wn0Orrs65rLdXneT7tlixX5Q5OXW460-zzw6IkAye7k,4788
356
+ omlish/manifests/types.py,sha256=d8bv5tknCJqclRfxCpao_8XxHo2yofhLpVHQTB-MfNw,260
353
357
  omlish/marshal/__init__.py,sha256=iVA7n31L08Bdub6HKPvYOXVvDhk2CMA6rPeKDL_u1to,2298
354
358
  omlish/marshal/any.py,sha256=e82OyYK3Emm1P1ClnsnxP7fIWC2iNVyW0H5nK4mLmWM,779
355
359
  omlish/marshal/base.py,sha256=HEzfby-PgGzIhiRpBkFrkw5-hKacRSC5W_jwLjT8aYw,6740
@@ -500,9 +504,9 @@ omlish/text/glyphsplit.py,sha256=Ug-dPRO7x-OrNNr8g1y6DotSZ2KH0S-VcOmUobwa4B0,329
500
504
  omlish/text/indent.py,sha256=6Jj6TFY9unaPa4xPzrnZemJ-fHsV53IamP93XGjSUHs,1274
501
505
  omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
502
506
  omlish/text/random.py,sha256=jNWpqiaKjKyTdMXC-pWAsSC10AAP-cmRRPVhm59ZWLk,194
503
- omlish-0.0.0.dev144.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
504
- omlish-0.0.0.dev144.dist-info/METADATA,sha256=iSpb58aExr5aGcD3lhNq7BsAewClNKVvMdnbWH4u3sU,4264
505
- omlish-0.0.0.dev144.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
506
- omlish-0.0.0.dev144.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
507
- omlish-0.0.0.dev144.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
508
- omlish-0.0.0.dev144.dist-info/RECORD,,
507
+ omlish-0.0.0.dev146.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
508
+ omlish-0.0.0.dev146.dist-info/METADATA,sha256=V8cPQmzScS8Lnw8b-HzO9Pg_uvOnOaPZxPJ_yrzxTc8,4264
509
+ omlish-0.0.0.dev146.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
510
+ omlish-0.0.0.dev146.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
511
+ omlish-0.0.0.dev146.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
512
+ omlish-0.0.0.dev146.dist-info/RECORD,,