omdev 0.0.0.dev158__py3-none-any.whl → 0.0.0.dev160__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.

omdev/amalg/amalg.py CHANGED
@@ -41,7 +41,7 @@ import tokenize_rt as trt
41
41
  from omlish import check
42
42
  from omlish import collections as col
43
43
  from omlish import lang
44
- from omlish.lite.runtime import REQUIRED_PYTHON_VERSION
44
+ from omlish.lite.runtime import LITE_REQUIRED_PYTHON_VERSION
45
45
  from omlish.logs import all as logs
46
46
 
47
47
  from .. import magic
@@ -595,11 +595,11 @@ def gen_amalg(
595
595
  out.write('\n\n')
596
596
 
597
597
  version_check_fail_msg = (
598
- f'Requires python {REQUIRED_PYTHON_VERSION!r}, '
598
+ f'Requires python {LITE_REQUIRED_PYTHON_VERSION!r}, '
599
599
  f'got {{sys.version_info}} from {{sys.executable}}'
600
600
  )
601
601
  out.write(textwrap.dedent(f"""
602
- if sys.version_info < {REQUIRED_PYTHON_VERSION!r}:
602
+ if sys.version_info < {LITE_REQUIRED_PYTHON_VERSION!r}:
603
603
  raise OSError(f{version_check_fail_msg!r}) # noqa
604
604
  """).lstrip())
605
605
  out.write('\n\n')
omdev/cache/data/cache.py CHANGED
@@ -27,7 +27,7 @@ from omlish import marshal as msh
27
27
  from omlish.formats import json
28
28
  from omlish.os.files import touch
29
29
 
30
- from ... import git
30
+ from ...git.subtrees import git_clone_subtree
31
31
  from .actions import Action
32
32
  from .actions import ExtractAction
33
33
  from .manifests import Manifest
@@ -148,7 +148,7 @@ class Cache:
148
148
 
149
149
  log.info('Cloning git repo: %s -> %s', spec.url, tmp_dir)
150
150
 
151
- git.git_clone_subtree(
151
+ git_clone_subtree(
152
152
  base_dir=tmp_dir,
153
153
  repo_url=spec.url,
154
154
  repo_dir='data',
@@ -4,7 +4,7 @@ from omlish import __about__ as about
4
4
  from omlish import cached
5
5
  from omlish import dataclasses as dc
6
6
 
7
- from ...git import get_git_revision
7
+ from ...git.revisions import get_git_revision
8
8
  from .consts import SERIALIZATION_VERSION
9
9
  from .specs import Spec
10
10
 
omdev/git/__init__.py ADDED
File without changes
omdev/git/revisions.py ADDED
@@ -0,0 +1,50 @@
1
+ # ruff: noqa: UP006 UP007
2
+ # @omlish-lite
3
+ import os.path
4
+ import subprocess
5
+ import typing as ta
6
+
7
+ from omlish.subprocesses import subprocess_maybe_shell_wrap_exec
8
+ from omlish.subprocesses import subprocesses
9
+
10
+
11
+ def get_git_revision(
12
+ *,
13
+ cwd: ta.Optional[str] = None,
14
+ ) -> ta.Optional[str]:
15
+ subprocesses.check_output('git', '--version')
16
+
17
+ if cwd is None:
18
+ cwd = os.getcwd()
19
+
20
+ if subprocess.run( # noqa
21
+ subprocess_maybe_shell_wrap_exec(
22
+ 'git',
23
+ 'rev-parse',
24
+ '--is-inside-work-tree',
25
+ ),
26
+ stdout=subprocess.PIPE,
27
+ stderr=subprocess.PIPE,
28
+ ).returncode:
29
+ return None
30
+
31
+ has_untracked = bool(subprocesses.check_output(
32
+ 'git',
33
+ 'ls-files',
34
+ '.',
35
+ '--exclude-standard',
36
+ '--others',
37
+ cwd=cwd,
38
+ ).decode().strip())
39
+
40
+ dirty_rev = subprocesses.check_output(
41
+ 'git',
42
+ 'describe',
43
+ '--match=NeVeRmAtCh',
44
+ '--always',
45
+ '--abbrev=40',
46
+ '--dirty',
47
+ cwd=cwd,
48
+ ).decode().strip()
49
+
50
+ return dirty_rev + ('-untracked' if has_untracked else '')
@@ -1,11 +1,5 @@
1
1
  # ruff: noqa: UP006 UP007
2
2
  # @omlish-lite
3
- """
4
- git status
5
- --porcelain=v1
6
- --ignore-submodules
7
- 2>/dev/null
8
- """
9
3
  import dataclasses as dc
10
4
  import enum
11
5
  import os.path
@@ -16,111 +10,6 @@ from omlish.lite.check import check
16
10
  from omlish.subprocesses import subprocess_maybe_shell_wrap_exec
17
11
 
18
12
 
19
- ##
20
-
21
-
22
- def git_clone_subtree(
23
- *,
24
- base_dir: str,
25
- repo_url: str,
26
- repo_dir: str,
27
- branch: ta.Optional[str] = None,
28
- rev: ta.Optional[str] = None,
29
- repo_subtrees: ta.Sequence[str],
30
- ) -> None:
31
- if not bool(branch) ^ bool(rev):
32
- raise ValueError('must set branch or rev')
33
-
34
- if isinstance(repo_subtrees, str):
35
- raise TypeError(repo_subtrees)
36
-
37
- git_opts = [
38
- '-c', 'advice.detachedHead=false',
39
- ]
40
-
41
- subprocess.check_call(
42
- subprocess_maybe_shell_wrap_exec(
43
- 'git',
44
- *git_opts,
45
- 'clone',
46
- '-n',
47
- '--depth=1',
48
- '--filter=tree:0',
49
- *(['-b', branch] if branch else []),
50
- '--single-branch',
51
- repo_url,
52
- repo_dir,
53
- ),
54
- cwd=base_dir,
55
- )
56
-
57
- rd = os.path.join(base_dir, repo_dir)
58
- subprocess.check_call(
59
- subprocess_maybe_shell_wrap_exec(
60
- 'git',
61
- *git_opts,
62
- 'sparse-checkout',
63
- 'set',
64
- '--no-cone',
65
- *repo_subtrees,
66
- ),
67
- cwd=rd,
68
- )
69
-
70
- subprocess.check_call(
71
- subprocess_maybe_shell_wrap_exec(
72
- 'git',
73
- *git_opts,
74
- 'checkout',
75
- *([rev] if rev else []),
76
- ),
77
- cwd=rd,
78
- )
79
-
80
-
81
- def get_git_revision(
82
- *,
83
- cwd: ta.Optional[str] = None,
84
- ) -> ta.Optional[str]:
85
- subprocess.check_output(subprocess_maybe_shell_wrap_exec('git', '--version'))
86
-
87
- if cwd is None:
88
- cwd = os.getcwd()
89
-
90
- if subprocess.run( # noqa
91
- subprocess_maybe_shell_wrap_exec(
92
- 'git',
93
- 'rev-parse',
94
- '--is-inside-work-tree',
95
- ),
96
- stdout=subprocess.PIPE,
97
- stderr=subprocess.PIPE,
98
- ).returncode:
99
- return None
100
-
101
- has_untracked = bool(subprocess.check_output(subprocess_maybe_shell_wrap_exec(
102
- 'git',
103
- 'ls-files',
104
- '.',
105
- '--exclude-standard',
106
- '--others',
107
- ), cwd=cwd).decode().strip())
108
-
109
- dirty_rev = subprocess.check_output(subprocess_maybe_shell_wrap_exec(
110
- 'git',
111
- 'describe',
112
- '--match=NeVeRmAtCh',
113
- '--always',
114
- '--abbrev=40',
115
- '--dirty',
116
- ), cwd=cwd).decode().strip()
117
-
118
- return dirty_rev + ('-untracked' if has_untracked else '')
119
-
120
-
121
- ##
122
-
123
-
124
13
  _GIT_STATUS_LINE_ESCAPE_CODES: ta.Mapping[str, str] = {
125
14
  '\\': '\\',
126
15
  '"': '"',
omdev/git/subtrees.py ADDED
@@ -0,0 +1,100 @@
1
+ # ruff: noqa: UP006 UP007
2
+ # @omlish-lite
3
+ import dataclasses as dc
4
+ import os.path
5
+ import typing as ta
6
+
7
+ from omlish.subprocesses import subprocesses
8
+
9
+
10
+ @dc.dataclass(frozen=True)
11
+ class GitSubtreeCloner:
12
+ base_dir: str
13
+ repo_url: str
14
+ repo_dir: str
15
+
16
+ # _: dc.KW_ONLY
17
+
18
+ repo_subtrees: ta.Sequence[str]
19
+
20
+ branch: ta.Optional[str] = None
21
+ rev: ta.Optional[str] = None
22
+
23
+ def __post_init__(self) -> None:
24
+ if not bool(self.branch) ^ bool(self.rev):
25
+ raise ValueError('must set branch or rev')
26
+
27
+ if isinstance(self.repo_subtrees, str):
28
+ raise TypeError(self.repo_subtrees)
29
+
30
+ @dc.dataclass(frozen=True)
31
+ class Command:
32
+ cmd: ta.Sequence[str]
33
+ cwd: str
34
+
35
+ def build_commands(self) -> ta.Iterator[Command]:
36
+ git_opts = [
37
+ '-c', 'advice.detachedHead=false',
38
+ ]
39
+
40
+ yield GitSubtreeCloner.Command(
41
+ cmd=(
42
+ 'git',
43
+ *git_opts,
44
+ 'clone',
45
+ '-n',
46
+ '--depth=1',
47
+ '--filter=tree:0',
48
+ *(['-b', self.branch] if self.branch else []),
49
+ '--single-branch',
50
+ self.repo_url,
51
+ self.repo_dir,
52
+ ),
53
+ cwd=self.base_dir,
54
+ )
55
+
56
+ rd = os.path.join(self.base_dir, self.repo_dir)
57
+ yield GitSubtreeCloner.Command(
58
+ cmd=(
59
+ 'git',
60
+ *git_opts,
61
+ 'sparse-checkout',
62
+ 'set',
63
+ '--no-cone',
64
+ *self.repo_subtrees,
65
+ ),
66
+ cwd=rd,
67
+ )
68
+
69
+ yield GitSubtreeCloner.Command(
70
+ cmd=(
71
+ 'git',
72
+ *git_opts,
73
+ 'checkout',
74
+ *([self.rev] if self.rev else []),
75
+ ),
76
+ cwd=rd,
77
+ )
78
+
79
+
80
+ def git_clone_subtree(
81
+ *,
82
+ base_dir: str,
83
+ repo_url: str,
84
+ repo_dir: str,
85
+ branch: ta.Optional[str] = None,
86
+ rev: ta.Optional[str] = None,
87
+ repo_subtrees: ta.Sequence[str],
88
+ ) -> None:
89
+ for cmd in GitSubtreeCloner(
90
+ base_dir=base_dir,
91
+ repo_url=repo_url,
92
+ repo_dir=repo_dir,
93
+ branch=branch,
94
+ rev=rev,
95
+ repo_subtrees=repo_subtrees,
96
+ ).build_commands():
97
+ subprocesses.check_call(
98
+ *cmd.cmd,
99
+ cwd=cmd.cwd,
100
+ )
omdev/interp/cli.py CHANGED
@@ -12,7 +12,7 @@ import asyncio
12
12
  import typing as ta
13
13
 
14
14
  from omlish.lite.check import check
15
- from omlish.lite.runtime import check_runtime_version
15
+ from omlish.lite.runtime import check_lite_runtime_version
16
16
  from omlish.logs.standard import configure_standard_logging
17
17
 
18
18
  from .resolvers import DEFAULT_INTERP_RESOLVER
@@ -58,7 +58,7 @@ def _build_parser() -> argparse.ArgumentParser:
58
58
 
59
59
 
60
60
  async def _async_main(argv: ta.Optional[ta.Sequence[str]] = None) -> None:
61
- check_runtime_version()
61
+ check_lite_runtime_version()
62
62
  configure_standard_logging()
63
63
 
64
64
  parser = _build_parser()
omdev/pyproject/cli.py CHANGED
@@ -39,7 +39,7 @@ from omlish.argparse.cli import argparse_command
39
39
  from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
40
40
  from omlish.lite.cached import cached_nullary
41
41
  from omlish.lite.check import check
42
- from omlish.lite.runtime import check_runtime_version
42
+ from omlish.lite.runtime import check_lite_runtime_version
43
43
  from omlish.logs.standard import configure_standard_logging
44
44
 
45
45
  from ..toml.parser import toml_loads
@@ -288,7 +288,7 @@ class PyprojectCli(ArgparseCli):
288
288
 
289
289
 
290
290
  async def _async_main(argv: ta.Optional[ta.Sequence[str]] = None) -> None:
291
- check_runtime_version()
291
+ check_lite_runtime_version()
292
292
  configure_standard_logging()
293
293
 
294
294
  await PyprojectCli(argv).async_cli_run()
omdev/revisions.py CHANGED
@@ -18,7 +18,7 @@ from omlish.lite.check import check
18
18
  from omlish.lite.logs import log
19
19
  from omlish.logs.standard import configure_standard_logging
20
20
 
21
- from .git import get_git_revision
21
+ from .git.revisions import get_git_revision
22
22
  from .wheelfile import WheelFile
23
23
 
24
24
 
omdev/scripts/interp.py CHANGED
@@ -1086,6 +1086,10 @@ def is_new_type(spec: ta.Any) -> bool:
1086
1086
  return isinstance(spec, types.FunctionType) and spec.__code__ is ta.NewType.__code__.co_consts[1] # type: ignore # noqa
1087
1087
 
1088
1088
 
1089
+ def get_new_type_supertype(spec: ta.Any) -> ta.Any:
1090
+ return spec.__supertype__
1091
+
1092
+
1089
1093
  def deep_subclasses(cls: ta.Type[T]) -> ta.Iterator[ta.Type[T]]:
1090
1094
  seen = set()
1091
1095
  todo = list(reversed(cls.__subclasses__()))
@@ -1806,12 +1810,12 @@ def is_debugger_attached() -> bool:
1806
1810
  return any(frame[1].endswith('pydevd.py') for frame in inspect.stack())
1807
1811
 
1808
1812
 
1809
- REQUIRED_PYTHON_VERSION = (3, 8)
1813
+ LITE_REQUIRED_PYTHON_VERSION = (3, 8)
1810
1814
 
1811
1815
 
1812
- def check_runtime_version() -> None:
1813
- if sys.version_info < REQUIRED_PYTHON_VERSION:
1814
- raise OSError(f'Requires python {REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
1816
+ def check_lite_runtime_version() -> None:
1817
+ if sys.version_info < LITE_REQUIRED_PYTHON_VERSION:
1818
+ raise OSError(f'Requires python {LITE_REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
1815
1819
 
1816
1820
 
1817
1821
  ########################################
@@ -1968,6 +1972,7 @@ TODO:
1968
1972
  - structured
1969
1973
  - prefixed
1970
1974
  - debug
1975
+ - optional noisy? noisy will never be lite - some kinda configure_standard callback mechanism?
1971
1976
  """
1972
1977
 
1973
1978
 
@@ -2004,8 +2009,9 @@ class StandardLogFormatter(logging.Formatter):
2004
2009
  ##
2005
2010
 
2006
2011
 
2007
- class StandardLogHandler(ProxyLogHandler):
2008
- pass
2012
+ class StandardConfiguredLogHandler(ProxyLogHandler):
2013
+ def __init_subclass__(cls, **kwargs):
2014
+ raise TypeError('This class serves only as a marker and should not be subclassed.')
2009
2015
 
2010
2016
 
2011
2017
  ##
@@ -2036,7 +2042,7 @@ def configure_standard_logging(
2036
2042
  target: ta.Optional[logging.Logger] = None,
2037
2043
  force: bool = False,
2038
2044
  handler_factory: ta.Optional[ta.Callable[[], logging.Handler]] = None,
2039
- ) -> ta.Optional[StandardLogHandler]:
2045
+ ) -> ta.Optional[StandardConfiguredLogHandler]:
2040
2046
  with _locking_logging_module_lock():
2041
2047
  if target is None:
2042
2048
  target = logging.root
@@ -2044,7 +2050,7 @@ def configure_standard_logging(
2044
2050
  #
2045
2051
 
2046
2052
  if not force:
2047
- if any(isinstance(h, StandardLogHandler) for h in list(target.handlers)):
2053
+ if any(isinstance(h, StandardConfiguredLogHandler) for h in list(target.handlers)):
2048
2054
  return None
2049
2055
 
2050
2056
  #
@@ -2078,7 +2084,7 @@ def configure_standard_logging(
2078
2084
 
2079
2085
  #
2080
2086
 
2081
- return StandardLogHandler(handler)
2087
+ return StandardConfiguredLogHandler(handler)
2082
2088
 
2083
2089
 
2084
2090
  ########################################
@@ -3486,7 +3492,7 @@ def _build_parser() -> argparse.ArgumentParser:
3486
3492
 
3487
3493
 
3488
3494
  async def _async_main(argv: ta.Optional[ta.Sequence[str]] = None) -> None:
3489
- check_runtime_version()
3495
+ check_lite_runtime_version()
3490
3496
  configure_standard_logging()
3491
3497
 
3492
3498
  parser = _build_parser()
@@ -2378,6 +2378,10 @@ def is_new_type(spec: ta.Any) -> bool:
2378
2378
  return isinstance(spec, types.FunctionType) and spec.__code__ is ta.NewType.__code__.co_consts[1] # type: ignore # noqa
2379
2379
 
2380
2380
 
2381
+ def get_new_type_supertype(spec: ta.Any) -> ta.Any:
2382
+ return spec.__supertype__
2383
+
2384
+
2381
2385
  def deep_subclasses(cls: ta.Type[T]) -> ta.Iterator[ta.Type[T]]:
2382
2386
  seen = set()
2383
2387
  todo = list(reversed(cls.__subclasses__()))
@@ -3680,9 +3684,7 @@ class ArgparseCli:
3680
3684
  """
3681
3685
  TODO:
3682
3686
  - pickle stdlib objs? have to pin to 3.8 pickle protocol, will be cross-version
3683
- - namedtuple
3684
3687
  - literals
3685
- - newtypes?
3686
3688
  """
3687
3689
 
3688
3690
 
@@ -3692,7 +3694,7 @@ TODO:
3692
3694
  @dc.dataclass(frozen=True)
3693
3695
  class ObjMarshalOptions:
3694
3696
  raw_bytes: bool = False
3695
- nonstrict_dataclasses: bool = False
3697
+ non_strict_fields: bool = False
3696
3698
 
3697
3699
 
3698
3700
  class ObjMarshaler(abc.ABC):
@@ -3821,10 +3823,10 @@ class IterableObjMarshaler(ObjMarshaler):
3821
3823
 
3822
3824
 
3823
3825
  @dc.dataclass(frozen=True)
3824
- class DataclassObjMarshaler(ObjMarshaler):
3826
+ class FieldsObjMarshaler(ObjMarshaler):
3825
3827
  ty: type
3826
3828
  fs: ta.Mapping[str, ObjMarshaler]
3827
- nonstrict: bool = False
3829
+ non_strict: bool = False
3828
3830
 
3829
3831
  def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
3830
3832
  return {
@@ -3836,7 +3838,7 @@ class DataclassObjMarshaler(ObjMarshaler):
3836
3838
  return self.ty(**{
3837
3839
  k: self.fs[k].unmarshal(v, ctx)
3838
3840
  for k, v in o.items()
3839
- if not (self.nonstrict or ctx.options.nonstrict_dataclasses) or k in self.fs
3841
+ if not (self.non_strict or ctx.options.non_strict_fields) or k in self.fs
3840
3842
  })
3841
3843
 
3842
3844
 
@@ -3968,7 +3970,7 @@ class ObjMarshalerManager:
3968
3970
  ty: ta.Any,
3969
3971
  rec: ta.Callable[[ta.Any], ObjMarshaler],
3970
3972
  *,
3971
- nonstrict_dataclasses: bool = False,
3973
+ non_strict_fields: bool = False,
3972
3974
  ) -> ObjMarshaler:
3973
3975
  if isinstance(ty, type):
3974
3976
  if abc.ABC in ty.__bases__:
@@ -3990,12 +3992,22 @@ class ObjMarshalerManager:
3990
3992
  return EnumObjMarshaler(ty)
3991
3993
 
3992
3994
  if dc.is_dataclass(ty):
3993
- return DataclassObjMarshaler(
3995
+ return FieldsObjMarshaler(
3994
3996
  ty,
3995
3997
  {f.name: rec(f.type) for f in dc.fields(ty)},
3996
- nonstrict=nonstrict_dataclasses,
3998
+ non_strict=non_strict_fields,
3999
+ )
4000
+
4001
+ if issubclass(ty, tuple) and hasattr(ty, '_fields'):
4002
+ return FieldsObjMarshaler(
4003
+ ty,
4004
+ {p.name: rec(p.annotation) for p in inspect.signature(ty).parameters.values()},
4005
+ non_strict=non_strict_fields,
3997
4006
  )
3998
4007
 
4008
+ if is_new_type(ty):
4009
+ return rec(get_new_type_supertype(ty))
4010
+
3999
4011
  if is_generic_alias(ty):
4000
4012
  try:
4001
4013
  mt = self._generic_mapping_types[ta.get_origin(ty)]
@@ -4129,12 +4141,12 @@ def is_debugger_attached() -> bool:
4129
4141
  return any(frame[1].endswith('pydevd.py') for frame in inspect.stack())
4130
4142
 
4131
4143
 
4132
- REQUIRED_PYTHON_VERSION = (3, 8)
4144
+ LITE_REQUIRED_PYTHON_VERSION = (3, 8)
4133
4145
 
4134
4146
 
4135
- def check_runtime_version() -> None:
4136
- if sys.version_info < REQUIRED_PYTHON_VERSION:
4137
- raise OSError(f'Requires python {REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
4147
+ def check_lite_runtime_version() -> None:
4148
+ if sys.version_info < LITE_REQUIRED_PYTHON_VERSION:
4149
+ raise OSError(f'Requires python {LITE_REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
4138
4150
 
4139
4151
 
4140
4152
  ########################################
@@ -4389,6 +4401,7 @@ TODO:
4389
4401
  - structured
4390
4402
  - prefixed
4391
4403
  - debug
4404
+ - optional noisy? noisy will never be lite - some kinda configure_standard callback mechanism?
4392
4405
  """
4393
4406
 
4394
4407
 
@@ -4425,8 +4438,9 @@ class StandardLogFormatter(logging.Formatter):
4425
4438
  ##
4426
4439
 
4427
4440
 
4428
- class StandardLogHandler(ProxyLogHandler):
4429
- pass
4441
+ class StandardConfiguredLogHandler(ProxyLogHandler):
4442
+ def __init_subclass__(cls, **kwargs):
4443
+ raise TypeError('This class serves only as a marker and should not be subclassed.')
4430
4444
 
4431
4445
 
4432
4446
  ##
@@ -4457,7 +4471,7 @@ def configure_standard_logging(
4457
4471
  target: ta.Optional[logging.Logger] = None,
4458
4472
  force: bool = False,
4459
4473
  handler_factory: ta.Optional[ta.Callable[[], logging.Handler]] = None,
4460
- ) -> ta.Optional[StandardLogHandler]:
4474
+ ) -> ta.Optional[StandardConfiguredLogHandler]:
4461
4475
  with _locking_logging_module_lock():
4462
4476
  if target is None:
4463
4477
  target = logging.root
@@ -4465,7 +4479,7 @@ def configure_standard_logging(
4465
4479
  #
4466
4480
 
4467
4481
  if not force:
4468
- if any(isinstance(h, StandardLogHandler) for h in list(target.handlers)):
4482
+ if any(isinstance(h, StandardConfiguredLogHandler) for h in list(target.handlers)):
4469
4483
  return None
4470
4484
 
4471
4485
  #
@@ -4499,7 +4513,7 @@ def configure_standard_logging(
4499
4513
 
4500
4514
  #
4501
4515
 
4502
- return StandardLogHandler(handler)
4516
+ return StandardConfiguredLogHandler(handler)
4503
4517
 
4504
4518
 
4505
4519
  ########################################
@@ -4831,404 +4845,49 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
4831
4845
 
4832
4846
 
4833
4847
  ########################################
4834
- # ../../git.py
4835
- """
4836
- git status
4837
- --porcelain=v1
4838
- --ignore-submodules
4839
- 2>/dev/null
4840
- """
4841
-
4842
-
4843
- ##
4844
-
4845
-
4846
- def git_clone_subtree(
4847
- *,
4848
- base_dir: str,
4849
- repo_url: str,
4850
- repo_dir: str,
4851
- branch: ta.Optional[str] = None,
4852
- rev: ta.Optional[str] = None,
4853
- repo_subtrees: ta.Sequence[str],
4854
- ) -> None:
4855
- if not bool(branch) ^ bool(rev):
4856
- raise ValueError('must set branch or rev')
4857
-
4858
- if isinstance(repo_subtrees, str):
4859
- raise TypeError(repo_subtrees)
4860
-
4861
- git_opts = [
4862
- '-c', 'advice.detachedHead=false',
4863
- ]
4864
-
4865
- subprocess.check_call(
4866
- subprocess_maybe_shell_wrap_exec(
4867
- 'git',
4868
- *git_opts,
4869
- 'clone',
4870
- '-n',
4871
- '--depth=1',
4872
- '--filter=tree:0',
4873
- *(['-b', branch] if branch else []),
4874
- '--single-branch',
4875
- repo_url,
4876
- repo_dir,
4877
- ),
4878
- cwd=base_dir,
4879
- )
4880
-
4881
- rd = os.path.join(base_dir, repo_dir)
4882
- subprocess.check_call(
4883
- subprocess_maybe_shell_wrap_exec(
4884
- 'git',
4885
- *git_opts,
4886
- 'sparse-checkout',
4887
- 'set',
4888
- '--no-cone',
4889
- *repo_subtrees,
4890
- ),
4891
- cwd=rd,
4892
- )
4893
-
4894
- subprocess.check_call(
4895
- subprocess_maybe_shell_wrap_exec(
4896
- 'git',
4897
- *git_opts,
4898
- 'checkout',
4899
- *([rev] if rev else []),
4900
- ),
4901
- cwd=rd,
4902
- )
4848
+ # ../../git/revisions.py
4903
4849
 
4904
4850
 
4905
4851
  def get_git_revision(
4906
4852
  *,
4907
4853
  cwd: ta.Optional[str] = None,
4908
4854
  ) -> ta.Optional[str]:
4909
- subprocess.check_output(subprocess_maybe_shell_wrap_exec('git', '--version'))
4855
+ subprocesses.check_output('git', '--version')
4910
4856
 
4911
4857
  if cwd is None:
4912
4858
  cwd = os.getcwd()
4913
4859
 
4914
4860
  if subprocess.run( # noqa
4915
- subprocess_maybe_shell_wrap_exec(
4916
- 'git',
4917
- 'rev-parse',
4918
- '--is-inside-work-tree',
4919
- ),
4920
- stdout=subprocess.PIPE,
4921
- stderr=subprocess.PIPE,
4861
+ subprocess_maybe_shell_wrap_exec(
4862
+ 'git',
4863
+ 'rev-parse',
4864
+ '--is-inside-work-tree',
4865
+ ),
4866
+ stdout=subprocess.PIPE,
4867
+ stderr=subprocess.PIPE,
4922
4868
  ).returncode:
4923
4869
  return None
4924
4870
 
4925
- has_untracked = bool(subprocess.check_output(subprocess_maybe_shell_wrap_exec(
4871
+ has_untracked = bool(subprocesses.check_output(
4926
4872
  'git',
4927
4873
  'ls-files',
4928
4874
  '.',
4929
4875
  '--exclude-standard',
4930
4876
  '--others',
4931
- ), cwd=cwd).decode().strip())
4877
+ cwd=cwd,
4878
+ ).decode().strip())
4932
4879
 
4933
- dirty_rev = subprocess.check_output(subprocess_maybe_shell_wrap_exec(
4880
+ dirty_rev = subprocesses.check_output(
4934
4881
  'git',
4935
4882
  'describe',
4936
4883
  '--match=NeVeRmAtCh',
4937
4884
  '--always',
4938
4885
  '--abbrev=40',
4939
4886
  '--dirty',
4940
- ), cwd=cwd).decode().strip()
4941
-
4942
- return dirty_rev + ('-untracked' if has_untracked else '')
4943
-
4944
-
4945
- ##
4946
-
4947
-
4948
- _GIT_STATUS_LINE_ESCAPE_CODES: ta.Mapping[str, str] = {
4949
- '\\': '\\',
4950
- '"': '"',
4951
- 'n': '\n',
4952
- 't': '\t',
4953
- }
4954
-
4955
-
4956
- def yield_git_status_line_fields(l: str) -> ta.Iterator[str]:
4957
- def find_any(chars: str, start: int = 0) -> int:
4958
- ret = -1
4959
- for c in chars:
4960
- if (found := l.find(c, start)) >= 0 and (ret < 0 or ret > found):
4961
- ret = found
4962
- return ret
4963
-
4964
- p = 0
4965
- while True:
4966
- if l[p] == '"':
4967
- p += 1
4968
- s = []
4969
- while (n := find_any('\\"', p)) > 0:
4970
- if (c := l[n]) == '\\':
4971
- s.append(l[p:n])
4972
- s.append(_GIT_STATUS_LINE_ESCAPE_CODES[l[n + 1]])
4973
- p = n + 2
4974
- elif c == '"':
4975
- s.append(l[p:n])
4976
- p = n
4977
- break
4978
- else:
4979
- raise ValueError(l)
4980
-
4981
- if l[p] != '"':
4982
- raise ValueError(l)
4983
-
4984
- yield ''.join(s)
4985
-
4986
- p += 1
4987
- if p == len(l):
4988
- return
4989
- elif l[p] != ' ':
4990
- raise ValueError(l)
4991
-
4992
- p += 1
4993
-
4994
- else:
4995
- if (e := l.find(' ', p)) < 0:
4996
- yield l[p:]
4997
- return
4998
-
4999
- yield l[p:e]
5000
- p = e + 1
5001
-
5002
-
5003
- """
5004
- When merge is occurring and was successful, or outside of a merge situation, X shows the status of the index and Y shows
5005
- the status of the working tree:
5006
- -------------------------------------------------
5007
- X Y Meaning
5008
- -------------------------------------------------
5009
- [AMD] not updated
5010
- M [ MTD] updated in index
5011
- T [ MTD] type changed in index
5012
- A [ MTD] added to index
5013
- D deleted from index
5014
- R [ MTD] renamed in index
5015
- C [ MTD] copied in index
5016
- [MTARC] index and work tree matches
5017
- [ MTARC] M work tree changed since index
5018
- [ MTARC] T type changed in work tree since index
5019
- [ MTARC] D deleted in work tree
5020
- R renamed in work tree
5021
- C copied in work tree
5022
-
5023
- When merge conflict has occurred and has not yet been resolved, X and Y show the state introduced by each head of the
5024
- merge, relative to the common ancestor:
5025
- -------------------------------------------------
5026
- X Y Meaning
5027
- -------------------------------------------------
5028
- D D unmerged, both deleted
5029
- A U unmerged, added by us
5030
- U D unmerged, deleted by them
5031
- U A unmerged, added by them
5032
- D U unmerged, deleted by us
5033
- A A unmerged, both added
5034
- U U unmerged, both modified
5035
-
5036
- When path is untracked, X and Y are always the same, since they are unknown to the index:
5037
- -------------------------------------------------
5038
- X Y Meaning
5039
- -------------------------------------------------
5040
- ? ? untracked
5041
- ! ! ignored
5042
-
5043
- Submodules have more state and instead report
5044
-
5045
- - M = the submodule has a different HEAD than recorded in the index
5046
- - m = the submodule has modified content
5047
- - ? = the submodule has untracked files
5048
-
5049
- This is since modified content or untracked files in a submodule cannot be added via git add in the superproject to
5050
- prepare a commit. m and ? are applied recursively. For example if a nested submodule in a submodule contains an
5051
- untracked file, this is reported as ? as well.
5052
- """ # noqa
5053
-
5054
-
5055
- class GitStatusState(enum.Enum):
5056
- UNMODIFIED = ' '
5057
- MODIFIED = 'M'
5058
- FILE_TYPE_CHANGED = 'T'
5059
- ADDED = 'A'
5060
- DELETED = 'D'
5061
- RENAMED = 'R'
5062
- COPIED = 'C'
5063
- UPDATED_BUT_UNMERGED = 'U'
5064
- UNTRACKED = '?'
5065
- IGNORED = '!'
5066
- SUBMODULE_MODIFIED_CONTENT = 'm'
5067
-
5068
-
5069
- _UNMERGED_GIT_STATUS_STATES: ta.FrozenSet[GitStatusState] = frozenset([
5070
- GitStatusState.UPDATED_BUT_UNMERGED,
5071
- ])
5072
-
5073
- _UNMERGED_GIT_STATUS_STATE_PAIRS: ta.FrozenSet[ta.Tuple[GitStatusState, GitStatusState]] = frozenset([
5074
- (GitStatusState.ADDED, GitStatusState.ADDED),
5075
- (GitStatusState.DELETED, GitStatusState.DELETED),
5076
- ])
5077
-
5078
-
5079
- @dc.dataclass(frozen=True)
5080
- class GitStatusItem:
5081
- x: GitStatusState
5082
- y: GitStatusState
5083
-
5084
- a: str
5085
- b: ta.Optional[str]
5086
-
5087
- @property
5088
- def is_unmerged(self) -> bool:
5089
- return (
5090
- self.x in _UNMERGED_GIT_STATUS_STATE_PAIRS or
5091
- self.y in _UNMERGED_GIT_STATUS_STATE_PAIRS or
5092
- (self.x, self.y) in _UNMERGED_GIT_STATUS_STATE_PAIRS
5093
- )
5094
-
5095
- def __repr__(self) -> str:
5096
- return (
5097
- f'{self.__class__.__name__}('
5098
- f'x={self.x.name}, '
5099
- f'y={self.y.name}, '
5100
- f'a={self.a!r}' +
5101
- (f', b={self.b!r}' if self.b is not None else '') +
5102
- ')'
5103
- )
5104
-
5105
-
5106
- def parse_git_status_line(l: str) -> GitStatusItem:
5107
- if len(l) < 3 or l[2] != ' ':
5108
- raise ValueError(l)
5109
- x, y = l[0], l[1]
5110
-
5111
- fields = list(yield_git_status_line_fields(l[3:]))
5112
- if len(fields) == 1:
5113
- a, b = fields[0], None
5114
- elif len(fields) == 3:
5115
- check.state(fields[1] == '->', l)
5116
- a, b = fields[0], fields[2]
5117
- else:
5118
- raise ValueError(l)
5119
-
5120
- return GitStatusItem(
5121
- GitStatusState(x),
5122
- GitStatusState(y),
5123
- a,
5124
- b,
5125
- )
5126
-
5127
-
5128
- class GitStatus(ta.Sequence[GitStatusItem]):
5129
- def __init__(self, lines: ta.Iterable[GitStatusItem]) -> None:
5130
- super().__init__()
5131
-
5132
- self._lst = list(lines)
5133
-
5134
- by_x: ta.Dict[GitStatusState, list[GitStatusItem]] = {}
5135
- by_y: ta.Dict[GitStatusState, list[GitStatusItem]] = {}
5136
-
5137
- by_a: ta.Dict[str, GitStatusItem] = {}
5138
- by_b: ta.Dict[str, GitStatusItem] = {}
5139
-
5140
- for l in self._lst:
5141
- by_x.setdefault(l.x, []).append(l)
5142
- by_y.setdefault(l.y, []).append(l)
5143
-
5144
- if l.a in by_a:
5145
- raise KeyError(l.a)
5146
- by_a[l.a] = l
5147
-
5148
- if l.b is not None:
5149
- if l.b in by_b:
5150
- raise KeyError(l.b)
5151
- by_b[l.b] = l
5152
-
5153
- self._by_x = by_x
5154
- self._by_y = by_y
5155
-
5156
- self._by_a = by_a
5157
- self._by_b = by_b
5158
-
5159
- self._has_unmerged = any(l.is_unmerged for l in self)
5160
-
5161
- #
5162
-
5163
- def __iter__(self) -> ta.Iterator[GitStatusItem]:
5164
- return iter(self._lst)
5165
-
5166
- def __getitem__(self, index):
5167
- return self._lst[index]
5168
-
5169
- def __len__(self) -> int:
5170
- return len(self._lst)
5171
-
5172
- #
5173
-
5174
- @property
5175
- def by_x(self) -> ta.Mapping[GitStatusState, ta.Sequence[GitStatusItem]]:
5176
- return self._by_x
5177
-
5178
- @property
5179
- def by_y(self) -> ta.Mapping[GitStatusState, ta.Sequence[GitStatusItem]]:
5180
- return self._by_y
5181
-
5182
- @property
5183
- def by_a(self) -> ta.Mapping[str, GitStatusItem]:
5184
- return self._by_a
5185
-
5186
- @property
5187
- def by_b(self) -> ta.Mapping[str, GitStatusItem]:
5188
- return self._by_b
5189
-
5190
- #
5191
-
5192
- @property
5193
- def has_unmerged(self) -> bool:
5194
- return self._has_unmerged
5195
-
5196
- @property
5197
- def has_staged(self) -> bool:
5198
- return any(l.x != GitStatusState.UNMODIFIED for l in self._lst)
5199
-
5200
- @property
5201
- def has_dirty(self) -> bool:
5202
- return any(l.y != GitStatusState.UNMODIFIED for l in self._lst)
5203
-
5204
-
5205
- def parse_git_status(s: str) -> GitStatus:
5206
- return GitStatus(parse_git_status_line(l) for l in s.splitlines())
5207
-
5208
-
5209
- def get_git_status(
5210
- *,
5211
- cwd: ta.Optional[str] = None,
5212
- ignore_submodules: bool = False,
5213
- verbose: bool = False,
5214
- ) -> GitStatus:
5215
- if cwd is None:
5216
- cwd = os.getcwd()
5217
-
5218
- proc = subprocess.run( # type: ignore
5219
- subprocess_maybe_shell_wrap_exec(
5220
- 'git',
5221
- 'status',
5222
- '--porcelain=v1',
5223
- *(['--ignore-submodules'] if ignore_submodules else []),
5224
- ),
5225
4887
  cwd=cwd,
5226
- stdout=subprocess.PIPE,
5227
- **(dict(stderr=subprocess.PIPE) if not verbose else {}),
5228
- check=True,
5229
- )
4888
+ ).decode().strip()
5230
4889
 
5231
- return parse_git_status(proc.stdout.decode()) # noqa
4890
+ return dirty_rev + ('-untracked' if has_untracked else '')
5232
4891
 
5233
4892
 
5234
4893
  ########################################
@@ -7290,7 +6949,7 @@ class PyprojectCli(ArgparseCli):
7290
6949
 
7291
6950
 
7292
6951
  async def _async_main(argv: ta.Optional[ta.Sequence[str]] = None) -> None:
7293
- check_runtime_version()
6952
+ check_lite_runtime_version()
7294
6953
  configure_standard_logging()
7295
6954
 
7296
6955
  await PyprojectCli(argv).async_cli_run()
omdev/tools/git.py CHANGED
@@ -15,8 +15,8 @@ from omlish.formats import json
15
15
  from omlish.logs import all as logs
16
16
 
17
17
  from ..cli import CliModule
18
- from ..git import GitStatusItem
19
- from ..git import get_git_status
18
+ from ..git.status import GitStatusItem
19
+ from ..git.status import get_git_status
20
20
 
21
21
 
22
22
  def rev_parse(rev: str) -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omdev
3
- Version: 0.0.0.dev158
3
+ Version: 0.0.0.dev160
4
4
  Summary: omdev
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -12,7 +12,7 @@ Classifier: Operating System :: OS Independent
12
12
  Classifier: Operating System :: POSIX
13
13
  Requires-Python: >=3.12
14
14
  License-File: LICENSE
15
- Requires-Dist: omlish==0.0.0.dev158
15
+ Requires-Dist: omlish==0.0.0.dev160
16
16
  Provides-Extra: all
17
17
  Requires-Dist: black~=24.10; extra == "all"
18
18
  Requires-Dist: pycparser~=2.22; extra == "all"
@@ -5,16 +5,15 @@ omdev/bracepy.py,sha256=I8EdqtDvxzAi3I8TuMEW-RBfwXfqKbwp06CfOdj3L1o,2743
5
5
  omdev/classdot.py,sha256=YOvgy6x295I_8NKBbBlRVd3AN7Osirm_Lqt4Wj0j9rY,1631
6
6
  omdev/cmake.py,sha256=Diy2ry65806dQP125DAstD3w46z_wszMH7PwC2-6iik,4578
7
7
  omdev/findimports.py,sha256=2t8QP852saEEJFeXySEzhi_nxRSxghlkXz2jVdvy08M,2392
8
- omdev/git.py,sha256=sVTkHCXEXJTbSl9SRM7UnrQC775muYWVR6OB8IywUXQ,10532
9
8
  omdev/imgur.py,sha256=NK-kqGqGu4rDfpPbRyLEnIMJ2GHQQft5nSuwxLgyhNQ,2996
10
9
  omdev/pip.py,sha256=7cZ_IOpekQvgPm_gKnX3Pr8xjqUid50PPScTlZCYVlM,2118
11
- omdev/revisions.py,sha256=FXRQubv060G8gETpshA2l68-u-ytN6BBlKoVqp2fk00,4998
10
+ omdev/revisions.py,sha256=7Bgwd7cuKtcXJE4eDXmWP4Qx1aqZqf_LNFkOCuYS9I0,5008
12
11
  omdev/secrets.py,sha256=bcquaBIDKqX4UIKOzUuKrX7nxVCenj67rRHIMIrd9bk,540
13
12
  omdev/tokens.py,sha256=zh2TCAfCbcq8ZnoVdQ824jrTiwNy3XJ_oCqlZpLpcCY,1574
14
13
  omdev/wheelfile.py,sha256=yfupGcGkbFlmzGzKU64k_vmOKpaKnUlDWxeGn2KdekU,10005
15
14
  omdev/amalg/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
15
  omdev/amalg/__main__.py,sha256=h94M-VqZ3AFBU2a8zOsjeKK7RF6uINhTHl6OiGbVMgw,163
17
- omdev/amalg/amalg.py,sha256=hfs1gk7pmyp8NrzIZdJcKkr__oULLeFnyQxD5OFdonE,19318
16
+ omdev/amalg/amalg.py,sha256=qJ-Kllp4mdmx28nt_JTlQnuO-o4XZnTTZP7Uh448b68,19333
18
17
  omdev/antlr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
18
  omdev/antlr/consts.py,sha256=8pR6r0m0P3hAiyiAoJZ-nptd2GYbZ98mxwPL9cpaRuw,279
20
19
  omdev/antlr/gen.py,sha256=QnPyVWUrJYqHoOc3XsXA8fJdoiwAj6pyUwdG-DVrIeA,2953
@@ -29,10 +28,10 @@ omdev/cache/compute/storage.py,sha256=woCUqHg8ZrwLEejRG3zu1L5ZXxGNNXveh3E8FnlEkj
29
28
  omdev/cache/compute/types.py,sha256=NpCTTJHDmpERjrbO6dh9TEzHuP6-vOuoX3ym9sA0ukc,2639
30
29
  omdev/cache/data/__init__.py,sha256=SQXtugLceRif463rcoklpQ33pxYLgEIm0xiI6NvOI6M,301
31
30
  omdev/cache/data/actions.py,sha256=KVYb3tBYP5c0g-wK1bXih_K7L0ER9UINKChhfc7mwKQ,1071
32
- omdev/cache/data/cache.py,sha256=JZ5iYtJB_OPjEVLtvkLpPtKpRIImTpbY0tFUmHPtbMM,7720
31
+ omdev/cache/data/cache.py,sha256=mxO3RqEhj1UbPgnhSQGZZ5mSLy_r5f9O05sahlP29Q4,7742
33
32
  omdev/cache/data/consts.py,sha256=d6W_aeMqgah6PmPYi9RA8Be54oQ4BcNCy8kDQ7FlB_Q,26
34
33
  omdev/cache/data/defaults.py,sha256=HrapVUIf9Ozu3qSfRPyQj-vx-dz6Yyedjb-k3yV4CW8,277
35
- omdev/cache/data/manifests.py,sha256=CupK71fL3_PnDzUqjrWLNt64KfGKF-K4ycMkT5p0gPA,979
34
+ omdev/cache/data/manifests.py,sha256=4BparztsMZo9DDVVPhv6iv5g4kK7QAi8Vqtj3PbKkco,989
36
35
  omdev/cache/data/specs.py,sha256=0a9NPJ76Wz69s94KlNbr1Xma3UQ0z2oCAQN7s6uXe4w,2497
37
36
  omdev/cexts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
37
  omdev/cexts/_boilerplate.cc,sha256=sbpXEgdFrkdzZXgaNWFFNN27fL9TZu6VrwvMY4-nnFM,1726
@@ -69,9 +68,13 @@ omdev/clipboard/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
68
  omdev/clipboard/clipboard.py,sha256=9HFpcijpn0XDTI89ZRm2WA1G7O4HsTdVXZHqMULu3N0,1630
70
69
  omdev/clipboard/darwin_cf.py,sha256=SDUMfQtT_IJeDEwmsnxe6YyrZS5tPh_7ujkk1dg65Hg,7688
71
70
  omdev/clipboard/linux_x11.py,sha256=oa-mxMRNaZJOdBAZ8Nki-CAGIb63X8OFUTXKjmiwfSo,6718
71
+ omdev/git/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
+ omdev/git/revisions.py,sha256=1YY3Kf2WSalNVE2TgLXmOETct8HfiVEOqfV-qcvMVr4,1161
73
+ omdev/git/status.py,sha256=s_5kzyaSO-ikimdi54A6DrjOQPMeM5SRXLTrb22Alp4,8106
74
+ omdev/git/subtrees.py,sha256=XFxE74PBqu_E5arpkCRRgsus5nof0TBfd2nmgh4cczA,2398
72
75
  omdev/interp/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
73
76
  omdev/interp/__main__.py,sha256=GMCqeGYltgt5dlJzHxY9gqisa8cRkrPfmZYuZnjg4WI,162
74
- omdev/interp/cli.py,sha256=3MaH1YfXbYqIa1ymAfSeP-GgZbk2djTSdhcVjVStEeE,2224
77
+ omdev/interp/cli.py,sha256=kgqA-Pc2RVkvkEpAKde30R5JKemgwurUcG6uPaNJyFc,2234
75
78
  omdev/interp/inspect.py,sha256=ORfO90xfGftyvEJHuEOD5yPk-9mxdxn27SYHwZywWFI,2888
76
79
  omdev/interp/providers.py,sha256=yHZQ6gYjkvSmMBvrKy3I77D7PnW67Bf3igTKY8DD9K4,1839
77
80
  omdev/interp/pyenv.py,sha256=8SromtT5y6f5q0hT__-r5PZSOHg-PQc-6t-ITdS5eo4,14302
@@ -113,7 +116,7 @@ omdev/pycharm/cli.py,sha256=dYRDCzRSLBTmoNg6Flswu3gI62yAGUtoh1aNcpBUBYU,3797
113
116
  omdev/pyproject/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
114
117
  omdev/pyproject/__main__.py,sha256=gn3Rl1aYPYdiTtEqa9ifi0t-e4ZwPY0vhJ4UXvYdJDY,165
115
118
  omdev/pyproject/cexts.py,sha256=x13piOOnNrYbA17qZLDVuR0p1sqhgEwpk4FtImX-klM,4281
116
- omdev/pyproject/cli.py,sha256=ZM-xJ77WCCQ19Qa59JG0KbI9Kmx9BRct85oe3LMLgNo,8755
119
+ omdev/pyproject/cli.py,sha256=TXoYDfX-FotgCT9LVFfNMwqmfhfvW0-I7dYTG2ub67Y,8765
117
120
  omdev/pyproject/configs.py,sha256=K9H5cGwVLgHi8wKwtYvlXHZ9ThtmnI4jo8JAb-t1-70,2859
118
121
  omdev/pyproject/pkg.py,sha256=x71WLK3Amnt2Wjhpqz3_lBRGEdsjN5vRGlAr5eDVFqE,14552
119
122
  omdev/pyproject/reqs.py,sha256=8feZ71YnGzwKbLK4zO28CDQeNcZIIuq6cnkBhs6M-7E,2406
@@ -123,8 +126,8 @@ omdev/scripts/bumpversion.py,sha256=Kn7fo73Hs8uJh3Hi3EIyLOlzLPWAC6dwuD_lZ3cIzuY,
123
126
  omdev/scripts/execrss.py,sha256=mR0G0wERBYtQmVIn63lCIIFb5zkCM6X_XOENDFYDBKc,651
124
127
  omdev/scripts/exectime.py,sha256=sFb376GflU6s9gNX-2-we8hgH6w5MuQNS9g6i4SqJIo,610
125
128
  omdev/scripts/importtrace.py,sha256=oa7CtcWJVMNDbyIEiRHej6ICfABfErMeo4_haIqe18Q,14041
126
- omdev/scripts/interp.py,sha256=VS3fF-yvykf3NWedbN4WJtvq0FSfLfDHVZp2pXBNfP4,99512
127
- omdev/scripts/pyproject.py,sha256=e5PodMqdqzRlTaivEemrlFYQYpb0IpWuw8qEZ032HLg,213529
129
+ omdev/scripts/interp.py,sha256=3_c7Kdni7-oZQVrS9Vb2h1gaW5XOy9ebgShPdCapHyM,99882
130
+ omdev/scripts/pyproject.py,sha256=d7LuBO6NzgQSjx97OMQ8r5QHABULEE2bN9-EQvBJu00,204901
128
131
  omdev/scripts/slowcat.py,sha256=lssv4yrgJHiWfOiHkUut2p8E8Tq32zB-ujXESQxFFHY,2728
129
132
  omdev/scripts/tmpexec.py,sha256=WTYcf56Tj2qjYV14AWmV8SfT0u6Y8eIU6cKgQRvEK3c,1442
130
133
  omdev/toml/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
@@ -134,7 +137,7 @@ omdev/tools/__init__.py,sha256=iVJAOQ0viGTQOm0DLX4uZLro-9jOioYJGLg9s0kDx1A,78
134
137
  omdev/tools/cloc.py,sha256=13lUsYLyn1LoelhsCeKrRkIwwPE0x54JmdhXJ_lvWh0,3811
135
138
  omdev/tools/doc.py,sha256=iblgUq9_7JZN2i8qmvewrz4OX0paObscBaCj8u77WqI,2555
136
139
  omdev/tools/docker.py,sha256=mu0sWnH_L1JjScfWCXXYaux03mcotCS03SD65I93qHI,7384
137
- omdev/tools/git.py,sha256=_ERM-VmrKrPJO9OHQEc-Jn59_Lmu3Be0Ej8kkQNGQOk,7000
140
+ omdev/tools/git.py,sha256=zfdPnN-9WSeOQlLoTw5aqAX-UWvz-2p330dx_zaU0WQ,7014
138
141
  omdev/tools/importscan.py,sha256=nhJIhtjDY6eFVlReP7fegvv6L5ZjN-Z2VeyhsBonev4,4639
139
142
  omdev/tools/mkrelimp.py,sha256=kyu_BbUakKHEEOxNEvYWk7tH1ixCfVb3NqqT8U-BozE,4066
140
143
  omdev/tools/notebook.py,sha256=lIQIG-ytxGistyt7twuTbquSKbd7HQzR2jgBcGApwu8,3498
@@ -153,9 +156,9 @@ omdev/tools/json/rendering.py,sha256=jNShMfCpFR9-Kcn6cUFuOChXHjg71diuTC4x7Ofmz-o
153
156
  omdev/tools/pawk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
154
157
  omdev/tools/pawk/__main__.py,sha256=VCqeRVnqT1RPEoIrqHFSu4PXVMg4YEgF4qCQm90-eRI,66
155
158
  omdev/tools/pawk/pawk.py,sha256=Eckymn22GfychCQcQi96BFqRo_LmiJ-EPhC8TTUJdB4,11446
156
- omdev-0.0.0.dev158.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
157
- omdev-0.0.0.dev158.dist-info/METADATA,sha256=9EXzAXkkf_s5bjBdFrX6Mc17p9sgfKJiBEYHp6aAARo,1760
158
- omdev-0.0.0.dev158.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
159
- omdev-0.0.0.dev158.dist-info/entry_points.txt,sha256=dHLXFmq5D9B8qUyhRtFqTGWGxlbx3t5ejedjrnXNYLU,33
160
- omdev-0.0.0.dev158.dist-info/top_level.txt,sha256=1nr7j30fEWgLYHW3lGR9pkdHkb7knv1U1ES1XRNVQ6k,6
161
- omdev-0.0.0.dev158.dist-info/RECORD,,
159
+ omdev-0.0.0.dev160.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
160
+ omdev-0.0.0.dev160.dist-info/METADATA,sha256=s2OLsw8nRKCVQHgJfv-UbxudBYvFl__fdyh86RJXeVI,1760
161
+ omdev-0.0.0.dev160.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
162
+ omdev-0.0.0.dev160.dist-info/entry_points.txt,sha256=dHLXFmq5D9B8qUyhRtFqTGWGxlbx3t5ejedjrnXNYLU,33
163
+ omdev-0.0.0.dev160.dist-info/top_level.txt,sha256=1nr7j30fEWgLYHW3lGR9pkdHkb7knv1U1ES1XRNVQ6k,6
164
+ omdev-0.0.0.dev160.dist-info/RECORD,,