omdev 0.0.0.dev416__py3-none-any.whl → 0.0.0.dev500__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.

Potentially problematic release.


This version of omdev might be problematic. Click here for more details.

Files changed (211) hide show
  1. omdev/{.manifests.json → .omlish-manifests.json} +23 -47
  2. omdev/README.md +51 -0
  3. omdev/__about__.py +12 -8
  4. omdev/amalg/cli/main.py +1 -2
  5. omdev/amalg/gen/gen.py +49 -6
  6. omdev/amalg/gen/imports.py +1 -1
  7. omdev/amalg/gen/manifests.py +1 -1
  8. omdev/amalg/gen/resources.py +1 -1
  9. omdev/amalg/gen/srcfiles.py +26 -3
  10. omdev/amalg/gen/strip.py +1 -1
  11. omdev/amalg/gen/types.py +1 -1
  12. omdev/amalg/gen/typing.py +1 -1
  13. omdev/amalg/info.py +32 -0
  14. omdev/cache/compute/storage.py +3 -1
  15. omdev/cache/data/actions.py +1 -1
  16. omdev/cache/data/cache.py +2 -2
  17. omdev/cache/data/specs.py +1 -1
  18. omdev/cexts/_boilerplate.cc +2 -3
  19. omdev/cexts/_distutils/build_ext.py +5 -2
  20. omdev/cexts/_distutils/compilers/ccompiler.py +5 -2
  21. omdev/cexts/_distutils/compilers/options.py +3 -0
  22. omdev/cexts/_distutils/compilers/unixccompiler.py +6 -2
  23. omdev/cexts/_distutils/dir_util.py +6 -2
  24. omdev/cexts/_distutils/errors.py +3 -0
  25. omdev/cexts/_distutils/extension.py +3 -0
  26. omdev/cexts/_distutils/file_util.py +6 -2
  27. omdev/cexts/_distutils/modified.py +3 -0
  28. omdev/cexts/_distutils/spawn.py +6 -2
  29. omdev/cexts/_distutils/sysconfig.py +3 -0
  30. omdev/cexts/_distutils/util.py +6 -2
  31. omdev/cexts/_distutils/version.py +3 -0
  32. omdev/cexts/cmake.py +5 -3
  33. omdev/cexts/scan.py +1 -2
  34. omdev/ci/cache.py +7 -3
  35. omdev/ci/cli.py +6 -4
  36. omdev/ci/docker/buildcaching.py +3 -1
  37. omdev/ci/docker/cache.py +2 -1
  38. omdev/ci/docker/cacheserved/cache.py +4 -1
  39. omdev/ci/docker/cacheserved/manifests.py +2 -2
  40. omdev/ci/docker/dataserver.py +2 -2
  41. omdev/ci/docker/imagepulling.py +2 -1
  42. omdev/ci/docker/packing.py +1 -1
  43. omdev/ci/docker/repositories.py +2 -1
  44. omdev/ci/github/api/clients.py +8 -4
  45. omdev/ci/github/api/v1/client.py +4 -1
  46. omdev/ci/github/api/v2/api.py +2 -0
  47. omdev/ci/github/api/v2/azure.py +4 -1
  48. omdev/ci/github/api/v2/client.py +4 -1
  49. omdev/cli/clicli.py +37 -7
  50. omdev/clipboard/clipboard.py +1 -1
  51. omdev/cmake.py +2 -1
  52. omdev/cmdlog/cli.py +1 -2
  53. omdev/dataclasses/_dumping.py +1960 -0
  54. omdev/dataclasses/_template.py +22 -0
  55. omdev/dataclasses/cli.py +7 -2
  56. omdev/dataclasses/codegen.py +342 -62
  57. omdev/dataclasses/dumping.py +200 -0
  58. omdev/dataserver/handlers.py +3 -2
  59. omdev/dataserver/targets.py +2 -2
  60. omdev/imgur.py +2 -2
  61. omdev/interp/cli.py +1 -1
  62. omdev/interp/inspect.py +2 -1
  63. omdev/interp/providers/base.py +3 -2
  64. omdev/interp/providers/standalone.py +4 -1
  65. omdev/interp/providers/system.py +2 -2
  66. omdev/interp/pyenv/install.py +2 -1
  67. omdev/interp/pyenv/provider.py +2 -2
  68. omdev/interp/types.py +3 -2
  69. omdev/interp/uv/provider.py +40 -2
  70. omdev/interp/uv/uv.py +2 -2
  71. omdev/interp/venvs.py +3 -2
  72. omdev/irc/messages/base.py +50 -0
  73. omdev/irc/messages/formats.py +92 -0
  74. omdev/irc/messages/messages.py +775 -0
  75. omdev/irc/messages/parsing.py +99 -0
  76. omdev/irc/numerics/formats.py +97 -0
  77. omdev/irc/numerics/numerics.py +865 -0
  78. omdev/irc/numerics/types.py +59 -0
  79. omdev/irc/protocol/LICENSE +11 -0
  80. omdev/irc/protocol/__init__.py +61 -0
  81. omdev/irc/protocol/consts.py +6 -0
  82. omdev/irc/protocol/errors.py +30 -0
  83. omdev/irc/protocol/message.py +21 -0
  84. omdev/irc/protocol/nuh.py +55 -0
  85. omdev/irc/protocol/parsing.py +158 -0
  86. omdev/irc/protocol/rendering.py +153 -0
  87. omdev/irc/protocol/tags.py +102 -0
  88. omdev/irc/protocol/utils.py +30 -0
  89. omdev/manifests/_dumping.py +529 -136
  90. omdev/manifests/building.py +6 -3
  91. omdev/manifests/main.py +1 -1
  92. omdev/markdown/__init__.py +0 -0
  93. omdev/markdown/incparse.py +116 -0
  94. omdev/markdown/tokens.py +51 -0
  95. omdev/oci/data.py +2 -2
  96. omdev/oci/datarefs.py +2 -2
  97. omdev/oci/media.py +2 -2
  98. omdev/oci/repositories.py +3 -2
  99. omdev/packaging/marshal.py +9 -9
  100. omdev/packaging/requires.py +6 -6
  101. omdev/packaging/revisions.py +5 -2
  102. omdev/packaging/specifiers.py +41 -42
  103. omdev/packaging/versions.py +10 -10
  104. omdev/packaging/wheelfile.py +4 -2
  105. omdev/precheck/blanklines.py +66 -0
  106. omdev/precheck/caches.py +1 -1
  107. omdev/precheck/imports.py +14 -1
  108. omdev/precheck/lite.py +2 -2
  109. omdev/precheck/main.py +5 -5
  110. omdev/precheck/unicode.py +39 -15
  111. omdev/py/asts/__init__.py +0 -0
  112. omdev/py/asts/parents.py +28 -0
  113. omdev/py/asts/toplevel.py +123 -0
  114. omdev/py/asts/visitors.py +18 -0
  115. omdev/py/attrdocs.py +6 -7
  116. omdev/py/bracepy.py +12 -4
  117. omdev/py/docstrings/numpydoc.py +4 -4
  118. omdev/py/reprs.py +32 -0
  119. omdev/py/scripts/execstat.py +31 -26
  120. omdev/py/srcheaders.py +1 -1
  121. omdev/py/tokens/__init__.py +0 -0
  122. omdev/{tokens → py/tokens}/utils.py +2 -1
  123. omdev/py/tools/importscan.py +2 -2
  124. omdev/py/tools/mkrelimp.py +3 -4
  125. omdev/py/tools/pipdepup.py +686 -0
  126. omdev/pyproject/cli.py +1 -1
  127. omdev/pyproject/pkg.py +197 -48
  128. omdev/pyproject/reqs.py +36 -10
  129. omdev/pyproject/tools/__init__.py +0 -0
  130. omdev/pyproject/tools/aboutdeps.py +60 -0
  131. omdev/pyproject/venvs.py +12 -2
  132. omdev/rs/__init__.py +0 -0
  133. omdev/scripts/ci.py +9551 -6982
  134. omdev/scripts/interp.py +1323 -892
  135. omdev/scripts/lib/__init__.py +0 -0
  136. omdev/scripts/lib/inject.py +2086 -0
  137. omdev/scripts/lib/logs.py +2175 -0
  138. omdev/scripts/lib/marshal.py +1731 -0
  139. omdev/scripts/pyproject.py +4979 -1874
  140. omdev/tools/docker.py +19 -7
  141. omdev/tools/git/cli.py +56 -16
  142. omdev/tools/git/messages.py +2 -2
  143. omdev/tools/json/cli.py +6 -6
  144. omdev/tools/json/formats.py +2 -0
  145. omdev/tools/json/parsing.py +5 -5
  146. omdev/tools/json/processing.py +6 -3
  147. omdev/tools/json/rendering.py +2 -2
  148. omdev/tools/jsonview/cli.py +49 -65
  149. omdev/tools/jsonview/resources/jsonview.html.j2 +43 -0
  150. omdev/tools/pawk/README.md +195 -0
  151. omdev/tools/pawk/pawk.py +2 -2
  152. omdev/tools/pip.py +8 -0
  153. omdev/tui/__init__.py +0 -0
  154. omdev/tui/apps/__init__.py +0 -0
  155. omdev/tui/apps/edit/__init__.py +0 -0
  156. omdev/tui/apps/edit/main.py +167 -0
  157. omdev/tui/apps/irc/__init__.py +0 -0
  158. omdev/tui/apps/irc/__main__.py +4 -0
  159. omdev/tui/apps/irc/app.py +286 -0
  160. omdev/tui/apps/irc/client.py +187 -0
  161. omdev/tui/apps/irc/commands.py +175 -0
  162. omdev/tui/apps/irc/main.py +26 -0
  163. omdev/tui/apps/markdown/__init__.py +0 -0
  164. omdev/tui/apps/markdown/__main__.py +11 -0
  165. omdev/{ptk → tui/apps}/markdown/cli.py +5 -7
  166. omdev/tui/rich/__init__.py +46 -0
  167. omdev/tui/rich/console2.py +20 -0
  168. omdev/tui/rich/markdown2.py +186 -0
  169. omdev/tui/textual/__init__.py +265 -0
  170. omdev/tui/textual/app2.py +16 -0
  171. omdev/tui/textual/autocomplete/LICENSE +21 -0
  172. omdev/tui/textual/autocomplete/__init__.py +33 -0
  173. omdev/tui/textual/autocomplete/matching.py +226 -0
  174. omdev/tui/textual/autocomplete/paths.py +202 -0
  175. omdev/tui/textual/autocomplete/widget.py +612 -0
  176. omdev/tui/textual/debug/__init__.py +10 -0
  177. omdev/tui/textual/debug/dominfo.py +151 -0
  178. omdev/tui/textual/debug/screen.py +24 -0
  179. omdev/tui/textual/devtools.py +187 -0
  180. omdev/tui/textual/drivers2.py +55 -0
  181. omdev/tui/textual/logging2.py +20 -0
  182. omdev/tui/textual/types.py +45 -0
  183. {omdev-0.0.0.dev416.dist-info → omdev-0.0.0.dev500.dist-info}/METADATA +18 -12
  184. omdev-0.0.0.dev500.dist-info/RECORD +386 -0
  185. omdev/ptk/__init__.py +0 -103
  186. omdev/ptk/apps/ncdu.py +0 -167
  187. omdev/ptk/confirm.py +0 -60
  188. omdev/ptk/markdown/LICENSE +0 -22
  189. omdev/ptk/markdown/__init__.py +0 -10
  190. omdev/ptk/markdown/__main__.py +0 -11
  191. omdev/ptk/markdown/border.py +0 -94
  192. omdev/ptk/markdown/markdown.py +0 -390
  193. omdev/ptk/markdown/parser.py +0 -42
  194. omdev/ptk/markdown/styles.py +0 -29
  195. omdev/ptk/markdown/tags.py +0 -299
  196. omdev/ptk/markdown/utils.py +0 -366
  197. omdev/pyproject/cexts.py +0 -110
  198. omdev/tools/antlr/__main__.py +0 -11
  199. omdev/tools/antlr/cli.py +0 -62
  200. omdev/tools/antlr/consts.py +0 -7
  201. omdev/tools/antlr/gen.py +0 -188
  202. omdev-0.0.0.dev416.dist-info/RECORD +0 -332
  203. /omdev/{ptk/apps → irc}/__init__.py +0 -0
  204. /omdev/{tokens → irc/messages}/__init__.py +0 -0
  205. /omdev/{tools/antlr → irc/numerics}/__init__.py +0 -0
  206. /omdev/{tokens → py/tokens}/all.py +0 -0
  207. /omdev/{tokens → py/tokens}/tokenizert.py +0 -0
  208. {omdev-0.0.0.dev416.dist-info → omdev-0.0.0.dev500.dist-info}/WHEEL +0 -0
  209. {omdev-0.0.0.dev416.dist-info → omdev-0.0.0.dev500.dist-info}/entry_points.txt +0 -0
  210. {omdev-0.0.0.dev416.dist-info → omdev-0.0.0.dev500.dist-info}/licenses/LICENSE +0 -0
  211. {omdev-0.0.0.dev416.dist-info → omdev-0.0.0.dev500.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,8 @@
1
1
  # ruff: noqa: UP006 UP007 UP045
2
- import abc
3
2
  import dataclasses as dc
4
3
  import typing as ta
5
4
 
5
+ from omlish.lite.abstract import Abstract
6
6
  from omlish.lite.check import check
7
7
  from omlish.lite.dataclasses import dataclass_maybe_post_init
8
8
  from omlish.lite.marshal import OBJ_MARSHALER_OMIT_IF_NONE
@@ -12,7 +12,7 @@ from omlish.lite.marshal import OBJ_MARSHALER_OMIT_IF_NONE
12
12
 
13
13
 
14
14
  @dc.dataclass(frozen=True)
15
- class DataServerTarget(abc.ABC): # noqa
15
+ class DataServerTarget(Abstract):
16
16
  content_type: ta.Optional[str] = dc.field(default=None, metadata={OBJ_MARSHALER_OMIT_IF_NONE: True})
17
17
  content_length: ta.Optional[int] = dc.field(default=None, metadata={OBJ_MARSHALER_OMIT_IF_NONE: True})
18
18
 
omdev/imgur.py CHANGED
@@ -130,11 +130,11 @@ def _main() -> None:
130
130
 
131
131
  print(resp.data.link)
132
132
 
133
- Cli()(exit=True)
133
+ Cli()(exit=True) # noqa
134
134
 
135
135
 
136
136
  # @omlish-manifest
137
- _FOO_CLI_MODULE = CliModule('imgur', __name__)
137
+ _CLI_MODULE = CliModule('imgur', __name__)
138
138
 
139
139
 
140
140
  if __name__ == '__main__':
omdev/interp/cli.py CHANGED
@@ -17,7 +17,7 @@ from omlish.lite.check import check
17
17
  from omlish.lite.inject import Injector
18
18
  from omlish.lite.inject import inj
19
19
  from omlish.lite.runtime import check_lite_runtime_version
20
- from omlish.logs.standard import configure_standard_logging
20
+ from omlish.logs.std.standard import configure_standard_logging
21
21
 
22
22
  from .inject import bind_interp
23
23
  from .resolvers import InterpResolver
omdev/interp/inspect.py CHANGED
@@ -6,6 +6,7 @@ import sys
6
6
  import typing as ta
7
7
 
8
8
  from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
9
+ from omlish.logs.protocols import LoggerLike
9
10
 
10
11
  from ..packaging.versions import Version
11
12
  from .types import InterpOpts
@@ -48,7 +49,7 @@ class InterpInspector:
48
49
  def __init__(
49
50
  self,
50
51
  *,
51
- log: ta.Optional[logging.Logger] = None,
52
+ log: ta.Optional[LoggerLike] = None,
52
53
  ) -> None:
53
54
  super().__init__()
54
55
 
@@ -9,6 +9,7 @@ TODO:
9
9
  import abc
10
10
  import typing as ta
11
11
 
12
+ from omlish.lite.abstract import Abstract
12
13
  from omlish.lite.strings import snake_case
13
14
 
14
15
  from ..types import Interp
@@ -19,13 +20,13 @@ from ..types import InterpVersion
19
20
  ##
20
21
 
21
22
 
22
- class InterpProvider(abc.ABC):
23
+ class InterpProvider(Abstract):
23
24
  name: ta.ClassVar[str]
24
25
 
25
26
  def __init_subclass__(cls, **kwargs: ta.Any) -> None:
26
27
  super().__init_subclass__(**kwargs)
27
28
 
28
- if abc.ABC not in cls.__bases__ and 'name' not in cls.__dict__:
29
+ if Abstract not in cls.__bases__ and 'name' not in cls.__dict__:
29
30
  sfx = 'InterpProvider'
30
31
  if not cls.__name__.endswith(sfx):
31
32
  raise NameError(cls)
@@ -33,7 +33,10 @@ import urllib.request
33
33
 
34
34
  from omlish.lite.cached import cached_nullary
35
35
  from omlish.lite.check import check
36
- from omlish.lite.logs import log
36
+ from omlish.logs.modules import get_module_logger
37
+
38
+
39
+ log = get_module_logger(globals()) # noqa
37
40
 
38
41
 
39
42
  ##
@@ -5,13 +5,13 @@ TODO:
5
5
  - check if path py's are venvs: sys.prefix != sys.base_prefix
6
6
  """
7
7
  import dataclasses as dc
8
- import logging
9
8
  import os
10
9
  import re
11
10
  import typing as ta
12
11
 
13
12
  from omlish.lite.cached import cached_nullary
14
13
  from omlish.lite.check import check
14
+ from omlish.logs.protocols import LoggerLike
15
15
 
16
16
  from ...packaging.versions import InvalidVersion
17
17
  from ..inspect import InterpInspector
@@ -37,7 +37,7 @@ class SystemInterpProvider(InterpProvider):
37
37
  options: Options = Options(),
38
38
  *,
39
39
  inspector: ta.Optional[InterpInspector] = None,
40
- log: ta.Optional[logging.Logger] = None,
40
+ log: ta.Optional[LoggerLike] = None,
41
41
  ) -> None:
42
42
  super().__init__()
43
43
 
@@ -8,6 +8,7 @@ import sys
8
8
  import typing as ta
9
9
 
10
10
  from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
11
+ from omlish.lite.abstract import Abstract
11
12
  from omlish.lite.cached import async_cached_nullary
12
13
  from omlish.lite.cached import cached_nullary
13
14
  from omlish.lite.check import check
@@ -89,7 +90,7 @@ THREADED_PYENV_INSTALL_OPTS = PyenvInstallOpts(conf_opts=['--disable-gil'])
89
90
  #
90
91
 
91
92
 
92
- class PyenvInstallOptsProvider(abc.ABC):
93
+ class PyenvInstallOptsProvider(Abstract):
93
94
  @abc.abstractmethod
94
95
  def opts(self) -> ta.Awaitable[PyenvInstallOpts]:
95
96
  raise NotImplementedError
@@ -1,9 +1,9 @@
1
1
  # ruff: noqa: UP006 UP007 UP045
2
2
  import dataclasses as dc
3
- import logging
4
3
  import typing as ta
5
4
 
6
5
  from omlish.lite.check import check
6
+ from omlish.logs.protocols import LoggerLike
7
7
 
8
8
  from ...packaging.versions import InvalidVersion
9
9
  from ...packaging.versions import Version
@@ -33,7 +33,7 @@ class PyenvInterpProvider(InterpProvider):
33
33
  *,
34
34
  pyenv: Pyenv,
35
35
  inspector: InterpInspector,
36
- log: ta.Optional[logging.Logger] = None,
36
+ log: ta.Optional[LoggerLike] = None,
37
37
  ) -> None:
38
38
  super().__init__()
39
39
 
omdev/interp/types.py CHANGED
@@ -85,9 +85,10 @@ class InterpSpecifier:
85
85
  def parse(cls, s: str) -> 'InterpSpecifier':
86
86
  s, o = InterpOpts.parse_suffix(s)
87
87
  if not any(s.startswith(o) for o in Specifier.OPERATORS):
88
- s = '~=' + s
89
88
  if s.count('.') < 2:
90
- s += '.0'
89
+ s = '~=' + s + '.0'
90
+ else:
91
+ s = '==' + s
91
92
  return cls(
92
93
  specifier=Specifier(s),
93
94
  opts=o,
@@ -4,10 +4,14 @@ uv run pip
4
4
  uv run --python 3.11.6 pip
5
5
  uv venv --python 3.11.6 --seed barf
6
6
  python3 -m venv barf && barf/bin/pip install uv && barf/bin/uv venv --python 3.11.6 --seed barf2
7
+ uv python find '3.13.10'
8
+ uv python list --output-format=json
7
9
  """
8
- import logging
10
+ import dataclasses as dc
9
11
  import typing as ta
10
12
 
13
+ from omlish.logs.protocols import LoggerLike
14
+
11
15
  from ..inspect import InterpInspector
12
16
  from ..providers.base import InterpProvider
13
17
  from ..types import Interp
@@ -19,13 +23,41 @@ from .uv import Uv
19
23
  ##
20
24
 
21
25
 
26
+ @dc.dataclass(frozen=True)
27
+ class UvPythonListOutput:
28
+ key: str
29
+ version: str
30
+
31
+ @dc.dataclass(frozen=True)
32
+ class VersionParts:
33
+ major: int
34
+ minor: int
35
+ patch: int
36
+
37
+ version_parts: VersionParts
38
+
39
+ path: ta.Optional[str]
40
+ symlink: ta.Optional[str]
41
+
42
+ url: str
43
+
44
+ os: str # emscripten linux macos
45
+ variant: str # default freethreaded
46
+ implementation: str # cpython graalpy pyodide pypy
47
+ arch: str # aarch64 wasm32 x86_64
48
+ libc: str # gnu musl none
49
+
50
+
51
+ ##
52
+
53
+
22
54
  class UvInterpProvider(InterpProvider):
23
55
  def __init__(
24
56
  self,
25
57
  *,
26
58
  pyenv: Uv,
27
59
  inspector: InterpInspector,
28
- log: ta.Optional[logging.Logger] = None,
60
+ log: ta.Optional[LoggerLike] = None,
29
61
  ) -> None:
30
62
  super().__init__()
31
63
 
@@ -38,3 +70,9 @@ class UvInterpProvider(InterpProvider):
38
70
 
39
71
  async def get_installed_version(self, version: InterpVersion) -> Interp:
40
72
  raise NotImplementedError
73
+
74
+ # async def get_installable_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
75
+ # return []
76
+
77
+ # async def install_version(self, version: InterpVersion) -> Interp:
78
+ # raise TypeError
omdev/interp/uv/uv.py CHANGED
@@ -1,6 +1,5 @@
1
1
  # ruff: noqa: UP006 UP007 UP045
2
2
  import dataclasses as dc
3
- import logging
4
3
  import os.path
5
4
  import shutil
6
5
  import sys
@@ -10,6 +9,7 @@ import typing as ta
10
9
  from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
11
10
  from omlish.lite.cached import async_cached_nullary
12
11
  from omlish.lite.check import check
12
+ from omlish.logs.protocols import LoggerLike
13
13
 
14
14
 
15
15
  ##
@@ -26,7 +26,7 @@ class Uv:
26
26
  self,
27
27
  config: UvConfig = UvConfig(),
28
28
  *,
29
- log: ta.Optional[logging.Logger] = None,
29
+ log: ta.Optional[LoggerLike] = None,
30
30
  ) -> None:
