omlish 0.0.0.dev424__py3-none-any.whl → 0.0.0.dev426__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.
Files changed (126) hide show
  1. omlish/__about__.py +3 -3
  2. omlish/c3.py +4 -1
  3. omlish/configs/processing/flattening.py +1 -1
  4. omlish/configs/processing/merging.py +8 -6
  5. omlish/dataclasses/impl/concerns/doc.py +1 -1
  6. omlish/dataclasses/impl/configs.py +2 -1
  7. omlish/diag/_pycharm/runhack.py +1 -1
  8. omlish/diag/procfs.py +2 -2
  9. omlish/formats/json/stream/lexing.py +69 -14
  10. omlish/formats/json/stream/parsing.py +1 -1
  11. omlish/formats/json/stream/utils.py +3 -0
  12. omlish/formats/json5/streams.py +22 -0
  13. omlish/formats/logfmt.py +8 -2
  14. omlish/funcs/genmachine.py +1 -1
  15. omlish/http/sse.py +1 -1
  16. omlish/inject/impl/injector.py +1 -1
  17. omlish/inject/impl/multis.py +2 -2
  18. omlish/inject/impl/providers.py +0 -4
  19. omlish/inject/impl/proxy.py +0 -2
  20. omlish/inject/scopes.py +0 -4
  21. omlish/io/buffers.py +1 -1
  22. omlish/lang/__init__.py +26 -14
  23. omlish/lang/asyncs.py +12 -0
  24. omlish/lang/{attrs.py → attrstorage.py} +15 -15
  25. omlish/lang/cached/property.py +2 -2
  26. omlish/lang/classes/simple.py +26 -4
  27. omlish/lang/collections.py +1 -1
  28. omlish/lang/functions.py +0 -11
  29. omlish/lang/iterables.py +2 -2
  30. omlish/lang/lazyglobals.py +27 -5
  31. omlish/lang/maysync.py +2 -2
  32. omlish/lifecycles/contextmanagers.py +1 -2
  33. omlish/lifecycles/controller.py +1 -2
  34. omlish/lite/asyncs.py +20 -0
  35. omlish/lite/attrops.py +332 -0
  36. omlish/lite/cached.py +1 -1
  37. omlish/lite/maybes.py +2 -0
  38. omlish/lite/strings.py +0 -7
  39. omlish/lite/timing.py +6 -3
  40. omlish/logs/all.py +25 -32
  41. omlish/logs/base.py +248 -0
  42. omlish/logs/callers.py +21 -15
  43. omlish/logs/infos.py +105 -0
  44. omlish/logs/levels.py +64 -0
  45. omlish/logs/modules.py +10 -0
  46. omlish/logs/protocols.py +31 -0
  47. omlish/logs/standard.py +12 -11
  48. omlish/logs/std/adapters.py +41 -0
  49. omlish/logs/std/configs.py +29 -0
  50. omlish/logs/{filters.py → std/filters.py} +1 -1
  51. omlish/logs/{handlers.py → std/handlers.py} +1 -1
  52. omlish/logs/{json.py → std/json.py} +2 -2
  53. omlish/logs/{proxy.py → std/proxy.py} +3 -3
  54. omlish/logs/std/records.py +286 -0
  55. omlish/logs/times.py +86 -0
  56. omlish/logs/typed/bindings.py +24 -0
  57. omlish/logs/utils.py +60 -4
  58. omlish/logs/warnings.py +8 -0
  59. omlish/manifests/loading.py +1 -1
  60. omlish/os/atomics.py +1 -1
  61. omlish/os/journald.py +3 -3
  62. omlish/reflect/types.py +22 -0
  63. omlish/testing/pytest/plugins/skips.py +0 -4
  64. {omlish-0.0.0.dev424.dist-info → omlish-0.0.0.dev426.dist-info}/METADATA +2 -2
  65. {omlish-0.0.0.dev424.dist-info → omlish-0.0.0.dev426.dist-info}/RECORD +72 -114
  66. omlish/defs.py +0 -216
  67. omlish/dispatch/_dispatch2.py +0 -69
  68. omlish/dispatch/_dispatch3.py +0 -108
  69. omlish/dynamic.py +0 -219
  70. omlish/formats/json/Json.g4 +0 -77
  71. omlish/formats/json/_antlr/JsonLexer.py +0 -109
  72. omlish/formats/json/_antlr/JsonListener.py +0 -61
  73. omlish/formats/json/_antlr/JsonParser.py +0 -457
  74. omlish/formats/json/_antlr/JsonVisitor.py +0 -42
  75. omlish/io/trampoline.py +0 -289
  76. omlish/lite/logs.py +0 -4
  77. omlish/lite/reprs.py +0 -85
  78. omlish/logs/abc.py +0 -319
  79. omlish/logs/color.py +0 -27
  80. omlish/logs/configs.py +0 -29
  81. omlish/logs/protocol.py +0 -218
  82. omlish/logs/timing.py +0 -58
  83. omlish/specs/irc/__init__.py +0 -0
  84. omlish/specs/irc/messages/__init__.py +0 -0
  85. omlish/specs/irc/messages/base.py +0 -49
  86. omlish/specs/irc/messages/formats.py +0 -92
  87. omlish/specs/irc/messages/messages.py +0 -774
  88. omlish/specs/irc/messages/parsing.py +0 -98
  89. omlish/specs/irc/numerics/__init__.py +0 -0
  90. omlish/specs/irc/numerics/formats.py +0 -97
  91. omlish/specs/irc/numerics/numerics.py +0 -865
  92. omlish/specs/irc/numerics/types.py +0 -59
  93. omlish/specs/irc/protocol/LICENSE +0 -11
  94. omlish/specs/irc/protocol/__init__.py +0 -61
  95. omlish/specs/irc/protocol/consts.py +0 -6
  96. omlish/specs/irc/protocol/errors.py +0 -30
  97. omlish/specs/irc/protocol/message.py +0 -21
  98. omlish/specs/irc/protocol/nuh.py +0 -55
  99. omlish/specs/irc/protocol/parsing.py +0 -158
  100. omlish/specs/irc/protocol/rendering.py +0 -153
  101. omlish/specs/irc/protocol/tags.py +0 -102
  102. omlish/specs/irc/protocol/utils.py +0 -30
  103. omlish/specs/proto/Protobuf3.g4 +0 -396
  104. omlish/specs/proto/__init__.py +0 -0
  105. omlish/specs/proto/_antlr/Protobuf3Lexer.py +0 -340
  106. omlish/specs/proto/_antlr/Protobuf3Listener.py +0 -448
  107. omlish/specs/proto/_antlr/Protobuf3Parser.py +0 -3909
  108. omlish/specs/proto/_antlr/Protobuf3Visitor.py +0 -257
  109. omlish/specs/proto/_antlr/__init__.py +0 -0
  110. omlish/specs/proto/nodes.py +0 -54
  111. omlish/specs/proto/parsing.py +0 -97
  112. omlish/sql/parsing/Minisql.g4 +0 -292
  113. omlish/sql/parsing/__init__.py +0 -0
  114. omlish/sql/parsing/_antlr/MinisqlLexer.py +0 -322
  115. omlish/sql/parsing/_antlr/MinisqlListener.py +0 -511
  116. omlish/sql/parsing/_antlr/MinisqlParser.py +0 -3763
  117. omlish/sql/parsing/_antlr/MinisqlVisitor.py +0 -292
  118. omlish/sql/parsing/_antlr/__init__.py +0 -0
  119. omlish/sql/parsing/parsing.py +0 -119
  120. /omlish/{.manifests.json → .omlish-manifests.json} +0 -0
  121. /omlish/{formats/json/_antlr → logs/std}/__init__.py +0 -0
  122. /omlish/logs/{noisy.py → std/noisy.py} +0 -0
  123. {omlish-0.0.0.dev424.dist-info → omlish-0.0.0.dev426.dist-info}/WHEEL +0 -0
  124. {omlish-0.0.0.dev424.dist-info → omlish-0.0.0.dev426.dist-info}/entry_points.txt +0 -0
  125. {omlish-0.0.0.dev424.dist-info → omlish-0.0.0.dev426.dist-info}/licenses/LICENSE +0 -0
  126. {omlish-0.0.0.dev424.dist-info → omlish-0.0.0.dev426.dist-info}/top_level.txt +0 -0
