omlish 0.0.0.dev167__py3-none-any.whl → 0.0.0.dev169__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.dev167'
2
- __revision__ = '4dc487c3620d4629b8a2895a84511a4be478a801'
1
+ __version__ = '0.0.0.dev169'
2
+ __revision__ = 'ad8bd22d9c1cd7a5a22af3b9d27906ce64fd8451'
3
3
 
4
4
 
5
5
  #
omlish/lite/check.py CHANGED
@@ -2,6 +2,8 @@
2
2
  """
3
3
  TODO:
4
4
  - def maybe(v: lang.Maybe[T])
5
+ - def not_ ?
6
+ - ** class @dataclass Raise - user message should be able to be an exception type or instance or factory
5
7
  """
6
8
  import collections
7
9
  import threading
@@ -0,0 +1,32 @@
1
+ # ruff: noqa: UP006 UP007
2
+ import dataclasses as dc
3
+
4
+
5
+ def cache_dataclass_hash(
6
+ *,
7
+ cached_hash_attr: str = '__dataclass_hash__',
8
+ ):
9
+ def inner(cls):
10
+ if not isinstance(cls, type) and dc.is_dataclass(cls):
11
+ raise TypeError(cls)
12
+
13
+ if (
14
+ cls.__hash__ is object.__hash__ or
15
+ '__hash__' not in cls.__dict__
16
+ ):
17
+ raise TypeError(cls)
18
+
19
+ real_hash = cls.__hash__
20
+
21
+ def cached_hash(self) -> int:
22
+ try:
23
+ return object.__getattribute__(self, cached_hash_attr)
24
+ except AttributeError:
25
+ object.__setattr__(self, cached_hash_attr, h := real_hash(self)) # type: ignore[call-arg]
26
+ return h
27
+
28
+ cls.__hash__ = cached_hash # type: ignore[method-assign]
29
+
30
+ return cls
31
+
32
+ return inner
omlish/lite/strings.py CHANGED
@@ -27,6 +27,28 @@ def strip_with_newline(s: str) -> str:
27
27
  return s.strip() + '\n'
28
28
 
29
29
 
30
+ @ta.overload
31
+ def split_keep_delimiter(s: str, d: str) -> str:
32
+ ...
33
+
34
+
35
+ @ta.overload
36
+ def split_keep_delimiter(s: bytes, d: bytes) -> bytes:
37
+ ...
38
+
39
+
40
+ def split_keep_delimiter(s, d):
41
+ ps = []
42
+ i = 0
43
+ while i < len(s):
44
+ if (n := s.find(d, i)) < i:
45
+ ps.append(s[i:])
46
+ break
47
+ ps.append(s[i:n + 1])
48
+ i = n + 1
49
+ return ps
50
+
51
+
30
52
  ##
31
53
 
32
54
 
omlish/os/paths.py CHANGED
@@ -21,8 +21,12 @@ def relative_symlink(
21
21
  *,
22
22
  target_is_directory: bool = False,
23
23
  dir_fd: ta.Optional[int] = None,
24
+ make_dirs: bool = False,
24
25
  **kwargs: ta.Any,
25
26
  ) -> None:
