omdev 0.0.0.dev101__py3-none-any.whl → 0.0.0.dev112__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.
- omdev/.manifests.json +39 -3
- omdev/__about__.py +4 -0
- omdev/cli/clicli.py +1 -1
- omdev/clipboard/darwin.py +37 -3
- omdev/packaging/__init__.py +0 -1
- omdev/packaging/marshal.py +82 -0
- omdev/packaging/names.py +1 -0
- omdev/packaging/requires.py +14 -5
- omdev/packaging/specifiers.py +1 -0
- omdev/packaging/versions.py +1 -0
- omdev/ptk/apps/ncdu.py +4 -2
- omdev/pycharm/__init__.py +0 -0
- omdev/pycharm/__main__.py +11 -0
- omdev/pycharm/cli.py +94 -0
- omdev/scripts/execrss.py +11 -1
- omdev/scripts/exectime.py +11 -1
- omdev/scripts/interp.py +24 -2
- omdev/scripts/pyproject.py +93 -30
- omdev/scripts/tmpexec.py +58 -0
- omdev/tools/git.py +36 -32
- omdev/tools/pip.py +77 -1
- omdev/tools/qr.py +79 -0
- {omdev-0.0.0.dev101.dist-info → omdev-0.0.0.dev112.dist-info}/METADATA +5 -2
- {omdev-0.0.0.dev101.dist-info → omdev-0.0.0.dev112.dist-info}/RECORD +28 -22
- {omdev-0.0.0.dev101.dist-info → omdev-0.0.0.dev112.dist-info}/WHEEL +1 -1
- {omdev-0.0.0.dev101.dist-info → omdev-0.0.0.dev112.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev101.dist-info → omdev-0.0.0.dev112.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev101.dist-info → omdev-0.0.0.dev112.dist-info}/top_level.txt +0 -0
omdev/.manifests.json
CHANGED
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
"module": ".ptk.apps.ncdu",
|
|
124
124
|
"attr": "_CLI_MODULE",
|
|
125
125
|
"file": "omdev/ptk/apps/ncdu.py",
|
|
126
|
-
"line":
|
|
126
|
+
"line": 159,
|
|
127
127
|
"value": {
|
|
128
128
|
"$.cli.types.CliModule": {
|
|
129
129
|
"cmd_name": "ptk/ncdu",
|
|
@@ -131,6 +131,18 @@
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
},
|
|
134
|
+
{
|
|
135
|
+
"module": ".pycharm.__main__",
|
|
136
|
+
"attr": "_CLI_MODULE",
|
|
137
|
+
"file": "omdev/pycharm/__main__.py",
|
|
138
|
+
"line": 4,
|
|
139
|
+
"value": {
|
|
140
|
+
"$.cli.types.CliModule": {
|
|
141
|
+
"cmd_name": "pycharm",
|
|
142
|
+
"mod_name": "omdev.pycharm.__main__"
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
},
|
|
134
146
|
{
|
|
135
147
|
"module": ".pyproject.__main__",
|
|
136
148
|
"attr": "_CLI_MODULE",
|
|
@@ -191,6 +203,18 @@
|
|
|
191
203
|
}
|
|
192
204
|
}
|
|
193
205
|
},
|
|
206
|
+
{
|
|
207
|
+
"module": ".scripts.tmpexec",
|
|
208
|
+
"attr": "_CLI_MODULE",
|
|
209
|
+
"file": "omdev/scripts/tmpexec.py",
|
|
210
|
+
"line": 50,
|
|
211
|
+
"value": {
|
|
212
|
+
"$.cli.types.CliModule": {
|
|
213
|
+
"cmd_name": "tmpexec",
|
|
214
|
+
"mod_name": "omdev.scripts.tmpexec"
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
},
|
|
194
218
|
{
|
|
195
219
|
"module": ".tools.doc",
|
|
196
220
|
"attr": "_CLI_MODULE",
|
|
@@ -219,7 +243,7 @@
|
|
|
219
243
|
"module": ".tools.git",
|
|
220
244
|
"attr": "_CLI_MODULE",
|
|
221
245
|
"file": "omdev/tools/git.py",
|
|
222
|
-
"line":
|
|
246
|
+
"line": 128,
|
|
223
247
|
"value": {
|
|
224
248
|
"$.cli.types.CliModule": {
|
|
225
249
|
"cmd_name": "git",
|
|
@@ -282,7 +306,7 @@
|
|
|
282
306
|
"module": ".tools.pip",
|
|
283
307
|
"attr": "_CLI_MODULE",
|
|
284
308
|
"file": "omdev/tools/pip.py",
|
|
285
|
-
"line":
|
|
309
|
+
"line": 164,
|
|
286
310
|
"value": {
|
|
287
311
|
"$.cli.types.CliModule": {
|
|
288
312
|
"cmd_name": "pip",
|
|
@@ -302,6 +326,18 @@
|
|
|
302
326
|
}
|
|
303
327
|
}
|
|
304
328
|
},
|
|
329
|
+
{
|
|
330
|
+
"module": ".tools.qr",
|
|
331
|
+
"attr": "_CLI_MODULE",
|
|
332
|
+
"file": "omdev/tools/qr.py",
|
|
333
|
+
"line": 74,
|
|
334
|
+
"value": {
|
|
335
|
+
"$.cli.types.CliModule": {
|
|
336
|
+
"cmd_name": "qr",
|
|
337
|
+
"mod_name": "omdev.tools.qr"
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
},
|
|
305
341
|
{
|
|
306
342
|
"module": ".tools.sqlrepl",
|
|
307
343
|
"attr": "_CLI_MODULE",
|
omdev/__about__.py
CHANGED
omdev/cli/clicli.py
CHANGED
|
@@ -51,7 +51,7 @@ class CliCli(ap.Cli):
|
|
|
51
51
|
)
|
|
52
52
|
def reinstall(self) -> None:
|
|
53
53
|
mod_name = globals()['__spec__'].name
|
|
54
|
-
tool_name = '.'.join([mod_name.partition('.')[0], 'tools', '
|
|
54
|
+
tool_name = '.'.join([mod_name.partition('.')[0], 'tools', 'pip'])
|
|
55
55
|
|
|
56
56
|
out = subprocess.check_output([
|
|
57
57
|
sys.executable,
|
omdev/clipboard/darwin.py
CHANGED
|
@@ -1,4 +1,31 @@
|
|
|
1
1
|
# ruff: noqa: N802 N816
|
|
2
|
+
"""
|
|
3
|
+
imageProperties = dict(
|
|
4
|
+
ColorModel = "RGB"
|
|
5
|
+
DPIHeight = 144
|
|
6
|
+
DPIWidth = 144
|
|
7
|
+
Depth = 8
|
|
8
|
+
PixelHeight = 1236
|
|
9
|
+
PixelWidth = 602
|
|
10
|
+
ProfileName = "Color LCD"
|
|
11
|
+
kCGImageDestinationAllowAlpha = true
|
|
12
|
+
{Exif} = dict(
|
|
13
|
+
PixelXDimension = 602
|
|
14
|
+
PixelYDimension = 1236
|
|
15
|
+
UserComment = "Screenshot"
|
|
16
|
+
)
|
|
17
|
+
{PNG} = dict(
|
|
18
|
+
InterlaceType = 0
|
|
19
|
+
XPixelsPerMeter = 5669
|
|
20
|
+
YPixelsPerMeter = 5669
|
|
21
|
+
)
|
|
22
|
+
{TIFF} = dict(
|
|
23
|
+
ResolutionUnit = 2
|
|
24
|
+
XResolution = 144
|
|
25
|
+
YResolution = 144
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
"""
|
|
2
29
|
import ctypes as ct
|
|
3
30
|
import ctypes.util
|
|
4
31
|
import dataclasses as dc
|
|
@@ -114,7 +141,7 @@ def cfstring_to_string(cf_string: CFStringRef) -> str:
|
|
|
114
141
|
max_size = cf.CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1
|
|
115
142
|
buffer = ct.create_string_buffer(max_size)
|
|
116
143
|
|
|
117
|
-
if success := cf.CFStringGetCString(cf_string, buffer, max_size, kCFStringEncodingUTF8): # noqa
|
|
144
|
+
if not (success := cf.CFStringGetCString(cf_string, buffer, max_size, kCFStringEncodingUTF8)): # noqa
|
|
118
145
|
return ''
|
|
119
146
|
|
|
120
147
|
return buffer.value.decode('utf-8')
|
|
@@ -142,6 +169,7 @@ class DarwinClipboardItem:
|
|
|
142
169
|
def get_darwin_clipboard_data(
|
|
143
170
|
*,
|
|
144
171
|
types: ta.Container[str | None] | None = None,
|
|
172
|
+
skip_types: ta.Container[str | None] | None = None,
|
|
145
173
|
strict: bool = False,
|
|
146
174
|
types_only: bool = False,
|
|
147
175
|
) -> list[DarwinClipboardItem]:
|
|
@@ -179,6 +207,8 @@ def get_darwin_clipboard_data(
|
|
|
179
207
|
|
|
180
208
|
if types is not None and data_type_str not in types:
|
|
181
209
|
continue
|
|
210
|
+
if skip_types is not None and data_type_str in skip_types:
|
|
211
|
+
continue
|
|
182
212
|
|
|
183
213
|
if types_only:
|
|
184
214
|
lst.append(DarwinClipboardItem(
|
|
@@ -188,10 +218,14 @@ def get_darwin_clipboard_data(
|
|
|
188
218
|
continue
|
|
189
219
|
|
|
190
220
|
data = CFDataRef()
|
|
221
|
+
|
|
222
|
+
# FIXME: dumps to stderr lol:
|
|
223
|
+
# data_type_str = 'public.heics'
|
|
191
224
|
if status := aps.PasteboardCopyItemFlavorData(pasteboard, item_id, data_type, ct.byref(data)):
|
|
192
225
|
if not strict:
|
|
193
226
|
continue
|
|
194
227
|
raise StatusDarwinClipboardError('PasteboardCopyItemFlavorData', status)
|
|
228
|
+
|
|
195
229
|
if not data:
|
|
196
230
|
continue
|
|
197
231
|
|
|
@@ -221,8 +255,8 @@ def get_darwin_clipboard_data(
|
|
|
221
255
|
|
|
222
256
|
|
|
223
257
|
def _main() -> None:
|
|
224
|
-
for i in get_darwin_clipboard_data():
|
|
225
|
-
print(i)
|
|
258
|
+
for i in get_darwin_clipboard_data(skip_types={'public.heics'}):
|
|
259
|
+
print(f'type: {i.type}, len: {len(i.data) if i.data is not None else None}')
|
|
226
260
|
|
|
227
261
|
|
|
228
262
|
if __name__ == '__main__':
|
omdev/packaging/__init__.py
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# @omlish-lite
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""
|
|
2
|
+
NOTE: This cannot be auto-imported as @omlish-lite usage of other modules in this package requires it be importable on
|
|
3
|
+
8.
|
|
4
|
+
"""
|
|
5
|
+
import dataclasses as dc
|
|
6
|
+
import typing as ta
|
|
7
|
+
|
|
8
|
+
from omlish import lang
|
|
9
|
+
from omlish import marshal as msh
|
|
10
|
+
from omlish import matchfns as mfs
|
|
11
|
+
from omlish import reflect as rfl
|
|
12
|
+
|
|
13
|
+
from .requires import RequiresMarkerItem
|
|
14
|
+
from .requires import RequiresMarkerList
|
|
15
|
+
from .requires import RequiresNode
|
|
16
|
+
from .requires import RequiresOp
|
|
17
|
+
from .requires import RequiresValue
|
|
18
|
+
from .requires import RequiresVariable
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class MarshalRequiresMarkerList(lang.NotInstantiable, lang.Final):
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dc.dataclass(frozen=True)
|
|
29
|
+
class RequiresMarkerListMarshaler(msh.Marshaler):
|
|
30
|
+
item_m: msh.Marshaler
|
|
31
|
+
node_m: msh.Marshaler
|
|
32
|
+
|
|
33
|
+
def marshal(self, ctx: msh.MarshalContext, o: ta.Any) -> msh.Value:
|
|
34
|
+
def inner(c: ta.Any) -> ta.Any:
|
|
35
|
+
if isinstance(c, str):
|
|
36
|
+
return c
|
|
37
|
+
elif isinstance(c, RequiresMarkerItem):
|
|
38
|
+
return self.item_m.marshal(ctx, c)
|
|
39
|
+
elif isinstance(c, ta.Iterable):
|
|
40
|
+
return [inner(e) for e in c]
|
|
41
|
+
else:
|
|
42
|
+
raise TypeError(c)
|
|
43
|
+
return [inner(e) for e in o]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class RequiresMarkerListMarshalerFactory(msh.MarshalerFactoryMatchClass):
|
|
47
|
+
@mfs.simple(lambda _, ctx, rty: rty is MarshalRequiresMarkerList)
|
|
48
|
+
def _build(self, ctx: msh.MarshalContext, rty: rfl.Type) -> msh.Marshaler:
|
|
49
|
+
return RequiresMarkerListMarshaler(
|
|
50
|
+
ctx.make(RequiresMarkerItem),
|
|
51
|
+
ctx.make(RequiresNode),
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
##
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@lang.static_init
|
|
59
|
+
def _install_standard_marshalling() -> None:
|
|
60
|
+
requires_node_poly = msh.Polymorphism(
|
|
61
|
+
RequiresNode,
|
|
62
|
+
[
|
|
63
|
+
msh.Impl(RequiresVariable, 'variable'),
|
|
64
|
+
msh.Impl(RequiresValue, 'value'),
|
|
65
|
+
msh.Impl(RequiresOp, 'op'),
|
|
66
|
+
],
|
|
67
|
+
)
|
|
68
|
+
msh.STANDARD_MARSHALER_FACTORIES[0:0] = [
|
|
69
|
+
msh.PolymorphismMarshalerFactory(requires_node_poly),
|
|
70
|
+
msh.PolymorphismUnionMarshalerFactory(requires_node_poly.impls, allow_partial=True),
|
|
71
|
+
RequiresMarkerListMarshalerFactory(),
|
|
72
|
+
|
|
73
|
+
]
|
|
74
|
+
msh.STANDARD_UNMARSHALER_FACTORIES[0:0] = [
|
|
75
|
+
msh.PolymorphismUnmarshalerFactory(requires_node_poly),
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
msh.GLOBAL_REGISTRY.register(
|
|
79
|
+
RequiresMarkerList,
|
|
80
|
+
msh.ReflectOverride(MarshalRequiresMarkerList),
|
|
81
|
+
identity=True,
|
|
82
|
+
)
|
omdev/packaging/names.py
CHANGED
omdev/packaging/requires.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# @omlish-lite
|
|
1
2
|
# Copyright (c) Donald Stufft and individual contributors.
|
|
2
3
|
# All rights reserved.
|
|
3
4
|
#
|
|
@@ -194,10 +195,9 @@ class RequiresTokenizer:
|
|
|
194
195
|
self.read()
|
|
195
196
|
|
|
196
197
|
|
|
198
|
+
@dc.dataclass(frozen=True)
|
|
197
199
|
class RequiresNode:
|
|
198
|
-
|
|
199
|
-
super().__init__()
|
|
200
|
-
self.value = value
|
|
200
|
+
value: str
|
|
201
201
|
|
|
202
202
|
def __str__(self) -> str:
|
|
203
203
|
return self.value
|
|
@@ -209,27 +209,36 @@ class RequiresNode:
|
|
|
209
209
|
raise NotImplementedError
|
|
210
210
|
|
|
211
211
|
|
|
212
|
+
@dc.dataclass(frozen=True)
|
|
212
213
|
class RequiresVariable(RequiresNode):
|
|
213
214
|
def serialize(self) -> str:
|
|
214
215
|
return str(self)
|
|
215
216
|
|
|
216
217
|
|
|
218
|
+
@dc.dataclass(frozen=True)
|
|
217
219
|
class RequiresValue(RequiresNode):
|
|
218
220
|
def serialize(self) -> str:
|
|
219
221
|
return f'"{self}"'
|
|
220
222
|
|
|
221
223
|
|
|
224
|
+
@dc.dataclass(frozen=True)
|
|
222
225
|
class RequiresOp(RequiresNode):
|
|
223
226
|
def serialize(self) -> str:
|
|
224
227
|
return str(self)
|
|
225
228
|
|
|
226
229
|
|
|
227
230
|
RequiresMarkerVar = ta.Union['RequiresVariable', 'RequiresValue']
|
|
228
|
-
|
|
231
|
+
|
|
229
232
|
RequiresMarkerAtom = ta.Union['RequiresMarkerItem', ta.Sequence['RequiresMarkerAtom']]
|
|
230
233
|
RequiresMarkerList = ta.Sequence[ta.Union['RequiresMarkerList', 'RequiresMarkerAtom', str]]
|
|
231
234
|
|
|
232
235
|
|
|
236
|
+
class RequiresMarkerItem(ta.NamedTuple):
|
|
237
|
+
l: ta.Union[RequiresVariable, RequiresValue]
|
|
238
|
+
op: RequiresOp
|
|
239
|
+
r: ta.Union[RequiresVariable, RequiresValue]
|
|
240
|
+
|
|
241
|
+
|
|
233
242
|
class ParsedRequirement(ta.NamedTuple):
|
|
234
243
|
name: str
|
|
235
244
|
url: str
|
|
@@ -441,7 +450,7 @@ def _parse_requires_marker_item(tokenizer: RequiresTokenizer) -> RequiresMarkerI
|
|
|
441
450
|
tokenizer.consume('WS')
|
|
442
451
|
marker_var_right = _parse_requires_marker_var(tokenizer)
|
|
443
452
|
tokenizer.consume('WS')
|
|
444
|
-
return (marker_var_left, marker_op, marker_var_right)
|
|
453
|
+
return RequiresMarkerItem(marker_var_left, marker_op, marker_var_right)
|
|
445
454
|
|
|
446
455
|
|
|
447
456
|
def _parse_requires_marker_var(tokenizer: RequiresTokenizer) -> RequiresMarkerVar:
|
omdev/packaging/specifiers.py
CHANGED
omdev/packaging/versions.py
CHANGED
omdev/ptk/apps/ncdu.py
CHANGED
|
@@ -73,8 +73,10 @@ class NcduApp:
|
|
|
73
73
|
self._kb.add(k)(self.move_up)
|
|
74
74
|
for k in ['down', 'n']:
|
|
75
75
|
self._kb.add(k)(self.move_down)
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
for k in ['right', 'enter']:
|
|
77
|
+
self._kb.add(k)(self.enter_directory)
|
|
78
|
+
for k in ['left', 'backspace']:
|
|
79
|
+
self._kb.add(k)(self.go_back)
|
|
78
80
|
|
|
79
81
|
self._layout = ptk.Layout(ptk.Frame(self._text_area))
|
|
80
82
|
|
|
File without changes
|
omdev/pycharm/cli.py
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
import os.path
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
import tempfile
|
|
6
|
+
|
|
7
|
+
from omlish import argparse as ap
|
|
8
|
+
from omlish.diag.pycharm import get_pycharm_version
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
_DARWIN_OPEN_SCRIPT = """
|
|
12
|
+
tell application "PyCharm"
|
|
13
|
+
activate
|
|
14
|
+
open "{dir}"
|
|
15
|
+
end tell
|
|
16
|
+
return
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
_LINUX_OPEN_SCRIPT = """
|
|
21
|
+
# Check if PyCharm is already running
|
|
22
|
+
if pgrep -x "pycharm.sh" > /dev/null; then
|
|
23
|
+
echo "PyCharm is already running. Opening project..."
|
|
24
|
+
|
|
25
|
+
# Bring PyCharm to the foreground
|
|
26
|
+
wmctrl -a "PyCharm"
|
|
27
|
+
|
|
28
|
+
# Simulate the keyboard shortcut to open a new project
|
|
29
|
+
xdotool key --delay 100 ctrl+shift+a
|
|
30
|
+
xdotool type "$PROJECT_PATH"
|
|
31
|
+
xdotool key Return
|
|
32
|
+
|
|
33
|
+
else
|
|
34
|
+
echo "Starting PyCharm with project..."
|
|
35
|
+
nohup pycharm.sh "$PROJECT_PATH" > /dev/null 2>&1 &
|
|
36
|
+
fi
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class Cli(ap.Cli):
|
|
41
|
+
@ap.command()
|
|
42
|
+
def version(self) -> None:
|
|
43
|
+
print(get_pycharm_version())
|
|
44
|
+
|
|
45
|
+
@ap.command(
|
|
46
|
+
ap.arg('python-exe'),
|
|
47
|
+
ap.arg('args', nargs=ap.REMAINDER),
|
|
48
|
+
)
|
|
49
|
+
def runhack(self) -> int:
|
|
50
|
+
if not os.path.isfile(exe := self.args.python_exe):
|
|
51
|
+
raise FileNotFoundError(exe)
|
|
52
|
+
|
|
53
|
+
from omlish.diag._pycharm import runhack # noqa
|
|
54
|
+
src = inspect.getsource(runhack)
|
|
55
|
+
|
|
56
|
+
src_file = tempfile.mktemp(__package__ + '-runhack') # noqa
|
|
57
|
+
with open(src_file, 'w') as f:
|
|
58
|
+
f.write(src)
|
|
59
|
+
|
|
60
|
+
proc = subprocess.run([exe, src_file, *self.args.args], check=False)
|
|
61
|
+
return proc.returncode
|
|
62
|
+
|
|
63
|
+
@ap.command(
|
|
64
|
+
ap.arg('dir', nargs='?'),
|
|
65
|
+
)
|
|
66
|
+
def open(self) -> None:
|
|
67
|
+
dir = os.path.abspath(self.args.dir or '.') # noqa
|
|
68
|
+
|
|
69
|
+
if (plat := sys.platform) == 'darwin':
|
|
70
|
+
if '"' in dir:
|
|
71
|
+
raise ValueError(dir)
|
|
72
|
+
|
|
73
|
+
scpt_src = _DARWIN_OPEN_SCRIPT.format(dir=dir)
|
|
74
|
+
|
|
75
|
+
scpt_file = tempfile.mktemp(__package__ + '-pycharm-open') # noqa
|
|
76
|
+
with open(scpt_file, 'w') as f:
|
|
77
|
+
f.write(scpt_src)
|
|
78
|
+
|
|
79
|
+
subprocess.check_call(['osascript', scpt_file])
|
|
80
|
+
|
|
81
|
+
elif plat == 'linux':
|
|
82
|
+
# FIXME:
|
|
83
|
+
raise NotImplementedError
|
|
84
|
+
|
|
85
|
+
else:
|
|
86
|
+
raise OSError(plat)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _main() -> None:
|
|
90
|
+
Cli().call_and_exit()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
if __name__ == '__main__':
|
|
94
|
+
_main()
|
omdev/scripts/execrss.py
CHANGED
|
@@ -16,7 +16,17 @@ _CLI_MODULE = {'$omdev.cli.types.CliModule': {
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
def _main() -> None:
|
|
19
|
-
|
|
19
|
+
if len(sys.argv) == 2:
|
|
20
|
+
pre = None
|
|
21
|
+
[src] = sys.argv[1:]
|
|
22
|
+
elif len(sys.argv) == 3:
|
|
23
|
+
[pre, src] = sys.argv[1:]
|
|
24
|
+
else:
|
|
25
|
+
raise Exception('Invalid arguments')
|
|
26
|
+
|
|
27
|
+
if pre:
|
|
28
|
+
exec(pre)
|
|
29
|
+
|
|
20
30
|
start = _get_rss()
|
|
21
31
|
exec(src)
|
|
22
32
|
end = _get_rss()
|
omdev/scripts/exectime.py
CHANGED
|
@@ -12,7 +12,17 @@ _CLI_MODULE = {'$omdev.cli.types.CliModule': {
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def _main() -> None:
|
|
15
|
-
|
|
15
|
+
if len(sys.argv) == 2:
|
|
16
|
+
pre = None
|
|
17
|
+
[src] = sys.argv[1:]
|
|
18
|
+
elif len(sys.argv) == 3:
|
|
19
|
+
[pre, src] = sys.argv[1:]
|
|
20
|
+
else:
|
|
21
|
+
raise Exception('Invalid arguments')
|
|
22
|
+
|
|
23
|
+
if pre:
|
|
24
|
+
exec(pre)
|
|
25
|
+
|
|
16
26
|
co = compile(src, '<string>', 'exec')
|
|
17
27
|
start = time.time_ns()
|
|
18
28
|
exec(co)
|
omdev/scripts/interp.py
CHANGED
|
@@ -51,7 +51,7 @@ VersionCmpLocalType = ta.Union['NegativeInfinityVersionType', _VersionCmpLocalTy
|
|
|
51
51
|
VersionCmpKey = ta.Tuple[int, ta.Tuple[int, ...], VersionCmpPrePostDevType, VersionCmpPrePostDevType, VersionCmpPrePostDevType, VersionCmpLocalType] # noqa
|
|
52
52
|
VersionComparisonMethod = ta.Callable[[VersionCmpKey, VersionCmpKey], bool]
|
|
53
53
|
|
|
54
|
-
# ../../../omlish/lite/
|
|
54
|
+
# ../../../omlish/lite/cached.py
|
|
55
55
|
T = ta.TypeVar('T')
|
|
56
56
|
|
|
57
57
|
# ../../packaging/specifiers.py
|
|
@@ -471,7 +471,7 @@ def canonicalize_version(
|
|
|
471
471
|
# ../../../omlish/lite/cached.py
|
|
472
472
|
|
|
473
473
|
|
|
474
|
-
class
|
|
474
|
+
class _cached_nullary: # noqa
|
|
475
475
|
def __init__(self, fn):
|
|
476
476
|
super().__init__()
|
|
477
477
|
self._fn = fn
|
|
@@ -488,6 +488,10 @@ class cached_nullary: # noqa
|
|
|
488
488
|
return bound
|
|
489
489
|
|
|
490
490
|
|
|
491
|
+
def cached_nullary(fn: ta.Callable[..., T]) -> ta.Callable[..., T]:
|
|
492
|
+
return _cached_nullary(fn)
|
|
493
|
+
|
|
494
|
+
|
|
491
495
|
########################################
|
|
492
496
|
# ../../../omlish/lite/check.py
|
|
493
497
|
|
|
@@ -1692,6 +1696,24 @@ def subprocess_try_output_str(*args: str, **kwargs: ta.Any) -> ta.Optional[str]:
|
|
|
1692
1696
|
return out.decode().strip() if out is not None else None
|
|
1693
1697
|
|
|
1694
1698
|
|
|
1699
|
+
##
|
|
1700
|
+
|
|
1701
|
+
|
|
1702
|
+
def subprocess_close(
|
|
1703
|
+
proc: subprocess.Popen,
|
|
1704
|
+
timeout: ta.Optional[float] = None,
|
|
1705
|
+
) -> None:
|
|
1706
|
+
# TODO: terminate, sleep, kill
|
|
1707
|
+
if proc.stdout:
|
|
1708
|
+
proc.stdout.close()
|
|
1709
|
+
if proc.stderr:
|
|
1710
|
+
proc.stderr.close()
|
|
1711
|
+
if proc.stdin:
|
|
1712
|
+
proc.stdin.close()
|
|
1713
|
+
|
|
1714
|
+
proc.wait(timeout)
|
|
1715
|
+
|
|
1716
|
+
|
|
1695
1717
|
########################################
|
|
1696
1718
|
# ../inspect.py
|
|
1697
1719
|
|
omdev/scripts/pyproject.py
CHANGED
|
@@ -90,7 +90,7 @@ TomlParseFloat = ta.Callable[[str], ta.Any]
|
|
|
90
90
|
TomlKey = ta.Tuple[str, ...]
|
|
91
91
|
TomlPos = int # ta.TypeAlias
|
|
92
92
|
|
|
93
|
-
# ../../../omlish/lite/
|
|
93
|
+
# ../../../omlish/lite/cached.py
|
|
94
94
|
T = ta.TypeVar('T')
|
|
95
95
|
|
|
96
96
|
# ../../packaging/specifiers.py
|
|
@@ -1862,7 +1862,7 @@ class WheelFile(zipfile.ZipFile):
|
|
|
1862
1862
|
# ../../../omlish/lite/cached.py
|
|
1863
1863
|
|
|
1864
1864
|
|
|
1865
|
-
class
|
|
1865
|
+
class _cached_nullary: # noqa
|
|
1866
1866
|
def __init__(self, fn):
|
|
1867
1867
|
super().__init__()
|
|
1868
1868
|
self._fn = fn
|
|
@@ -1879,6 +1879,10 @@ class cached_nullary: # noqa
|
|
|
1879
1879
|
return bound
|
|
1880
1880
|
|
|
1881
1881
|
|
|
1882
|
+
def cached_nullary(fn: ta.Callable[..., T]) -> ta.Callable[..., T]:
|
|
1883
|
+
return _cached_nullary(fn)
|
|
1884
|
+
|
|
1885
|
+
|
|
1882
1886
|
########################################
|
|
1883
1887
|
# ../../../omlish/lite/check.py
|
|
1884
1888
|
|
|
@@ -3235,7 +3239,7 @@ class DataclassObjMarshaler(ObjMarshaler):
|
|
|
3235
3239
|
return {k: m.marshal(getattr(o, k)) for k, m in self.fs.items()}
|
|
3236
3240
|
|
|
3237
3241
|
def unmarshal(self, o: ta.Any) -> ta.Any:
|
|
3238
|
-
return self.ty(**{k: self.fs[k].unmarshal(v) for k, v in o.items() if self.nonstrict or k in self.fs})
|
|
3242
|
+
return self.ty(**{k: self.fs[k].unmarshal(v) for k, v in o.items() if not self.nonstrict or k in self.fs})
|
|
3239
3243
|
|
|
3240
3244
|
|
|
3241
3245
|
@dc.dataclass(frozen=True)
|
|
@@ -3295,7 +3299,10 @@ class UuidObjMarshaler(ObjMarshaler):
|
|
|
3295
3299
|
return uuid.UUID(o)
|
|
3296
3300
|
|
|
3297
3301
|
|
|
3298
|
-
|
|
3302
|
+
##
|
|
3303
|
+
|
|
3304
|
+
|
|
3305
|
+
_DEFAULT_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
|
|
3299
3306
|
**{t: NopObjMarshaler() for t in (type(None),)},
|
|
3300
3307
|
**{t: CastObjMarshaler(t) for t in (int, float, str, bool)},
|
|
3301
3308
|
**{t: Base64ObjMarshaler(t) for t in (bytes, bytearray)},
|
|
@@ -3324,20 +3331,19 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
|
|
|
3324
3331
|
}
|
|
3325
3332
|
|
|
3326
3333
|
|
|
3327
|
-
def
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
|
|
3334
|
+
def _make_obj_marshaler(
|
|
3335
|
+
ty: ta.Any,
|
|
3336
|
+
rec: ta.Callable[[ta.Any], ObjMarshaler],
|
|
3337
|
+
*,
|
|
3338
|
+
nonstrict_dataclasses: bool = False,
|
|
3339
|
+
) -> ObjMarshaler:
|
|
3334
3340
|
if isinstance(ty, type):
|
|
3335
3341
|
if abc.ABC in ty.__bases__:
|
|
3336
3342
|
impls = [ # type: ignore
|
|
3337
3343
|
PolymorphicObjMarshaler.Impl(
|
|
3338
3344
|
ity,
|
|
3339
3345
|
ity.__qualname__,
|
|
3340
|
-
|
|
3346
|
+
rec(ity),
|
|
3341
3347
|
)
|
|
3342
3348
|
for ity in deep_subclasses(ty)
|
|
3343
3349
|
if abc.ABC not in ity.__bases__
|
|
@@ -3353,7 +3359,8 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
|
|
|
3353
3359
|
if dc.is_dataclass(ty):
|
|
3354
3360
|
return DataclassObjMarshaler(
|
|
3355
3361
|
ty,
|
|
3356
|
-
{f.name:
|
|
3362
|
+
{f.name: rec(f.type) for f in dc.fields(ty)},
|
|
3363
|
+
nonstrict=nonstrict_dataclasses,
|
|
3357
3364
|
)
|
|
3358
3365
|
|
|
3359
3366
|
if is_generic_alias(ty):
|
|
@@ -3363,7 +3370,7 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
|
|
|
3363
3370
|
pass
|
|
3364
3371
|
else:
|
|
3365
3372
|
k, v = ta.get_args(ty)
|
|
3366
|
-
return MappingObjMarshaler(mt,
|
|
3373
|
+
return MappingObjMarshaler(mt, rec(k), rec(v))
|
|
3367
3374
|
|
|
3368
3375
|
try:
|
|
3369
3376
|
st = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES[ta.get_origin(ty)]
|
|
@@ -3371,33 +3378,71 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
|
|
|
3371
3378
|
pass
|
|
3372
3379
|
else:
|
|
3373
3380
|
[e] = ta.get_args(ty)
|
|
3374
|
-
return IterableObjMarshaler(st,
|
|
3381
|
+
return IterableObjMarshaler(st, rec(e))
|
|
3375
3382
|
|
|
3376
3383
|
if is_union_alias(ty):
|
|
3377
|
-
return OptionalObjMarshaler(
|
|
3384
|
+
return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
|
|
3378
3385
|
|
|
3379
3386
|
raise TypeError(ty)
|
|
3380
3387
|
|
|
3381
3388
|
|
|
3382
|
-
|
|
3383
|
-
try:
|
|
3384
|
-
return _OBJ_MARSHALERS[ty]
|
|
3385
|
-
except KeyError:
|
|
3386
|
-
pass
|
|
3389
|
+
##
|
|
3387
3390
|
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3391
|
+
|
|
3392
|
+
_OBJ_MARSHALERS_LOCK = threading.RLock()
|
|
3393
|
+
|
|
3394
|
+
_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
|
|
3395
|
+
|
|
3396
|
+
_OBJ_MARSHALER_PROXIES: ta.Dict[ta.Any, ProxyObjMarshaler] = {}
|
|
3397
|
+
|
|
3398
|
+
|
|
3399
|
+
def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
|
|
3400
|
+
with _OBJ_MARSHALERS_LOCK:
|
|
3401
|
+
if ty in _OBJ_MARSHALERS:
|
|
3402
|
+
raise KeyError(ty)
|
|
3397
3403
|
_OBJ_MARSHALERS[ty] = m
|
|
3404
|
+
|
|
3405
|
+
|
|
3406
|
+
def get_obj_marshaler(
|
|
3407
|
+
ty: ta.Any,
|
|
3408
|
+
*,
|
|
3409
|
+
no_cache: bool = False,
|
|
3410
|
+
**kwargs: ta.Any,
|
|
3411
|
+
) -> ObjMarshaler:
|
|
3412
|
+
with _OBJ_MARSHALERS_LOCK:
|
|
3413
|
+
if not no_cache:
|
|
3414
|
+
try:
|
|
3415
|
+
return _OBJ_MARSHALERS[ty]
|
|
3416
|
+
except KeyError:
|
|
3417
|
+
pass
|
|
3418
|
+
|
|
3419
|
+
try:
|
|
3420
|
+
return _OBJ_MARSHALER_PROXIES[ty]
|
|
3421
|
+
except KeyError:
|
|
3422
|
+
pass
|
|
3423
|
+
|
|
3424
|
+
rec = functools.partial(
|
|
3425
|
+
get_obj_marshaler,
|
|
3426
|
+
no_cache=no_cache,
|
|
3427
|
+
**kwargs,
|
|
3428
|
+
)
|
|
3429
|
+
|
|
3430
|
+
p = ProxyObjMarshaler()
|
|
3431
|
+
_OBJ_MARSHALER_PROXIES[ty] = p
|
|
3432
|
+
try:
|
|
3433
|
+
m = _make_obj_marshaler(ty, rec, **kwargs)
|
|
3434
|
+
finally:
|
|
3435
|
+
del _OBJ_MARSHALER_PROXIES[ty]
|
|
3436
|
+
p.m = m
|
|
3437
|
+
|
|
3438
|
+
if not no_cache:
|
|
3439
|
+
_OBJ_MARSHALERS[ty] = m
|
|
3398
3440
|
return m
|
|
3399
3441
|
|
|
3400
3442
|
|
|
3443
|
+
##
|
|
3444
|
+
|
|
3445
|
+
|
|
3401
3446
|
def marshal_obj(o: ta.Any, ty: ta.Any = None) -> ta.Any:
|
|
3402
3447
|
return get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
|
|
3403
3448
|
|
|
@@ -3916,6 +3961,24 @@ def subprocess_try_output_str(*args: str, **kwargs: ta.Any) -> ta.Optional[str]:
|
|
|
3916
3961
|
return out.decode().strip() if out is not None else None
|
|
3917
3962
|
|
|
3918
3963
|
|
|
3964
|
+
##
|
|
3965
|
+
|
|
3966
|
+
|
|
3967
|
+
def subprocess_close(
|
|
3968
|
+
proc: subprocess.Popen,
|
|
3969
|
+
timeout: ta.Optional[float] = None,
|
|
3970
|
+
) -> None:
|
|
3971
|
+
# TODO: terminate, sleep, kill
|
|
3972
|
+
if proc.stdout:
|
|
3973
|
+
proc.stdout.close()
|
|
3974
|
+
if proc.stderr:
|
|
3975
|
+
proc.stderr.close()
|
|
3976
|
+
if proc.stdin:
|
|
3977
|
+
proc.stdin.close()
|
|
3978
|
+
|
|
3979
|
+
proc.wait(timeout)
|
|
3980
|
+
|
|
3981
|
+
|
|
3919
3982
|
########################################
|
|
3920
3983
|
# ../../interp/inspect.py
|
|
3921
3984
|
|
omdev/scripts/tmpexec.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# @omlish-script
|
|
3
|
+
"""
|
|
4
|
+
TODO:
|
|
5
|
+
- can xargs just do this lol
|
|
6
|
+
"""
|
|
7
|
+
import argparse
|
|
8
|
+
import os
|
|
9
|
+
import subprocess
|
|
10
|
+
import sys
|
|
11
|
+
import tempfile
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _main() -> None:
|
|
15
|
+
parser = argparse.ArgumentParser()
|
|
16
|
+
parser.add_argument('-I', '--replstr', default='%')
|
|
17
|
+
parser.add_argument('-Q', '--stdout-silenced', action='store_true')
|
|
18
|
+
parser.add_argument('-E', '--stdout-to-stderr', action='store_true')
|
|
19
|
+
parser.add_argument('-c', '--cat', action='store_true')
|
|
20
|
+
parser.add_argument('-k', '--keep', action='store_true')
|
|
21
|
+
parser.add_argument('--read-size', type=int, default=0x4000)
|
|
22
|
+
args, rest = parser.parse_known_args()
|
|
23
|
+
|
|
24
|
+
fd, tmp_file = tempfile.mkstemp()
|
|
25
|
+
os.close(fd)
|
|
26
|
+
|
|
27
|
+
argv = [tmp_file if a == args.replstr else a for a in rest]
|
|
28
|
+
|
|
29
|
+
kw: dict = {}
|
|
30
|
+
if args.stdout_silenced:
|
|
31
|
+
kw.update(stdout=open('/dev/null', 'wb')) # noqa
|
|
32
|
+
elif args.stdout_to_stderr:
|
|
33
|
+
kw.update(stdout=sys.stderr)
|
|
34
|
+
|
|
35
|
+
subprocess.check_call(argv, **kw)
|
|
36
|
+
|
|
37
|
+
if args.cat:
|
|
38
|
+
try:
|
|
39
|
+
with open(tmp_file, 'rb') as f:
|
|
40
|
+
while buf := f.read(args.read_size):
|
|
41
|
+
sys.stdout.buffer.write(buf)
|
|
42
|
+
finally:
|
|
43
|
+
if not args.keep:
|
|
44
|
+
os.unlink(tmp_file)
|
|
45
|
+
|
|
46
|
+
else:
|
|
47
|
+
print(tmp_file)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# @omlish-manifest
|
|
51
|
+
_CLI_MODULE = {'$omdev.cli.types.CliModule': {
|
|
52
|
+
'cmd_name': 'tmpexec',
|
|
53
|
+
'mod_name': __name__,
|
|
54
|
+
}}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if __name__ == '__main__':
|
|
58
|
+
_main()
|
omdev/tools/git.py
CHANGED
|
@@ -61,38 +61,42 @@ class Cli(ap.Cli):
|
|
|
61
61
|
accepts_unknown=True,
|
|
62
62
|
)
|
|
63
63
|
def clone(self) -> None:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
'
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
64
|
+
# And expected usage is `cd $(om git clone foo/bar)` and an empty cd arg will return to the previous directory,
|
|
65
|
+
# so always output at least a . so it'll cd to the current dir at least lol - it still runs even if the proc
|
|
66
|
+
# fails.
|
|
67
|
+
out_dir = '.'
|
|
68
|
+
try:
|
|
69
|
+
if (m := self._GITHUB_PAT.fullmatch(self.args.repo)):
|
|
70
|
+
user = m.group('user')
|
|
71
|
+
repo = m.group('repo')
|
|
72
|
+
|
|
73
|
+
os.makedirs(user, 0o755, exist_ok=True)
|
|
74
|
+
|
|
75
|
+
subprocess.check_call([
|
|
76
|
+
'git',
|
|
77
|
+
'clone',
|
|
78
|
+
*self.unknown_args,
|
|
79
|
+
*self.args.args,
|
|
80
|
+
f'git@github.com:{user}/{repo}.git',
|
|
81
|
+
os.path.join(user, repo),
|
|
82
|
+
])
|
|
83
|
+
|
|
84
|
+
out_dir = os.path.join(user, repo)
|
|
85
|
+
|
|
86
|
+
else:
|
|
87
|
+
parsed = urllib.parse.urlparse(self.args.repo)
|
|
88
|
+
out_dir = parsed.path.split('/')[-1]
|
|
89
|
+
|
|
90
|
+
subprocess.check_call([
|
|
91
|
+
'git',
|
|
92
|
+
'clone',
|
|
93
|
+
*self.unknown_args,
|
|
94
|
+
*self.args.args,
|
|
95
|
+
self.args.repo,
|
|
96
|
+
])
|
|
97
|
+
|
|
98
|
+
finally:
|
|
99
|
+
print(out_dir)
|
|
96
100
|
|
|
97
101
|
@ap.command(
|
|
98
102
|
ap.arg('rev', nargs='?', default='HEAD'),
|
omdev/tools/pip.py
CHANGED
|
@@ -1,18 +1,35 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- https://github.com/pypa/pip/blob/420435903ff2fc694d6950a47b896427ecaed78f/src/pip/_internal/req/req_file.py ?
|
|
4
|
+
"""
|
|
5
|
+
import contextlib
|
|
1
6
|
import importlib.metadata
|
|
2
7
|
import io
|
|
8
|
+
import os.path
|
|
3
9
|
import sys
|
|
10
|
+
import typing as ta
|
|
4
11
|
import urllib.request
|
|
5
|
-
import xml.etree.ElementTree as ET # noqa
|
|
6
12
|
|
|
7
13
|
from omlish import argparse as ap
|
|
8
14
|
from omlish import check
|
|
15
|
+
from omlish import lang
|
|
16
|
+
from omlish import marshal as msh
|
|
17
|
+
from omlish.formats import json
|
|
9
18
|
|
|
10
19
|
from ..cli import CliModule
|
|
20
|
+
from ..packaging import marshal as _ # noqa
|
|
11
21
|
from ..packaging.names import canonicalize_name
|
|
22
|
+
from ..packaging.requires import ParsedRequirement
|
|
12
23
|
from ..packaging.requires import RequiresVariable
|
|
13
24
|
from ..packaging.requires import parse_requirement
|
|
14
25
|
|
|
15
26
|
|
|
27
|
+
if ta.TYPE_CHECKING:
|
|
28
|
+
import xml.etree.ElementTree as ET # noqa
|
|
29
|
+
else:
|
|
30
|
+
ET = lang.proxy_import('xml.etree.ElementTree')
|
|
31
|
+
|
|
32
|
+
|
|
16
33
|
PYPI_URL = 'https://pypi.org/'
|
|
17
34
|
|
|
18
35
|
|
|
@@ -84,6 +101,65 @@ class Cli(ap.Cli):
|
|
|
84
101
|
if not uses_by_req.get(d):
|
|
85
102
|
print(d)
|
|
86
103
|
|
|
104
|
+
@ap.command(
|
|
105
|
+
ap.arg('files', nargs='*'),
|
|
106
|
+
ap.arg('-r', '--follow-requirements', action='store_true'),
|
|
107
|
+
ap.arg('-j', '--json', action='store_true'),
|
|
108
|
+
ap.arg('-b', '--bare', action='store_true'),
|
|
109
|
+
)
|
|
110
|
+
def parse(self) -> None:
|
|
111
|
+
def print_req(req: ParsedRequirement) -> None:
|
|
112
|
+
if self.args.json:
|
|
113
|
+
req_m = msh.marshal(req)
|
|
114
|
+
print(json.dumps(req_m))
|
|
115
|
+
|
|
116
|
+
elif self.args.bare:
|
|
117
|
+
print(req.name)
|
|
118
|
+
|
|
119
|
+
else:
|
|
120
|
+
print(f'{req.name}{req.specifier or ""}')
|
|
121
|
+
|
|
122
|
+
#
|
|
123
|
+
|
|
124
|
+
seen_files: set[str] = set()
|
|
125
|
+
|
|
126
|
+
def do_file(file: ta.TextIO | str) -> None:
|
|
127
|
+
if isinstance(file, str) and file in seen_files:
|
|
128
|
+
return
|
|
129
|
+
|
|
130
|
+
with contextlib.ExitStack() as es:
|
|
131
|
+
f: ta.TextIO
|
|
132
|
+
if isinstance(file, str):
|
|
133
|
+
f = es.enter_context(open(file))
|
|
134
|
+
else:
|
|
135
|
+
f = file
|
|
136
|
+
|
|
137
|
+
for l in f:
|
|
138
|
+
if '#' in l:
|
|
139
|
+
l = l.partition('#')[0]
|
|
140
|
+
|
|
141
|
+
if not (l := l.strip()):
|
|
142
|
+
continue
|
|
143
|
+
|
|
144
|
+
if l.startswith('git+'):
|
|
145
|
+
continue # FIXME
|
|
146
|
+
|
|
147
|
+
elif l.startswith('-r'): # noqa
|
|
148
|
+
if self.args.follow_requirements:
|
|
149
|
+
base_dir = os.path.dirname(file) if isinstance(file, str) else '.'
|
|
150
|
+
r_file = os.path.join(base_dir, l[2:].strip())
|
|
151
|
+
do_file(r_file)
|
|
152
|
+
|
|
153
|
+
else:
|
|
154
|
+
req = parse_requirement(l)
|
|
155
|
+
print_req(req)
|
|
156
|
+
|
|
157
|
+
if self.args.files:
|
|
158
|
+
for file in self.args.files:
|
|
159
|
+
do_file(file)
|
|
160
|
+
else:
|
|
161
|
+
do_file(sys.stdin)
|
|
162
|
+
|
|
87
163
|
|
|
88
164
|
# @omlish-manifest
|
|
89
165
|
_CLI_MODULE = CliModule('pip', __name__)
|
omdev/tools/qr.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""
|
|
2
|
+
https://segno.readthedocs.io/en/stable/comparison-qrcode-libs.html
|
|
3
|
+
- https://github.com/nayuki/QR-Code-generator
|
|
4
|
+
- https://github.com/heuer/segno/
|
|
5
|
+
- https://github.com/lincolnloop/python-qrcode
|
|
6
|
+
"""
|
|
7
|
+
import argparse
|
|
8
|
+
import os
|
|
9
|
+
import subprocess
|
|
10
|
+
import sys
|
|
11
|
+
import tempfile
|
|
12
|
+
import typing as ta
|
|
13
|
+
|
|
14
|
+
from omlish import lang
|
|
15
|
+
|
|
16
|
+
from ..cli import CliModule
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
if ta.TYPE_CHECKING:
|
|
20
|
+
import segno
|
|
21
|
+
else:
|
|
22
|
+
segno = lang.proxy_import('segno')
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _main() -> None:
|
|
26
|
+
parser = argparse.ArgumentParser()
|
|
27
|
+
parser.add_argument('content', nargs='?')
|
|
28
|
+
|
|
29
|
+
parser.add_argument('-x', '--target-size', type=int)
|
|
30
|
+
|
|
31
|
+
parser.add_argument('-o', '--output')
|
|
32
|
+
parser.add_argument('-O', '--open', action='store_true')
|
|
33
|
+
|
|
34
|
+
parser.add_argument(
|
|
35
|
+
'--error', '-e',
|
|
36
|
+
help=(
|
|
37
|
+
'Error correction level: '
|
|
38
|
+
'"L": 7%% (default), '
|
|
39
|
+
'"M": 15%%, '
|
|
40
|
+
'"Q": 25%%, '
|
|
41
|
+
'"H": 30%%, '
|
|
42
|
+
'"-": no error correction (used for M1 symbols)'
|
|
43
|
+
),
|
|
44
|
+
choices=('L', 'M', 'Q', 'H', '-'),
|
|
45
|
+
)
|
|
46
|
+
args = parser.parse_args()
|
|
47
|
+
|
|
48
|
+
if (content := args.content) is None:
|
|
49
|
+
content = sys.stdin.read()
|
|
50
|
+
|
|
51
|
+
qr = segno.make(content)
|
|
52
|
+
|
|
53
|
+
if (tx := args.target_size) is not None:
|
|
54
|
+
sz = max(*qr.symbol_size())
|
|
55
|
+
sc = max(float(tx) / sz, 1)
|
|
56
|
+
else:
|
|
57
|
+
sc = 1
|
|
58
|
+
|
|
59
|
+
if args.output is not None:
|
|
60
|
+
out_file = args.output
|
|
61
|
+
else:
|
|
62
|
+
fd, out_file = tempfile.mkstemp(suffix='-qrcode.png')
|
|
63
|
+
os.close(fd)
|
|
64
|
+
|
|
65
|
+
qr.save(out_file, scale=sc)
|
|
66
|
+
|
|
67
|
+
if args.output is None:
|
|
68
|
+
print(out_file)
|
|
69
|
+
|
|
70
|
+
if args.open:
|
|
71
|
+
subprocess.check_call(['open', out_file])
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# @omlish-manifest
|
|
75
|
+
_CLI_MODULE = CliModule('qr', __name__)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
if __name__ == '__main__':
|
|
79
|
+
_main()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: omdev
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev112
|
|
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.
|
|
15
|
+
Requires-Dist: omlish ==0.0.0.dev112
|
|
16
16
|
Provides-Extra: all
|
|
17
17
|
Requires-Dist: black ~=24.10 ; extra == 'all'
|
|
18
18
|
Requires-Dist: pycparser ~=2.22 ; extra == 'all'
|
|
@@ -23,6 +23,7 @@ Requires-Dist: markdown ~=3.7 ; extra == 'all'
|
|
|
23
23
|
Requires-Dist: mypy ~=1.11 ; extra == 'all'
|
|
24
24
|
Requires-Dist: gprof2dot ~=2024.6 ; extra == 'all'
|
|
25
25
|
Requires-Dist: prompt-toolkit ~=3.0 ; extra == 'all'
|
|
26
|
+
Requires-Dist: segno ~=1.6 ; extra == 'all'
|
|
26
27
|
Requires-Dist: tokenize-rt ~=6.1 ; extra == 'all'
|
|
27
28
|
Requires-Dist: wheel ~=0.44 ; extra == 'all'
|
|
28
29
|
Provides-Extra: black
|
|
@@ -40,6 +41,8 @@ Provides-Extra: prof
|
|
|
40
41
|
Requires-Dist: gprof2dot ~=2024.6 ; extra == 'prof'
|
|
41
42
|
Provides-Extra: ptk
|
|
42
43
|
Requires-Dist: prompt-toolkit ~=3.0 ; extra == 'ptk'
|
|
44
|
+
Provides-Extra: qr
|
|
45
|
+
Requires-Dist: segno ~=1.6 ; extra == 'qr'
|
|
43
46
|
Provides-Extra: tokens
|
|
44
47
|
Requires-Dist: tokenize-rt ~=6.1 ; extra == 'tokens'
|
|
45
48
|
Provides-Extra: wheel
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
omdev/.manifests.json,sha256=
|
|
2
|
-
omdev/__about__.py,sha256=
|
|
1
|
+
omdev/.manifests.json,sha256=CttiykwDkNVtWsqk7xCLY0o7eUxPVTJvfS5enx6xg5g,7479
|
|
2
|
+
omdev/__about__.py,sha256=n5x-SO70OgbDQFzQ1d7sZDVMsnkQc4PxQZPFaIQFa0E,1281
|
|
3
3
|
omdev/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
omdev/bracepy.py,sha256=I8EdqtDvxzAi3I8TuMEW-RBfwXfqKbwp06CfOdj3L1o,2743
|
|
5
5
|
omdev/classdot.py,sha256=YOvgy6x295I_8NKBbBlRVd3AN7Osirm_Lqt4Wj0j9rY,1631
|
|
@@ -60,14 +60,14 @@ omdev/cexts/_distutils/compilers/unixccompiler.py,sha256=o1h8QuyupLntv4F21_XjzAZ
|
|
|
60
60
|
omdev/cli/__init__.py,sha256=V_l6VP1SZMlJbO-8CJwSuO9TThOy2S_oaPepNYgIrbE,37
|
|
61
61
|
omdev/cli/__main__.py,sha256=mOJpgc07o0r5luQ1DlX4tk2PqZkgmbwPbdzJ3KmtjgQ,138
|
|
62
62
|
omdev/cli/_pathhack.py,sha256=kxqb2kHap68Lkh8b211rDbcgj06hidBiAKA3f9posyc,2119
|
|
63
|
-
omdev/cli/clicli.py,sha256=
|
|
63
|
+
omdev/cli/clicli.py,sha256=oD54mXX-j9UeeCIW2640m8ip5LtAqQvT0hJRbl1zmf8,2874
|
|
64
64
|
omdev/cli/install.py,sha256=C-W171YlIHt4Cfok-nWSMbHwWhqF_PFqq2HixFttYx8,4460
|
|
65
65
|
omdev/cli/main.py,sha256=nD3bW3MkI0KuDSLpX_PTnl-lBnm4hIxVqczvvMHtupo,7058
|
|
66
66
|
omdev/cli/managers.py,sha256=BV98_n30Jj63OJrFgRoVZRfICxMLXEZKoEn4rMj9LV4,1160
|
|
67
67
|
omdev/cli/types.py,sha256=bqKw9SbtBtAip2vF9v4khh0CqKG6LBr6n9VzWBz7AJE,474
|
|
68
68
|
omdev/clipboard/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
69
69
|
omdev/clipboard/clipboard.py,sha256=CmnozkRljJ9UQDHLfCS8wKU0Xg-HfbsAkagAfMEias0,567
|
|
70
|
-
omdev/clipboard/darwin.py,sha256=
|
|
70
|
+
omdev/clipboard/darwin.py,sha256=zKPmI4mdTTo5ixbOVIBt6OnZE6BrpXgTPf0Tgz_-ds0,7556
|
|
71
71
|
omdev/interp/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
|
72
72
|
omdev/interp/__main__.py,sha256=GMCqeGYltgt5dlJzHxY9gqisa8cRkrPfmZYuZnjg4WI,162
|
|
73
73
|
omdev/interp/cli.py,sha256=sh7PZQoLletUViw1Y9OXNr9ekyNZ6YyxYuOQ_n9hyqU,2072
|
|
@@ -89,11 +89,12 @@ omdev/manifests/load.py,sha256=LtEsluDdd8CkNGj0QGBxee3twBn095Fru0xz2mtr7uk,4788
|
|
|
89
89
|
omdev/manifests/types.py,sha256=Jv6PAdVLPb9Hh4y6vDhPlWuMNBBViin1bC_u83jfsH4,234
|
|
90
90
|
omdev/mypy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
91
91
|
omdev/mypy/debug.py,sha256=WcZw-3Z1njg_KFGqi3DB6RuqbBa3dLArJnjVCuY1Mn0,3003
|
|
92
|
-
omdev/packaging/__init__.py,sha256=
|
|
93
|
-
omdev/packaging/
|
|
94
|
-
omdev/packaging/
|
|
95
|
-
omdev/packaging/
|
|
96
|
-
omdev/packaging/
|
|
92
|
+
omdev/packaging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
93
|
+
omdev/packaging/marshal.py,sha256=mWRuZ_okYxRJXylKFQLQpC8Pp7xjkUEfWYNzQIS5A2c,2376
|
|
94
|
+
omdev/packaging/names.py,sha256=-a7AykFPVR1i6EYJepbe3ABRrZQ_tPPmK5olzbn9HLI,2528
|
|
95
|
+
omdev/packaging/requires.py,sha256=kyyVCM0RyaKqmXd6tU5zf0QjWvCLQMNV_ev5hvOee_o,15731
|
|
96
|
+
omdev/packaging/specifiers.py,sha256=X8xOcwRLXTQYx5mYAS3ijqoTLlCtYESyUu4fX9bvblY,17447
|
|
97
|
+
omdev/packaging/versions.py,sha256=K4eUOUvLmYcR4aeUywekeWTBqAvZchrIxLf7dl07MS4,12261
|
|
97
98
|
omdev/precheck/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
98
99
|
omdev/precheck/__main__.py,sha256=UEuS4z5-heIrwTtB-ONe1KeXJdqj8tYXMqWMpuO10so,165
|
|
99
100
|
omdev/precheck/base.py,sha256=a_lGoFM-QhL8u8XDUYFhb-feEyfPbP4j8lcmNO51sHY,732
|
|
@@ -104,7 +105,10 @@ omdev/precheck/manifests.py,sha256=YfXqt6u0hlFXY0QkBMec6V_6Y9T4eCVAmrJDkQkB13U,7
|
|
|
104
105
|
omdev/precheck/scripts.py,sha256=Xw9kkQzlDd_2V9av9qlaNpNZG9jZdy3TTo7x60MeR2I,1273
|
|
105
106
|
omdev/ptk/__init__.py,sha256=StAwXQ96e8Xkkg7ciR9oBBhcSgqHT76vhoZML82BuY0,447
|
|
106
107
|
omdev/ptk/apps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
107
|
-
omdev/ptk/apps/ncdu.py,sha256=
|
|
108
|
+
omdev/ptk/apps/ncdu.py,sha256=dOkEJoc2Wjv1u_Uge7Vpei_LvXldoPP5833Eia355tc,4548
|
|
109
|
+
omdev/pycharm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
110
|
+
omdev/pycharm/__main__.py,sha256=hUPp11D024eMdT86BxXiRVtF7AGBk5W6Zn8_mEHSksY,163
|
|
111
|
+
omdev/pycharm/cli.py,sha256=XDR3fYUnGdK2oys3IKs7QrGbYwXUiMba16DNXdMVlAA,2209
|
|
108
112
|
omdev/pyproject/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
|
109
113
|
omdev/pyproject/__main__.py,sha256=gn3Rl1aYPYdiTtEqa9ifi0t-e4ZwPY0vhJ4UXvYdJDY,165
|
|
110
114
|
omdev/pyproject/cexts.py,sha256=x13piOOnNrYbA17qZLDVuR0p1sqhgEwpk4FtImX-klM,4281
|
|
@@ -114,31 +118,33 @@ omdev/pyproject/pkg.py,sha256=WB9k3zEpHSAR24H09kikgAnLMWUz-bk9f0aB-2L_ITw,14560
|
|
|
114
118
|
omdev/pyproject/reqs.py,sha256=8feZ71YnGzwKbLK4zO28CDQeNcZIIuq6cnkBhs6M-7E,2406
|
|
115
119
|
omdev/scripts/__init__.py,sha256=MKCvUAEQwsIvwLixwtPlpBqmkMXLCnjjXyAXvVpDwVk,91
|
|
116
120
|
omdev/scripts/bumpversion.py,sha256=Kn7fo73Hs8uJh3Hi3EIyLOlzLPWAC6dwuD_lZ3cIzuY,1064
|
|
117
|
-
omdev/scripts/execrss.py,sha256=
|
|
118
|
-
omdev/scripts/exectime.py,sha256=
|
|
121
|
+
omdev/scripts/execrss.py,sha256=mR0G0wERBYtQmVIn63lCIIFb5zkCM6X_XOENDFYDBKc,651
|
|
122
|
+
omdev/scripts/exectime.py,sha256=sFb376GflU6s9gNX-2-we8hgH6w5MuQNS9g6i4SqJIo,610
|
|
119
123
|
omdev/scripts/importtrace.py,sha256=Jbo3Yk2RAbE8_tJ97iTcVNpoxCJxrRb2tl1W_CV3NG0,14067
|
|
120
|
-
omdev/scripts/interp.py,sha256=
|
|
121
|
-
omdev/scripts/pyproject.py,sha256=
|
|
124
|
+
omdev/scripts/interp.py,sha256=U6mU2RPZjwcBhn4Vl4SrAyDUFcf7bBxBnPY5FHCxosw,72496
|
|
125
|
+
omdev/scripts/pyproject.py,sha256=RNWsO9-cu6MUXuWFT1Y200euUu6WcAC4orwGEUoGVWA,165526
|
|
122
126
|
omdev/scripts/slowcat.py,sha256=lssv4yrgJHiWfOiHkUut2p8E8Tq32zB-ujXESQxFFHY,2728
|
|
127
|
+
omdev/scripts/tmpexec.py,sha256=WTYcf56Tj2qjYV14AWmV8SfT0u6Y8eIU6cKgQRvEK3c,1442
|
|
123
128
|
omdev/toml/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
|
124
129
|
omdev/toml/parser.py,sha256=84bn09uhYHwQGyfww6Rw6y1RxPAE_HDltODOSakcqDM,29186
|
|
125
130
|
omdev/toml/writer.py,sha256=lk3on3YXVbWuLJa-xsOzOhs1bBAT1vXqw4mBbluZl_w,3040
|
|
126
131
|
omdev/tools/__init__.py,sha256=iVJAOQ0viGTQOm0DLX4uZLro-9jOioYJGLg9s0kDx1A,78
|
|
127
132
|
omdev/tools/doc.py,sha256=mv9XfitzqXl3vFHSenv01xHCxWf8g03rUAb_sqoty98,2556
|
|
128
133
|
omdev/tools/docker.py,sha256=k2BrVvFYwyGov064CPHd_HWo9aqR1zHc2UeEsVwPth4,6827
|
|
129
|
-
omdev/tools/git.py,sha256=
|
|
134
|
+
omdev/tools/git.py,sha256=IARrfL9R9BHpmTBia3svbPeCzf_4qlCCbOsLpohsfUI,4184
|
|
130
135
|
omdev/tools/importscan.py,sha256=QeGjR3UGcuuuDUiisFuAXWHlcKJScGxGEcU6tfOh2CM,4069
|
|
131
136
|
omdev/tools/mkrelimp.py,sha256=wsJAjTIf3nqcSfnT9TkDpS1VUOoM9W2Az5tZdWuzyLM,4054
|
|
132
137
|
omdev/tools/notebook.py,sha256=M8Xi_gfZdlahnyFLtp0RBgYZPSHWQStMMDYZc71Zync,3494
|
|
133
|
-
omdev/tools/pip.py,sha256
|
|
138
|
+
omdev/tools/pip.py,sha256=_O7WAACQ1F1ffH4ogZHcppT4P8VQxWQchJMLn9FvsJc,5073
|
|
134
139
|
omdev/tools/prof.py,sha256=8ZU9x_Dq8eT2ZFwU9sJpDIvxcIn9qBc8y2ELKPb5e5M,1382
|
|
140
|
+
omdev/tools/qr.py,sha256=tm68lPwEAkEwIL2sUKPKBYfwwPtjVWG1DBZwur8_jY8,1737
|
|
135
141
|
omdev/tools/sqlrepl.py,sha256=tmFZh80-xsGM62dyQ7_UGLebChrj7IHbIPYBWDJMgVk,5741
|
|
136
142
|
omdev/tools/pawk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
137
143
|
omdev/tools/pawk/__main__.py,sha256=VCqeRVnqT1RPEoIrqHFSu4PXVMg4YEgF4qCQm90-eRI,66
|
|
138
144
|
omdev/tools/pawk/pawk.py,sha256=Eckymn22GfychCQcQi96BFqRo_LmiJ-EPhC8TTUJdB4,11446
|
|
139
|
-
omdev-0.0.0.
|
|
140
|
-
omdev-0.0.0.
|
|
141
|
-
omdev-0.0.0.
|
|
142
|
-
omdev-0.0.0.
|
|
143
|
-
omdev-0.0.0.
|
|
144
|
-
omdev-0.0.0.
|
|
145
|
+
omdev-0.0.0.dev112.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
|
146
|
+
omdev-0.0.0.dev112.dist-info/METADATA,sha256=VeCQ5RyISLmbtXUOxqiBvvzJW3kHbcsb8l6KjNrg0C8,1810
|
|
147
|
+
omdev-0.0.0.dev112.dist-info/WHEEL,sha256=a7TGlA-5DaHMRrarXjVbQagU3Man_dCnGIWMJr5kRWo,91
|
|
148
|
+
omdev-0.0.0.dev112.dist-info/entry_points.txt,sha256=dHLXFmq5D9B8qUyhRtFqTGWGxlbx3t5ejedjrnXNYLU,33
|
|
149
|
+
omdev-0.0.0.dev112.dist-info/top_level.txt,sha256=1nr7j30fEWgLYHW3lGR9pkdHkb7knv1U1ES1XRNVQ6k,6
|
|
150
|
+
omdev-0.0.0.dev112.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|