omlish 0.0.0.dev291__py3-none-any.whl → 0.0.0.dev292__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.
- omlish/__about__.py +2 -2
- omlish/lang/__init__.py +3 -3
- omlish/lang/contextmanagers.py +0 -16
- omlish/lite/contextmanagers.py +6 -3
- omlish/subprocesses/editor.py +97 -0
- {omlish-0.0.0.dev291.dist-info → omlish-0.0.0.dev292.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev291.dist-info → omlish-0.0.0.dev292.dist-info}/RECORD +11 -10
- {omlish-0.0.0.dev291.dist-info → omlish-0.0.0.dev292.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev291.dist-info → omlish-0.0.0.dev292.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev291.dist-info → omlish-0.0.0.dev292.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev291.dist-info → omlish-0.0.0.dev292.dist-info}/top_level.txt +0 -0
omlish/__about__.py
CHANGED
omlish/lang/__init__.py
CHANGED
@@ -96,12 +96,10 @@ from .contextmanagers import ( # noqa
|
|
96
96
|
NOP_CONTEXT_MANAGER,
|
97
97
|
NopContextManager,
|
98
98
|
Timer,
|
99
|
-
a_defer,
|
100
99
|
breakpoint_on_exception,
|
101
100
|
context_var_setting,
|
102
101
|
context_wrapped,
|
103
102
|
default_lock,
|
104
|
-
defer,
|
105
103
|
disposing,
|
106
104
|
maybe_managing,
|
107
105
|
)
|
@@ -296,9 +294,11 @@ from .typing import ( # noqa
|
|
296
294
|
##
|
297
295
|
|
298
296
|
from ..lite.contextmanagers import ( # noqa
|
299
|
-
attr_setting,
|
300
297
|
AsyncExitStacked,
|
301
298
|
ExitStacked,
|
299
|
+
adefer,
|
300
|
+
attr_setting,
|
301
|
+
defer,
|
302
302
|
)
|
303
303
|
|
304
304
|
from ..lite.imports import ( # noqa
|
omlish/lang/contextmanagers.py
CHANGED
@@ -119,22 +119,6 @@ class AsyncContextManager(abc.ABC, ta.Generic[T]):
|
|
119
119
|
##
|
120
120
|
|
121
121
|
|
122
|
-
@contextlib.contextmanager
|
123
|
-
def defer(fn: ta.Callable) -> ta.Generator[ta.Callable, None, None]:
|
124
|
-
try:
|
125
|
-
yield fn
|
126
|
-
finally:
|
127
|
-
fn()
|
128
|
-
|
129
|
-
|
130
|
-
@contextlib.asynccontextmanager
|
131
|
-
async def a_defer(fn: ta.Awaitable) -> ta.AsyncGenerator[ta.Awaitable, None]:
|
132
|
-
try:
|
133
|
-
yield fn
|
134
|
-
finally:
|
135
|
-
await fn
|
136
|
-
|
137
|
-
|
138
122
|
@contextlib.contextmanager
|
139
123
|
def maybe_managing(obj: T) -> ta.Iterator[T]:
|
140
124
|
if isinstance(obj, ta.ContextManager):
|
omlish/lite/contextmanagers.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# ruff: noqa: UP007
|
2
2
|
import contextlib
|
3
|
+
import functools
|
3
4
|
import sys
|
4
5
|
import typing as ta
|
5
6
|
|
@@ -146,7 +147,9 @@ class AsyncExitStacked:
|
|
146
147
|
|
147
148
|
|
148
149
|
@contextlib.contextmanager
|
149
|
-
def defer(fn: ta.Callable) -> ta.Generator[ta.Callable, None, None]:
|
150
|
+
def defer(fn: ta.Callable, *args: ta.Any, **kwargs: ta.Any) -> ta.Generator[ta.Callable, None, None]:
|
151
|
+
if args or kwargs:
|
152
|
+
fn = functools.partial(fn, *args, **kwargs)
|
150
153
|
try:
|
151
154
|
yield fn
|
152
155
|
finally:
|
@@ -154,11 +157,11 @@ def defer(fn: ta.Callable) -> ta.Generator[ta.Callable, None, None]:
|
|
154
157
|
|
155
158
|
|
156
159
|
@contextlib.asynccontextmanager
|
157
|
-
async def adefer(fn: ta.
|
160
|
+
async def adefer(fn: ta.Awaitable) -> ta.AsyncGenerator[ta.Awaitable, None]:
|
158
161
|
try:
|
159
162
|
yield fn
|
160
163
|
finally:
|
161
|
-
await fn
|
164
|
+
await fn
|
162
165
|
|
163
166
|
|
164
167
|
##
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
# @omlish-lite
|
3
|
+
import dataclasses as dc
|
4
|
+
import os
|
5
|
+
import tempfile
|
6
|
+
import typing as ta
|
7
|
+
|
8
|
+
from ..lite.cached import cached_nullary
|
9
|
+
from ..lite.contextmanagers import ExitStacked
|
10
|
+
from ..lite.contextmanagers import defer
|
11
|
+
from .run import SubprocessRun
|
12
|
+
from .run import SubprocessRunnable
|
13
|
+
from .run import SubprocessRunOutput
|
14
|
+
|
15
|
+
|
16
|
+
##
|
17
|
+
|
18
|
+
|
19
|
+
class EditTextWithUserEditor(SubprocessRunnable, ExitStacked):
|
20
|
+
def __init__(self, initial_text: str = '') -> None:
|
21
|
+
super().__init__()
|
22
|
+
|
23
|
+
self._initial_text = initial_text
|
24
|
+
|
25
|
+
@dc.dataclass(frozen=True)
|
26
|
+
class _TempFile:
|
27
|
+
path: str
|
28
|
+
before_mtime: float
|
29
|
+
|
30
|
+
@cached_nullary
|
31
|
+
def _temp_file(self) -> _TempFile:
|
32
|
+
with tempfile.NamedTemporaryFile(
|
33
|
+
mode='r+',
|
34
|
+
delete=False,
|
35
|
+
) as ntf:
|
36
|
+
ntf.write(self._initial_text)
|
37
|
+
ntf.flush()
|
38
|
+
before_mtime = os.stat(ntf.name).st_mtime
|
39
|
+
|
40
|
+
self._enter_context(defer(os.unlink, ntf.name)) # noqa
|
41
|
+
|
42
|
+
return EditTextWithUserEditor._TempFile(
|
43
|
+
ntf.name,
|
44
|
+
before_mtime,
|
45
|
+
)
|
46
|
+
|
47
|
+
def make_run(self) -> SubprocessRun:
|
48
|
+
tf = self._temp_file()
|
49
|
+
|
50
|
+
editor = os.environ.get('EDITOR', 'vi')
|
51
|
+
|
52
|
+
return SubprocessRun.of(
|
53
|
+
editor,
|
54
|
+
tf.path,
|
55
|
+
)
|
56
|
+
|
57
|
+
def handle_run_output(self, output: SubprocessRunOutput) -> ta.Optional[str]:
|
58
|
+
tf = self._temp_file()
|
59
|
+
|
60
|
+
if output.returncode != 0:
|
61
|
+
return None
|
62
|
+
|
63
|
+
after_mtime = os.stat(tf.path).st_mtime
|
64
|
+
|
65
|
+
if after_mtime == tf.before_mtime:
|
66
|
+
# No changes made; assuming cancel.
|
67
|
+
return None
|
68
|
+
|
69
|
+
with open(tf.path) as f:
|
70
|
+
content = f.read().strip()
|
71
|
+
if not content:
|
72
|
+
# Empty file; assuming cancel.
|
73
|
+
return None
|
74
|
+
|
75
|
+
return content
|
76
|
+
|
77
|
+
|
78
|
+
def edit_text_with_user_editor(
|
79
|
+
initial_text: str = '',
|
80
|
+
subprocesses: ta.Optional[ta.Any] = None, # AbstractSubprocesses
|
81
|
+
) -> ta.Optional[str]:
|
82
|
+
with EditTextWithUserEditor(initial_text) as cmd:
|
83
|
+
return cmd.run(subprocesses)
|
84
|
+
|
85
|
+
|
86
|
+
##
|
87
|
+
|
88
|
+
|
89
|
+
if __name__ == '__main__':
|
90
|
+
def _main() -> None:
|
91
|
+
text = edit_text_with_user_editor('# Write your message here.\n')
|
92
|
+
if text is not None:
|
93
|
+
print('User submitted:\n', text)
|
94
|
+
else:
|
95
|
+
print('Operation canceled.')
|
96
|
+
|
97
|
+
_main()
|
@@ -1,5 +1,5 @@
|
|
1
1
|
omlish/.manifests.json,sha256=pjGUyLHaoWpPqRP3jz2u1fC1qoRc2lvrEcpU_Ax2tdg,8253
|
2
|
-
omlish/__about__.py,sha256=
|
2
|
+
omlish/__about__.py,sha256=35DcIUR8xZ1fV59-t4ejDVrAHFLqGSDxuBoLBDriBvA,3444
|
3
3
|
omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
|
4
4
|
omlish/c3.py,sha256=rer-TPOFDU6fYq_AWio_AmA-ckZ8JDY5shIzQ_yXfzA,8414
|
5
5
|
omlish/cached.py,sha256=MLap_p0rdGoDIMVhXVHm1tsbcWobJF0OanoodV03Ju8,542
|
@@ -460,12 +460,12 @@ omlish/iterators/iterators.py,sha256=RxW35yQ5ed8vBQ22IqpDXFx-i5JiLQdp7-pkMZXhJJ8
|
|
460
460
|
omlish/iterators/recipes.py,sha256=wOwOZg-zWG9Zc3wcAxJFSe2rtavVBYwZOfG09qYEx_4,472
|
461
461
|
omlish/iterators/tools.py,sha256=c4hArZEVV8y9_dFfmRwakusv1cWJLT4MkTkGRjnGN5U,2556
|
462
462
|
omlish/iterators/unique.py,sha256=Nw0pSaNEcHAkve0ugfLPvJcirDOn9ECyC5wIL8JlJKI,1395
|
463
|
-
omlish/lang/__init__.py,sha256=
|
463
|
+
omlish/lang/__init__.py,sha256=KCzbT9IMWi2TNldAlDZ6b8Rr-7hyV9Ne6kIKJLXNAxg,5315
|
464
464
|
omlish/lang/attrs.py,sha256=i7euRF81uNF8QDmUVXSK_BtqLGshaMi4VVdUnMjiMwg,5050
|
465
465
|
omlish/lang/clsdct.py,sha256=HAGIvBSbCefzRjXriwYSBLO7QHKRv2UsE78jixOb-fA,1828
|
466
466
|
omlish/lang/collections.py,sha256=aGi0j6VzVe2nz4l357Y4RD5_XNl8OJbmM5qM6BclrrY,1895
|
467
467
|
omlish/lang/comparison.py,sha256=MOwEG0Yny-jBPHO9kQto9FSRyeNpQW24UABsghkrHxY,1356
|
468
|
-
omlish/lang/contextmanagers.py,sha256=
|
468
|
+
omlish/lang/contextmanagers.py,sha256=pN8X4ZCagqU9_xWumi8gZPdMIWlInA-_zQrkl7o5VP0,7258
|
469
469
|
omlish/lang/datetimes.py,sha256=mrTtA67JYpfQwSlzdPcBtvm6dAyYM_dXNnlxFwFQH0M,228
|
470
470
|
omlish/lang/descriptors.py,sha256=zBtgO9LjdSTGHNUgiIqswh78WOVoGH6KzS0NbgB1Wls,6572
|
471
471
|
omlish/lang/enums.py,sha256=F9tflHfaAoV2MpyuhZzpfX9-H55M3zNa9hCszsngEo8,111
|
@@ -502,7 +502,7 @@ omlish/lite/__init__.py,sha256=ISLhM4q0LR1XXTCaHdZOZxBRyIsoZqYm4u0bf1BPcVk,148
|
|
502
502
|
omlish/lite/cached.py,sha256=O7ozcoDNFm1Hg2wtpHEqYSp_i_nCLNOP6Ueq_Uk-7mU,1300
|
503
503
|
omlish/lite/check.py,sha256=OLwtE2x6nlbGx4vS3Rda7zMHpgqzDSLJminTAX2lqLA,13529
|
504
504
|
omlish/lite/configs.py,sha256=Ev_19sbII67pTWzInYjYqa9VyTiZBvyjhZqyG8TtufE,908
|
505
|
-
omlish/lite/contextmanagers.py,sha256=
|
505
|
+
omlish/lite/contextmanagers.py,sha256=WrL2NPT7OA5JvHp4H-opwsCpYTHod27EJ4qB1cJ9Mjc,5691
|
506
506
|
omlish/lite/dataclasses.py,sha256=t1G5-xOuvE6o6w9RyqHzLT9wHD0HkqBh5P8HUZWxGzs,1912
|
507
507
|
omlish/lite/imports.py,sha256=o9WWrNrWg0hKeMvaj91giaovED_9VFanN2MyEHBGekY,1346
|
508
508
|
omlish/lite/inject.py,sha256=-tTsOqqef-Ix5Tgl2DP_JAsNWJQDFUptERl3lk14Uzs,29007
|
@@ -769,6 +769,7 @@ omlish/sql/tabledefs/tabledefs.py,sha256=lIhvlt0pk6G7RZAtDFsFXm5j0l9BvRfnP7vNGey
|
|
769
769
|
omlish/subprocesses/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
770
770
|
omlish/subprocesses/async_.py,sha256=hPQTWFa3k5CE_s9p1JTY4KdTPOsqLJtq3lGMRznrVpY,2373
|
771
771
|
omlish/subprocesses/base.py,sha256=W6El-PUKKF9KLAks5LB6kzqs_n3FfkblJ-JOv6NFQbY,6133
|
772
|
+
omlish/subprocesses/editor.py,sha256=nLrudPayAZxv0u5LtZFecR_zdSEk0bd8G3XFjbOD81M,2386
|
772
773
|
omlish/subprocesses/run.py,sha256=3jwSnQJvFMDMHmJvtAkrrK5D-i7_8cw12vX84EWTuJo,3668
|
773
774
|
omlish/subprocesses/sync.py,sha256=HKmKM99_Y7tkJRg_n5onXrw41IZt5M5fqU0281LY-mo,3671
|
774
775
|
omlish/subprocesses/utils.py,sha256=MJb6hvKhZceTmBeFVqlc5oM7rDxWkUzSzK9nKvbIvM8,396
|
@@ -831,9 +832,9 @@ omlish/typedvalues/holder.py,sha256=4SwRezsmuDDEO5gENGx8kTm30pblF5UktoEAu02i-Gk,
|
|
831
832
|
omlish/typedvalues/marshal.py,sha256=Rr-4DZ90BoD5Z9gT18QhZH2yMA3-gPJBK8GUrGkp8VA,4245
|
832
833
|
omlish/typedvalues/reflect.py,sha256=y_7IY8_4cLVRvD3ug-_-cDaO5RtzC1rLVFzkeAPALf8,683
|
833
834
|
omlish/typedvalues/values.py,sha256=Q_5IiQM3Vka4wGVd-scaslb4-oCMjFcIOksIrKE-JIM,1229
|
834
|
-
omlish-0.0.0.
|
835
|
-
omlish-0.0.0.
|
836
|
-
omlish-0.0.0.
|
837
|
-
omlish-0.0.0.
|
838
|
-
omlish-0.0.0.
|
839
|
-
omlish-0.0.0.
|
835
|
+
omlish-0.0.0.dev292.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
836
|
+
omlish-0.0.0.dev292.dist-info/METADATA,sha256=kDZfh7WmEgxzVyOJP7bSmYSh1RzTqJOv4VdFbKI55fk,4316
|
837
|
+
omlish-0.0.0.dev292.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
|
838
|
+
omlish-0.0.0.dev292.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
|
839
|
+
omlish-0.0.0.dev292.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
|
840
|
+
omlish-0.0.0.dev292.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|