31
31
  super().__init__()
32
32
 
omdev/interp/venvs.py CHANGED
@@ -1,6 +1,5 @@
1
1
  # ruff: noqa: UP006 UP007 UP045
2
2
  import dataclasses as dc
3
- import logging
4
3
  import os.path
5
4
  import typing as ta
6
5
 
@@ -9,6 +8,7 @@ from omlish.lite.cached import async_cached_nullary
9
8
  from omlish.lite.cached import cached_nullary
10
9
  from omlish.lite.check import check
11
10
  from omlish.lite.typing import Func2
11
+ from omlish.logs.protocols import LoggerLike
12
12
 
13
13
  from .default import get_default_interp_resolver
14
14
  from .types import InterpSpecifier
@@ -21,6 +21,7 @@ from .types import InterpSpecifier
21
21
  class InterpVenvConfig:
22
22
  interp: ta.Optional[str] = None
23
23
  requires: ta.Optional[ta.Sequence[str]] = None
24
+ requires_pats: ta.Optional[ta.Sequence[str]] = None
24
25
  use_uv: ta.Optional[bool] = None
25
26
 
26
27
 
@@ -35,7 +36,7 @@ class InterpVenv:
35
36
  cfg: InterpVenvConfig,
36
37
  *,
37
38
  requirements_processor: ta.Optional[InterpVenvRequirementsProcessor] = None,
