omlish 0.0.0.dev72__py3-none-any.whl → 0.0.0.dev74__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/check.py +26 -26
- omlish/dataclasses/impl/fields.py +4 -0
- omlish/dataclasses/impl/metaclass.py +7 -1
- omlish/http/clients.py +1 -1
- omlish/http/headers.py +4 -3
- omlish/marshal/enums.py +1 -1
- omlish/sql/queries/__init__.py +24 -6
- omlish/sql/queries/binary.py +57 -10
- omlish/sql/queries/exprs.py +34 -0
- omlish/sql/queries/marshal.py +74 -0
- omlish/sql/queries/multi.py +10 -14
- omlish/sql/queries/ops.py +8 -0
- omlish/sql/queries/relations.py +5 -0
- omlish/sql/queries/rendering.py +180 -0
- omlish/sql/queries/selects.py +9 -9
- omlish/sql/queries/unary.py +26 -3
- omlish/sql/tabledefs/marshal.py +1 -4
- {omlish-0.0.0.dev72.dist-info → omlish-0.0.0.dev74.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev72.dist-info → omlish-0.0.0.dev74.dist-info}/RECORD +25 -22
- /omlish/sql/queries/{std.py → building.py} +0 -0
- {omlish-0.0.0.dev72.dist-info → omlish-0.0.0.dev74.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev72.dist-info → omlish-0.0.0.dev74.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev72.dist-info → omlish-0.0.0.dev74.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev72.dist-info → omlish-0.0.0.dev74.dist-info}/top_level.txt +0 -0
omlish/__about__.py
CHANGED
omlish/check.py
CHANGED
@@ -96,7 +96,7 @@ def _default_exception_factory(exc_cls: type[Exception], *args, **kwargs) -> Exc
|
|
96
96
|
_EXCEPTION_FACTORY = _default_exception_factory
|
97
97
|
|
98
98
|
|
99
|
-
class
|
99
|
+
class _ArgsKwargs:
|
100
100
|
def __init__(self, *args, **kwargs):
|
101
101
|
self.args = args
|
102
102
|
self.kwargs = kwargs
|
@@ -106,7 +106,7 @@ def _raise(
|
|
106
106
|
exception_type: type[Exception],
|
107
107
|
default_message: str,
|
108
108
|
message: Message,
|
109
|
-
ak:
|
109
|
+
ak: _ArgsKwargs = _ArgsKwargs(),
|
110
110
|
*,
|
111
111
|
render_fmt: str | None = None,
|
112
112
|
) -> ta.NoReturn:
|
@@ -159,7 +159,7 @@ def isinstance(v: ta.Any, spec: type[T] | tuple, msg: Message = None) -> T: # n
|
|
159
159
|
TypeError,
|
160
160
|
'Must be instance',
|
161
161
|
msg,
|
162
|
-
|
162
|
+
_ArgsKwargs(v, spec),
|
163
163
|
render_fmt='not isinstance(%s, %s)',
|
164
164
|
)
|
165
165
|
|
@@ -179,7 +179,7 @@ def cast(v: ta.Any, cls: type[T], msg: Message = None) -> T: # noqa
|
|
179
179
|
TypeError,
|
180
180
|
'Must be instance',
|
181
181
|
msg,
|
182
|
-
|
182
|
+
_ArgsKwargs(v, cls),
|
183
183
|
)
|
184
184
|
|
185
185
|
return v
|
@@ -198,7 +198,7 @@ def not_isinstance(v: T, spec: ta.Any, msg: Message = None) -> T: # noqa
|
|
198
198
|
TypeError,
|
199
199
|
'Must not be instance',
|
200
200
|
msg,
|
201
|
-
|
201
|
+
_ArgsKwargs(v, spec),
|
202
202
|
render_fmt='isinstance(%s, %s)',
|
203
203
|
)
|
204
204
|
|
@@ -221,7 +221,7 @@ def issubclass(v: type[T], spec: ta.Any, msg: Message = None) -> type[T]: # noq
|
|
221
221
|
TypeError,
|
222
222
|
'Must be subclass',
|
223
223
|
msg,
|
224
|
-
|
224
|
+
_ArgsKwargs(v, spec),
|
225
225
|
render_fmt='not issubclass(%s, %s)',
|
226
226
|
)
|
227
227
|
|
@@ -234,7 +234,7 @@ def not_issubclass(v: type[T], spec: ta.Any, msg: Message = None) -> type[T]: #
|
|
234
234
|
TypeError,
|
235
235
|
'Must not be subclass',
|
236
236
|
msg,
|
237
|
-
|
237
|
+
_ArgsKwargs(v, spec),
|
238
238
|
render_fmt='issubclass(%s, %s)',
|
239
239
|
)
|
240
240
|
|
@@ -250,7 +250,7 @@ def in_(v: T, c: ta.Container[T], msg: Message = None) -> T:
|
|
250
250
|
ValueError,
|
251
251
|
'Must be in',
|
252
252
|
msg,
|
253
|
-
|
253
|
+
_ArgsKwargs(v, c),
|
254
254
|
render_fmt='%s not in %s',
|
255
255
|
)
|
256
256
|
|
@@ -263,7 +263,7 @@ def not_in(v: T, c: ta.Container[T], msg: Message = None) -> T:
|
|
263
263
|
ValueError,
|
264
264
|
'Must not be in',
|
265
265
|
msg,
|
266
|
-
|
266
|
+
_ArgsKwargs(v, c),
|
267
267
|
render_fmt='%s in %s',
|
268
268
|
)
|
269
269
|
|
@@ -276,7 +276,7 @@ def empty(v: SizedT, msg: Message = None) -> SizedT:
|
|
276
276
|
ValueError,
|
277
277
|
'Must be empty',
|
278
278
|
msg,
|
279
|
-
|
279
|
+
_ArgsKwargs(v),
|
280
280
|
render_fmt='%s',
|
281
281
|
)
|
282
282
|
|
@@ -294,7 +294,7 @@ def iterempty(v: ta.Iterable[T], msg: Message = None) -> ta.Iterable[T]:
|
|
294
294
|
ValueError,
|
295
295
|
'Must be empty',
|
296
296
|
msg,
|
297
|
-
|
297
|
+
_ArgsKwargs(v),
|
298
298
|
render_fmt='%s',
|
299
299
|
)
|
300
300
|
|
@@ -307,7 +307,7 @@ def not_empty(v: SizedT, msg: Message = None) -> SizedT:
|
|
307
307
|
ValueError,
|
308
308
|
'Must not be empty',
|
309
309
|
msg,
|
310
|
-
|
310
|
+
_ArgsKwargs(v),
|
311
311
|
render_fmt='%s',
|
312
312
|
)
|
313
313
|
|
@@ -321,7 +321,7 @@ def unique(it: ta.Iterable[T], msg: Message = None) -> ta.Iterable[T]:
|
|
321
321
|
ValueError,
|
322
322
|
'Must be unique',
|
323
323
|
msg,
|
324
|
-
|
324
|
+
_ArgsKwargs(it, dupes),
|
325
325
|
)
|
326
326
|
|
327
327
|
return it
|
@@ -335,7 +335,7 @@ def single(obj: ta.Iterable[T], message: Message = None) -> T:
|
|
335
335
|
ValueError,
|
336
336
|
'Must be single',
|
337
337
|
message,
|
338
|
-
|
338
|
+
_ArgsKwargs(obj),
|
339
339
|
render_fmt='%s',
|
340
340
|
)
|
341
341
|
|
@@ -358,7 +358,7 @@ def opt_single(obj: ta.Iterable[T], message: Message = None) -> T | None:
|
|
358
358
|
ValueError,
|
359
359
|
'Must be empty or single',
|
360
360
|
message,
|
361
|
-
|
361
|
+
_ArgsKwargs(obj),
|
362
362
|
render_fmt='%s',
|
363
363
|
)
|
364
364
|
|
@@ -372,7 +372,7 @@ def none(v: ta.Any, msg: Message = None) -> None:
|
|
372
372
|
ValueError,
|
373
373
|
'Must be None',
|
374
374
|
msg,
|
375
|
-
|
375
|
+
_ArgsKwargs(v),
|
376
376
|
render_fmt='%s',
|
377
377
|
)
|
378
378
|
|
@@ -383,7 +383,7 @@ def not_none(v: T | None, msg: Message = None) -> T:
|
|
383
383
|
ValueError,
|
384
384
|
'Must not be None',
|
385
385
|
msg,
|
386
|
-
|
386
|
+
_ArgsKwargs(v),
|
387
387
|
render_fmt='%s',
|
388
388
|
)
|
389
389
|
|
@@ -399,7 +399,7 @@ def equal(v: T, o: ta.Any, msg: Message = None) -> T:
|
|
399
399
|
ValueError,
|
400
400
|
'Must be equal',
|
401
401
|
msg,
|
402
|
-
|
402
|
+
_ArgsKwargs(v, o),
|
403
403
|
render_fmt='%s != %s',
|
404
404
|
)
|
405
405
|
|
@@ -412,7 +412,7 @@ def is_(v: T, o: ta.Any, msg: Message = None) -> T:
|
|
412
412
|
ValueError,
|
413
413
|
'Must be the same',
|
414
414
|
msg,
|
415
|
-
|
415
|
+
_ArgsKwargs(v, o),
|
416
416
|
render_fmt='%s is not %s',
|
417
417
|
)
|
418
418
|
|
@@ -425,7 +425,7 @@ def is_not(v: T, o: ta.Any, msg: Message = None) -> T:
|
|
425
425
|
ValueError,
|
426
426
|
'Must not be the same',
|
427
427
|
msg,
|
428
|
-
|
428
|
+
_ArgsKwargs(v, o),
|
429
429
|
render_fmt='%s is %s',
|
430
430
|
)
|
431
431
|
|
@@ -438,7 +438,7 @@ def callable(v: T, msg: Message = None) -> T: # noqa
|
|
438
438
|
TypeError,
|
439
439
|
'Must be callable',
|
440
440
|
msg,
|
441
|
-
|
441
|
+
_ArgsKwargs(v),
|
442
442
|
render_fmt='%s',
|
443
443
|
)
|
444
444
|
|
@@ -451,7 +451,7 @@ def non_empty_str(v: str | None, msg: Message = None) -> str:
|
|
451
451
|
ValueError,
|
452
452
|
'Must be non-empty str',
|
453
453
|
msg,
|
454
|
-
|
454
|
+
_ArgsKwargs(v),
|
455
455
|
render_fmt='%s',
|
456
456
|
)
|
457
457
|
|
@@ -464,7 +464,7 @@ def replacing(expected: ta.Any, old: ta.Any, new: T, msg: Message = None) -> T:
|
|
464
464
|
ValueError,
|
465
465
|
'Must be replacing',
|
466
466
|
msg,
|
467
|
-
|
467
|
+
_ArgsKwargs(expected, old, new),
|
468
468
|
render_fmt='%s -> %s -> %s',
|
469
469
|
)
|
470
470
|
|
@@ -477,7 +477,7 @@ def replacing_none(old: ta.Any, new: T, msg: Message = None) -> T:
|
|
477
477
|
ValueError,
|
478
478
|
'Must be replacing None',
|
479
479
|
msg,
|
480
|
-
|
480
|
+
_ArgsKwargs(old, new),
|
481
481
|
render_fmt='%s -> %s',
|
482
482
|
)
|
483
483
|
|
@@ -493,7 +493,7 @@ def arg(v: bool, msg: Message = None) -> None:
|
|
493
493
|
RuntimeError,
|
494
494
|
'Argument condition not met',
|
495
495
|
msg,
|
496
|
-
|
496
|
+
_ArgsKwargs(v),
|
497
497
|
render_fmt='%s',
|
498
498
|
)
|
499
499
|
|
@@ -504,6 +504,6 @@ def state(v: bool, msg: Message = None) -> None:
|
|
504
504
|
RuntimeError,
|
505
505
|
'State condition not met',
|
506
506
|
msg,
|
507
|
-
|
507
|
+
_ArgsKwargs(v),
|
508
508
|
render_fmt='%s',
|
509
509
|
)
|
@@ -108,7 +108,11 @@ class DataMeta(abc.ABCMeta):
|
|
108
108
|
|
109
109
|
|
110
110
|
# @ta.dataclass_transform(field_specifiers=(field,)) # FIXME: ctor
|
111
|
-
class Data(
|
111
|
+
class Data(
|
112
|
+
eq=False,
|
113
|
+
order=False,
|
114
|
+
metaclass=DataMeta,
|
115
|
+
):
|
112
116
|
def __init__(self, *args, **kwargs):
|
113
117
|
super().__init__(*args, **kwargs)
|
114
118
|
|
@@ -125,6 +129,8 @@ class Data(metaclass=DataMeta):
|
|
125
129
|
class Frozen(
|
126
130
|
Data,
|
127
131
|
frozen=True,
|
132
|
+
eq=False,
|
133
|
+
order=False,
|
128
134
|
confer=frozenset([
|
129
135
|
'frozen',
|
130
136
|
'cache_hash',
|
omlish/http/clients.py
CHANGED
@@ -133,7 +133,7 @@ class UrllibHttpClient(HttpClient):
|
|
133
133
|
|
134
134
|
# urllib headers are dumb dicts [1], and keys *must* be strings or it will automatically add problematic default
|
135
135
|
# headers because it doesn't see string keys in its header dict [2]. frustratingly it has no problem accepting
|
136
|
-
# bytes
|
136
|
+
# bytes values though [3].
|
137
137
|
# [1]: https://github.com/python/cpython/blob/232b303e4ca47892f544294bf42e31dc34f0ec72/Lib/urllib/request.py#L319-L325 # noqa
|
138
138
|
# [2]: https://github.com/python/cpython/blob/232b303e4ca47892f544294bf42e31dc34f0ec72/Lib/urllib/request.py#L1276-L1279 # noqa
|
139
139
|
# [3]: https://github.com/python/cpython/blob/232b303e4ca47892f544294bf42e31dc34f0ec72/Lib/http/client.py#L1300-L1301 # noqa
|
omlish/http/headers.py
CHANGED
@@ -12,13 +12,14 @@ CanHttpHeaders: ta.TypeAlias = ta.Union[
|
|
12
12
|
|
13
13
|
ta.Mapping[str, str],
|
14
14
|
ta.Mapping[str, ta.Sequence[str]],
|
15
|
+
ta.Mapping[str, str | ta.Sequence[str]],
|
15
16
|
|
16
17
|
ta.Mapping[bytes, bytes],
|
17
18
|
ta.Mapping[bytes, ta.Sequence[bytes]],
|
19
|
+
ta.Mapping[bytes, bytes | ta.Sequence[bytes]],
|
18
20
|
|
19
21
|
ta.Mapping[StrOrBytes, StrOrBytes],
|
20
22
|
ta.Mapping[StrOrBytes, ta.Sequence[StrOrBytes]],
|
21
|
-
|
22
23
|
ta.Mapping[StrOrBytes, StrOrBytes | ta.Sequence[StrOrBytes]],
|
23
24
|
|
24
25
|
ta.Sequence[tuple[str, str]],
|
@@ -153,11 +154,11 @@ class HttpHeaders:
|
|
153
154
|
...
|
154
155
|
|
155
156
|
@ta.overload
|
156
|
-
def __getitem__(self, item: int) -> StrOrBytes:
|
157
|
+
def __getitem__(self, item: int) -> tuple[StrOrBytes, StrOrBytes]:
|
157
158
|
...
|
158
159
|
|
159
160
|
@ta.overload
|
160
|
-
def __getitem__(self, item: slice) -> ta.Sequence[StrOrBytes]:
|
161
|
+
def __getitem__(self, item: slice) -> ta.Sequence[tuple[StrOrBytes, StrOrBytes]]:
|
161
162
|
...
|
162
163
|
|
163
164
|
def __getitem__(self, item):
|
omlish/marshal/enums.py
CHANGED
@@ -28,7 +28,7 @@ class EnumMarshalerFactory(MarshalerFactory):
|
|
28
28
|
def fn(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
|
29
29
|
ty = check.isinstance(rty, type)
|
30
30
|
check.state(issubclass(ty, enum.Enum))
|
31
|
-
return EnumMarshaler(ty)
|
31
|
+
return EnumMarshaler(ty) # noqa
|
32
32
|
|
33
33
|
|
34
34
|
@dc.dataclass(frozen=True)
|
omlish/sql/queries/__init__.py
CHANGED
@@ -11,6 +11,10 @@ from .binary import ( # noqa
|
|
11
11
|
BinaryOps,
|
12
12
|
)
|
13
13
|
|
14
|
+
from .building import ( # noqa
|
15
|
+
StdBuilder,
|
16
|
+
)
|
17
|
+
|
14
18
|
from .exprs import ( # noqa
|
15
19
|
CanExpr,
|
16
20
|
CanLiteral,
|
@@ -18,6 +22,7 @@ from .exprs import ( # noqa
|
|
18
22
|
ExprBuilder,
|
19
23
|
Literal,
|
20
24
|
NameExpr,
|
25
|
+
Param,
|
21
26
|
)
|
22
27
|
|
23
28
|
from .idents import ( # noqa
|
@@ -29,8 +34,7 @@ from .idents import ( # noqa
|
|
29
34
|
from .multi import ( # noqa
|
30
35
|
Multi,
|
31
36
|
MultiBuilder,
|
32
|
-
|
33
|
-
MultiOps,
|
37
|
+
MultiKind,
|
34
38
|
)
|
35
39
|
|
36
40
|
from .names import ( # noqa
|
@@ -39,6 +43,10 @@ from .names import ( # noqa
|
|
39
43
|
NameBuilder,
|
40
44
|
)
|
41
45
|
|
46
|
+
from .ops import ( # noqa
|
47
|
+
OpKind,
|
48
|
+
)
|
49
|
+
|
42
50
|
from .relations import ( # noqa
|
43
51
|
CanRelation,
|
44
52
|
CanTable,
|
@@ -47,6 +55,12 @@ from .relations import ( # noqa
|
|
47
55
|
Table,
|
48
56
|
)
|
49
57
|
|
58
|
+
from .rendering import ( # noqa
|
59
|
+
Renderer,
|
60
|
+
StdRenderer,
|
61
|
+
render,
|
62
|
+
)
|
63
|
+
|
50
64
|
from .selects import ( # noqa
|
51
65
|
CanRelation,
|
52
66
|
Select,
|
@@ -54,10 +68,6 @@ from .selects import ( # noqa
|
|
54
68
|
SelectItem,
|
55
69
|
)
|
56
70
|
|
57
|
-
from .std import ( # noqa
|
58
|
-
StdBuilder,
|
59
|
-
)
|
60
|
-
|
61
71
|
from .stmts import ( # noqa
|
62
72
|
CanExpr,
|
63
73
|
ExprStmt,
|
@@ -77,3 +87,11 @@ from .unary import ( # noqa
|
|
77
87
|
|
78
88
|
|
79
89
|
Q = StdBuilder()
|
90
|
+
|
91
|
+
|
92
|
+
##
|
93
|
+
|
94
|
+
|
95
|
+
from ...lang.imports import _register_conditional_import # noqa
|
96
|
+
|
97
|
+
_register_conditional_import('...marshal', '.marshal', __package__)
|
omlish/sql/queries/binary.py
CHANGED
@@ -1,24 +1,41 @@
|
|
1
|
+
"""
|
2
|
+
TODO:
|
3
|
+
- in_
|
4
|
+
- like
|
5
|
+
- no this is a dedicated node, escape / negation in grammar
|
6
|
+
"""
|
1
7
|
from ... import check
|
8
|
+
from ... import dataclasses as dc
|
2
9
|
from ... import lang
|
3
|
-
from .base import Node
|
4
10
|
from .exprs import CanExpr
|
5
11
|
from .exprs import Expr
|
6
12
|
from .exprs import ExprBuilder
|
13
|
+
from .ops import OpKind
|
7
14
|
|
8
15
|
|
9
16
|
##
|
10
17
|
|
11
18
|
|
12
|
-
class BinaryOp(
|
19
|
+
class BinaryOp(dc.Frozen, lang.Final, eq=False):
|
13
20
|
name: str
|
21
|
+
kind: OpKind
|
14
22
|
|
15
23
|
|
16
24
|
class BinaryOps(lang.Namespace):
|
17
|
-
|
18
|
-
|
25
|
+
EQ = BinaryOp('eq', OpKind.CMP)
|
26
|
+
NE = BinaryOp('ne', OpKind.CMP)
|
27
|
+
LT = BinaryOp('lt', OpKind.CMP)
|
28
|
+
LE = BinaryOp('le', OpKind.CMP)
|
29
|
+
GT = BinaryOp('gt', OpKind.CMP)
|
30
|
+
GE = BinaryOp('ge', OpKind.CMP)
|
19
31
|
|
20
|
-
|
21
|
-
|
32
|
+
ADD = BinaryOp('add', OpKind.ARITH)
|
33
|
+
SUB = BinaryOp('sub', OpKind.ARITH)
|
34
|
+
MUL = BinaryOp('mul', OpKind.ARITH)
|
35
|
+
DIV = BinaryOp('div', OpKind.ARITH)
|
36
|
+
MOD = BinaryOp('mod', OpKind.ARITH)
|
37
|
+
|
38
|
+
CONCAT = BinaryOp('concat', OpKind.STR)
|
22
39
|
|
23
40
|
|
24
41
|
class Binary(Expr, lang.Final):
|
@@ -35,14 +52,44 @@ class BinaryBuilder(ExprBuilder):
|
|
35
52
|
l = Binary(op, l, self.expr(r))
|
36
53
|
return l
|
37
54
|
|
55
|
+
#
|
56
|
+
|
57
|
+
def eq(self, *es: CanExpr) -> Expr:
|
58
|
+
return self.binary(BinaryOps.EQ, *es)
|
59
|
+
|
60
|
+
def ne(self, *es: CanExpr) -> Expr:
|
61
|
+
return self.binary(BinaryOps.NE, *es)
|
62
|
+
|
63
|
+
def lt(self, *es: CanExpr) -> Expr:
|
64
|
+
return self.binary(BinaryOps.LT, *es)
|
65
|
+
|
66
|
+
def le(self, *es: CanExpr) -> Expr:
|
67
|
+
return self.binary(BinaryOps.LE, *es)
|
68
|
+
|
69
|
+
def gt(self, *es: CanExpr) -> Expr:
|
70
|
+
return self.binary(BinaryOps.GT, *es)
|
71
|
+
|
72
|
+
def ge(self, *es: CanExpr) -> Expr:
|
73
|
+
return self.binary(BinaryOps.GE, *es)
|
74
|
+
|
75
|
+
#
|
76
|
+
|
38
77
|
def add(self, *es: CanExpr) -> Expr:
|
39
78
|
return self.binary(BinaryOps.ADD, *es)
|
40
79
|
|
41
80
|
def sub(self, *es: CanExpr) -> Expr:
|
42
81
|
return self.binary(BinaryOps.SUB, *es)
|
43
82
|
|
44
|
-
def
|
45
|
-
return self.binary(BinaryOps.
|
83
|
+
def mul(self, *es: CanExpr) -> Expr:
|
84
|
+
return self.binary(BinaryOps.MUL, *es)
|
46
85
|
|
47
|
-
def
|
48
|
-
return self.binary(BinaryOps.
|
86
|
+
def div(self, *es: CanExpr) -> Expr:
|
87
|
+
return self.binary(BinaryOps.DIV, *es)
|
88
|
+
|
89
|
+
def mod(self, *es: CanExpr) -> Expr:
|
90
|
+
return self.binary(BinaryOps.MOD, *es)
|
91
|
+
|
92
|
+
#
|
93
|
+
|
94
|
+
def concat(self, *es: CanExpr) -> Expr:
|
95
|
+
return self.binary(BinaryOps.CONCAT, *es)
|
omlish/sql/queries/exprs.py
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
"""
|
2
|
+
TODO:
|
3
|
+
- case
|
4
|
+
- cast / ::
|
5
|
+
"""
|
1
6
|
import typing as ta
|
2
7
|
|
3
8
|
from ... import lang
|
@@ -24,6 +29,24 @@ class NameExpr(Expr, lang.Final):
|
|
24
29
|
n: Name
|
25
30
|
|
26
31
|
|
32
|
+
class Param(Expr, lang.Final):
|
33
|
+
n: str | None = None
|
34
|
+
|
35
|
+
def __repr__(self) -> str:
|
36
|
+
if self.n is not None:
|
37
|
+
return f'{self.__class__.__name__}({self.n!r})'
|
38
|
+
else:
|
39
|
+
return f'{self.__class__.__name__}(@{hex(id(self))[2:]})'
|
40
|
+
|
41
|
+
def __eq__(self, other):
|
42
|
+
if not isinstance(other, Param):
|
43
|
+
return False
|
44
|
+
if self.n is None and other.n is None:
|
45
|
+
return self is other
|
46
|
+
else:
|
47
|
+
return self.n == other.n
|
48
|
+
|
49
|
+
|
27
50
|
CanLiteral: ta.TypeAlias = Literal | Value
|
28
51
|
CanExpr: ta.TypeAlias = Expr | CanName | CanLiteral
|
29
52
|
|
@@ -41,6 +64,8 @@ class ExprBuilder(NameBuilder):
|
|
41
64
|
def l(self, o: CanLiteral) -> Literal: # noqa
|
42
65
|
return self.literal(o)
|
43
66
|
|
67
|
+
#
|
68
|
+
|
44
69
|
def expr(self, o: CanExpr) -> Expr:
|
45
70
|
if isinstance(o, Expr):
|
46
71
|
return o
|
@@ -52,3 +77,12 @@ class ExprBuilder(NameBuilder):
|
|
52
77
|
@ta.final
|
53
78
|
def e(self, o: CanExpr) -> Expr:
|
54
79
|
return self.expr(o)
|
80
|
+
|
81
|
+
#
|
82
|
+
|
83
|
+
def param(self, n: str | None = None) -> Param:
|
84
|
+
return Param(n)
|
85
|
+
|
86
|
+
@ta.final
|
87
|
+
def p(self, n: str | None = None) -> Param:
|
88
|
+
return self.param(n)
|
@@ -0,0 +1,74 @@
|
|
1
|
+
import enum
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
from ... import cached
|
5
|
+
from ... import check
|
6
|
+
from ... import collections as col
|
7
|
+
from ... import dataclasses as dc
|
8
|
+
from ... import lang
|
9
|
+
from ... import marshal as msh
|
10
|
+
from .base import Node
|
11
|
+
from .binary import BinaryOp
|
12
|
+
from .binary import BinaryOps
|
13
|
+
from .exprs import Expr
|
14
|
+
from .multi import MultiKind
|
15
|
+
from .relations import Relation
|
16
|
+
from .stmts import Stmt
|
17
|
+
from .unary import UnaryOp
|
18
|
+
from .unary import UnaryOps
|
19
|
+
|
20
|
+
|
21
|
+
@dc.dataclass(frozen=True)
|
22
|
+
class OpMarshalerUnmarshaler(msh.Marshaler, msh.Unmarshaler):
|
23
|
+
ty: type
|
24
|
+
ns: type[lang.Namespace]
|
25
|
+
|
26
|
+
@cached.property
|
27
|
+
@dc.init
|
28
|
+
def by_name(self) -> ta.Mapping[str, ta.Any]:
|
29
|
+
return col.make_map(((o.name, o) for _, o in self.ns), strict=True)
|
30
|
+
|
31
|
+
def marshal(self, ctx: msh.MarshalContext, o: ta.Any) -> msh.Value:
|
32
|
+
return check.isinstance(o, self.ty).name # type: ignore # noqa
|
33
|
+
|
34
|
+
def unmarshal(self, ctx: msh.UnmarshalContext, v: msh.Value) -> ta.Any:
|
35
|
+
return self.by_name[check.isinstance(v, str)]
|
36
|
+
|
37
|
+
|
38
|
+
@dc.dataclass(frozen=True)
|
39
|
+
class LowerEnumMarshaler(msh.Marshaler, msh.Unmarshaler):
|
40
|
+
ty: type[enum.Enum]
|
41
|
+
|
42
|
+
@cached.property
|
43
|
+
@dc.init
|
44
|
+
def by_name(self) -> ta.Mapping[str, ta.Any]:
|
45
|
+
return col.make_map(((o.name.lower(), o) for o in self.ty), strict=True)
|
46
|
+
|
47
|
+
def marshal(self, ctx: msh.MarshalContext, o: ta.Any) -> msh.Value:
|
48
|
+
return o.name.lower()
|
49
|
+
|
50
|
+
def unmarshal(self, ctx: msh.UnmarshalContext, v: msh.Value) -> ta.Any:
|
51
|
+
return self.by_name[check.isinstance(v, str).lower()]
|
52
|
+
|
53
|
+
|
54
|
+
@lang.static_init
|
55
|
+
def _install_standard_marshalling() -> None:
|
56
|
+
for ty, ns in [
|
57
|
+
(BinaryOp, BinaryOps),
|
58
|
+
(UnaryOp, UnaryOps),
|
59
|
+
]:
|
60
|
+
msh.STANDARD_MARSHALER_FACTORIES[0:0] = [msh.TypeMapMarshalerFactory({ty: OpMarshalerUnmarshaler(ty, ns)})]
|
61
|
+
msh.STANDARD_UNMARSHALER_FACTORIES[0:0] = [msh.TypeMapUnmarshalerFactory({ty: OpMarshalerUnmarshaler(ty, ns)})]
|
62
|
+
|
63
|
+
msh.STANDARD_MARSHALER_FACTORIES[0:0] = [msh.TypeMapMarshalerFactory({MultiKind: LowerEnumMarshaler(MultiKind)})]
|
64
|
+
msh.STANDARD_UNMARSHALER_FACTORIES[0:0] = [msh.TypeMapUnmarshalerFactory({MultiKind: LowerEnumMarshaler(MultiKind)})] # noqa
|
65
|
+
|
66
|
+
for cls in [
|
67
|
+
Expr,
|
68
|
+
Node,
|
69
|
+
Relation,
|
70
|
+
Stmt,
|
71
|
+
]:
|
72
|
+
p = msh.polymorphism_from_subclasses(cls, naming=msh.Naming.SNAKE)
|
73
|
+
msh.STANDARD_MARSHALER_FACTORIES[0:0] = [msh.PolymorphismMarshalerFactory(p)]
|
74
|
+
msh.STANDARD_UNMARSHALER_FACTORIES[0:0] = [msh.PolymorphismUnmarshalerFactory(p)]
|
omlish/sql/queries/multi.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
+
import enum
|
1
2
|
import typing as ta
|
2
3
|
|
3
4
|
from ... import check
|
4
5
|
from ... import dataclasses as dc
|
5
6
|
from ... import lang
|
6
|
-
from .base import Node
|
7
7
|
from .exprs import CanExpr
|
8
8
|
from .exprs import Expr
|
9
9
|
from .exprs import ExprBuilder
|
@@ -12,30 +12,26 @@ from .exprs import ExprBuilder
|
|
12
12
|
##
|
13
13
|
|
14
14
|
|
15
|
-
class
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
class MultiOps(lang.Namespace):
|
20
|
-
AND = MultiOp('and')
|
21
|
-
OR = MultiOp('or')
|
15
|
+
class MultiKind(enum.Enum):
|
16
|
+
AND = enum.auto()
|
17
|
+
OR = enum.auto()
|
22
18
|
|
23
19
|
|
24
20
|
class Multi(Expr, lang.Final):
|
25
|
-
|
26
|
-
es: ta.Sequence[Expr] = dc.xfield(coerce=tuple)
|
21
|
+
k: MultiKind
|
22
|
+
es: ta.Sequence[Expr] = dc.xfield(coerce=tuple, validate=lambda es: len(es) > 1)
|
27
23
|
|
28
24
|
|
29
25
|
class MultiBuilder(ExprBuilder):
|
30
|
-
def multi(self,
|
26
|
+
def multi(self, k: MultiKind, *es: CanExpr) -> Expr:
|
31
27
|
check.not_empty(es)
|
32
28
|
if len(es) == 1:
|
33
29
|
return self.expr(es[0])
|
34
30
|
else:
|
35
|
-
return Multi(
|
31
|
+
return Multi(k, [self.expr(e) for e in es])
|
36
32
|
|
37
33
|
def and_(self, *es: CanExpr) -> Expr:
|
38
|
-
return self.multi(
|
34
|
+
return self.multi(MultiKind.AND, *es)
|
39
35
|
|
40
36
|
def or_(self, *es: CanExpr) -> Expr:
|
41
|
-
return self.multi(
|
37
|
+
return self.multi(MultiKind.OR, *es)
|
omlish/sql/queries/relations.py
CHANGED
@@ -0,0 +1,180 @@
|
|
1
|
+
"""
|
2
|
+
TODO:
|
3
|
+
- minimal parens
|
4
|
+
- text.parts
|
5
|
+
- QuoteStyle
|
6
|
+
- ParamStyle
|
7
|
+
|
8
|
+
==
|
9
|
+
|
10
|
+
def needs_parens(self, e: Expr) -> bool:
|
11
|
+
if isinstance(e, (Literal, Ident, Name)):
|
12
|
+
return True
|
13
|
+
elif isinstance(e, Expr):
|
14
|
+
return False
|
15
|
+
else:
|
16
|
+
raise TypeError(e)
|
17
|
+
"""
|
18
|
+
import io
|
19
|
+
import typing as ta
|
20
|
+
|
21
|
+
from ... import dispatch
|
22
|
+
from ... import lang
|
23
|
+
from .base import Node
|
24
|
+
from .binary import Binary
|
25
|
+
from .binary import BinaryOp
|
26
|
+
from .binary import BinaryOps
|
27
|
+
from .exprs import Literal
|
28
|
+
from .exprs import NameExpr
|
29
|
+
from .idents import Ident
|
30
|
+
from .multi import Multi
|
31
|
+
from .multi import MultiKind
|
32
|
+
from .names import Name
|
33
|
+
from .relations import Table
|
34
|
+
from .selects import Select
|
35
|
+
from .selects import SelectItem
|
36
|
+
from .unary import Unary
|
37
|
+
from .unary import UnaryOp
|
38
|
+
from .unary import UnaryOps
|
39
|
+
|
40
|
+
|
41
|
+
class Renderer(lang.Abstract):
|
42
|
+
def __init__(self, out: ta.TextIO) -> None:
|
43
|
+
super().__init__()
|
44
|
+
self._out = out
|
45
|
+
|
46
|
+
@dispatch.method
|
47
|
+
def render(self, o: ta.Any) -> None:
|
48
|
+
raise TypeError(o)
|
49
|
+
|
50
|
+
@classmethod
|
51
|
+
def render_str(cls, o: ta.Any, *args: ta.Any, **kwargs: ta.Any) -> str:
|
52
|
+
out = io.StringIO()
|
53
|
+
cls(out, *args, **kwargs).render(o)
|
54
|
+
return out.getvalue()
|
55
|
+
|
56
|
+
|
57
|
+
class StdRenderer(Renderer):
|
58
|
+
# binary
|
59
|
+
|
60
|
+
BINARY_OP_TO_STR: ta.ClassVar[ta.Mapping[BinaryOp, str]] = {
|
61
|
+
BinaryOps.EQ: '=',
|
62
|
+
BinaryOps.NE: '!=',
|
63
|
+
BinaryOps.LT: '<',
|
64
|
+
BinaryOps.LE: '<=',
|
65
|
+
BinaryOps.GT: '>',
|
66
|
+
BinaryOps.GE: '>=',
|
67
|
+
|
68
|
+
BinaryOps.ADD: '+',
|
69
|
+
BinaryOps.SUB: '-',
|
70
|
+
BinaryOps.MUL: '*',
|
71
|
+
BinaryOps.DIV: '/',
|
72
|
+
BinaryOps.MOD: '%',
|
73
|
+
|
74
|
+
BinaryOps.CONCAT: '||',
|
75
|
+
}
|
76
|
+
|
77
|
+
@Renderer.render.register
|
78
|
+
def render_binary(self, o: Binary) -> None:
|
79
|
+
self._out.write('(')
|
80
|
+
self.render(o.l)
|
81
|
+
self._out.write(f' {self.BINARY_OP_TO_STR[o.op]} ')
|
82
|
+
self.render(o.r)
|
83
|
+
self._out.write(')')
|
84
|
+
|
85
|
+
# exprs
|
86
|
+
|
87
|
+
@Renderer.render.register
|
88
|
+
def render_literal(self, o: Literal) -> None:
|
89
|
+
self._out.write(repr(o.v))
|
90
|
+
|
91
|
+
@Renderer.render.register
|
92
|
+
def render_name_expr(self, o: NameExpr) -> None:
|
93
|
+
self.render(o.n)
|
94
|
+
|
95
|
+
# idents
|
96
|
+
|
97
|
+
@Renderer.render.register
|
98
|
+
def render_ident(self, o: Ident) -> None:
|
99
|
+
self._out.write(f'"{o.s}"')
|
100
|
+
|
101
|
+
# multis
|
102
|
+
|
103
|
+
MULTI_KIND_TO_STR: ta.ClassVar[ta.Mapping[MultiKind, str]] = {
|
104
|
+
MultiKind.AND: 'and',
|
105
|
+
MultiKind.OR: 'or',
|
106
|
+
|
107
|
+
}
|
108
|
+
|
109
|
+
@Renderer.render.register
|
110
|
+
def render_multi(self, o: Multi) -> None:
|
111
|
+
d = f' {self.MULTI_KIND_TO_STR[o.k]} '
|
112
|
+
self._out.write('(')
|
113
|
+
for i, e in enumerate(o.es):
|
114
|
+
if i:
|
115
|
+
self._out.write(d)
|
116
|
+
self.render(e)
|
117
|
+
self._out.write(')')
|
118
|
+
|
119
|
+
# names
|
120
|
+
|
121
|
+
@Renderer.render.register
|
122
|
+
def render_name(self, o: Name) -> None:
|
123
|
+
for n, i in enumerate(o.ps):
|
124
|
+
if n:
|
125
|
+
self._out.write('.')
|
126
|
+
self.render(i)
|
127
|
+
|
128
|
+
# relations
|
129
|
+
|
130
|
+
@Renderer.render.register
|
131
|
+
def render_table(self, o: Table) -> None:
|
132
|
+
self.render(o.n)
|
133
|
+
if o.a is not None:
|
134
|
+
self._out.write(' as ')
|
135
|
+
self.render(o.a)
|
136
|
+
|
137
|
+
# selects
|
138
|
+
|
139
|
+
@Renderer.render.register
|
140
|
+
def render_select_item(self, o: SelectItem) -> None:
|
141
|
+
self.render(o.v)
|
142
|
+
if o.a is not None:
|
143
|
+
self._out.write(' as ')
|
144
|
+
self.render(o.a)
|
145
|
+
|
146
|
+
@Renderer.render.register
|
147
|
+
def render_select(self, o: Select) -> None:
|
148
|
+
self._out.write('select ')
|
149
|
+
for i, it in enumerate(o.items):
|
150
|
+
if i:
|
151
|
+
self._out.write(', ')
|
152
|
+
self.render(it)
|
153
|
+
if o.from_ is not None:
|
154
|
+
self._out.write(' from ')
|
155
|
+
self.render(o.from_)
|
156
|
+
if o.where:
|
157
|
+
self._out.write(' where ')
|
158
|
+
self.render(o.where)
|
159
|
+
|
160
|
+
# unary
|
161
|
+
|
162
|
+
UNARY_OP_TO_STR: ta.ClassVar[ta.Mapping[UnaryOp, tuple[str, str]]] = {
|
163
|
+
UnaryOps.NOT: ('not ', ''),
|
164
|
+
UnaryOps.IS_NULL: ('', ' is null'),
|
165
|
+
UnaryOps.IS_NOT_NULL: ('', ' is not null'),
|
166
|
+
|
167
|
+
UnaryOps.POS: ('+', ''),
|
168
|
+
UnaryOps.NEG: ('-', ''),
|
169
|
+
}
|
170
|
+
|
171
|
+
@Renderer.render.register
|
172
|
+
def render_unary(self, o: Unary) -> None:
|
173
|
+
pfx, sfx = self.UNARY_OP_TO_STR[o.op]
|
174
|
+
self._out.write(pfx)
|
175
|
+
self.render(o.v)
|
176
|
+
self._out.write(sfx)
|
177
|
+
|
178
|
+
|
179
|
+
def render(n: Node) -> str:
|
180
|
+
return StdRenderer.render_str(n)
|
omlish/sql/queries/selects.py
CHANGED
@@ -22,9 +22,9 @@ class SelectItem(Node, lang.Final):
|
|
22
22
|
|
23
23
|
|
24
24
|
class Select(Stmt, lang.Final):
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
items: ta.Sequence[SelectItem] = dc.xfield(coerce=tuple)
|
26
|
+
from_: Relation | None = dc.xfield(None, repr_fn=dc.opt_repr)
|
27
|
+
where: Expr | None = dc.xfield(None, repr_fn=dc.opt_repr)
|
28
28
|
|
29
29
|
|
30
30
|
CanSelectItem: ta.TypeAlias = SelectItem | CanExpr
|
@@ -39,12 +39,12 @@ class SelectBuilder(ExprBuilder, RelationBuilder):
|
|
39
39
|
|
40
40
|
def select(
|
41
41
|
self,
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
items: ta.Sequence[CanSelectItem],
|
43
|
+
from_: CanRelation | None = None,
|
44
|
+
where: CanExpr | None = None,
|
45
45
|
) -> Select:
|
46
46
|
return Select(
|
47
|
-
[self.select_item(i) for i in
|
48
|
-
|
49
|
-
|
47
|
+
[self.select_item(i) for i in items],
|
48
|
+
from_=self.relation(from_) if from_ is not None else None,
|
49
|
+
where=self.expr(where) if where is not None else None,
|
50
50
|
)
|
omlish/sql/queries/unary.py
CHANGED
@@ -1,19 +1,26 @@
|
|
1
|
+
from ... import dataclasses as dc
|
1
2
|
from ... import lang
|
2
|
-
from .base import Node
|
3
3
|
from .exprs import CanExpr
|
4
4
|
from .exprs import Expr
|
5
5
|
from .exprs import ExprBuilder
|
6
|
+
from .ops import OpKind
|
6
7
|
|
7
8
|
|
8
9
|
##
|
9
10
|
|
10
11
|
|
11
|
-
class UnaryOp(
|
12
|
+
class UnaryOp(dc.Frozen, lang.Final, eq=False):
|
12
13
|
name: str
|
14
|
+
kind: OpKind
|
13
15
|
|
14
16
|
|
15
17
|
class UnaryOps(lang.Namespace):
|
16
|
-
NOT = UnaryOp('not')
|
18
|
+
NOT = UnaryOp('not', OpKind.CMP)
|
19
|
+
IS_NULL = UnaryOp('is_null', OpKind.CMP)
|
20
|
+
IS_NOT_NULL = UnaryOp('is_not_null', OpKind.CMP)
|
21
|
+
|
22
|
+
POS = UnaryOp('pos', OpKind.ARITH)
|
23
|
+
NEG = UnaryOp('neg', OpKind.ARITH)
|
17
24
|
|
18
25
|
|
19
26
|
class Unary(Expr, lang.Final):
|
@@ -25,5 +32,21 @@ class UnaryBuilder(ExprBuilder):
|
|
25
32
|
def unary(self, op: UnaryOp, v: CanExpr) -> Unary:
|
26
33
|
return Unary(op, self.expr(v))
|
27
34
|
|
35
|
+
#
|
36
|
+
|
28
37
|
def not_(self, v: CanExpr) -> Unary:
|
29
38
|
return self.unary(UnaryOps.NOT, v)
|
39
|
+
|
40
|
+
def is_null(self, v: CanExpr) -> Unary:
|
41
|
+
return self.unary(UnaryOps.IS_NULL, v)
|
42
|
+
|
43
|
+
def is_not_null(self, v: CanExpr) -> Unary:
|
44
|
+
return self.unary(UnaryOps.IS_NOT_NULL, v)
|
45
|
+
|
46
|
+
#
|
47
|
+
|
48
|
+
def pos(self, v: CanExpr) -> Unary:
|
49
|
+
return self.unary(UnaryOps.POS, v)
|
50
|
+
|
51
|
+
def neg(self, v: CanExpr) -> Unary:
|
52
|
+
return self.unary(UnaryOps.NEG, v)
|
omlish/sql/tabledefs/marshal.py
CHANGED
@@ -10,10 +10,7 @@ def _install_poly(cls: type) -> None:
|
|
10
10
|
msh.STANDARD_UNMARSHALER_FACTORIES[0:0] = [msh.PolymorphismUnmarshalerFactory(p)]
|
11
11
|
|
12
12
|
|
13
|
-
@lang.
|
13
|
+
@lang.static_init
|
14
14
|
def _install_standard_marshalling() -> None:
|
15
15
|
_install_poly(Dtype)
|
16
16
|
_install_poly(Element)
|
17
|
-
|
18
|
-
|
19
|
-
_install_standard_marshalling()
|
@@ -1,10 +1,10 @@
|
|
1
1
|
omlish/.manifests.json,sha256=TXvFdkAU0Zr2FKdo7fyvt9nr3UjCtrnAZ0diZXSAteE,1430
|
2
|
-
omlish/__about__.py,sha256=
|
2
|
+
omlish/__about__.py,sha256=6L5yBogPnXXOqNId_oVRZJ4kjVB68VskkdZvIJ7NlE0,3420
|
3
3
|
omlish/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
omlish/argparse.py,sha256=Dc73G8lyoQBLvXhMYUbzQUh4SJu_OTvKUXjSUxq_ang,7499
|
5
5
|
omlish/c3.py,sha256=4vogWgwPb8TbNS2KkZxpoWbwjj7MuHG2lQG-hdtkvjI,8062
|
6
6
|
omlish/cached.py,sha256=UAizxlH4eMWHPzQtmItmyE6FEpFEUFzIkxaO2BHWZ5s,196
|
7
|
-
omlish/check.py,sha256=
|
7
|
+
omlish/check.py,sha256=rZFEn6IHiMq4KGCYxlUGcUCJP12pPPUs_-AG0aouPM8,10540
|
8
8
|
omlish/datetimes.py,sha256=HajeM1kBvwlTa-uR1TTZHmZ3zTPnnUr1uGGQhiO1XQ0,2152
|
9
9
|
omlish/defs.py,sha256=T3bq_7h_tO3nDB5RAFBn7DkdeQgqheXzkFColbOHZko,4890
|
10
10
|
omlish/dynamic.py,sha256=35C_cCX_Vq2HrHzGk5T-zbrMvmUdiIiwDzDNixczoDo,6541
|
@@ -132,13 +132,13 @@ omlish/dataclasses/impl/as_.py,sha256=CD-t7hkC1EP2F_jvZKIA_cVoDuwZ-Ln_xC4fJumPYX
|
|
132
132
|
omlish/dataclasses/impl/copy.py,sha256=Tn8_n6Vohs-w4otbGdubBEvhd3TsSTaM3EfNGdS2LYo,591
|
133
133
|
omlish/dataclasses/impl/descriptors.py,sha256=rEYE1Len99agTQCC25hSPMnM19BgPr0ZChABGi58Fdk,2476
|
134
134
|
omlish/dataclasses/impl/exceptions.py,sha256=DeiM6rcjgncudn-XVuph9TDbVDEwBtyYb1bcbO3FFcA,193
|
135
|
-
omlish/dataclasses/impl/fields.py,sha256=
|
135
|
+
omlish/dataclasses/impl/fields.py,sha256=mr8tnSDceHGZ6VBbeegt-iCzQJbtCXoWOUwltjRULy4,6521
|
136
136
|
omlish/dataclasses/impl/frozen.py,sha256=x87DSM8FIMZ3c_BIUE8NooCkExFjPsabeqIueEP5qKs,2988
|
137
137
|
omlish/dataclasses/impl/hashing.py,sha256=FKnHuXCg9ylrzK2TLGqO5yfRN4HX3F415CSLlVYXtYE,3190
|
138
138
|
omlish/dataclasses/impl/init.py,sha256=IgxO9nwHaHF8jGrUAk-Y5xke9uV2OwzfEe-88McE1Wg,6161
|
139
139
|
omlish/dataclasses/impl/internals.py,sha256=UvZYjrLT1S8ntyxJ_vRPIkPOF00K8HatGAygErgoXTU,2990
|
140
140
|
omlish/dataclasses/impl/main.py,sha256=Ti0PKbFKraKvfmoPuR-G7nLVNzRC8mvEuXhCuC-M2kc,2574
|
141
|
-
omlish/dataclasses/impl/metaclass.py,sha256=
|
141
|
+
omlish/dataclasses/impl/metaclass.py,sha256=Fb0ExFiyYdOpvck4ayXMr_vEVDvHLhe28Ns3F4aduM8,3222
|
142
142
|
omlish/dataclasses/impl/metadata.py,sha256=4veWwTr-aA0KP-Y1cPEeOcXHup9EKJTYNJ0ozIxtzD4,1401
|
143
143
|
omlish/dataclasses/impl/order.py,sha256=zWvWDkSTym8cc7vO1cLHqcBhhjOlucHOCUVJcdh4jt0,1369
|
144
144
|
omlish/dataclasses/impl/params.py,sha256=zsobAD6QvMAZeMsohP8nKFyv_w6Q4buocARQG1y1etA,2768
|
@@ -202,13 +202,13 @@ omlish/graphs/dot/rendering.py,sha256=2UgXvMRN4Z9cfIqLlC7Iu_8bWbwUDEL4opHHkFfSqT
|
|
202
202
|
omlish/graphs/dot/utils.py,sha256=_FMwn77WfiiAfLsRTOKWm4IYbNv5kQN22YJ5psw6CWg,801
|
203
203
|
omlish/http/__init__.py,sha256=-ENDALr8ehHvivRD6cxIbEC94t0RHhrakf6CQRDTc8o,625
|
204
204
|
omlish/http/asgi.py,sha256=wXhBZ21bEl32Kv9yBrRwUR_7pHEgVtHP8ZZwbasQ6-4,3307
|
205
|
-
omlish/http/clients.py,sha256=
|
205
|
+
omlish/http/clients.py,sha256=eOY4bmbGdXuOOabt9NLAcTO7G49u85-HoAFW28mCXS4,6004
|
206
206
|
omlish/http/collections.py,sha256=s8w5s4Gewgxxhe2Ai0R45PgJYYifrLgTbU3VXVflHj4,260
|
207
207
|
omlish/http/consts.py,sha256=FTolezLknKU6WJjk_x2T3a5LEMlnZSqv7gzTq55lxcU,2147
|
208
208
|
omlish/http/cookies.py,sha256=uuOYlHR6e2SC3GM41V0aozK10nef9tYg83Scqpn5-HM,6351
|
209
209
|
omlish/http/dates.py,sha256=Otgp8wRxPgNGyzx8LFowu1vC4EKJYARCiAwLFncpfHM,2875
|
210
210
|
omlish/http/encodings.py,sha256=w2WoKajpaZnQH8j-IBvk5ZFL2O2pAU_iBvZnkocaTlw,164
|
211
|
-
omlish/http/headers.py,sha256=
|
211
|
+
omlish/http/headers.py,sha256=S66wiXezBHybrnjAM15E9x4GJvPRvFQHeKaXdJ799fw,5028
|
212
212
|
omlish/http/json.py,sha256=9XwAsl4966Mxrv-1ytyCqhcE6lbBJw-0_tFZzGszgHE,7440
|
213
213
|
omlish/http/sessions.py,sha256=VZ_WS5uiQG5y7i3u8oKuQMqf8dPKUOjFm_qk_0OvI8c,4793
|
214
214
|
omlish/http/wsgi.py,sha256=czZsVUX-l2YTlMrUjKN49wRoP4rVpS0qpeBn4O5BoMY,948
|
@@ -299,7 +299,7 @@ omlish/marshal/base.py,sha256=_ZKSSuv6p9r86sja_jaxI09WYpjCBFi0KTsOiZCYyk0,6587
|
|
299
299
|
omlish/marshal/base64.py,sha256=F-3ogJdcFCtWINRgJgWT0rErqgx6f4qahhcg8OrkqhE,1089
|
300
300
|
omlish/marshal/dataclasses.py,sha256=G6Uh8t4vvNBAx2BhzH8ksj8Hq_bo6npFphQhyF298VU,6892
|
301
301
|
omlish/marshal/datetimes.py,sha256=0ffg8cEvx9SMKIXZGD9b7MqpLfmgw0uKKdn6YTfoqok,3714
|
302
|
-
omlish/marshal/enums.py,sha256
|
302
|
+
omlish/marshal/enums.py,sha256=CMAbx6RI2EcQoo7SoD-5q2l-3DFKreWMiOxs6mFpl_4,1472
|
303
303
|
omlish/marshal/exceptions.py,sha256=jwQWn4LcPnadT2KRI_1JJCOSkwWh0yHnYK9BmSkNN4U,302
|
304
304
|
omlish/marshal/factories.py,sha256=UV2Svjok-lTWsRqKGh-CeuAhvlohw9uJe7ZLyoKMvTM,2968
|
305
305
|
omlish/marshal/forbidden.py,sha256=BNshzm4lN5O8sUZ1YvxrSYq3WPklq9NMQCRZ7RC3DLM,865
|
@@ -388,24 +388,27 @@ omlish/sql/alchemy/duckdb.py,sha256=kr7pIhiBLNAuZrcigHDtFg9zHkVcrRW3LfryO9VJ4mk,
|
|
388
388
|
omlish/sql/alchemy/exprs.py,sha256=gO4Fj4xEY-PuDgV-N8hBMy55glZz7O-4H7v1LWabfZY,323
|
389
389
|
omlish/sql/alchemy/secrets.py,sha256=EMfy4EfTbEvrlv_41oOhn8qsoF-eTkY7HciPenIE6rI,178
|
390
390
|
omlish/sql/alchemy/sqlean.py,sha256=RbkuOuFIfM4fowwKk8-sQ6Dxk-tTUwxS94nY5Kxt52s,403
|
391
|
-
omlish/sql/queries/__init__.py,sha256=
|
391
|
+
omlish/sql/queries/__init__.py,sha256=BdhONMw2JebX-jEgYb1WrM5L3vkJOzQRm0nt04IYKgQ,1229
|
392
392
|
omlish/sql/queries/base.py,sha256=_8O3MbH_OEjBnhp2oIJUZ3ClaQ8l4Sj9BdPdsP0Ie-g,224
|
393
|
-
omlish/sql/queries/binary.py,sha256=
|
394
|
-
omlish/sql/queries/
|
393
|
+
omlish/sql/queries/binary.py,sha256=dcEzeEn104AMPuQ7QrJU2O-YCN3SUdxB5S4jaWKOUqY,2253
|
394
|
+
omlish/sql/queries/building.py,sha256=pddD8-WDDGwX97OW7MLahaZTLsO_0NLxxIIAXXq1N40,537
|
395
|
+
omlish/sql/queries/exprs.py,sha256=kAI5PmvfJ-TqEzzc9H4_womFShT1eA0jWSZH2j2Wg-c,1802
|
395
396
|
omlish/sql/queries/idents.py,sha256=erW6fE9UapuvW1ZeLfGFz7yuW6zzktWIWmOuAHeF8_g,496
|
396
|
-
omlish/sql/queries/
|
397
|
+
omlish/sql/queries/marshal.py,sha256=MKZ3CVcr7mpnmg25twVgErWk1SpRBEkE1mu2fE8QwUA,2508
|
398
|
+
omlish/sql/queries/multi.py,sha256=KKHf8uS3Akk-YACPUwaqQO20NlDdrB3gbauOAejZzgU,832
|
397
399
|
omlish/sql/queries/names.py,sha256=YiIyS6ehYMYrdLlUxMawV_Xf2zdi7RwVO9Qsxr_W4_4,772
|
398
|
-
omlish/sql/queries/
|
399
|
-
omlish/sql/queries/
|
400
|
-
omlish/sql/queries/
|
400
|
+
omlish/sql/queries/ops.py,sha256=B7IDfjr2DW5LJhWoNaY1WW90BJhe5ZtmxIELhWXbW-0,129
|
401
|
+
omlish/sql/queries/relations.py,sha256=-d3n-dN17c3TPMZmzSplhWawllUzdq12XPDAuzoeMEQ,838
|
402
|
+
omlish/sql/queries/rendering.py,sha256=AC2PSGFCLXYk38mnH7EAMV7hQOKp5x6O-ZYV8FXgnAM,4360
|
403
|
+
omlish/sql/queries/selects.py,sha256=EcHlyKl5kGSY1d3GVxnImhGCTB6WvwQnlSA9eZanBqU,1364
|
401
404
|
omlish/sql/queries/stmts.py,sha256=pBqwD7dRlqMu6uh6vR3xaWOEgbZCcFWbOQ9ryYd17T4,441
|
402
|
-
omlish/sql/queries/unary.py,sha256=
|
405
|
+
omlish/sql/queries/unary.py,sha256=MEYBDZn_H0bexmUrJeONOv5-gIpYowUaXOsEHeQM4ks,1144
|
403
406
|
omlish/sql/tabledefs/__init__.py,sha256=TvtQsp-jJu6_ZahyCOFAaElSSBcRftNyJpdiDPGYCDk,190
|
404
407
|
omlish/sql/tabledefs/alchemy.py,sha256=MiNfVSgX_Ka6PmVTgAcCmS3ULK5mfVRXD_VC2-9TidU,485
|
405
408
|
omlish/sql/tabledefs/dtypes.py,sha256=egZDi-A17MC-4R_ZKR_3uQf1a6mGm91Gmh0b72O85bQ,362
|
406
409
|
omlish/sql/tabledefs/elements.py,sha256=lP_Ch19hKmiGYPQVeC8HpFaKdTYnXi2FfpfwKMxZOck,1674
|
407
410
|
omlish/sql/tabledefs/lower.py,sha256=YQf8gl1kxD5Fm-vOxV6G0Feh_D9PP1pYwz_vz6XjTPQ,1405
|
408
|
-
omlish/sql/tabledefs/marshal.py,sha256=
|
411
|
+
omlish/sql/tabledefs/marshal.py,sha256=j-Rz1HsiXmABv39-2VoJdzSSB3kbxqaVevbdkZWMyG8,504
|
409
412
|
omlish/sql/tabledefs/tabledefs.py,sha256=lIhvlt0pk6G7RZAtDFsFXm5j0l9BvRfnP7vNGeydHtE,816
|
410
413
|
omlish/testing/__init__.py,sha256=M_BQrcCHkoL-ZvE-UpQ8XxXNYRRawhjUz4rCJnAqM2A,152
|
411
414
|
omlish/testing/testing.py,sha256=TT2wwSzPZ_KhIvKxpM1qc1yHKD-LHDNgGrcr_h8vs7c,2895
|
@@ -433,9 +436,9 @@ omlish/text/delimit.py,sha256=ubPXcXQmtbOVrUsNh5gH1mDq5H-n1y2R4cPL5_DQf68,4928
|
|
433
436
|
omlish/text/glyphsplit.py,sha256=Ug-dPRO7x-OrNNr8g1y6DotSZ2KH0S-VcOmUobwa4B0,3296
|
434
437
|
omlish/text/indent.py,sha256=6Jj6TFY9unaPa4xPzrnZemJ-fHsV53IamP93XGjSUHs,1274
|
435
438
|
omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
|
436
|
-
omlish-0.0.0.
|
437
|
-
omlish-0.0.0.
|
438
|
-
omlish-0.0.0.
|
439
|
-
omlish-0.0.0.
|
440
|
-
omlish-0.0.0.
|
441
|
-
omlish-0.0.0.
|
439
|
+
omlish-0.0.0.dev74.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
440
|
+
omlish-0.0.0.dev74.dist-info/METADATA,sha256=fnVoKX28JDI8_XtMIkZGO22Po_cPDkZIi8nGwf6A_84,4167
|
441
|
+
omlish-0.0.0.dev74.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
442
|
+
omlish-0.0.0.dev74.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
|
443
|
+
omlish-0.0.0.dev74.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
|
444
|
+
omlish-0.0.0.dev74.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|