omdev 0.0.0.dev440__py3-none-any.whl → 0.0.0.dev495__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/.omlish-manifests.json +18 -30
- omdev/README.md +51 -0
- omdev/__about__.py +11 -7
- omdev/amalg/gen/gen.py +49 -6
- omdev/amalg/gen/imports.py +1 -1
- omdev/amalg/gen/manifests.py +1 -1
- omdev/amalg/gen/resources.py +1 -1
- omdev/amalg/gen/srcfiles.py +13 -3
- omdev/amalg/gen/strip.py +1 -1
- omdev/amalg/gen/types.py +1 -1
- omdev/amalg/gen/typing.py +1 -1
- omdev/amalg/info.py +32 -0
- omdev/cache/data/actions.py +1 -1
- omdev/cache/data/specs.py +1 -1
- omdev/cexts/_boilerplate.cc +2 -3
- omdev/cexts/cmake.py +4 -1
- omdev/ci/cli.py +2 -3
- omdev/cli/clicli.py +37 -7
- omdev/cmdlog/cli.py +1 -2
- omdev/dataclasses/_dumping.py +1960 -0
- omdev/dataclasses/_template.py +22 -0
- omdev/dataclasses/cli.py +7 -2
- omdev/dataclasses/codegen.py +340 -60
- omdev/dataclasses/dumping.py +200 -0
- omdev/interp/cli.py +1 -1
- omdev/interp/types.py +3 -2
- omdev/interp/uv/provider.py +37 -0
- omdev/interp/venvs.py +1 -0
- omdev/irc/messages/base.py +50 -0
- omdev/irc/messages/formats.py +92 -0
- omdev/irc/messages/messages.py +775 -0
- omdev/irc/messages/parsing.py +99 -0
- omdev/irc/numerics/__init__.py +0 -0
- omdev/irc/numerics/formats.py +97 -0
- omdev/irc/numerics/numerics.py +865 -0
- omdev/irc/numerics/types.py +59 -0
- omdev/irc/protocol/LICENSE +11 -0
- omdev/irc/protocol/__init__.py +61 -0
- omdev/irc/protocol/consts.py +6 -0
- omdev/irc/protocol/errors.py +30 -0
- omdev/irc/protocol/message.py +21 -0
- omdev/irc/protocol/nuh.py +55 -0
- omdev/irc/protocol/parsing.py +158 -0
- omdev/irc/protocol/rendering.py +153 -0
- omdev/irc/protocol/tags.py +102 -0
- omdev/irc/protocol/utils.py +30 -0
- omdev/manifests/_dumping.py +125 -25
- omdev/manifests/main.py +1 -1
- omdev/markdown/__init__.py +0 -0
- omdev/markdown/incparse.py +116 -0
- omdev/markdown/tokens.py +51 -0
- omdev/packaging/marshal.py +8 -8
- omdev/packaging/requires.py +6 -6
- omdev/packaging/revisions.py +1 -1
- omdev/packaging/specifiers.py +2 -1
- omdev/packaging/versions.py +4 -4
- omdev/packaging/wheelfile.py +2 -0
- omdev/precheck/blanklines.py +66 -0
- omdev/precheck/caches.py +1 -1
- omdev/precheck/imports.py +14 -1
- omdev/precheck/main.py +4 -3
- omdev/precheck/unicode.py +39 -15
- omdev/py/asts/__init__.py +0 -0
- omdev/py/asts/parents.py +28 -0
- omdev/py/asts/toplevel.py +123 -0
- omdev/py/asts/visitors.py +18 -0
- omdev/py/attrdocs.py +1 -1
- omdev/py/bracepy.py +12 -4
- omdev/py/reprs.py +32 -0
- omdev/py/srcheaders.py +1 -1
- omdev/py/tokens/__init__.py +0 -0
- omdev/py/tools/mkrelimp.py +1 -1
- omdev/py/tools/pipdepup.py +686 -0
- omdev/pyproject/cli.py +1 -1
- omdev/pyproject/pkg.py +190 -45
- omdev/pyproject/reqs.py +31 -9
- omdev/pyproject/tools/__init__.py +0 -0
- omdev/pyproject/tools/aboutdeps.py +60 -0
- omdev/pyproject/venvs.py +8 -1
- omdev/rs/__init__.py +0 -0
- omdev/scripts/ci.py +752 -98
- omdev/scripts/interp.py +232 -39
- omdev/scripts/lib/inject.py +74 -27
- omdev/scripts/lib/logs.py +187 -43
- omdev/scripts/lib/marshal.py +67 -25
- omdev/scripts/pyproject.py +1369 -143
- omdev/tools/git/cli.py +10 -0
- omdev/tools/json/formats.py +2 -0
- omdev/tools/json/processing.py +5 -2
- omdev/tools/jsonview/cli.py +49 -65
- omdev/tools/jsonview/resources/jsonview.html.j2 +43 -0
- omdev/tools/pawk/README.md +195 -0
- omdev/tools/pawk/pawk.py +2 -2
- omdev/tools/pip.py +8 -0
- omdev/tui/__init__.py +0 -0
- omdev/tui/apps/__init__.py +0 -0
- omdev/tui/apps/edit/__init__.py +0 -0
- omdev/tui/apps/edit/main.py +167 -0
- omdev/tui/apps/irc/__init__.py +0 -0
- omdev/tui/apps/irc/__main__.py +4 -0
- omdev/tui/apps/irc/app.py +286 -0
- omdev/tui/apps/irc/client.py +187 -0
- omdev/tui/apps/irc/commands.py +175 -0
- omdev/tui/apps/irc/main.py +26 -0
- omdev/tui/apps/markdown/__init__.py +0 -0
- omdev/tui/apps/markdown/__main__.py +11 -0
- omdev/{ptk → tui/apps}/markdown/cli.py +5 -7
- omdev/tui/rich/__init__.py +46 -0
- omdev/tui/rich/console2.py +20 -0
- omdev/tui/rich/markdown2.py +186 -0
- omdev/tui/textual/__init__.py +265 -0
- omdev/tui/textual/app2.py +16 -0
- omdev/tui/textual/autocomplete/LICENSE +21 -0
- omdev/tui/textual/autocomplete/__init__.py +33 -0
- omdev/tui/textual/autocomplete/matching.py +226 -0
- omdev/tui/textual/autocomplete/paths.py +202 -0
- omdev/tui/textual/autocomplete/widget.py +612 -0
- omdev/tui/textual/debug/__init__.py +10 -0
- omdev/tui/textual/debug/dominfo.py +151 -0
- omdev/tui/textual/debug/screen.py +24 -0
- omdev/tui/textual/devtools.py +187 -0
- omdev/tui/textual/drivers2.py +55 -0
- omdev/tui/textual/logging2.py +20 -0
- omdev/tui/textual/types.py +45 -0
- {omdev-0.0.0.dev440.dist-info → omdev-0.0.0.dev495.dist-info}/METADATA +15 -9
- {omdev-0.0.0.dev440.dist-info → omdev-0.0.0.dev495.dist-info}/RECORD +135 -80
- omdev/ptk/__init__.py +0 -103
- omdev/ptk/apps/ncdu.py +0 -167
- omdev/ptk/confirm.py +0 -60
- omdev/ptk/markdown/LICENSE +0 -22
- omdev/ptk/markdown/__init__.py +0 -10
- omdev/ptk/markdown/__main__.py +0 -11
- omdev/ptk/markdown/border.py +0 -94
- omdev/ptk/markdown/markdown.py +0 -390
- omdev/ptk/markdown/parser.py +0 -42
- omdev/ptk/markdown/styles.py +0 -29
- omdev/ptk/markdown/tags.py +0 -299
- omdev/ptk/markdown/utils.py +0 -366
- omdev/pyproject/cexts.py +0 -110
- /omdev/{ptk/apps → irc}/__init__.py +0 -0
- /omdev/{tokens → irc/messages}/__init__.py +0 -0
- /omdev/{tokens → py/tokens}/all.py +0 -0
- /omdev/{tokens → py/tokens}/tokenizert.py +0 -0
- /omdev/{tokens → py/tokens}/utils.py +0 -0
- {omdev-0.0.0.dev440.dist-info → omdev-0.0.0.dev495.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev440.dist-info → omdev-0.0.0.dev495.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev440.dist-info → omdev-0.0.0.dev495.dist-info}/licenses/LICENSE +0 -0
- {omdev-0.0.0.dev440.dist-info → omdev-0.0.0.dev495.dist-info}/top_level.txt +0 -0
omdev/precheck/unicode.py
CHANGED
|
@@ -29,6 +29,18 @@ class UnicodePrecheck(Precheck['UnicodePrecheck.Config']):
|
|
|
29
29
|
|
|
30
30
|
permitted_categories: ta.AbstractSet[str] = DEFAULT_PERMITTED_CATEGORIES
|
|
31
31
|
|
|
32
|
+
DEFAULT_FILE_EXTENSIONS: ta.ClassVar[ta.AbstractSet[str]] = frozenset([
|
|
33
|
+
'py',
|
|
34
|
+
|
|
35
|
+
'c',
|
|
36
|
+
'cc',
|
|
37
|
+
'cu',
|
|
38
|
+
'h',
|
|
39
|
+
'hh',
|
|
40
|
+
])
|
|
41
|
+
|
|
42
|
+
file_extensions: ta.AbstractSet[str] = DEFAULT_FILE_EXTENSIONS
|
|
43
|
+
|
|
32
44
|
def __init__(
|
|
33
45
|
self,
|
|
34
46
|
context: PrecheckContext,
|
|
@@ -46,19 +58,15 @@ class UnicodePrecheck(Precheck['UnicodePrecheck.Config']):
|
|
|
46
58
|
self._text_file_cache = text_file_cache
|
|
47
59
|
self._headers_cache = headers_cache
|
|
48
60
|
|
|
49
|
-
async def
|
|
50
|
-
if
|
|
51
|
-
|
|
52
|
-
if any(hl.src.strip() == '# @omlish-precheck-allow-any-unicode' for hl in header_lines):
|
|
53
|
-
return
|
|
54
|
-
|
|
55
|
-
src = self._text_file_cache.get_entry(py_file).text()
|
|
61
|
+
async def _run_file(self, file: str, src: str | None = None) -> ta.AsyncGenerator[Precheck.Violation]:
|
|
62
|
+
if src is None:
|
|
63
|
+
src = self._text_file_cache.get_entry(file).text()
|
|
56
64
|
|
|
57
65
|
illegal_chars = {
|
|
58
66
|
ch
|
|
59
67
|
for ch in src
|
|
60
|
-
if ord(ch) > 255
|
|
61
|
-
unicodedata.category(ch) not in self._config.permitted_categories
|
|
68
|
+
if ord(ch) > 255
|
|
69
|
+
and unicodedata.category(ch) not in self._config.permitted_categories
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
if illegal_chars:
|
|
@@ -66,16 +74,32 @@ class UnicodePrecheck(Precheck['UnicodePrecheck.Config']):
|
|
|
66
74
|
f'({ch!r}, {unicodedata.category(ch)})'
|
|
67
75
|
for ch in sorted(illegal_chars)
|
|
68
76
|
]
|
|
69
|
-
yield Precheck.Violation(self, f'source file {
|
|
77
|
+
yield Precheck.Violation(self, f'source file {file} has illegal unicode characters: {", ".join(sl)}')
|
|
78
|
+
|
|
79
|
+
async def _run_py_file(self, py_file: str) -> ta.AsyncGenerator[Precheck.Violation]:
|
|
80
|
+
if isinstance(header_lines := self._headers_cache.get_file_headers(py_file), Exception):
|
|
81
|
+
return
|
|
82
|
+
if any(hl.src.strip() == '# @omlish-precheck-allow-any-unicode' for hl in header_lines):
|
|
83
|
+
return
|
|
84
|
+
|
|
85
|
+
async for v in self._run_file(py_file):
|
|
86
|
+
yield v
|
|
70
87
|
|
|
71
88
|
async def run(self) -> ta.AsyncGenerator[Precheck.Violation]:
|
|
72
|
-
|
|
89
|
+
files = [
|
|
73
90
|
os.path.join(e.root, f)
|
|
74
91
|
for src_root in self._context.src_roots
|
|
75
92
|
for e in self._dir_walk_cache.list_dir(src_root)
|
|
76
93
|
for f in e.files
|
|
77
|
-
if
|
|
94
|
+
if '.' in f
|
|
95
|
+
and any(f.endswith('.' + ext) for ext in self._config.file_extensions)
|
|
78
96
|
]
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
97
|
+
|
|
98
|
+
for file in sorted(files):
|
|
99
|
+
if file.endswith('.py'):
|
|
100
|
+
async for v in self._run_py_file(file):
|
|
101
|
+
yield v
|
|
102
|
+
|
|
103
|
+
else:
|
|
104
|
+
async for v in self._run_file(file):
|
|
105
|
+
yield v
|
|
File without changes
|
omdev/py/asts/parents.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import ast
|
|
2
|
+
|
|
3
|
+
from omlish import check
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
##
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class _ParentsNodeVisitor(ast.NodeVisitor):
|
|
10
|
+
def __init__(self) -> None:
|
|
11
|
+
super().__init__()
|
|
12
|
+
|
|
13
|
+
self.parents: dict[ast.AST, ast.AST | None] = {}
|
|
14
|
+
|
|
15
|
+
parent: ast.AST | None = None
|
|
16
|
+
|
|
17
|
+
def generic_visit(self, node: ast.AST) -> None:
|
|
18
|
+
check.not_in(node, self.parents)
|
|
19
|
+
prev_parent = self.parents[node] = self.parent
|
|
20
|
+
self.parent = node
|
|
21
|
+
super().generic_visit(node)
|
|
22
|
+
self.parent = prev_parent
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_node_parents(node: ast.AST) -> dict[ast.AST, ast.AST | None]:
|
|
26
|
+
visitor = _ParentsNodeVisitor()
|
|
27
|
+
visitor.visit(node)
|
|
28
|
+
return visitor.parents
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Quite, quite lame, but sufficient for immediate needs. Accurate static symbol resolution is in development but can't
|
|
3
|
+
block other work.
|
|
4
|
+
"""
|
|
5
|
+
import ast
|
|
6
|
+
import dataclasses as dc
|
|
7
|
+
import typing as ta
|
|
8
|
+
|
|
9
|
+
from omlish import check
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
16
|
+
class TopLevelImport:
|
|
17
|
+
spec: str
|
|
18
|
+
name: str
|
|
19
|
+
node: ast.Import | ast.ImportFrom
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
23
|
+
class TopLevelCall:
|
|
24
|
+
node: ast.Call
|
|
25
|
+
imp: TopLevelImport
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
29
|
+
class TopLevelFindings:
|
|
30
|
+
imports: ta.Mapping[str, TopLevelImport]
|
|
31
|
+
calls: ta.Sequence[TopLevelCall]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
##
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class _TopLevelModuleVisitor(ast.NodeVisitor):
|
|
38
|
+
def __init__(self, module_name: str) -> None:
|
|
39
|
+
super().__init__()
|
|
40
|
+
|
|
41
|
+
self.module_name = module_name
|
|
42
|
+
self.module_name_parts = module_name.split('.')
|
|
43
|
+
|
|
44
|
+
self.imports: dict[str, TopLevelImport] = {}
|
|
45
|
+
self.calls: list[TopLevelCall] = []
|
|
46
|
+
|
|
47
|
+
#
|
|
48
|
+
|
|
49
|
+
def visit_Import(self, node: ast.Import) -> None:
|
|
50
|
+
for alias in node.names:
|
|
51
|
+
name = alias.asname if alias.asname else alias.name
|
|
52
|
+
self.imports[name] = TopLevelImport(
|
|
53
|
+
spec=alias.name,
|
|
54
|
+
name=name,
|
|
55
|
+
node=node,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
self.generic_visit(node)
|
|
59
|
+
|
|
60
|
+
def visit_ImportFrom(self, node: ast.ImportFrom) -> None:
|
|
61
|
+
if node.level:
|
|
62
|
+
check.state(node.level < len(self.module_name_parts))
|
|
63
|
+
module = '.'.join([
|
|
64
|
+
*self.module_name_parts[:-node.level],
|
|
65
|
+
*([node.module] if node.module else []),
|
|
66
|
+
])
|
|
67
|
+
else:
|
|
68
|
+
module = check.not_none(node.module)
|
|
69
|
+
|
|
70
|
+
for alias in node.names:
|
|
71
|
+
name = alias.asname if alias.asname else alias.name
|
|
72
|
+
self.imports[name] = TopLevelImport(
|
|
73
|
+
spec='.'.join([module, alias.name]),
|
|
74
|
+
name=name,
|
|
75
|
+
node=node,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
self.generic_visit(node)
|
|
79
|
+
|
|
80
|
+
#
|
|
81
|
+
|
|
82
|
+
def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> None:
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
def visit_ClassDef(self, node: ast.ClassDef) -> None:
|
|
86
|
+
pass
|
|
87
|
+
|
|
88
|
+
def visit_FunctionDef(self, node: ast.FunctionDef) -> None:
|
|
89
|
+
pass
|
|
90
|
+
|
|
91
|
+
#
|
|
92
|
+
|
|
93
|
+
def handle_call(self, node: ast.Call) -> None:
|
|
94
|
+
if not (
|
|
95
|
+
isinstance(attr := node.func, ast.Attribute) and
|
|
96
|
+
isinstance(attr.ctx, ast.Load) and
|
|
97
|
+
isinstance(name := attr.value, ast.Name) and
|
|
98
|
+
isinstance(name.ctx, ast.Load)
|
|
99
|
+
):
|
|
100
|
+
return
|
|
101
|
+
|
|
102
|
+
if (imp := self.imports.get(name.id)) is None:
|
|
103
|
+
return
|
|
104
|
+
|
|
105
|
+
self.calls.append(TopLevelCall(
|
|
106
|
+
node=node,
|
|
107
|
+
imp=imp,
|
|
108
|
+
))
|
|
109
|
+
|
|
110
|
+
def visit_Call(self, node: ast.Call) -> None:
|
|
111
|
+
self.handle_call(node)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def analyze_module_top_level(
|
|
115
|
+
module: ast.Module,
|
|
116
|
+
module_name: str,
|
|
117
|
+
) -> TopLevelFindings:
|
|
118
|
+
visitor = _TopLevelModuleVisitor(module_name)
|
|
119
|
+
visitor.visit(module)
|
|
120
|
+
return TopLevelFindings(
|
|
121
|
+
imports=visitor.imports,
|
|
122
|
+
calls=visitor.calls,
|
|
123
|
+
)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import ast
|
|
2
|
+
|
|
3
|
+
from omlish import check
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
##
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class StackNodeVisitor(ast.NodeVisitor):
|
|
10
|
+
def __init__(self) -> None:
|
|
11
|
+
super().__init__()
|
|
12
|
+
|
|
13
|
+
self.node_stack: list[ast.AST] = []
|
|
14
|
+
|
|
15
|
+
def generic_visit(self, node: ast.AST) -> None:
|
|
16
|
+
self.node_stack.append(node)
|
|
17
|
+
super().generic_visit(node)
|
|
18
|
+
check.is_(self.node_stack.pop(), node)
|
omdev/py/attrdocs.py
CHANGED
omdev/py/bracepy.py
CHANGED
|
@@ -101,18 +101,26 @@ _CLI_MODULE = {'!.cli.types.CliModule': {
|
|
|
101
101
|
if __name__ == '__main__':
|
|
102
102
|
def _main(argv=None) -> None:
|
|
103
103
|
import argparse
|
|
104
|
+
import sys
|
|
104
105
|
|
|
105
106
|
parser = argparse.ArgumentParser()
|
|
106
107
|
parser.add_argument('-x', '--exec', action='store_true')
|
|
107
|
-
parser.add_argument('
|
|
108
|
+
parser.add_argument('-i', '--indent', type=int)
|
|
109
|
+
parser.add_argument('code', nargs='?')
|
|
108
110
|
|
|
109
111
|
args = parser.parse_args(argv)
|
|
110
112
|
|
|
111
|
-
|
|
113
|
+
if (code := args.code) is None:
|
|
114
|
+
code = sys.stdin.read()
|
|
115
|
+
|
|
116
|
+
out = translate_brace_python(
|
|
117
|
+
code,
|
|
118
|
+
**(dict(indent_width=args.indent) if args.indent is not None else {}),
|
|
119
|
+
)
|
|
112
120
|
|
|
113
121
|
if args.exec:
|
|
114
|
-
exec(
|
|
122
|
+
exec(out)
|
|
115
123
|
else:
|
|
116
|
-
print(
|
|
124
|
+
print(out)
|
|
117
125
|
|
|
118
126
|
_main()
|
omdev/py/reprs.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
def textwrap_repr(text: str, width: int = 120, quote_char: str = '"') -> list[str]:
|
|
2
|
+
escaped_quote = '\\' + quote_char
|
|
3
|
+
content_width = width - 2
|
|
4
|
+
|
|
5
|
+
lines: list[str] = []
|
|
6
|
+
current_line: list[str] = []
|
|
7
|
+
current_length = 0
|
|
8
|
+
|
|
9
|
+
for char in text:
|
|
10
|
+
if char == quote_char:
|
|
11
|
+
safe_char = escaped_quote
|
|
12
|
+
elif char == '\\':
|
|
13
|
+
safe_char = '\\\\'
|
|
14
|
+
elif not char.isprintable():
|
|
15
|
+
safe_char = repr(char)[1:-1]
|
|
16
|
+
if quote_char in safe_char:
|
|
17
|
+
safe_char = safe_char.replace(quote_char, escaped_quote)
|
|
18
|
+
else:
|
|
19
|
+
safe_char = char
|
|
20
|
+
|
|
21
|
+
if current_length + len(safe_char) > content_width:
|
|
22
|
+
lines.append(f"{quote_char}{''.join(current_line)}{quote_char}")
|
|
23
|
+
current_line = []
|
|
24
|
+
current_length = 0
|
|
25
|
+
|
|
26
|
+
current_line.append(safe_char)
|
|
27
|
+
current_length += len(safe_char)
|
|
28
|
+
|
|
29
|
+
if current_line:
|
|
30
|
+
lines.append(f"{quote_char}{''.join(current_line)}{quote_char}")
|
|
31
|
+
|
|
32
|
+
return lines
|
omdev/py/srcheaders.py
CHANGED
|
File without changes
|