omlish/__about__.py CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev424'
2
- __revision__ = '74da5ba6eafb03e4fbf36459215eaf1864903ee2'
1
+ __version__ = '0.0.0.dev426'
2
+ __revision__ = '94f5fd2fe7124da5d9b5af104cba12b1bbdb3286'
3
3
 
4
4
 
5
5
  #
@@ -175,7 +175,7 @@ class SetuptoolsBase:
175
175
  '*.g4',
176
176
  '*.h',
177
177
 
178
- '.manifests.json',
178
+ '.omlish-manifests.json',
179
179
 
180
180
  'LICENSE',
181
181
  'LICENSE.txt',
omlish/c3.py CHANGED
@@ -33,6 +33,7 @@
33
33
  #
34
34
  # 8. By copying, installing or otherwise using Python, Licensee agrees to be bound by the terms and conditions of this
35
35
  # License Agreement.
36
+ import abc
36
37
  import functools
37
38
  import operator
38
39
  import typing as ta
@@ -75,7 +76,9 @@ def merge(seqs: ta.MutableSequence[list[T]]) -> list[T]:
75
76
 
76
77
 
77
78
  def _default_is_abstract(obj: ta.Any) -> bool:
78
- return hasattr(obj, '__abstractmethods__')
79
+ # .lite.abstracts.Abstract has '__abstractmethods__' but is not an ABCMeta, and thus for the purposes of c3 mro are
80
+ # not considered 'abstract'. What 'abstract' means in this context is 'can have virtual subclasses'.
81
+ return hasattr(obj, '__abstractmethods__') and isinstance(obj, abc.ABCMeta)
79
82
 