27
+ if make_dirs:
28
+ os.makedirs(os.path.dirname(dst), exist_ok=True)
29
+
26
30
  os.symlink(
27
31
  os.path.relpath(src, os.path.dirname(dst)),
28
32
  dst,
@@ -22,13 +22,13 @@ from .exprs import ( # noqa
22
22
  ExprBuilder,
23
23
  Literal,
24
24
  NameExpr,
25
- Param,
26
25
  )
27
26
 
28
27
  from .idents import ( # noqa
29
28
  CanIdent,
30
29
  Ident,
31
30
  IdentBuilder,
31
+ IdentLike,
32
32
  )
33
33
 
34
34
  from .multi import ( # noqa
@@ -41,12 +41,20 @@ from .names import ( # noqa
41
41
  CanName,
42
42
  Name,
43
43
  NameBuilder,
44
+ NameLike,
44
45
  )
45
46
 
46
47
  from .ops import ( # noqa
47
48
  OpKind,
48
49
  )
49
50
 
51
+ from .params import ( # noqa
52
+ CanParam,
53
+ Param,
54
+ ParamBuilder,
55
+ as_param,
56
+ )
57
+
50
58
  from .relations import ( # noqa
51
59
  CanRelation,
52
60
  CanTable,
@@ -5,6 +5,7 @@ from .idents import IdentBuilder
5
5
  from .inserts import InsertBuilder
6
6
  from .multi import MultiBuilder
7
7
  from .names import NameBuilder
8
+ from .params import ParamBuilder
8
9
  from .relations import RelationBuilder
9
10
  from .selects import SelectBuilder
10
11
  from .stmts import StmtBuilder
@@ -23,6 +24,8 @@ class StdBuilder(
23
24
 
24
25
  RelationBuilder,
25
26
 
27
+ ParamBuilder,
28
+
26
29
  NameBuilder,
27
30
  IdentBuilder,
28
31
 
@@ -8,10 +8,11 @@ import typing as ta
8
8
  from ... import lang
9
9
  from .base import Node
10
10
  from .base import Value
11
- from .idents import Ident
11
+ from .idents import IdentLike
12
12
  from .names import CanName
13
13
  from .names import Name
14
14
  from .names import NameBuilder
15
+ from .names import NameLike
15
16
 
16
17
 
17
18
  ##
@@ -21,30 +22,21 @@ class Expr(Node, lang.Abstract):
21
22
  pass
22
23
 
23
24
 
25
+ #
26
+
27
+
24
28
  class Literal(Expr, lang.Final):
25
29
  v: Value
26
30
 
27
31
 
28
- class NameExpr(Expr, lang.Final):
29
- n: Name
32
+ #
30
33
 
31
34
 
32
- class Param(Expr, lang.Final):
33
- n: str | None = None
35
+ class NameExpr(Expr, lang.Final):
36
+ n: Name
34
37
 
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
38
 
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
39
+ ##
48
40
 
49
41
 
50
42
  CanLiteral: ta.TypeAlias = Literal | Value
@@ -69,7 +61,7 @@ class ExprBuilder(NameBuilder):
69
61
  def expr(self, o: CanExpr) -> Expr:
70
62
  if isinstance(o, Expr):
71
63
  return o
72
- elif isinstance(o, (Name, Ident)):
64
+ elif isinstance(o, (NameLike, IdentLike)):
73
65
  return NameExpr(self.name(o))
74
66
  else:
75
67
  return self.literal(o)
@@ -77,12 +69,3 @@ class ExprBuilder(NameBuilder):
77
69
  @ta.final
78
70
  def e(self, o: CanExpr) -> Expr:
79
71
  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)
@@ -1,3 +1,5 @@
1
+ import abc
2
+ import functools
1
3
  import typing as ta
2
4
 
3
5
  from ... import lang
@@ -8,22 +10,58 @@ from .base import Node
8
10
  ##
9
11
 
10
12
 
11
- class Ident(Node, lang.Final):
13
+ class IdentLike(abc.ABC): # noqa
14
+ pass
15
+
16
+
17
+ ##
18
+
19
+
20
+ class Ident(Node, IdentLike, lang.Final):
12
21
  s: str
13
22
 
14
23
 
15
- CanIdent: ta.TypeAlias = Ident | str
24
+ ##
25
+
26
+
27
+ @functools.singledispatch
28
+ def as_ident(o: ta.Any) -> Ident:
29
+ raise TypeError(o)
30
+
31
+
32
+ @as_ident.register
33
+ def _(i: Ident) -> Ident:
34
+ return i
35
+
36
+
37
+ @as_ident.register
38
+ def _(s: str) -> Ident:
39
+ return Ident(s)
40
+
41
+
42
+ ##
43
+
44
+
45
+ CanIdent: ta.TypeAlias = IdentLike | Ident | str
46
+
47
+
48
+ class IdentAccessor(lang.Final):
49
+ def __getattr__(self, s: str) -> Ident:
50
+ return Ident(s)
51
+
52
+ def __call__(self, o: CanIdent) -> Ident:
53
+ return as_ident(o)
54
+
55
+
56
+ ##
16
57
 
17
58
 
18
59
  class IdentBuilder(Builder):
60
+ @ta.final
19
61
  def ident(self, o: CanIdent) -> Ident:
20
- if isinstance(o, Ident):
21
- return o
22
- elif isinstance(o, str):
23
- return Ident(o)
24
- else:
25
- raise TypeError(o)
62
+ return as_ident(o)
26
63
 
27
64
  @ta.final
28
- def i(self, o: CanIdent) -> Ident:
29
- return self.ident(o)
65
+ @property
66
+ def i(self) -> IdentAccessor:
67
+ return IdentAccessor()
@@ -1,34 +1,101 @@
1
+ import abc
2
+ import functools
1
3
  import typing as ta
2
4
 
5
+ from ... import check
3
6
  from ... import dataclasses as dc
4
7
  from ... import lang
5
8
  from .base import Node
6
9
  from .idents import CanIdent
7
10
  from .idents import Ident
8
11
  from .idents import IdentBuilder
12
+ from .idents import as_ident
9
13
 
10
14
 
11
15
  ##
12
16
 
13
17
 
14
- class Name(Node, lang.Final):
15
- ps: ta.Sequence[Ident] = dc.xfield(coerce=tuple)
18
+ class NameLike(abc.ABC): # noqa
19
+ pass
16
20
 
17
21
 
18
- CanName: ta.TypeAlias = Name | CanIdent | ta.Sequence[CanIdent]
22
+ ##
23
+
24
+
25
+ def _coerce_name_parts(o: ta.Iterable[Ident]) -> ta.Sequence[Ident]:
26
+ check.not_isinstance(o, str)
27
+ return check.not_empty(tuple(check.isinstance(e, Ident) for e in o))
28
+
29
+
30
+ class Name(Node, NameLike, lang.Final):
31
+ ps: ta.Sequence[Ident] = dc.xfield(coerce=_coerce_name_parts)
32
+
33
+
34
+ ##
35
+
36
+
37
+ @functools.singledispatch
38
+ def as_name(o: ta.Any) -> Name:
39
+ if isinstance(o, ta.Sequence):
40
+ return Name([as_ident(p) for p in o])
41
+ else:
42
+ raise TypeError(o)
43
+
44
+
45
+ @as_name.register
46
+ def _(n: Name) -> Name:
47
+ return n
48
+
49
+
50
+ @as_name.register
51
+ def _(o: Ident | str) -> Name:
52
+ return Name([as_ident(o)])
53
+
54
+
55
+ ##
56
+
57
+
58
+ CanName: ta.TypeAlias = ta.Union[
59
+ NameLike,
60
+ Name,
61
+ CanIdent,
62
+ ta.Sequence[CanIdent],
63
+ 'NameAccessor',
64
+ ]
65
+
66
+
67
+ class NameAccessor(NameLike, lang.Final):
68
+ def __init__(self, ps: tuple[str, ...] = ()) -> None:
69
+ super().__init__()
70
+ self.__query_name_parts__ = ps
71
+
72
+ def __repr__(self) -> str:
73
+ return f'{self.__class__.__name__}({self.__query_name_parts__!r})'
74
+
75
+ def __getattr__(self, s: str) -> 'NameAccessor':
76
+ return NameAccessor((*self.__query_name_parts__, s))
77
+
78
+ def __call__(self, o: CanName) -> Name:
79
+ n = as_name(o)
80
+ if (ps := self.__query_name_parts__):
81
+ n = Name(tuple(*tuple(Ident(p) for p in ps), *n.ps)) # type: ignore[arg-type]
82
+ return n
83
+
84
+
85
+ @as_name.register
86
+ def _(a: NameAccessor) -> Name:
87
+ return Name(tuple(Ident(p) for p in a.__query_name_parts__))
88
+
89
+
90
+ ##
19
91
 
20
92
 
21
93
  class NameBuilder(IdentBuilder):
94
+ @ta.final
22
95
  def name(self, o: CanName) -> Name:
23
- if isinstance(o, Name):
24
- return o
25
- elif isinstance(o, (Ident, str)):
26
- return Name([self.ident(o)])
27
- elif isinstance(o, ta.Sequence):
28
- return Name([self.ident(p) for p in o])
29
- else:
30
- raise TypeError(o)
96
+ return as_name(o)
31
97
 
32
98
  @ta.final
33
- def n(self, o: CanName) -> Name:
34
- return self.name(o)
99
+ @property
100
+ def n(self) -> NameAccessor:
101
+ return NameAccessor()
@@ -0,0 +1,64 @@
1
+ import typing as ta
2
+
3
+ from ... import lang
4
+ from .base import Builder
5
+ from .exprs import Expr
6
+
7
+
8
+ ##
9
+
10
+
11
+ class Param(Expr, lang.Final):
12
+ n: str | None = None
13
+
14
+ def __repr__(self) -> str:
15
+ if self.n is not None:
16
+ return f'{self.__class__.__name__}({self.n!r})'
17
+ else:
18
+ return f'{self.__class__.__name__}(@{hex(id(self))[2:]})'
19
+
20
+ def __eq__(self, other):
21
+ if not isinstance(other, Param):
22
+ return False
23
+ if self.n is None and other.n is None:
24
+ return self is other
25
+ else:
26
+ return self.n == other.n
27
+
28
+
29
+ ##
30
+
31
+
32
+ CanParam: ta.TypeAlias = Param | str | None
33
+
34
+
35
+ def as_param(o: CanParam = None) -> Param:
36
+ if isinstance(o, Param):
37
+ return o
38
+ else:
39
+ return Param(o)
40
+
41
+
42
+ ##
43
+
44
+
45
+ class ParamAccessor(lang.Final):
46
+ def __getattr__(self, s: str) -> Param:
47
+ return Param(s)
48
+
49
+ def __call__(self, o: CanParam = None) -> Param:
50
+ return as_param(o)
51
+
52
+
53
+ ##
54
+
55
+
56
+ class ParamBuilder(Builder):
57
+ @ta.final
58
+ def param(self, o: CanParam = None) -> Param:
59
+ return as_param(o)
60
+
61
+ @ta.final
62
+ @property
63
+ def p(self) -> ParamAccessor:
64
+ return ParamAccessor()
@@ -29,13 +29,13 @@ from .binary import BinaryOp
29
29
  from .binary import BinaryOps
30
30
  from .exprs import Literal
31
31
  from .exprs import NameExpr
32
- from .exprs import Param
33
32
  from .idents import Ident
34
33
  from .inserts import Insert
35
34
  from .inserts import Values
36
35
  from .multi import Multi
37
36
  from .multi import MultiKind
38
37
  from .names import Name
38
+ from .params import Param
39
39
  from .relations import Table
40
40
  from .selects import Select
41
41
  from .selects import SelectItem
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omlish
3
- Version: 0.0.0.dev167
3
+ Version: 0.0.0.dev169
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -1,5 +1,5 @@
1
1
  omlish/.manifests.json,sha256=0BnQGD2dcXEma0Jop2ZesvDNzSj3CAJBNq8aTGuBz9A,7276
2
- omlish/__about__.py,sha256=6MZuOZq8DwHRIcwPmVPdl5xZJjs_D7eV9-nFWn00wgI,3409
2
+ omlish/__about__.py,sha256=Vbn2IOi3EX8LX5PEfmtAHPOYwizDkndZ2-r_FU5omCw,3409
3
3
  omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
4
4
  omlish/c3.py,sha256=ubu7lHwss5V4UznbejAI0qXhXahrU01MysuHOZI9C4U,8116
5
5
  omlish/cached.py,sha256=UI-XTFBwA6YXWJJJeBn-WkwBkfzDjLBBaZf4nIJA9y0,510
@@ -367,8 +367,9 @@ omlish/lifecycles/states.py,sha256=zqMOU2ZU-MDNnWuwauM3_anIAiXM8LoBDElDEraptFg,1
367
367
  omlish/lifecycles/transitions.py,sha256=qQtFby-h4VzbvgaUqT2NnbNumlcOx9FVVADP9t83xj4,1939
368
368
  omlish/lite/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
369
369
  omlish/lite/cached.py,sha256=O7ozcoDNFm1Hg2wtpHEqYSp_i_nCLNOP6Ueq_Uk-7mU,1300
370
- omlish/lite/check.py,sha256=KvcO86LqWlh2j4ORaZXRR4FM8fFb7kUkNqq3lTs0Ta0,12821
370
+ omlish/lite/check.py,sha256=0PD-GKtaDqDX6jU5KbzbMvH-vl6jH82xgYfplmfTQkg,12941
371
371
  omlish/lite/contextmanagers.py,sha256=m9JO--p7L7mSl4cycXysH-1AO27weDKjP3DZG61cwwM,1683
372
+ omlish/lite/dataclasses.py,sha256=Yaf56l2Lor8bcPCnhRVxvLnJoFqxKf9l358b3WsK8SM,848
372
373
  omlish/lite/inject.py,sha256=EEaioN9ESAveVCMe2s5osjwI97FPRUVoU8P95vGUiYo,23376
373
374
  omlish/lite/json.py,sha256=7-02Ny4fq-6YAu5ynvqoijhuYXWpLmfCI19GUeZnb1c,740
374
375
  omlish/lite/logs.py,sha256=CWFG0NKGhqNeEgryF5atN2gkPYbUdTINEw_s1phbINM,51
@@ -381,7 +382,7 @@ omlish/lite/runtime.py,sha256=XQo408zxTdJdppUZqOWHyeUR50VlCpNIExNGHz4U6O4,459
381
382
  omlish/lite/secrets.py,sha256=3Mz3V2jf__XU9qNHcH56sBSw95L3U2UPL24bjvobG0c,816
382
383
  omlish/lite/socket.py,sha256=7OYgkXTcQv0wq7TQuLnl9y6dJA1ZT6Vbc1JH59QlxgY,1792
383
384
  omlish/lite/socketserver.py,sha256=doTXIctu_6c8XneFtzPFVG_Wq6xVmA3p9ymut8IvBoU,1586
384
- omlish/lite/strings.py,sha256=SkCQPtw1grKGr1KFgJr3CL3ocvCEcPwH7XIzb-JxFAY,1610
385
+ omlish/lite/strings.py,sha256=nGWaOi9LzTjkc5kPN2IqsVN8PUw8m_2yllTGRUQU5PI,1983
385
386
  omlish/lite/typing.py,sha256=U3-JaEnkDSYxK4tsu_MzUn3RP6qALBe5FXQXpD-licE,1090
386
387
  omlish/logs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
387
388
  omlish/logs/abc.py,sha256=ho4ABKYMKX-V7g4sp1BByuOLzslYzLlQ0MESmjEpT-o,8005
@@ -438,7 +439,7 @@ omlish/os/deathsig.py,sha256=hk9Yq2kyDdI-cI7OQH7mOfpRbOKzY_TfPKEqgrjVYbA,641
438
439
  omlish/os/files.py,sha256=1tNy1z5I_CgYKA5c6lOfsXc-hknP4tQDbSShdz8HArw,1308
439
440
  omlish/os/journald.py,sha256=2nI8Res1poXkbLc31--MPUlzYMESnCcPUkIxDOCjZW0,3903
440
441
  omlish/os/linux.py,sha256=whJ6scwMKSFBdXiVhJW0BCpJV4jOGMr-a_a3Bhwz6Ls,18938
441
- omlish/os/paths.py,sha256=o1vTpQgbOQR0X6Wtb_7oqajxykMy58yJ0WCQIaY9gAA,735
442
+ omlish/os/paths.py,sha256=hqPiyg_eYaRoIVPdAeX4oeLEV4Kpln_XsH0tHvbOf8Q,844
442
443
  omlish/os/pidfile.py,sha256=S4Nbe00oSxckY0qCC9AeTEZe7NSw4eJudnQX7wCXzks,1738
443
444
  omlish/os/sizes.py,sha256=ohkALLvqSqBX4iR-7DMKJ4pfOCRdZXV8htH4QywUNM0,152
444
445
  omlish/reflect/__init__.py,sha256=4-EuCSX1qpEWfScCFzAJv_XghHFu4cXxpxKeBKrosQ4,720
@@ -507,19 +508,20 @@ omlish/sql/alchemy/duckdb.py,sha256=kr7pIhiBLNAuZrcigHDtFg9zHkVcrRW3LfryO9VJ4mk,
507
508
  omlish/sql/alchemy/exprs.py,sha256=gO4Fj4xEY-PuDgV-N8hBMy55glZz7O-4H7v1LWabfZY,323
508
509
  omlish/sql/alchemy/secrets.py,sha256=EMfy4EfTbEvrlv_41oOhn8qsoF-eTkY7HciPenIE6rI,178
509
510
  omlish/sql/alchemy/sqlean.py,sha256=RbkuOuFIfM4fowwKk8-sQ6Dxk-tTUwxS94nY5Kxt52s,403
510
- omlish/sql/queries/__init__.py,sha256=BdhONMw2JebX-jEgYb1WrM5L3vkJOzQRm0nt04IYKgQ,1229
511
+ omlish/sql/queries/__init__.py,sha256=8wdq6PBf5YzqQWFu-CE8om6BN38sDAD9UEz9VzkojzM,1337
511
512
  omlish/sql/queries/base.py,sha256=_8O3MbH_OEjBnhp2oIJUZ3ClaQ8l4Sj9BdPdsP0Ie-g,224
512
513
  omlish/sql/queries/binary.py,sha256=dcEzeEn104AMPuQ7QrJU2O-YCN3SUdxB5S4jaWKOUqY,2253
513
- omlish/sql/queries/building.py,sha256=dIQyEqNef2egKAf5qO_aZvXxlAEfxIGWS23qvJ-ozqQ,591
514
- omlish/sql/queries/exprs.py,sha256=kAI5PmvfJ-TqEzzc9H4_womFShT1eA0jWSZH2j2Wg-c,1802
515
- omlish/sql/queries/idents.py,sha256=erW6fE9UapuvW1ZeLfGFz7yuW6zzktWIWmOuAHeF8_g,496
514
+ omlish/sql/queries/building.py,sha256=lmHItVEi0IkIDEhYL1le8adNhjah0SHhffm59CZtpH4,643
515
+ omlish/sql/queries/exprs.py,sha256=THeSyFF8bouDvU-Keej-hyFUwbp63bw0HpAF4lCYuiQ,1187
516
+ omlish/sql/queries/idents.py,sha256=w2RxO6SR3K-u30S259OtnAZaPv7YA70PzY9R7RtuCQ8,891
516
517
  omlish/sql/queries/inserts.py,sha256=Uo0ewnLPEt43dnX5AJWOC9ioViou7xYes7sGT9lD_0k,1281
517
518
  omlish/sql/queries/marshal.py,sha256=uLN_gOqiYHBQioZEvg7OREycY0bzKwzBw5mnbg_0cio,2938
518
519
  omlish/sql/queries/multi.py,sha256=7x6x-4jnPzxA6ZasBjnjFuhHFpWt5rGCua3UvuTMIJ0,837
519
- omlish/sql/queries/names.py,sha256=YiIyS6ehYMYrdLlUxMawV_Xf2zdi7RwVO9Qsxr_W4_4,772
520
+ omlish/sql/queries/names.py,sha256=4sDvgRobMEt_6mDeuYVbCqHzLCOwpXUdEyyB4-QjxKo,1996
520
521
  omlish/sql/queries/ops.py,sha256=B7IDfjr2DW5LJhWoNaY1WW90BJhe5ZtmxIELhWXbW-0,129
522
+ omlish/sql/queries/params.py,sha256=iR8tnetkZFWY378iUbPe08d86g-Wf1J3YqfZr_KhIwQ,1175
521
523
  omlish/sql/queries/relations.py,sha256=-d3n-dN17c3TPMZmzSplhWawllUzdq12XPDAuzoeMEQ,838
522
- omlish/sql/queries/rendering.py,sha256=DUmdsQqChCBxCSXSL0dDUz0H5joTL_qayhdErsWz6dQ,5945
524
+ omlish/sql/queries/rendering.py,sha256=NOJqwxK8yt3Morq5yhgI-zU_51MSyhDvSc8S-8tURVM,5946
523
525
  omlish/sql/queries/selects.py,sha256=8dqm4KyrJvOsW3KHSO7qLEfPlZa7sJDp8puuGxrfvoA,1369
524
526
  omlish/sql/queries/stmts.py,sha256=pBqwD7dRlqMu6uh6vR3xaWOEgbZCcFWbOQ9ryYd17T4,441
525
527
  omlish/sql/queries/unary.py,sha256=MEYBDZn_H0bexmUrJeONOv5-gIpYowUaXOsEHeQM4ks,1144
@@ -557,9 +559,9 @@ omlish/text/glyphsplit.py,sha256=Ug-dPRO7x-OrNNr8g1y6DotSZ2KH0S-VcOmUobwa4B0,329
557
559
  omlish/text/indent.py,sha256=6Jj6TFY9unaPa4xPzrnZemJ-fHsV53IamP93XGjSUHs,1274
558
560
  omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
559
561
  omlish/text/random.py,sha256=jNWpqiaKjKyTdMXC-pWAsSC10AAP-cmRRPVhm59ZWLk,194
560
- omlish-0.0.0.dev167.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
561
- omlish-0.0.0.dev167.dist-info/METADATA,sha256=XQoZ5IEtdiX_6-I2wMBv-GB3-Nz6-WbQLpzCKbEjxkI,4264
562
- omlish-0.0.0.dev167.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
563
- omlish-0.0.0.dev167.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
564
- omlish-0.0.0.dev167.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
565
- omlish-0.0.0.dev167.dist-info/RECORD,,
562
+ omlish-0.0.0.dev169.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
563
+ omlish-0.0.0.dev169.dist-info/METADATA,sha256=CsUpWiDs5ax6CJfLmh_ssyLkwhwgoju6FMPzic0v_58,4264
564
+ omlish-0.0.0.dev169.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
565
+ omlish-0.0.0.dev169.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
566
+ omlish-0.0.0.dev169.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
567
+ omlish-0.0.0.dev169.dist-info/RECORD,,