omlish 0.0.0.dev29__py3-none-any.whl → 0.0.0.dev30__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 +5 -5
- omlish/diag/replserver/server.py +1 -1
- omlish/fnpipes.py +82 -0
- omlish/http/sessions.py +2 -2
- omlish/lang/__init__.py +4 -0
- omlish/lang/classes/abstract.py +1 -1
- omlish/lang/contextmanagers.py +35 -0
- omlish/lang/resources.py +1 -0
- omlish/lang/strings.py +49 -1
- omlish/lite/logs.py +20 -5
- omlish/marshal/naming.py +5 -0
- omlish/marshal/polymorphism.py +20 -10
- omlish/os.py +17 -0
- omlish/specs/__init__.py +9 -0
- omlish/sql/__init__.py +0 -14
- omlish/sql/alchemy/__init__.py +13 -0
- omlish/sql/{asyncs.py → alchemy/asyncs.py} +1 -1
- omlish/sql/{duckdb.py → alchemy/duckdb.py} +1 -1
- omlish/sql/{secrets.py → alchemy/secrets.py} +1 -1
- omlish/testing/pytest/plugins/asyncs.py +5 -0
- {omlish-0.0.0.dev29.dist-info → omlish-0.0.0.dev30.dist-info}/METADATA +15 -15
- {omlish-0.0.0.dev29.dist-info → omlish-0.0.0.dev30.dist-info}/RECORD +27 -25
- /omlish/sql/{exprs.py → alchemy/exprs.py} +0 -0
- /omlish/sql/{sqlean.py → alchemy/sqlean.py} +0 -0
- {omlish-0.0.0.dev29.dist-info → omlish-0.0.0.dev30.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev29.dist-info → omlish-0.0.0.dev30.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev29.dist-info → omlish-0.0.0.dev30.dist-info}/top_level.txt +0 -0
omlish/__about__.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
__version__ = '0.0.0.
|
2
|
-
__revision__ = '
|
1
|
+
__version__ = '0.0.0.dev30'
|
2
|
+
__revision__ = '1378b0a61f7d3ec16204c06bc87e5215b062d378'
|
3
3
|
|
4
4
|
|
5
5
|
#
|
@@ -39,7 +39,7 @@ class Project(ProjectBase):
|
|
39
39
|
'trio-asyncio ~= 0.15',
|
40
40
|
],
|
41
41
|
|
42
|
-
'
|
42
|
+
'compress': [
|
43
43
|
'lz4 ~= 4.0',
|
44
44
|
|
45
45
|
'python-snappy ~= 0.7; python_version < "3.13"',
|
@@ -77,11 +77,11 @@ class Project(ProjectBase):
|
|
77
77
|
'cryptography ~= 43.0',
|
78
78
|
],
|
79
79
|
|
80
|
-
'
|
80
|
+
'sqlalchemy': [
|
81
81
|
'sqlalchemy[asyncio] ~= 2.0',
|
82
82
|
],
|
83
83
|
|
84
|
-
'
|
84
|
+
'sqlalchemy-drivers': [
|
85
85
|
'pg8000 ~= 1.31',
|
86
86
|
# 'psycopg2 ~= 2.9',
|
87
87
|
# 'psycopg ~= 3.2',
|
omlish/diag/replserver/server.py
CHANGED
@@ -9,7 +9,7 @@ TODO:
|
|
9
9
|
- optional ipython embed
|
10
10
|
- https://github.com/python/cpython/tree/56470004e58911b146c016fc9fec4461b8f69454/Lib/_pyrepl
|
11
11
|
|
12
|
-
|
12
|
+
See:
|
13
13
|
- https://github.com/vxgmichel/aioconsole/blob/e55f4b0601da3b3a40a88c965526d35ab38b5841/aioconsole/server.py
|
14
14
|
- https://github.com/nhoad/aiomanhole
|
15
15
|
- https://github.com/twisted/twisted/blob/00aa56f5257060304d41f09651c6ab58ee6104d6/src/twisted/conch/manhole.py
|
omlish/fnpipes.py
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
import abc
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
|
5
|
+
T = ta.TypeVar('T')
|
6
|
+
U = ta.TypeVar('U')
|
7
|
+
|
8
|
+
|
9
|
+
class Fn(abc.ABC, ta.Generic[T]):
|
10
|
+
@abc.abstractmethod
|
11
|
+
def __call__(self, *args: ta.Any, **kwargs: ta.Any) -> T:
|
12
|
+
raise NotImplementedError
|
13
|
+
|
14
|
+
def pipe(self, fn: ta.Callable[..., U], *args: ta.Any, **kwargs: ta.Any) -> 'Fn[U]':
|
15
|
+
return Pipe([self], Bind(fn, *args, **kwargs))
|
16
|
+
|
17
|
+
def __or__(self, fn: ta.Callable[..., U]) -> 'Fn[U]':
|
18
|
+
return self.pipe(fn)
|
19
|
+
|
20
|
+
def apply(self, fn: ta.Callable[[T], ta.Any], *args: ta.Any, **kwargs: ta.Any) -> 'Fn[T]':
|
21
|
+
return Pipe([self], Apply(Bind(fn, *args, **kwargs)))
|
22
|
+
|
23
|
+
def __and__(self, fn: ta.Callable[[T], ta.Any]) -> 'Fn[T]':
|
24
|
+
return self.apply(fn)
|
25
|
+
|
26
|
+
|
27
|
+
class Bind(Fn[T]):
|
28
|
+
def __init__(self, fn: ta.Callable[..., T], *args: ta.Any, **kwargs: ta.Any) -> None:
|
29
|
+
super().__init__()
|
30
|
+
if Ellipsis not in args and Ellipsis not in kwargs:
|
31
|
+
args += (Ellipsis,)
|
32
|
+
self._fn = fn
|
33
|
+
self._args = args
|
34
|
+
self._kwargs = kwargs
|
35
|
+
|
36
|
+
def __call__(self, *args: ta.Any, **kwargs: ta.Any) -> T:
|
37
|
+
fa: list = []
|
38
|
+
for a in self._args:
|
39
|
+
if a is Ellipsis:
|
40
|
+
fa.extend(args)
|
41
|
+
else:
|
42
|
+
fa.append(a)
|
43
|
+
|
44
|
+
fkw = {}
|
45
|
+
for k, v in self._kwargs.items():
|
46
|
+
if v is Ellipsis:
|
47
|
+
if len(args) != 1:
|
48
|
+
raise ValueError(args)
|
49
|
+
fkw[k] = args[0]
|
50
|
+
else:
|
51
|
+
fkw[k] = v
|
52
|
+
fkw.update(kwargs)
|
53
|
+
|
54
|
+
return self._fn(*fa, **fkw)
|
55
|
+
|
56
|
+
|
57
|
+
class Pipe(Fn[T]):
|
58
|
+
def __init__(self, lfns: ta.Sequence[ta.Callable], rfn: ta.Callable[..., T]) -> None:
|
59
|
+
super().__init__()
|
60
|
+
self._lfn, *self._rfns = [*lfns, rfn]
|
61
|
+
|
62
|
+
def __call__(self, *args: ta.Any, **kwargs: ta.Any) -> T:
|
63
|
+
o = self._lfn(*args, **kwargs)
|
64
|
+
for fn in self._rfns:
|
65
|
+
o = fn(o)
|
66
|
+
return o
|
67
|
+
|
68
|
+
|
69
|
+
class Apply(Fn[T]):
|
70
|
+
def __init__(self, *fns: ta.Callable[[T], ta.Any]) -> None:
|
71
|
+
super().__init__()
|
72
|
+
self._fns = fns
|
73
|
+
|
74
|
+
def __call__(self, o: T) -> T: # noqa
|
75
|
+
for fn in self._fns:
|
76
|
+
fn(o)
|
77
|
+
return o
|
78
|
+
|
79
|
+
|
80
|
+
bind = Bind
|
81
|
+
pipe = Pipe
|
82
|
+
apply = Apply
|
omlish/http/sessions.py
CHANGED
@@ -8,7 +8,7 @@ import time
|
|
8
8
|
import typing as ta
|
9
9
|
import zlib
|
10
10
|
|
11
|
-
from .. import fnpairs as
|
11
|
+
from .. import fnpairs as fpa
|
12
12
|
from .. import lang
|
13
13
|
from .. import secrets as sec
|
14
14
|
from .cookies import dump_cookie
|
@@ -92,7 +92,7 @@ class SessionMarshal:
|
|
92
92
|
def __init__(
|
93
93
|
self,
|
94
94
|
signer: Signer,
|
95
|
-
serializer:
|
95
|
+
serializer: fpa.ObjectStr = fpa.of(JSON_TAGGER.dumps, JSON_TAGGER.loads),
|
96
96
|
) -> None:
|
97
97
|
super().__init__()
|
98
98
|
|
omlish/lang/__init__.py
CHANGED
@@ -60,6 +60,7 @@ from .contextmanagers import ( # noqa
|
|
60
60
|
NOP_CONTEXT_MANAGER,
|
61
61
|
NopContextManaged,
|
62
62
|
NopContextManager,
|
63
|
+
Timer,
|
63
64
|
a_defer,
|
64
65
|
attr_setting,
|
65
66
|
breakpoint_on_exception,
|
@@ -188,8 +189,11 @@ from .strings import ( # noqa
|
|
188
189
|
is_ident_cont,
|
189
190
|
is_ident_start,
|
190
191
|
is_sunder,
|
192
|
+
prefix_delimited,
|
191
193
|
prefix_lines,
|
192
194
|
snake_case,
|
195
|
+
strip_prefix,
|
196
|
+
strip_suffix,
|
193
197
|
)
|
194
198
|
|
195
199
|
from .sys import ( # noqa
|
omlish/lang/classes/abstract.py
CHANGED
@@ -47,7 +47,7 @@ class Abstract(abc.ABC): # noqa
|
|
47
47
|
seen.update(dir(b))
|
48
48
|
if ams:
|
49
49
|
raise TypeError(
|
50
|
-
f'Cannot subclass abstract class {cls.__name__} with abstract methods'
|
50
|
+
f'Cannot subclass abstract class {cls.__name__} with abstract methods: '
|
51
51
|
f'{", ".join(map(str, sorted(ams)))}',
|
52
52
|
)
|
53
53
|
|
omlish/lang/contextmanagers.py
CHANGED
@@ -7,6 +7,7 @@ import contextlib
|
|
7
7
|
import contextvars
|
8
8
|
import functools
|
9
9
|
import threading
|
10
|
+
import time
|
10
11
|
import types
|
11
12
|
import typing as ta
|
12
13
|
|
@@ -367,3 +368,37 @@ def default_lock(value: DefaultLockable, default: DefaultLockable = None) -> Loc
|
|
367
368
|
|
368
369
|
else:
|
369
370
|
raise TypeError(value)
|
371
|
+
|
372
|
+
|
373
|
+
##
|
374
|
+
|
375
|
+
|
376
|
+
class Timer:
|
377
|
+
def __init__(
|
378
|
+
self,
|
379
|
+
clock: ta.Callable[[], float] | None = None,
|
380
|
+
) -> None:
|
381
|
+
super().__init__()
|
382
|
+
self._clock = clock if clock is not None else time.monotonic
|
383
|
+
|
384
|
+
_start: float
|
385
|
+
_end: float
|
386
|
+
|
387
|
+
@property
|
388
|
+
def start(self) -> float:
|
389
|
+
return self._start
|
390
|
+
|
391
|
+
@property
|
392
|
+
def end(self) -> float:
|
393
|
+
return self._end
|
394
|
+
|
395
|
+
@property
|
396
|
+
def elapsed(self) -> float:
|
397
|
+
return self._end - self._start
|
398
|
+
|
399
|
+
def __enter__(self) -> ta.Self:
|
400
|
+
self._start = self._clock()
|
401
|
+
return self
|
402
|
+
|
403
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
404
|
+
self._end = self._clock()
|
omlish/lang/resources.py
CHANGED
omlish/lang/strings.py
CHANGED
@@ -4,9 +4,22 @@ import unicodedata
|
|
4
4
|
|
5
5
|
##
|
6
6
|
|
7
|
+
@ta.overload
|
8
|
+
def prefix_delimited(s: str, p: str, d: str) -> str:
|
9
|
+
...
|
10
|
+
|
11
|
+
|
12
|
+
@ta.overload
|
13
|
+
def prefix_delimited(s: bytes, p: bytes, d: bytes) -> bytes:
|
14
|
+
...
|
15
|
+
|
16
|
+
|
17
|
+
def prefix_delimited(s, p, d):
|
18
|
+
return d.join([p + l for l in s.split(d)])
|
19
|
+
|
7
20
|
|
8
21
|
def prefix_lines(s: str, p: str) -> str:
|
9
|
-
return
|
22
|
+
return prefix_delimited(s, p, '\n')
|
10
23
|
|
11
24
|
|
12
25
|
def indent_lines(s: str, num: int) -> str:
|
@@ -16,6 +29,41 @@ def indent_lines(s: str, num: int) -> str:
|
|
16
29
|
##
|
17
30
|
|
18
31
|
|
32
|
+
@ta.overload
|
33
|
+
def strip_prefix(s: str, pfx: str) -> str:
|
34
|
+
...
|
35
|
+
|
36
|
+
|
37
|
+
@ta.overload
|
38
|
+
def strip_prefix(s: bytes, pfx: bytes) -> bytes:
|
39
|
+
...
|
40
|
+
|
41
|
+
|
42
|
+
def strip_prefix(s, pfx):
|
43
|
+
if not s.startswith(pfx):
|
44
|
+
raise ValueError(f'{s!r} does not start with {pfx!r}')
|
45
|
+
return s[len(pfx):]
|
46
|
+
|
47
|
+
|
48
|
+
@ta.overload
|
49
|
+
def strip_suffix(s: str, sfx: str) -> str:
|
50
|
+
...
|
51
|
+
|
52
|
+
|
53
|
+
@ta.overload
|
54
|
+
def strip_suffix(s: bytes, sfx: bytes) -> bytes:
|
55
|
+
...
|
56
|
+
|
57
|
+
|
58
|
+
def strip_suffix(s, sfx):
|
59
|
+
if not s.endswith(sfx):
|
60
|
+
raise ValueError(f'{s!r} does not end with {sfx!r}')
|
61
|
+
return s[:-len(sfx)]
|
62
|
+
|
63
|
+
|
64
|
+
##
|
65
|
+
|
66
|
+
|
19
67
|
def camel_case(name: str) -> str:
|
20
68
|
return ''.join(map(str.capitalize, name.split('_'))) # noqa
|
21
69
|
|
omlish/lite/logs.py
CHANGED
@@ -4,6 +4,7 @@ TODO:
|
|
4
4
|
- debug
|
5
5
|
"""
|
6
6
|
# ruff: noqa: UP006 UP007 N802
|
7
|
+
import contextlib
|
7
8
|
import datetime
|
8
9
|
import logging
|
9
10
|
import threading
|
@@ -203,6 +204,24 @@ class StandardLogHandler(ProxyLogHandler):
|
|
203
204
|
##
|
204
205
|
|
205
206
|
|
207
|
+
@contextlib.contextmanager
|
208
|
+
def _locking_logging_module_lock() -> ta.Iterator[None]:
|
209
|
+
if hasattr(logging, '_acquireLock'):
|
210
|
+
logging._acquireLock() # noqa
|
211
|
+
try:
|
212
|
+
yield
|
213
|
+
finally:
|
214
|
+
logging._releaseLock() # type: ignore # noqa
|
215
|
+
|
216
|
+
elif hasattr(logging, '_lock'):
|
217
|
+
# https://github.com/python/cpython/commit/74723e11109a320e628898817ab449b3dad9ee96
|
218
|
+
with logging._lock: # noqa
|
219
|
+
yield
|
220
|
+
|
221
|
+
else:
|
222
|
+
raise Exception("Can't find lock in logging module")
|
223
|
+
|
224
|
+
|
206
225
|
def configure_standard_logging(
|
207
226
|
level: ta.Union[int, str] = logging.INFO,
|
208
227
|
*,
|
@@ -210,8 +229,7 @@ def configure_standard_logging(
|
|
210
229
|
target: ta.Optional[logging.Logger] = None,
|
211
230
|
force: bool = False,
|
212
231
|
) -> ta.Optional[StandardLogHandler]:
|
213
|
-
|
214
|
-
try:
|
232
|
+
with _locking_logging_module_lock():
|
215
233
|
if target is None:
|
216
234
|
target = logging.root
|
217
235
|
|
@@ -250,6 +268,3 @@ def configure_standard_logging(
|
|
250
268
|
#
|
251
269
|
|
252
270
|
return StandardLogHandler(handler)
|
253
|
-
|
254
|
-
finally:
|
255
|
-
logging._releaseLock() # type: ignore # noqa
|
omlish/marshal/naming.py
CHANGED
omlish/marshal/polymorphism.py
CHANGED
@@ -98,24 +98,34 @@ def polymorphism_from_subclasses(
|
|
98
98
|
ty: type,
|
99
99
|
*,
|
100
100
|
naming: Naming | None = None,
|
101
|
+
strip_suffix: bool = False,
|
101
102
|
) -> Polymorphism:
|
102
103
|
dct: dict[str, Impl] = {}
|
104
|
+
|
103
105
|
seen: set[type] = set()
|
104
106
|
todo: list[type] = [ty]
|
105
107
|
while todo:
|
106
108
|
cur = todo.pop()
|
107
109
|
seen.add(cur)
|
108
|
-
|
109
|
-
nam = cur.__name__
|
110
|
-
if naming is not None:
|
111
|
-
nam = translate_name(nam, naming)
|
112
|
-
if nam in dct:
|
113
|
-
raise KeyError(f'Duplicate name: {nam}')
|
114
|
-
dct[nam] = Impl(
|
115
|
-
cur,
|
116
|
-
nam,
|
117
|
-
)
|
110
|
+
|
118
111
|
todo.extend(nxt for nxt in cur.__subclasses__() if nxt not in seen)
|
112
|
+
|
113
|
+
if lang.is_abstract_class(cur):
|
114
|
+
continue
|
115
|
+
|
116
|
+
name = cur.__name__
|
117
|
+
if strip_suffix:
|
118
|
+
name = lang.strip_suffix(name, ty.__name__)
|
119
|
+
if naming is not None:
|
120
|
+
name = translate_name(name, naming)
|
121
|
+
if name in dct:
|
122
|
+
raise KeyError(f'Duplicate name: {name}')
|
123
|
+
|
124
|
+
dct[name] = Impl(
|
125
|
+
cur,
|
126
|
+
name,
|
127
|
+
)
|
128
|
+
|
119
129
|
return Polymorphism(ty, dct.values())
|
120
130
|
|
121
131
|
|
omlish/os.py
CHANGED
@@ -103,3 +103,20 @@ class Pidfile:
|
|
103
103
|
def kill(self, sig: int = signal.SIGTERM) -> None:
|
104
104
|
pid = self.read()
|
105
105
|
os.kill(pid, sig) # Still racy
|
106
|
+
|
107
|
+
|
108
|
+
def touch(self, mode: int = 0o666, exist_ok: bool = True) -> None:
|
109
|
+
if exist_ok:
|
110
|
+
# First try to bump modification time
|
111
|
+
# Implementation note: GNU touch uses the UTIME_NOW option of the utimensat() / futimens() functions.
|
112
|
+
try:
|
113
|
+
os.utime(self, None)
|
114
|
+
except OSError:
|
115
|
+
pass
|
116
|
+
else:
|
117
|
+
return
|
118
|
+
flags = os.O_CREAT | os.O_WRONLY
|
119
|
+
if not exist_ok:
|
120
|
+
flags |= os.O_EXCL
|
121
|
+
fd = os.open(self, flags, mode)
|
122
|
+
os.close(fd)
|
omlish/specs/__init__.py
CHANGED
omlish/sql/__init__.py
CHANGED
@@ -1,13 +1,3 @@
|
|
1
|
-
from .asyncs import ( # noqa
|
2
|
-
AsyncConnection,
|
3
|
-
AsyncConnectionLike,
|
4
|
-
AsyncEngine,
|
5
|
-
AsyncEngineLike,
|
6
|
-
AsyncTransaction,
|
7
|
-
AsyncTransactionLike,
|
8
|
-
async_adapt,
|
9
|
-
)
|
10
|
-
|
11
1
|
from .dbs import ( # noqa
|
12
2
|
DbLoc,
|
13
3
|
DbSpec,
|
@@ -17,10 +7,6 @@ from .dbs import ( # noqa
|
|
17
7
|
UrlDbLoc,
|
18
8
|
)
|
19
9
|
|
20
|
-
from .exprs import ( # noqa
|
21
|
-
paren,
|
22
|
-
)
|
23
|
-
|
24
10
|
from .qualifiedname import ( # noqa
|
25
11
|
QualifiedName,
|
26
12
|
qn,
|
@@ -111,6 +111,11 @@ class AsyncsPlugin:
|
|
111
111
|
else:
|
112
112
|
return
|
113
113
|
|
114
|
+
if 'trio_asyncio' in bes:
|
115
|
+
# NOTE: Importing it here is apparently necessary to get its patching working - otherwise fails later with
|
116
|
+
# `no running event loop` in anyio._backends._asyncio and such.
|
117
|
+
import trio_asyncio # noqa
|
118
|
+
|
114
119
|
if pdu.is_present():
|
115
120
|
pdu.patch_for_trio_asyncio()
|
116
121
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: omlish
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev30
|
4
4
|
Summary: omlish
|
5
5
|
Author: wrmsr
|
6
6
|
License: BSD-3-Clause
|
@@ -47,10 +47,10 @@ Requires-Dist: sniffio ~=1.3 ; extra == 'async'
|
|
47
47
|
Requires-Dist: greenlet ~=3.1 ; extra == 'async'
|
48
48
|
Requires-Dist: trio ~=0.26 ; extra == 'async'
|
49
49
|
Requires-Dist: trio-asyncio ~=0.15 ; extra == 'async'
|
50
|
-
Provides-Extra:
|
51
|
-
Requires-Dist: lz4 ~=4.0 ; extra == '
|
52
|
-
Requires-Dist: zstd ~=1.5 ; extra == '
|
53
|
-
Requires-Dist: python-snappy ~=0.7 ; (python_version < "3.13") and extra == '
|
50
|
+
Provides-Extra: compress
|
51
|
+
Requires-Dist: lz4 ~=4.0 ; extra == 'compress'
|
52
|
+
Requires-Dist: zstd ~=1.5 ; extra == 'compress'
|
53
|
+
Requires-Dist: python-snappy ~=0.7 ; (python_version < "3.13") and extra == 'compress'
|
54
54
|
Provides-Extra: diag
|
55
55
|
Requires-Dist: asttokens ~=2.4 ; extra == 'diag'
|
56
56
|
Requires-Dist: executing ~=2.1 ; extra == 'diag'
|
@@ -67,16 +67,16 @@ Provides-Extra: misc
|
|
67
67
|
Requires-Dist: wrapt ~=1.14 ; extra == 'misc'
|
68
68
|
Provides-Extra: secrets
|
69
69
|
Requires-Dist: cryptography ~=43.0 ; extra == 'secrets'
|
70
|
-
Provides-Extra:
|
71
|
-
Requires-Dist: sqlalchemy[asyncio] ~=2.0 ; extra == '
|
72
|
-
Provides-Extra:
|
73
|
-
Requires-Dist: pg8000 ~=1.31 ; extra == '
|
74
|
-
Requires-Dist: pymysql ~=1.1 ; extra == '
|
75
|
-
Requires-Dist: aiomysql ~=0.2 ; extra == '
|
76
|
-
Requires-Dist: aiosqlite ~=0.20 ; extra == '
|
77
|
-
Requires-Dist: duckdb ~=1.1 ; extra == '
|
78
|
-
Requires-Dist: asyncpg ~=0.29 ; (python_version < "3.13") and extra == '
|
79
|
-
Requires-Dist: sqlean.py ~=3.45 ; (python_version < "3.13") and extra == '
|
70
|
+
Provides-Extra: sqlalchemy
|
71
|
+
Requires-Dist: sqlalchemy[asyncio] ~=2.0 ; extra == 'sqlalchemy'
|
72
|
+
Provides-Extra: sqlalchemy-drivers
|
73
|
+
Requires-Dist: pg8000 ~=1.31 ; extra == 'sqlalchemy-drivers'
|
74
|
+
Requires-Dist: pymysql ~=1.1 ; extra == 'sqlalchemy-drivers'
|
75
|
+
Requires-Dist: aiomysql ~=0.2 ; extra == 'sqlalchemy-drivers'
|
76
|
+
Requires-Dist: aiosqlite ~=0.20 ; extra == 'sqlalchemy-drivers'
|
77
|
+
Requires-Dist: duckdb ~=1.1 ; extra == 'sqlalchemy-drivers'
|
78
|
+
Requires-Dist: asyncpg ~=0.29 ; (python_version < "3.13") and extra == 'sqlalchemy-drivers'
|
79
|
+
Requires-Dist: sqlean.py ~=3.45 ; (python_version < "3.13") and extra == 'sqlalchemy-drivers'
|
80
80
|
Provides-Extra: testing
|
81
81
|
Requires-Dist: pytest ~=8.0 ; extra == 'testing'
|
82
82
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
omlish/.manifests.json,sha256=N1F-Xz3GaBn2H1p7uKzhkhKCQV8QVR0t76XD6wmFtXA,3
|
2
|
-
omlish/__about__.py,sha256=
|
2
|
+
omlish/__about__.py,sha256=fDFLSSMSxswk3iOzGDNumjsP4JcRrkaXRbp8w77f4ok,2709
|
3
3
|
omlish/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
omlish/argparse.py,sha256=QRQmX9G0-L_nATkFtGHvpd4qrpYzKATdjuFLbBqzJPM,6224
|
5
5
|
omlish/c3.py,sha256=W5EwYx9Por3rWYLkKUitJ6OoRMLLgVTfLTyroOz41Y0,8047
|
@@ -10,12 +10,13 @@ omlish/defs.py,sha256=T3bq_7h_tO3nDB5RAFBn7DkdeQgqheXzkFColbOHZko,4890
|
|
10
10
|
omlish/docker.py,sha256=wipM7Xsx7rUv7-PoBTTT2v0uk3JVan0USljgm2QesXg,6227
|
11
11
|
omlish/dynamic.py,sha256=35C_cCX_Vq2HrHzGk5T-zbrMvmUdiIiwDzDNixczoDo,6541
|
12
12
|
omlish/fnpairs.py,sha256=hVuLqQFdRNNze3FYH2cAQO3GC7nK5yQP_GWPUSbL7nE,10601
|
13
|
+
omlish/fnpipes.py,sha256=AJkgz9nvRRm7oqw7ZgYyz21klu276LWi54oYCLg-vOg,2196
|
13
14
|
omlish/genmachine.py,sha256=LCMiqvK32dAWtrlB6lKw9tXdQFiXC8rRdk4TMQYIroU,1603
|
14
15
|
omlish/iterators.py,sha256=GGLC7RIT86uXMjhIIIqnff_Iu5SI_b9rXYywYGFyzmo,7292
|
15
16
|
omlish/libc.py,sha256=u0481imCiTFqP_e-v9g0pD-0WD249j5vYzhtn-fnNkY,15308
|
16
17
|
omlish/matchfns.py,sha256=ygqbqthRxgF9I1PJaw9Xl7FoZnAVMmnKBrYgimKQ0ag,6152
|
17
18
|
omlish/multiprocessing.py,sha256=QZT4C7I-uThCAjaEY3xgUYb-5GagUlnE4etN01LDyU4,5186
|
18
|
-
omlish/os.py,sha256=
|
19
|
+
omlish/os.py,sha256=vO1sZCzAhVxo46tDFLrD52q2KuMFWQwu5MPJgSsnliI,3107
|
19
20
|
omlish/runmodule.py,sha256=PWvuAaJ9wQQn6bx9ftEL3_d04DyotNn8dR_twm2pgw0,700
|
20
21
|
omlish/sync.py,sha256=AqwIfIuCMVHLwlJUa7dmaSjfA4sM5AYPCD5-nsz3XVQ,1516
|
21
22
|
omlish/term.py,sha256=NEmxqAhicyInGtmFamZAizI2xdu819MzFYPEp0Fx97M,6111
|
@@ -101,7 +102,7 @@ omlish/diag/threads.py,sha256=1-x02VCDZ407gfbtXm1pWK-ubqhqfePm9PMqkHCVoqk,3642
|
|
101
102
|
omlish/diag/replserver/__init__.py,sha256=uLo6V2aQ29v9z3IMELlPDSlG3_2iOT4-_X8VniF-EgE,235
|
102
103
|
omlish/diag/replserver/__main__.py,sha256=LmU41lQ58bm1h4Mx7S8zhE_uEBSC6kPcp9mn5JRpulA,32
|
103
104
|
omlish/diag/replserver/console.py,sha256=XzBDVhYlr8FY6ym4OwoaIHuFOHnGK3dTYlMDIOMUUlA,7410
|
104
|
-
omlish/diag/replserver/server.py,sha256=
|
105
|
+
omlish/diag/replserver/server.py,sha256=5pRjBn-Vz8gtu45756ycdbJe58C_xrB9rElPytr6h5g,5345
|
105
106
|
omlish/dispatch/__init__.py,sha256=GsiGJ91NKiQptSROtnCSkrZExBkvfDwYvdoTu5dBqF0,117
|
106
107
|
omlish/dispatch/_dispatch2.py,sha256=v3tCNyxGpOwY8qTwdp54TlM8mG6OVwtQoUZfYJ_griU,1756
|
107
108
|
omlish/dispatch/_dispatch3.py,sha256=Vnu5DfoPWFJLodudBqoZBXGTi2wYk-Az56MXJgdQvwc,2608
|
@@ -130,7 +131,7 @@ omlish/http/cookies.py,sha256=uuOYlHR6e2SC3GM41V0aozK10nef9tYg83Scqpn5-HM,6351
|
|
130
131
|
omlish/http/dates.py,sha256=Otgp8wRxPgNGyzx8LFowu1vC4EKJYARCiAwLFncpfHM,2875
|
131
132
|
omlish/http/encodings.py,sha256=w2WoKajpaZnQH8j-IBvk5ZFL2O2pAU_iBvZnkocaTlw,164
|
132
133
|
omlish/http/json.py,sha256=9XwAsl4966Mxrv-1ytyCqhcE6lbBJw-0_tFZzGszgHE,7440
|
133
|
-
omlish/http/sessions.py,sha256=
|
134
|
+
omlish/http/sessions.py,sha256=VZ_WS5uiQG5y7i3u8oKuQMqf8dPKUOjFm_qk_0OvI8c,4793
|
134
135
|
omlish/http/wsgi.py,sha256=czZsVUX-l2YTlMrUjKN49wRoP4rVpS0qpeBn4O5BoMY,948
|
135
136
|
omlish/inject/__init__.py,sha256=JQ7x8l9MjU-kJ5ap7cPVq7SY7zbbCIrjyJAF0UeE5-s,1886
|
136
137
|
omlish/inject/binder.py,sha256=H8AQ4ecmBOtDL8fMgrU1yUJl1gBADLNcdysRbvO8Wso,4167
|
@@ -162,11 +163,11 @@ omlish/inject/impl/privates.py,sha256=alpCYyk5VJ9lJknbRH2nLVNFYVvFhkj-VC1Vco3zCF
|
|
162
163
|
omlish/inject/impl/providers.py,sha256=QnwhsujJFIHC0JTgd2Wlo1kP53i3CWTrj1nKU2DNxwg,2375
|
163
164
|
omlish/inject/impl/proxy.py,sha256=1ko0VaKqzu9UG8bIldp9xtUrAVUOFTKWKTjOCqIGr4s,1636
|
164
165
|
omlish/inject/impl/scopes.py,sha256=ASfULXgP_ETlsAqFJfrZmyEaZt64Zr8tNn5ScA-EoXk,5900
|
165
|
-
omlish/lang/__init__.py,sha256=
|
166
|
+
omlish/lang/__init__.py,sha256=0OCNjiSSyFL3RSNtakj0ILhC1K2P2WJkDTAgkC7xMjA,3601
|
166
167
|
omlish/lang/cached.py,sha256=LwsgWQjQ5op618rBvI8vbASOEGWDTt_SKq6Tc1vlgZM,7680
|
167
168
|
omlish/lang/clsdct.py,sha256=AjtIWLlx2E6D5rC97zQ3Lwq2SOMkbg08pdO_AxpzEHI,1744
|
168
169
|
omlish/lang/cmp.py,sha256=5vbzWWbqdzDmNKAGL19z6ZfUKe5Ci49e-Oegf9f4BsE,1346
|
169
|
-
omlish/lang/contextmanagers.py,sha256=
|
170
|
+
omlish/lang/contextmanagers.py,sha256=NEwaTLQMfhKawD5x_0HgI2RpeLXbMa5r9NqWqfDnUXI,10408
|
170
171
|
omlish/lang/datetimes.py,sha256=ehI_DhQRM-bDxAavnp470XcekbbXc4Gdw9y1KpHDJT0,223
|
171
172
|
omlish/lang/descriptors.py,sha256=OLM1qi14kY7PLGIJnvkd6CBEOzHgD9q8Cs2cB6Kzflk,6602
|
172
173
|
omlish/lang/exceptions.py,sha256=qJBo3NU1mOWWm-NhQUHCY5feYXR3arZVyEHinLsmRH4,47
|
@@ -176,13 +177,13 @@ omlish/lang/iterables.py,sha256=_q6rHbdFfW3VBqez0IV3rUABoNxsA_oBv_sykm5zsbQ,2243
|
|
176
177
|
omlish/lang/maybes.py,sha256=NYHZDjqDtwPMheDrj2VtUVujxRPf8Qpgk4ZlZCTvBZc,3492
|
177
178
|
omlish/lang/objects.py,sha256=1dY8dX5voIZf5FBYUiN0BRsWg2JCdsgRbDl9fLG7OtY,4310
|
178
179
|
omlish/lang/resolving.py,sha256=OuN2mDTPNyBUbcrswtvFKtj4xgH4H4WglgqSKv3MTy0,1606
|
179
|
-
omlish/lang/resources.py,sha256
|
180
|
-
omlish/lang/strings.py,sha256=
|
180
|
+
omlish/lang/resources.py,sha256=-NmVTrSMKFZ6smVfOMz46ekZYVGgYh8cPooxQlFpG6s,2135
|
181
|
+
omlish/lang/strings.py,sha256=LqxR49cF5owHKpbUX8nUIBPsZ-4w7xqHPhlB-HIWqUg,3628
|
181
182
|
omlish/lang/sys.py,sha256=UoZz_PJYVKLQAKqYxxn-LHz1okK_38I__maZgnXMcxU,406
|
182
183
|
omlish/lang/timeouts.py,sha256=vECdWYhc_IZgcal1Ng1Y42wf2FV3KAx-i8As-MgGHIQ,1186
|
183
184
|
omlish/lang/typing.py,sha256=lJ2NGe4Pmb61I0Tx4A_rOqXNFTws1XHOzafg2knRUio,4155
|
184
185
|
omlish/lang/classes/__init__.py,sha256=h9QXrvAKD17_pIog0uF-7BCqZbSpJZYxL7kzVzvljp0,583
|
185
|
-
omlish/lang/classes/abstract.py,sha256=
|
186
|
+
omlish/lang/classes/abstract.py,sha256=IRnjuLLNwpxvEJsp8fwoQdCIpw0MDAd0TiQfoDMgsn4,2306
|
186
187
|
omlish/lang/classes/restrict.py,sha256=pSK7ZT_kpwqS6lWRrxwuEe-tt07F0-uZVazgGh-HDco,3921
|
187
188
|
omlish/lang/classes/simple.py,sha256=JkWYrRWnSKil6kVMgXgRMJeCxkFHXQIKIzYtG1jK2Pk,3067
|
188
189
|
omlish/lang/classes/virtual.py,sha256=W-QJuKsDehOcrydwg6eMN0bFPTYbk3Tz84TSH3blb44,3367
|
@@ -199,7 +200,7 @@ omlish/lite/cached.py,sha256=dUm647FbIsoxWT23XUFM51F7i-C2Buxr5b5zzgbCtQI,546
|
|
199
200
|
omlish/lite/check.py,sha256=DYxkYkxpnQpjGpDwW_8M8YBXbswvnBUCr0UBPU7aNKo,642
|
200
201
|
omlish/lite/contextmanagers.py,sha256=HnQJiyrOmSvTL22XRJrFl5CLpCyHD9fsntEUAr9G-60,427
|
201
202
|
omlish/lite/json.py,sha256=7-02Ny4fq-6YAu5ynvqoijhuYXWpLmfCI19GUeZnb1c,740
|
202
|
-
omlish/lite/logs.py,sha256=
|
203
|
+
omlish/lite/logs.py,sha256=vkFkSX0Izb2P-NNMqqNLSec0BzeLOtHoQWgdXwQuDPU,6007
|
203
204
|
omlish/lite/marshal.py,sha256=u6jYUN_AndvI6__HJBvSw5ElHWC0CfHqgiDS28Vpqjg,8593
|
204
205
|
omlish/lite/reflect.py,sha256=9QYJwdINraq1JNMEgvoqeSlVvRRgOXpxAkpgX8EgRXc,1307
|
205
206
|
omlish/lite/runtime.py,sha256=VUhmNQvwf8QzkWSKj4Q0ReieJA_PzHaJNRBivfTseow,452
|
@@ -228,11 +229,11 @@ omlish/marshal/helpers.py,sha256=YA0pNo-Fkc-_qKeoRNXUpP36js8oelU7uENkvoGD4hY,120
|
|
228
229
|
omlish/marshal/iterables.py,sha256=6I_ZdJemLSQtJ4J5NrB9wi-eyxiJZS61HzHXp1yeiX8,2592
|
229
230
|
omlish/marshal/mappings.py,sha256=zhLtyot7tzQtBNj7C4RBxjMELxA5r2q2Mth8Br7xkFs,2803
|
230
231
|
omlish/marshal/maybes.py,sha256=tKkVsJATERgbVcEfBnsHBK_2_LCQIVyBzca-cA-9KH0,2112
|
231
|
-
omlish/marshal/naming.py,sha256=
|
232
|
+
omlish/marshal/naming.py,sha256=lIklR_Od4x1ghltAgOzqcKhHs-leeSv2YmFhCHO7GIs,613
|
232
233
|
omlish/marshal/numbers.py,sha256=oY_yMNJEnJhjfLh89gpPXvKqeUyhQcaTcQB6ecyHiG8,1704
|
233
234
|
omlish/marshal/objects.py,sha256=R-NPCT1-UZhONTnrsrAvZvAtM2qyQsKZ8CPLfqkSg5g,4494
|
234
235
|
omlish/marshal/optionals.py,sha256=r0XB5rqfasvgZJNrKYd6Unq2U4nHt3JURi26j0dYHlw,1499
|
235
|
-
omlish/marshal/polymorphism.py,sha256=
|
236
|
+
omlish/marshal/polymorphism.py,sha256=doA8aLUhna6aco5b2Ok3jsem1V4NsF3rM5RTfJt0a7U,5708
|
236
237
|
omlish/marshal/primitives.py,sha256=wcvcs5GH_TWVmzAszh3dvyKibJgBxnXke-AlAXiwrrI,1107
|
237
238
|
omlish/marshal/registries.py,sha256=GI2KogcxawMkk02Ky7-TsnijChoe1I7YTOPIbUNwSAI,1665
|
238
239
|
omlish/marshal/standard.py,sha256=uQZIGiCwihmhB1tmhpKnZWZly0DDkdGjCnN0d41WHho,2985
|
@@ -256,7 +257,7 @@ omlish/secrets/openssl.py,sha256=wxA_wIlxtuOUy71ABxAJgavh-UI_taOfm-A0dVlmSwM,621
|
|
256
257
|
omlish/secrets/passwords.py,sha256=3r-vEK6Gp6aq4L5Csnd06QnrjO9xfzHJP-g_7I9W_ao,4101
|
257
258
|
omlish/secrets/secrets.py,sha256=ClD7t_mkmWkseVk4ahLzYLuLXeTxiwwPiidYm42vLh4,6871
|
258
259
|
omlish/secrets/subprocesses.py,sha256=EcnKlHHtnUMHGrBWXDfu8tv28wlgZx4P4GOiuPW9Vo8,1105
|
259
|
-
omlish/specs/__init__.py,sha256=
|
260
|
+
omlish/specs/__init__.py,sha256=_CSPXx25uGhXkmqLs9CSdcWAkZaQnc3cJk3lb2dadgE,88
|
260
261
|
omlish/specs/jsonschema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
261
262
|
omlish/specs/jsonschema/types.py,sha256=qoxExgKfrI-UZXdk3qcVZIEyp1WckFbb85_eGInEoAY,467
|
262
263
|
omlish/specs/jsonschema/keywords/__init__.py,sha256=Zt2g1BXd654uU2AQ5P7_-x2Wrtf6cNbP9mxI1wGN4wo,596
|
@@ -279,15 +280,16 @@ omlish/specs/jsonschema/schemas/draft202012/vocabularies/format.json,sha256=UOu_
|
|
279
280
|
omlish/specs/jsonschema/schemas/draft202012/vocabularies/meta-data.json,sha256=j3bW4U9Bubku-TO3CM3FFEyLUmhlGtEZGEhfsXVPHHY,892
|
280
281
|
omlish/specs/jsonschema/schemas/draft202012/vocabularies/unevaluated.json,sha256=Lb-8tzmUtnCwl2SSre4f_7RsIWgnhNL1pMpWH54tDLQ,506
|
281
282
|
omlish/specs/jsonschema/schemas/draft202012/vocabularies/validation.json,sha256=cBCjHlQfMtK-ch4t40jfdcmzaHaj7TBId_wKvaHTelg,2834
|
282
|
-
omlish/sql/__init__.py,sha256=
|
283
|
+
omlish/sql/__init__.py,sha256=TpZLsEJKJzvJ0eMzuV8hwOJJbkxBCV1RZPUMLAVB6io,173
|
283
284
|
omlish/sql/_abc.py,sha256=HLhnnLZ7l0r_N99I-RCqJe6VHth-9iluU7cR-7-5jfs,1519
|
284
|
-
omlish/sql/asyncs.py,sha256=Wye3dwh7oZEGYz2Y4DZQSHtW4xjI2AH5qjW-BSS2IfU,3688
|
285
285
|
omlish/sql/dbs.py,sha256=lpdFmm2vTwLoBiVYGj9yPsVcTEYYNCxlYZZpjfChzkY,1870
|
286
|
-
omlish/sql/duckdb.py,sha256=Z3wiZEn_21Lu1ElFRX0ATzoBMCw0KJxINjTRuTexYGM,3748
|
287
|
-
omlish/sql/exprs.py,sha256=gO4Fj4xEY-PuDgV-N8hBMy55glZz7O-4H7v1LWabfZY,323
|
288
286
|
omlish/sql/qualifiedname.py,sha256=rlW3gVmyucJbqwcxj_7BfK4X2HoXrMroZT2H45zPgJQ,2264
|
289
|
-
omlish/sql/
|
290
|
-
omlish/sql/
|
287
|
+
omlish/sql/alchemy/__init__.py,sha256=1ruDMiviH5fjevn2xVki-QspcE9O3VPy4hxOqpHjI2s,224
|
288
|
+
omlish/sql/alchemy/asyncs.py,sha256=C1bIzz9m2Qbgl4qYGQt_FRQg4BKRcxUqMsVg9RtnTPg,3689
|
289
|
+
omlish/sql/alchemy/duckdb.py,sha256=kr7pIhiBLNAuZrcigHDtFg9zHkVcrRW3LfryO9VJ4mk,3749
|
290
|
+
omlish/sql/alchemy/exprs.py,sha256=gO4Fj4xEY-PuDgV-N8hBMy55glZz7O-4H7v1LWabfZY,323
|
291
|
+
omlish/sql/alchemy/secrets.py,sha256=EMfy4EfTbEvrlv_41oOhn8qsoF-eTkY7HciPenIE6rI,178
|
292
|
+
omlish/sql/alchemy/sqlean.py,sha256=RbkuOuFIfM4fowwKk8-sQ6Dxk-tTUwxS94nY5Kxt52s,403
|
291
293
|
omlish/testing/__init__.py,sha256=kfiF10ykrjWXniedIl3g8j3pNAFyuSbp1D3ZXug3-Eo,168
|
292
294
|
omlish/testing/testing.py,sha256=pJUbZ0ymdrQoNG9r9UlGXypeU1x9ntEp9xcYBnyOHUs,3088
|
293
295
|
omlish/testing/pytest/__init__.py,sha256=b6ObMEHTZnvGEI_de6nN1x5FyitV6B2mNYkurA4Q7fo,336
|
@@ -297,7 +299,7 @@ omlish/testing/pytest/inject/__init__.py,sha256=pdRKv1HcDmJ_yArKJbYITPXXZthRSGgB
|
|
297
299
|
omlish/testing/pytest/inject/harness.py,sha256=sMKjP2EWHq-eeTB1YVXcANli2Czxt56_9ERg4HtkVPg,5810
|
298
300
|
omlish/testing/pytest/plugins/__init__.py,sha256=ys1zXrYrNm7Uo6YOIVJ6Bd3dQo6kv387k7MbTYlqZSI,467
|
299
301
|
omlish/testing/pytest/plugins/_registry.py,sha256=IK04KlBgiOJxKAyCCgjpX2R-9tE-btalYJkgjLc8Te8,77
|
300
|
-
omlish/testing/pytest/plugins/asyncs.py,sha256=
|
302
|
+
omlish/testing/pytest/plugins/asyncs.py,sha256=SV6oKCy50CGkzLGYX-CT4MfWNqsrH8ONEbIWC3tFcHA,5324
|
301
303
|
omlish/testing/pytest/plugins/depskip.py,sha256=xithY-OMtjwhv8mcRNkv-WI_PSQtHldQ8H1s60MIXkk,2673
|
302
304
|
omlish/testing/pytest/plugins/logging.py,sha256=1zs6Xe54wiaSjabCviaFXwKkoN97CKm3mA5mEoUeJGs,380
|
303
305
|
omlish/testing/pytest/plugins/managermarks.py,sha256=pDEcCNdDAcTS4jjZHSnAfmzqMJDBcJcSsM3QNhbJ6Gs,1485
|
@@ -313,8 +315,8 @@ omlish/text/delimit.py,sha256=ubPXcXQmtbOVrUsNh5gH1mDq5H-n1y2R4cPL5_DQf68,4928
|
|
313
315
|
omlish/text/glyphsplit.py,sha256=Ug-dPRO7x-OrNNr8g1y6DotSZ2KH0S-VcOmUobwa4B0,3296
|
314
316
|
omlish/text/indent.py,sha256=6Jj6TFY9unaPa4xPzrnZemJ-fHsV53IamP93XGjSUHs,1274
|
315
317
|
omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
|
316
|
-
omlish-0.0.0.
|
317
|
-
omlish-0.0.0.
|
318
|
-
omlish-0.0.0.
|
319
|
-
omlish-0.0.0.
|
320
|
-
omlish-0.0.0.
|
318
|
+
omlish-0.0.0.dev30.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
319
|
+
omlish-0.0.0.dev30.dist-info/METADATA,sha256=IwpExBB3pJdmS4yOOGHNJjwusV5Xj5KOyW5aY9cHxV8,3694
|
320
|
+
omlish-0.0.0.dev30.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
321
|
+
omlish-0.0.0.dev30.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
|
322
|
+
omlish-0.0.0.dev30.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|