80
83
 
81
84
  def mro(
@@ -119,7 +119,7 @@ class ConfigFlattening:
119
119
  def unflatten(self, flattened: ta.Mapping[str, ta.Any]) -> ta.Mapping[str, ta.Any]:
120
120
  root = ConfigFlattening.UnflattenDict()
121
121
 
122
- def split_keys(fkey: str) -> ta.Iterable[ta.Union[str, int]]:
122
+ def split_keys(fkey: str) -> ta.Iterator[ta.Union[str, int]]:
123
123
  for part in fkey.split(self._delimiter):
124
124
  if self._index_open in part:
125
125
  check.state(part.endswith(self._index_close))
@@ -3,6 +3,7 @@
3
3
  """
4
4
  TODO:
5
5
  - smarter merging than just dumb dict-squashing
6
+ - at least sequence merging
6
7
  """
7
8
  import typing as ta
8
9
 
@@ -19,13 +20,14 @@ def merge_configs(*ms: ConfigMap) -> ConfigMap:
19
20
  e = o[k]
20
21
  except KeyError:
21
22
  o[k] = v
23
+ continue
24
+
25
+ if isinstance(e, ta.Mapping) and isinstance(v, ta.Mapping):
26
+ rec(e, v) # noqa
22
27
  else:
23
- if isinstance(e, ta.Mapping) and isinstance(v, ta.Mapping):
24
- rec(e, v) # noqa
25
- else:
26
- if isinstance(v, ta.Mapping):
27
- v = dict(v)
28
- o[k] = v
28
+ if isinstance(v, ta.Mapping):
29
+ v = dict(v)
30
+ o[k] = v
29
31
 
30
32
  o: dict = {}
31
33
  for i in ms:
@@ -36,7 +36,7 @@ def _build_cls_doc(cls: type) -> str:
36
36
 
37
37
 
38
38
  class _LazyClsDocDescriptor:
39
- def __get__(self, instance, owner):
39
+ def __get__(self, instance, owner=None):
40
40
  if instance is not None:
41
41
  owner = instance.__class__
42
42
  if not owner:
@@ -24,7 +24,8 @@ def init_package(
24
24
  *,
25
25
  codegen: bool = False,
26
26
  ) -> None:
27
- pass
27
+ if init_globals['__name__'] != init_globals['__package__']:
28
+ raise NameError('Must call dataclasses.init_package from __init__')
28
29
 
29
30
 
30
31
  ##
@@ -51,7 +51,7 @@ class _cached_nullary: # noqa
51
51
 
52
52
  return self._value
53
53
 
54
- def __get__(self, instance, owner): # noqa
54
+ def __get__(self, instance, owner=None): # noqa
55
55
  bound = instance.__dict__[self._fn.__name__] = self.__class__(self._fn.__get__(instance, owner))
56
56
  return bound
57
57
 
omlish/diag/procfs.py CHANGED
@@ -235,7 +235,7 @@ PAGEMAP_KEYS = (
235
235
  )
236
236
 
237
237
 
238
- def get_process_range_pagemaps(start: int, end: int, pid: PidLike = 'self') -> ta.Iterable[dict[str, int]]:
238
+ def get_process_range_pagemaps(start: int, end: int, pid: PidLike = 'self') -> ta.Iterator[dict[str, int]]:
239
239
  """https://www.kernel.org/doc/Documentation/vm/pagemap.txt"""
240
240
 
241
241
  _check_linux()
@@ -262,7 +262,7 @@ def get_process_range_pagemaps(start: int, end: int, pid: PidLike = 'self') -> t
262
262
  }