38
- log: ta.Optional[logging.Logger] = None,
39
+ log: ta.Optional[LoggerLike] = None,
39
40
  ) -> None:
40
41
  super().__init__()
41
42
 
@@ -0,0 +1,50 @@
1
+ import typing as ta
2
+
3
+ from omlish import check
4
+ from omlish import dataclasses as dc
5
+ from omlish.funcs import pairs as fps
6
+
7
+ from ..numerics import numerics as nr
8
+ from .formats import MessageFormat
9
+ from .formats import MessageParamsUnpacker
10
+
11
+
12
+ ##
13
+
14
+
15
+ class Message(dc.Case):
16
+ FORMAT: ta.ClassVar[MessageFormat]
17
+ REPLIES: ta.ClassVar[ta.Collection[nr.NumericReply]] = ()
18
+
19
+
20
+ ##
21
+
22
+
23
+ def list_pair_params_unpacker(
24
+ kwarg: str,
25
+ key_param: str,
26
+ value_param: str,
27
+ ) -> MessageParamsUnpacker:
28
+ def forward(params: ta.Mapping[str, str]) -> ta.Mapping[str, ta.Any]:
29
+ out: dict = dict(params)
30
+ ks = out.pop(key_param)
31
+ vs = out.pop(value_param, None)
32
+ if vs is not None:
33
+ out[kwarg] = list(zip(ks, vs, strict=True))
34
+ else:
35
+ out[kwarg] = ks
36
+ return out
37
+
38
+ def backward(kwargs: ta.Mapping[str, ta.Any]) -> ta.Mapping[str, str]:
39
+ out: dict = dict(kwargs)
40
+ ts = out.pop(kwarg)
41
+ is_ts = check.single({isinstance(e, tuple) for e in ts})
42
+ if is_ts:
43
+ ks, vs = zip(*ts)
44
+ out[key_param] = ks
45
+ out[value_param] = vs
46
+ else:
47
+ out[key_param] = ts
48
+ return out
49
+
50
+ return fps.of(forward, backward)
@@ -0,0 +1,92 @@
1
+ import enum
2
+ import typing as ta
3
+
4
+ from omlish import check
5
+ from omlish import dataclasses as dc
6
+ from omlish import lang
7
+ from omlish.funcs import pairs as fps
8
+
9
+
10
+ MessageParamsUnpacker: ta.TypeAlias = fps.FnPair[
11
+ ta.Mapping[str, str], # params
12
+ ta.Mapping[str, ta.Any], # kwargs
13
+ ]
14
+
15
+
16
+ ##
17
+
18
+
19
+ class MessageFormat(dc.Frozen, final=True):
20
+ name: str
21
+
22
+ class Param(dc.Case):
23
+ @classmethod
24
+ def of(cls, obj: ta.Any) -> 'MessageFormat.Param':
25
+ if isinstance(obj, MessageFormat.Param):
26
+ return obj
27
+
28
+ elif isinstance(obj, str):
29
+ s = check.non_empty_str(obj)
30
+
31
+ optional = False
32
+ if s.startswith('?'):
33
+ optional = True
34
+ s = s[1:]
35
+
36
+ arity = MessageFormat.KwargParam.Arity.SINGLE
37
+ if s.startswith('*'):
38
+ arity = MessageFormat.KwargParam.Arity.VARIADIC
39
+ s = s[1:]
40
+
41
+ elif s.startswith(','):
42
+ arity = MessageFormat.KwargParam.Arity.COMMA_LIST
43
+ s = s[1:]
44
+
45
+ return MessageFormat.KwargParam(
46
+ s,
47
+ optional=optional,
48
+ arity=arity,
49
+ )
50
+
51
+ else:
52
+ raise TypeError(obj)
53
+
54
+ class KwargParam(Param):
55
+ name: str = dc.xfield(validate=lang.is_ident)
56
+
57
+ optional: bool = False
58
+
59
+ class Arity(enum.Enum):
60
+ SINGLE = enum.auto() # <foo>
61
+ VARIADIC = enum.auto() # <foo>{ <foo>}
62
+ COMMA_LIST = enum.auto() # <foo>{,<foo>}
63
+
64
+ arity: Arity = Arity.SINGLE
65
+
66
+ class LiteralParam(Param):
67
+ text: str
68
+
69
+ params: ta.Sequence[Param]
70
+
71
+ _: dc.KW_ONLY
72
+
73
+ unpack_params: MessageParamsUnpacker | None = None
74
+
75
+ @dc.init
76
+ def _validate_params(self) -> None:
77
+ kws = [p for p in self.params if isinstance(p, MessageFormat.KwargParam)]
78
+ check.unique(p.name for p in kws)
79
+ check.state(all(p.arity is not MessageFormat.KwargParam.Arity.VARIADIC for p in kws[:-1]))
80
+
81
+ @classmethod
82
+ def of(
83
+ cls,
84
+ name: str,
85
+ *params: ta.Any,
86
+ **kwargs: ta.Any,
87
+ ) -> 'MessageFormat':
88
+ return cls(
89
+ name,
90
+ [MessageFormat.Param.of(p) for p in params],
91
+ **kwargs,
92
+ )