omlish 0.0.0.dev384__py3-none-any.whl → 0.0.0.dev386__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 CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev384'
2
- __revision__ = '13eb429134387bdc2ec6e494bd89553b650b23e3'
1
+ __version__ = '0.0.0.dev386'
2
+ __revision__ = 'e2f1a23f62c35a30fdb5a509f65af87289ceafef'
3
3
 
4
4
 
5
5
  #
omlish/lang/__init__.py CHANGED
@@ -250,6 +250,15 @@ from .iterables import ( # noqa
250
250
  take,
251
251
  )
252
252
 
253
+ from .maysync_ import ( # noqa
254
+ maysync_op,
255
+
256
+ maysync_yield,
257
+
258
+ maysync_wrap,
259
+ a_maysync_wrap,
260
+ )
261
+
253
262
  from .objects import ( # noqa
254
263
  Identity,
255
264
  SimpleProxy,
@@ -384,6 +393,18 @@ from ..lite.maybes import ( # noqa
384
393
  Maybe,
385
394
  )
386
395
 
396
+ from ..lite.maysync import ( # noqa
397
+ MaysyncGen,
398
+ MaysyncFn,
399
+
400
+ MaysyncOp,
401
+
402
+ maysync,
403
+ a_maysync,
404
+
405
+ MaysyncRunnable,
406
+ )
407
+
387
408
  empty = Maybe.empty
388
409
  just = Maybe.just
389
410
 
@@ -0,0 +1,53 @@
1
+ import functools
2
+ import typing as ta
3
+
4
+ from ..lite.maysync import MaysyncGen
5
+ from ..lite.maysync import MaysyncOp
6
+ from ..lite.maysync import a_maysync
7
+ from ..lite.maysync import maysync
8
+
9
+
10
+ T = ta.TypeVar('T')
11
+ P = ta.ParamSpec('P')
12
+
13
+
14
+ ##
15
+
16
+
17
+ def maysync_op(
18
+ fn: ta.Callable[P, T],
19
+ a_fn: ta.Callable[P, ta.Awaitable[T]],
20
+ ) -> MaysyncOp[T]:
21
+ return MaysyncOp(
22
+ fn,
23
+ a_fn,
24
+ )
25
+
26
+
27
+ ##
28
+
29
+
30
+ def maysync_yield(
31
+ fn: ta.Callable[P, T],
32
+ a_fn: ta.Callable[P, ta.Awaitable[T]],
33
+ ) -> ta.Callable[P, ta.Generator[ta.Any, ta.Any, T]]:
34
+ def inner(*args, **kwargs):
35
+ return (yield MaysyncOp(fn, a_fn)(*args, **kwargs))
36
+ return inner
37
+
38
+
39
+ ##
40
+
41
+
42
+ def maysync_wrap(fn: ta.Callable[P, MaysyncGen[T]]) -> ta.Callable[P, T]:
43
+ @functools.wraps(fn)
44
+ def inner(*args, **kwargs):
45
+ return maysync(fn, *args, **kwargs)
46
+ return inner
47
+
48
+
49
+ def a_maysync_wrap(fn: ta.Callable[P, MaysyncGen[T]]) -> ta.Callable[P, ta.Awaitable[T]]:
50
+ @functools.wraps(fn)
51
+ async def inner(*args, **kwargs):
52
+ return await a_maysync(fn, *args, **kwargs)
53
+ return inner
omlish/lite/args.py CHANGED
@@ -34,3 +34,10 @@ class Args:
34
34
 
35
35
  def __call__(self, fn: ta.Callable[..., T]) -> T:
36
36
  return fn(*self.args, **self.kwargs)
37
+
38
+ @staticmethod
39
+ def call(fn: ta.Callable[..., T], args: ta.Optional['Args']) -> T:
40
+ if args is not None:
41
+ return args(fn)
42
+ else:
43
+ return fn()
omlish/lite/maysync.py ADDED
@@ -0,0 +1,74 @@
1
+ # ruff: noqa: UP045
2
+ import abc
3
+ import dataclasses as dc
4
+ import typing as ta
5
+
6
+ from .args import Args
7
+
8
+
9
+ T = ta.TypeVar('T')
10
+
11
+
12
+ MaysyncGen = ta.Generator['MaysyncOp', ta.Any, T] # ta.TypeAlias
13
+ MaysyncFn = ta.Callable[..., MaysyncGen[T]] # ta.TypeAlias
14
+
15
+
16
+ ##
17
+
18
+
19
+ @dc.dataclass(frozen=True)
20
+ class MaysyncOp(ta.Generic[T]):
21
+ fn: ta.Callable[..., T]
22
+ a_fn: ta.Callable[..., ta.Awaitable[T]]
23
+
24
+ args: ta.Optional[Args] = None
25
+
26
+ def __call__(self, *args: ta.Any, **kwargs: ta.Any) -> 'MaysyncOp[T]':
27
+ if self.args is not None:
28
+ raise RuntimeError('Args already bound')
29
+ return dc.replace(self, args=Args(*args, **kwargs))
30
+
31
+
32
+ maysync_op = MaysyncOp
33
+
34
+
35
+ ##
36
+
37
+
38
+ def maysync(fn: MaysyncFn[T], *args: ta.Any, **kwargs: ta.Any) -> T:
39
+ g = fn(*args, **kwargs)
40
+ i = None
41
+ while True:
42
+ try:
43
+ o = g.send(i)
44
+ except StopIteration as e:
45
+ return e.value
46
+ i = Args.call(o.fn, o.args)
47
+
48
+
49
+ async def a_maysync(fn: MaysyncFn[T], *args: ta.Any, **kwargs: ta.Any) -> T:
50
+ g = fn(*args, **kwargs)
51
+ i = None
52
+ while True:
53
+ try:
54
+ o = g.send(i)
55
+ except StopIteration as e:
56
+ return e.value
57
+ i = await Args.call(o.a_fn, o.args)
58
+
59
+
60
+ ##
61
+
62
+
63
+ class MaysyncRunnable(abc.ABC, ta.Generic[T]):
64
+ @abc.abstractmethod
65
+ def m_run(self) -> MaysyncGen[T]:
66
+ raise NotImplementedError
67
+
68
+ @ta.final
69
+ def run(self) -> T:
70
+ return maysync(self.m_run)
71
+
72
+ @ta.final
73
+ async def a_run(self) -> T:
74
+ return await a_maysync(self.m_run)
omlish/os/environ.py ADDED
@@ -0,0 +1,153 @@
1
+ # ruff: noqa: UP045
2
+ # @omlish-lite
3
+ import contextlib
4
+ import os
5
+ import typing as ta
6
+
7
+
8
+ ##
9
+
10
+
11
+ class EnvVar:
12
+ def __init__(self, name: str) -> None:
13
+ super().__init__()
14
+
15
+ if not isinstance(name, str):
16
+ raise TypeError(name)
17
+ if not name:
18
+ raise NameError(name)
19
+ self._name = name
20
+
21
+ @property
22
+ def name(self) -> str:
23
+ return self._name
24
+
25
+ def __init_subclass__(cls, **kwargs):
26
+ raise TypeError
27
+
28
+ def __repr__(self) -> str:
29
+ return f'{self.__class__.__name__}({self._name!r})'
30
+
31
+ def __hash__(self) -> int:
32
+ return hash((self.__class__, self._name))
33
+
34
+ def __eq__(self, other):
35
+ if not isinstance(other, EnvVar):
36
+ return NotImplemented
37
+ return self._name == other._name
38
+
39
+ def __bool__(self) -> bool:
40
+ raise TypeError
41
+
42
+ def __str__(self) -> str:
43
+ raise TypeError
44
+
45
+ #
46
+
47
+ @classmethod
48
+ def _get_mut_environ(
49
+ cls,
50
+ environ: ta.Optional[ta.MutableMapping[str, str]] = None,
51
+ ) -> ta.MutableMapping[str, str]:
52
+ if environ is None:
53
+ return os.environ
54
+ return environ
55
+
56
+ @classmethod
57
+ def _get_environ(
58
+ cls,
59
+ environ: ta.Optional[ta.Mapping[str, str]] = None,
60
+ ) -> ta.Mapping[str, str]:
61
+ if environ is None:
62
+ return cls._get_mut_environ()
63
+ return environ
64
+
65
+ #
66
+
67
+ def is_set(self, environ: ta.Optional[ta.Mapping[str, str]] = None) -> bool:
68
+ return self._name in self._get_environ(environ)
69
+
70
+ _NO_DEFAULT: ta.ClassVar[ta.Any] = object()
71
+
72
+ @ta.overload
73
+ def get(
74
+ self,
75
+ *,
76
+ environ: ta.Optional[ta.Mapping[str, str]] = None,
77
+ ) -> str:
78
+ ...
79
+
80
+ @ta.overload
81
+ def get(
82
+ self,
83
+ default: str,
84
+ /,
85
+ *,
86
+ environ: ta.Optional[ta.Mapping[str, str]] = None,
87
+ ) -> str:
88
+ ...
89
+
90
+ @ta.overload
91
+ def get(
92
+ self,
93
+ default: ta.Optional[str],
94
+ /,
95
+ *,
96
+ environ: ta.Optional[ta.Mapping[str, str]] = None,
97
+ ) -> ta.Optional[str]:
98
+ ...
99
+
100
+ @ta.overload
101
+ def get(
102
+ self,
103
+ default: ta.Callable[[], str],
104
+ /,
105
+ *,
106
+ environ: ta.Optional[ta.Mapping[str, str]] = None,
107
+ ) -> str:
108
+ ...
109
+
110
+ @ta.overload
111
+ def get(
112
+ self,
113
+ default: ta.Callable[[], ta.Optional[str]],
114
+ /,
115
+ *,
116
+ environ: ta.Optional[ta.Mapping[str, str]] = None,
117
+ ) -> ta.Optional[str]:
118
+ ...
119
+
120
+ def get(self, default=_NO_DEFAULT, /, *, environ=None):
121
+ environ = self._get_environ(environ)
122
+ try:
123
+ return environ[self._name]
124
+ except KeyError:
125
+ if default is self._NO_DEFAULT:
126
+ raise
127
+ elif callable(default):
128
+ return default()
129
+ else:
130
+ return default
131
+
132
+ #
133
+
134
+ def set(self, value: ta.Optional[str], *, environ: ta.Optional[ta.MutableMapping[str, str]] = None) -> None:
135
+ environ = self._get_mut_environ(environ)
136
+ if value is not None:
137
+ environ[self._name] = value
138
+ else:
139
+ del environ[self._name]
140
+
141
+ @contextlib.contextmanager
142
+ def set_context(
143
+ self,
144
+ value: ta.Optional[str],
145
+ *,
146
+ environ: ta.Optional[ta.MutableMapping[str, str]] = None,
147
+ ) -> ta.Iterator[ta.Optional[str]]:
148
+ prev = self.get(None, environ=environ)
149
+ self.set(value, environ=environ)
150
+ try:
151
+ yield prev
152
+ finally:
153
+ self.set(prev, environ=environ)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omlish
3
- Version: 0.0.0.dev384
3
+ Version: 0.0.0.dev386
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License-Expression: BSD-3-Clause
@@ -1,5 +1,5 @@
1
1
  omlish/.manifests.json,sha256=aT8yZ-Zh-9wfHl5Ym5ouiWC1i0cy7Q7RlhzavB6VLPI,8587
2
- omlish/__about__.py,sha256=YCcIz5KJ2sBcOE5C5j7gQV_BFCDb-uuGb0eoIWjBUc0,3543
2
+ omlish/__about__.py,sha256=BY-Xe7WExFumskKfjUB2aFnO0UT88dNaM5Lzw8-VF1c,3543
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
@@ -420,7 +420,7 @@ omlish/iterators/iterators.py,sha256=RxW35yQ5ed8vBQ22IqpDXFx-i5JiLQdp7-pkMZXhJJ8
420
420
  omlish/iterators/recipes.py,sha256=wOwOZg-zWG9Zc3wcAxJFSe2rtavVBYwZOfG09qYEx_4,472
421
421
  omlish/iterators/tools.py,sha256=M16LXrJhMdsz5ea2qH0vws30ZvhQuQSCVFSLpRf_gTg,2096
422
422
  omlish/iterators/unique.py,sha256=Nw0pSaNEcHAkve0ugfLPvJcirDOn9ECyC5wIL8JlJKI,1395
423
- omlish/lang/__init__.py,sha256=1XbAE88POrWtIHreNk47HAcl6Ch15uTH4cJFo2L7wFM,6619
423
+ omlish/lang/__init__.py,sha256=GRMthX6oFZ4FdGjY5FvP30NT0DZck0CzaRjG2uPKrWM,6867
424
424
  omlish/lang/attrs.py,sha256=zFiVuGVOq88x45464T_LxDa-ZEq_RD9zJLq2zeVEBDc,5105
425
425
  omlish/lang/casing.py,sha256=cFUlbDdXLhwnWwcYx4qnM5c4zGX7hIRUfcjiZbxUD28,4636
426
426
  omlish/lang/clsdct.py,sha256=HAGIvBSbCefzRjXriwYSBLO7QHKRv2UsE78jixOb-fA,1828
@@ -435,6 +435,7 @@ omlish/lang/functions.py,sha256=aLdxhmqG0Pj9tBgsKdoCu_q15r82WIkNqDDSPQU19L8,5689
435
435
  omlish/lang/generators.py,sha256=a4D5HU_mySs2T2z3xCmE_s3t4QJkj0YRrK4-hhpGd0A,5197
436
436
  omlish/lang/imports.py,sha256=y9W9Y-d_cQ35QCLuSIPoa6vnEqSErFCz8b-34IH128U,10552
437
437
  omlish/lang/iterables.py,sha256=y1SX2Co3VsOeX2wlfFF7K3rwLvF7Dtre7VY6EpfwAwA,3338
438
+ omlish/lang/maysync_.py,sha256=ffabm266xc-nqH-3lM0tfyISAX7SO1FBjlIziT4sPIE,1093
438
439
  omlish/lang/objects.py,sha256=ZsibJwNp1EXorbaObm9TlCNtuuM65snCmVb7H4_llqI,6116
439
440
  omlish/lang/outcomes.py,sha256=0PqxoKaGbBXU9UYZ6AE2QSq94Z-gFDt6wYdp0KomNQw,8712
440
441
  omlish/lang/overrides.py,sha256=IBzK6ljfLX6TLgIyKTSjhqTLcuKRkQNVtEOnBLS4nuA,2095
@@ -465,7 +466,7 @@ omlish/lifecycles/manager.py,sha256=92s1IH_gDP25PM5tFuPMP2hD_6s5fPi_VzZiDS5549g,
465
466
  omlish/lifecycles/states.py,sha256=6gTdY3hn7-1sJ60lA3GeMx5RVKvXtFBBXE4KEjoO1Hs,1297
466
467
  omlish/lifecycles/transitions.py,sha256=3IFdWGtAeoy3XRlIyW7yCKV4e4Iof9ytkqklGMRFYQs,1944
467
468
  omlish/lite/__init__.py,sha256=cyZEpGob7XjU8DohyNxVe5CQRk4CQ5vrHL42OdhQb8w,148
468
- omlish/lite/args.py,sha256=_py7azSCqPJwA2P1qY0B91sSiORsvYIK7IBO6hPDYK4,739
469
+ omlish/lite/args.py,sha256=226ah28AjJKwG9X5dV6bxbuce0UF87MsonjHXh0eLtg,924
469
470
  omlish/lite/cached.py,sha256=O7ozcoDNFm1Hg2wtpHEqYSp_i_nCLNOP6Ueq_Uk-7mU,1300
470
471
  omlish/lite/check.py,sha256=ytCkwZoKfOlJqylL-AGm8C2WfsWJd2q3kFbnZCzX3_M,13844
471
472
  omlish/lite/configs.py,sha256=4-1uVxo-aNV7vMKa7PVNhM610eejG1WepB42-Dw2xQI,914
@@ -477,6 +478,7 @@ omlish/lite/json.py,sha256=m0Ce9eqUZG23-H7-oOp8n1sf4fzno5vtK4AK_4Vc-Mg,706
477
478
  omlish/lite/logs.py,sha256=CWFG0NKGhqNeEgryF5atN2gkPYbUdTINEw_s1phbINM,51
478
479
  omlish/lite/marshal.py,sha256=JD_8ox5-yeIo7MZ6iipCdiVxx33So52M02AtvFlRGC8,20392
479
480
  omlish/lite/maybes.py,sha256=0p_fzb6yiOjEpvMKaQ53Q6CH1VPW1or7v7Lt1JIKcgM,4359
481
+ omlish/lite/maysync.py,sha256=dwiJE5y8h1nBnrYsfuaxITGpik0RlhpAF8qpba_Z-1g,1537
480
482
  omlish/lite/pycharm.py,sha256=FRHGcCDo42UzZXqNwW_DkhI-6kb_CmJKPiQ8F6mYkLA,1174
481
483
  omlish/lite/reflect.py,sha256=pzOY2PPuHH0omdtglkN6DheXDrGopdL3PtTJnejyLFU,2189
482
484
  omlish/lite/reprs.py,sha256=Tiqf_ciD8FfS0ury7FcJ5G21yY342fW0vPacYlb8EO4,2014
@@ -564,6 +566,7 @@ omlish/multiprocessing/spawn.py,sha256=eukBCmlQy4Wt4VDOwHg42RDnMyxu-hGMe4csmkorb
564
566
  omlish/os/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
565
567
  omlish/os/atomics.py,sha256=uEvlO5iVD8zJTrnoPvoTD9nUnJIKiJiYqD1Ios927Pk,5252
566
568
  omlish/os/deathsig.py,sha256=k4Sa9nXQvn43k5DTPDzpX9q_Nfc2045dMEGh__rn__s,646
569
+ omlish/os/environ.py,sha256=fDjnSO2Qz6lpvICx54JZpdPF-BxL4zKAWU3x_6UTxCI,3681
567
570
  omlish/os/fcntl.py,sha256=EUa4TkeqdKix-uIweRitIZsgT9ohY7OQ5QiIhUW9S0c,1512
568
571
  omlish/os/filemodes.py,sha256=JjHXZ7_BUQRphlA6_DkQoRSOEXxQUWWoKiS2-54rMVo,4586
569
572
  omlish/os/files.py,sha256=PmFQIesLmpYORm4dMKTkj2PeS8iu-KbfPmjZHaabeVc,1117
@@ -891,9 +894,9 @@ omlish/typedvalues/marshal.py,sha256=AtBz7Jq-BfW8vwM7HSxSpR85JAXmxK2T0xDblmm1HI0
891
894
  omlish/typedvalues/of_.py,sha256=UXkxSj504WI2UrFlqdZJbu2hyDwBhL7XVrc2qdR02GQ,1309
892
895
  omlish/typedvalues/reflect.py,sha256=PAvKW6T4cW7u--iX80w3HWwZUS3SmIZ2_lQjT65uAyk,1026
893
896
  omlish/typedvalues/values.py,sha256=ym46I-q2QJ_6l4UlERqv3yj87R-kp8nCKMRph0xQ3UA,1307
894
- omlish-0.0.0.dev384.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
895
- omlish-0.0.0.dev384.dist-info/METADATA,sha256=PhVWxPb5TWMJN2-RnlTcRyIb2zPG8BQIz4F01yyIiqI,18825
896
- omlish-0.0.0.dev384.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
897
- omlish-0.0.0.dev384.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
898
- omlish-0.0.0.dev384.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
899
- omlish-0.0.0.dev384.dist-info/RECORD,,
897
+ omlish-0.0.0.dev386.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
898
+ omlish-0.0.0.dev386.dist-info/METADATA,sha256=VFOznLJPLfiKuYUYuRrJ3wFrH3TEMDQAqH_8H8RQY_g,18825
899
+ omlish-0.0.0.dev386.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
900
+ omlish-0.0.0.dev386.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
901
+ omlish-0.0.0.dev386.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
902
+ omlish-0.0.0.dev386.dist-info/RECORD,,