263
263
 
264
264
 
265
- def get_process_pagemaps(pid: PidLike = 'self') -> ta.Iterable[dict[str, int]]:
265
+ def get_process_pagemaps(pid: PidLike = 'self') -> ta.Iterator[dict[str, int]]:
266
266
  _check_linux()
267
267
  for m in get_process_maps(pid):
268
268
  yield from get_process_range_pagemaps(m['address'], m['end_address'], pid)
@@ -42,10 +42,13 @@ ControlTokenKind: ta.TypeAlias = ta.Literal[
42
42
 
43
43
  SpaceTokenKind: ta.TypeAlias = ta.Literal['SPACE']
44
44
 
45
+ CommentTokenKind: ta.TypeAlias = ta.Literal['COMMENT']
46
+
45
47
  TokenKind: ta.TypeAlias = ta.Union[ # noqa
46
48
  ValueTokenKind,
47
49
  ControlTokenKind,
48
50
  SpaceTokenKind,
51
+ CommentTokenKind,
49
52
  ]
50
53
 
51
54
 
@@ -117,9 +120,13 @@ class JsonStreamLexer(GenMachine[str, Token]):
117
120
  *,
118
121
  include_raw: bool = False,
119
122
  include_space: bool = False,
123
+ allow_comments: bool = False,
124
+ include_comments: bool = False,
120
125
  ) -> None:
121
126
  self._include_raw = include_raw
122
127
  self._include_space = include_space
128
+ self._allow_comments = allow_comments
129
+ self._include_comments = include_comments
123
130
 
124
131
  self._ofs = 0
125
132
  self._line = 1
@@ -155,7 +162,7 @@ class JsonStreamLexer(GenMachine[str, Token]):
155
162
  self,
156
163
  kind: TokenKind,
157
164
  value: ScalarValue,
158
- raw: str,
165
+ raw: str | None,
159
166
  pos: Position,
160
167
  ) -> ta.Sequence[Token]:
161
168
  tok = Token(
@@ -175,9 +182,13 @@ class JsonStreamLexer(GenMachine[str, Token]):
175
182
  def _raise(self, msg: str, src: Exception | None = None) -> ta.NoReturn:
176
183
  raise JsonStreamLexError(msg, self.pos) from src
177
184
 
178
- def _do_main(self):
185
+ def _do_main(self, peek: str | None = None):
179
186
  while True:
180
- c = self._char_in((yield None)) # noqa
187
+ if peek is not None:
188
+ c = peek
189
+ peek = None
190
+ else:
191
+ c = self._char_in((yield None)) # noqa
181
192
 
182
193
  if not c:
183
194
  return None
@@ -200,6 +211,10 @@ class JsonStreamLexer(GenMachine[str, Token]):
200
211
  if c in 'tfnIN':
201
212
  return self._do_const(c)
202
213
 
214
+ if self._allow_comments and c == '/':
215
+ yield from self._do_comment()
216
+ continue
217
+
203
218
  self._raise(f'Unexpected character: {c}')
204
219
 
205
220
  def _do_string(self):
@@ -290,17 +305,7 @@ class JsonStreamLexer(GenMachine[str, Token]):
290
305
  if not c:
291
306
  return None
292
307
 
293
- if c in CONTROL_TOKENS:
294
- yield self._make_tok(CONTROL_TOKENS[c], c, c, pos)
295
-
296
- elif c.isspace():
297
- if self._include_space:
298
- yield self._make_tok('SPACE', c, c, self.pos)
299
-
300
- else:
301
- self._raise(f'Unexpected character after number: {c}')
302
-
303
- return self._do_main()
308
+ return self._do_main(c)
304
309
 
305
310
  def _do_const(self, c: str):
306
311
  pos = self.pos
@@ -321,3 +326,53 @@ class JsonStreamLexer(GenMachine[str, Token]):
321
326
  yield self._make_tok(tk, tv, raw, pos)
322
327
 
323
328
  return self._do_main()
329
+
330
+ def _do_comment(self):
331
+ check.state(self._buf.tell() == 0)
332
+
333
+ pos = self.pos
334
+ try:
335
+ oc = self._char_in((yield None)) # noqa
336
+ except GeneratorExit:
337
+ self._raise('Unexpected end of input')
338
+
339
+ if oc == '/':
340
+ while True:
341
+ try:
342
+ ic = self._char_in((yield None)) # noqa
343
+ except GeneratorExit:
344
+ self._raise('Unexpected end of input')
345
+
346
+ if ic == '\n':
347
+ break
348
+
349
+ if self._include_comments:
350
+ self._buf.write(ic)
351
+
352
+ if self._include_comments:
353
+ cmt = self._flip_buf()
354
+ raw = f'//{cmt}\n' if self._include_raw else None
355
+ yield self._make_tok('COMMENT', cmt, raw, pos)
356
+
357
+ elif oc == '*':
358
+ lc: str | None = None
359
+ while True:
360
+ try:
361
+ ic = self._char_in((yield None)) # noqa
362
+ except GeneratorExit:
363
+ self._raise('Unexpected end of input')
364
+
365
+ if lc == '*' and ic == '/':
366
+ break
367
+
368
+ if lc is not None and self._include_comments:
369
+ self._buf.write(lc)
370
+ lc = ic
371
+
372
+ if self._include_comments:
373
+ cmt = self._flip_buf()
374
+ raw = f'/*{cmt}*/' if self._include_raw else None
375
+ yield self._make_tok('COMMENT', cmt, raw, pos)
376
+
377
+ else:
378
+ self._raise(f'Unexpected character after comment start: {oc}')
@@ -106,7 +106,7 @@ class JsonStreamParser(GenMachine[Token, JsonStreamParserEvent]):
106
106
  while True:
107
107
  tok = yield None
108
108
 
109
- if tok.kind != 'SPACE':
109
+ if tok.kind != 'SPACE' and tok.kind != 'COMMENT':
110
110
  return tok
111
111
 
112
112
  #
@@ -15,6 +15,8 @@ class JsonStreamValueParser(lang.ExitStacked):
15
15
  include_raw: bool = False
16
16
  yield_object_lists: bool = False
17
17
 
18
+ allow_comments: bool = False
19
+
18
20
  #
19
21
 
20
22
  _lex: JsonStreamLexer = dc.field(init=False)
@@ -24,6 +26,7 @@ class JsonStreamValueParser(lang.ExitStacked):
24
26
  def _enter_contexts(self) -> None:
25
27
  self._lex = JsonStreamLexer(
26
28
  include_raw=self.include_raw,
29
+ allow_comments=self.allow_comments,
27
30
  )
28
31
 
29
32
  self._parse = JsonStreamParser()
@@ -0,0 +1,22 @@
1
+ """
2
+ TODO:
3
+
4
+ Objects:
5
+ - Object keys may be an ECMAScript 5.1 IdentifierName.
6
+ - Objects may have a single trailing comma.
7
+ Arrays:
8
+ - Arrays may have a single trailing comma.
9
+ Strings:
10
+ - Strings may be single quoted.
11
+ - Strings may span multiple lines by escaping new line characters.
12
+ - Strings may include character escapes.
13
+ Numbers:
14
+ - Numbers may be hexadecimal.
15
+ - Numbers may have a leading or trailing decimal point.
16
+ - Numbers may be IEEE 754 positive infinity, negative infinity, and NaN.
17
+ - Numbers may begin with an explicit plus sign.
18
+ Comments:
19
+ - Single and multi-line comments are allowed.
20
+ White Space:
21
+ - Additional white space characters are allowed.
22
+ """
omlish/formats/logfmt.py CHANGED
@@ -20,7 +20,10 @@ def logfmt_encode(
20
20
  ) -> str:
21
21
  def encode(s: str) -> str:
22
22
  if _LOGFMT_ENCODE_WS_PAT.search(s) is not None:
23
- return '"' + s.replace('\\', '\\\\').replace('"', '\\"') + '"'
23
+ s = s.replace('\\', '\\\\')
24
+ s = s.replace('\n', '\\n')
25
+ s = s.replace('"', '\\"')
26
+ return f'"{s}"'
24
27
  else:
25
28
  return s
26
29
 
@@ -67,7 +70,10 @@ def logfmt_decode(
67
70
  if s.startswith('"'):
68
71
  if len(s) < 2 or not s.endswith('"'):
69
72
  raise ValueError(s)
70
- s = s[1:-1].replace('\\"', '"').replace('\\\\', '\\')
73
+ s = s[1:-1]
74
+ s = s.replace('\\"', '"')
75
+ s = s.replace('\\n', '\n')
76
+ s = s.replace('\\\\', '\\')
71
77
  return s
72
78
 
73
79
  if value_decoder is None:
@@ -88,7 +88,7 @@ class GenMachine(ta.Generic[I, O]):
88
88
 
89
89
  #
90
90
 
91
- def __call__(self, i: I) -> ta.Iterable[O]:
91
+ def __call__(self, i: I) -> ta.Iterator[O]:
92
92
  if self._gen is None:
93
93
  raise GenMachine.ClosedError
94
94
 
omlish/http/sse.py CHANGED
@@ -82,7 +82,7 @@ class SseDecoder:
82
82
 
83
83
  return e
84
84
 
85
- def process_line(self, line: bytes) -> ta.Iterable[SseDecoderOutput]:
85
+ def process_line(self, line: bytes) -> ta.Iterator[SseDecoderOutput]:
86
86
  if b'\r' in line or b'\n' in line:
87
87
  raise ValueError(line)
88
88
 
@@ -202,7 +202,7 @@ class InjectorImpl(Injector, lang.Final):
202
202
  #
203
203
 
204
204
  def try_provide(self, key: ta.Any) -> lang.Maybe[ta.Any]:
205
- return self.try_provide(key)
205
+ return self._try_provide(key)
206
206
 
207
207
  def provide(self, key: ta.Any) -> ta.Any:
208
208
  v = self._try_provide(key)
@@ -22,7 +22,7 @@ class SetProviderImpl(ProviderImpl, lang.Final):
22
22
  ps: ta.Sequence[ProviderImpl]
23
23
 
24
24
  @property
25
- def providers(self) -> ta.Iterable[Provider]:
25
+ def providers(self) -> ta.Iterator[Provider]:
26
26
  for p in self.ps:
27
27
  yield from p.providers
28
28
 
@@ -43,7 +43,7 @@ class MapProviderImpl(ProviderImpl, lang.Final):
43
43
  es: ta.Sequence[Entry]
44
44
 
45
45
  @property
46
- def providers(self) -> ta.Iterable[Provider]:
46
+ def providers(self) -> ta.Iterator[Provider]:
47
47
  for e in self.es:
48
48
  yield from e.v.providers
49
49
 
@@ -7,7 +7,6 @@ import typing as ta
7
7
 
8
8
  from ... import dataclasses as dc
9
9
  from ... import lang
10
- from ... import reflect as rfl
11
10
  from ..injector import Injector
12
11
  from ..inspect import KwargsTarget
13
12
  from ..providers import ConstProvider
@@ -39,9 +38,6 @@ class ProviderImpl(lang.Abstract):
39
38
  class InternalProvider(Provider):
40
39
  impl: ProviderImpl
41
40
 
42
- def provided_ty(self) -> rfl.Type | None:
43
- raise TypeError
44
-
45
41
 
46
42
  ##
47
43
 
@@ -12,7 +12,6 @@ def _cyclic_dependency_proxy() -> tuple[type, ta.Callable[[ta.Any, ta.Any], None
12
12
  import wrapt # noqa
13
13
 
14
14
  class _CyclicDependencyPlaceholder(lang.Final):
15
-
16
15
  def __init__(self, cls: ta.Any) -> None:
17
16
  super().__init__()
18
17
 
@@ -22,7 +21,6 @@ def _cyclic_dependency_proxy() -> tuple[type, ta.Callable[[ta.Any, ta.Any], None
22
21
  return f'{type(self).__name__}({self.__cls!r})'
23
22
 
24
23
  class _CyclicDependencyProxy(wrapt.ObjectProxy, lang.Final): # noqa
25
-
26
24
  def __init__(self, cls):
27
25
  super().__init__(_CyclicDependencyPlaceholder(cls))
28
26
 
omlish/inject/scopes.py CHANGED
@@ -5,7 +5,6 @@ import typing as ta
5
5
  from .. import check
6
6
  from .. import dataclasses as dc
7
7
  from .. import lang
8
- from .. import reflect as rfl
9
8
  from .bindings import Binding
10
9
  from .elements import Element
11
10
  from .keys import Key
@@ -76,9 +75,6 @@ class ScopeSeededProvider(Provider):
76
75
  ss: SeededScope = dc.xfield(coerce=check.of_isinstance(SeededScope))
77
76
  key: Key = dc.xfield(coerce=check.of_isinstance(Key))
78
77
 
79
- def provided_ty(self) -> rfl.Type | None:
80
- return self.key.ty
81
-
82
78
 
83
79
  def bind_scope_seed(k: ta.Any, ss: SeededScope) -> Element:
84
80
  k = as_key(k)
omlish/io/buffers.py CHANGED
@@ -3,8 +3,8 @@
3
3
  import io
4
4
  import typing as ta
5
5
 
6
+ from ..lite.attrops import attr_repr
6
7
  from ..lite.check import check
7
- from ..lite.strings import attr_repr
8
8
 
9
9
 
10
10
  ##
omlish/lang/__init__.py CHANGED
@@ -9,23 +9,29 @@ with _auto_proxy_init(
9
9
  ##
10
10
 
11
11
  from .asyncs import ( # noqa
12
+ as_async,
13
+
12
14
  async_list,
13
15
 
14
16
  sync_await,
15
17
  sync_async_list,
16
18
  )
17
19
 
18
- from .attrs import ( # noqa
19
- AttrOps,
20
+ from .attrstorage import ( # noqa
20
21
  AttributePresentError,
21
- DictAttrOps,
22
- STD_ATTR_OPS,
23
22
  SetAttrIfPresent,
24
- StdAttrOps,
25
- TRANSIENT_ATTR_OPS,
26
- TransientAttrOps,
27
- TransientDict,
28
23
  set_attr,
24
+
25
+ AttrStorage,
26
+
27
+ StdAttrStorage,
28
+ STD_ATTR_STORAGE,
29
+
30
+ DictAttrStorage,
31
+
32
+ TransientDict,
33
+ TransientAttrStorage,
34
+ TRANSIENT_ATTR_STORAGE,
29
35
  transient_delattr,
30
36
  transient_getattr,
31
37
  transient_setattr,
@@ -216,7 +222,6 @@ with _auto_proxy_init(
216
222
 
217
223
  from .functions import ( # noqa
218
224
  VoidError,
219
- as_async,
220
225
  call_with,
221
226
  coalesce,
222
227
  cond_kw,
@@ -306,6 +311,7 @@ with _auto_proxy_init(
306
311
  )
307
312
 
308
313
  from .lazyglobals import ( # noqa
314
+ AmbiguousLazyGlobalsFallbackError,
309
315
  LazyGlobals,
310
316
  )
311
317
 
@@ -443,6 +449,17 @@ with _auto_proxy_init(
443
449
  Args,
444
450
  )
445
451
 
452
+ from ..lite.asyncs import ( # noqa
453
+ opt_await,
454
+ )
455
+
456
+ from ..lite.attrops import ( # noqa
457
+ AttrOps,
458
+ attr_ops,
459
+
460
+ attr_repr,
461
+ )
462
+
446
463
  from ..lite.contextmanagers import ( # noqa
447
464
  AsyncExitStacked,
448
465
  ExitStacked,
@@ -487,11 +504,6 @@ with _auto_proxy_init(
487
504
  dir_dict,
488
505
  )
489
506
 
490
- from ..lite.reprs import ( # noqa
491
- AttrRepr,
492
- attr_repr,
493
- )
494
-
495
507
  from ..lite.timeouts import ( # noqa
496
508
  DeadlineTimeout,
497
509
  InfiniteTimeout,
omlish/lang/asyncs.py CHANGED
@@ -1,7 +1,19 @@
1
+ import functools
1
2
  import typing as ta
2
3
 
3
4
 
4
5
  T = ta.TypeVar('T')
6
+ P = ta.ParamSpec('P')
7
+
8
+
9
+ ##
10
+
11
+
12
+ def as_async(fn: ta.Callable[P, T], *, wrap: bool = False) -> ta.Callable[P, ta.Awaitable[T]]:
13
+ async def inner(*args, **kwargs):
14
+ return fn(*args, **kwargs)
15
+
16
+ return functools.wraps(fn)(inner) if wrap else inner
5
17
 
6
18
 
7
19
  ##
@@ -76,7 +76,7 @@ def set_attr(
76
76
  ##
77
77
 
78
78
 
79
- class AttrOps(Abstract):
79
+ class AttrStorage(Abstract):
80
80
  class NOT_SET: # noqa
81
81
  def __new__(cls, *args, **kwargs): # noqa
82
82
  raise TypeError
@@ -97,9 +97,9 @@ class AttrOps(Abstract):
97
97
  #
98
98
 
99
99
 
100
- class StdAttrOps(AttrOps):
101
- def getattr(self, obj: ta.Any, name: str, default: ta.Any = AttrOps.NOT_SET) -> ta.Any:
102
- if default is AttrOps.NOT_SET:
100
+ class StdAttrStorage(AttrStorage):
101
+ def getattr(self, obj: ta.Any, name: str, default: ta.Any = AttrStorage.NOT_SET) -> ta.Any:
102
+ if default is AttrStorage.NOT_SET:
103
103
  return getattr(obj, name)
104
104
  else:
105
105
  return getattr(obj, name, default)
@@ -111,13 +111,13 @@ class StdAttrOps(AttrOps):
111
111
  delattr(obj, name)
112
112
 
113
113
 
114
- STD_ATTR_OPS = StdAttrOps()
114
+ STD_ATTR_STORAGE = StdAttrStorage()
115
115
 
116
116
 
117
117
  #
118
118
 
119
119
 
120
- class DictAttrOps(AttrOps):
120
+ class DictAttrStorage(AttrStorage):
121
121
  def __init__(self, dct: ta.MutableMapping[str, ta.Any] | None = None) -> None:
122
122
  super().__init__()
123
123
 
@@ -125,11 +125,11 @@ class DictAttrOps(AttrOps):
125
125
  dct = {}
126
126
  self._dct = dct
127
127
 
128
- def getattr(self, obj: ta.Any, name: str, default: ta.Any = AttrOps.NOT_SET) -> ta.Any:
128
+ def getattr(self, obj: ta.Any, name: str, default: ta.Any = AttrStorage.NOT_SET) -> ta.Any:
129
129
  try:
130
130
  return self._dct[name]
131
131
  except KeyError:
132
- if default is not AttrOps.NOT_SET:
132
+ if default is not AttrStorage.NOT_SET:
133
133
  return default
134
134
  raise AttributeError(name) from None
135
135
 
@@ -205,13 +205,13 @@ def _get_object_transient_dict(obj: ta.Any) -> TransientDict:
205
205
  return obj.__dict__.setdefault(_TRANSIENT_DICT_ATTR, TransientDict())
206
206
 
207
207
 
208
- class TransientAttrOps(AttrOps):
209
- def getattr(self, obj: ta.Any, name: str, default: ta.Any = AttrOps.NOT_SET) -> ta.Any:
208
+ class TransientAttrStorage(AttrStorage):
209
+ def getattr(self, obj: ta.Any, name: str, default: ta.Any = AttrStorage.NOT_SET) -> ta.Any:
210
210
  td = _get_object_transient_dict(obj)
211
211
  try:
212
212
  return td[name]
213
213
  except KeyError:
214
- if default is not AttrOps.NOT_SET:
214
+ if default is not AttrStorage.NOT_SET:
215
215
  return default
216
216
  raise AttributeError(name) from None
217
217
 
@@ -227,8 +227,8 @@ class TransientAttrOps(AttrOps):
227
227
  raise AttributeError(name) from None
228
228
 
229
229
 
230
- TRANSIENT_ATTR_OPS = TransientAttrOps()
230
+ TRANSIENT_ATTR_STORAGE = TransientAttrStorage()
231
231
 
232
- transient_getattr = TRANSIENT_ATTR_OPS.getattr
233
- transient_setattr = TRANSIENT_ATTR_OPS.setattr
234
- transient_delattr = TRANSIENT_ATTR_OPS.delattr
232
+ transient_getattr = TRANSIENT_ATTR_STORAGE.getattr
233
+ transient_setattr = TRANSIENT_ATTR_STORAGE.setattr
234
+ transient_delattr = TRANSIENT_ATTR_STORAGE.delattr
@@ -2,8 +2,8 @@ import abc
2
2
  import functools
3
3
  import typing as ta
4
4
 
5
- from ..attrs import transient_getattr
6
- from ..attrs import transient_setattr
5
+ from ..attrstorage import transient_getattr
6
+ from ..attrstorage import transient_setattr
7
7
  from ..classes.abstract import Abstract
8
8
 
9
9