omlish 0.0.0.dev254__py3-none-any.whl → 0.0.0.dev256__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.
@@ -1,5 +1,5 @@
1
1
  omlish/.manifests.json,sha256=x26AIwDzScUvnX-p4xlq6Zc5QYrAo0Vmgf1qHc1KL_M,8253
2
- omlish/__about__.py,sha256=_UAdSthc_ThPG20zNClzsObtbtg1SgdxuKoWfomaXRw,3380
2
+ omlish/__about__.py,sha256=cOMhDxR5wugqDQKvpcilkCXkPARgj9bTuboNWlXD0DE,3380
3
3
  omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
4
4
  omlish/c3.py,sha256=ubu7lHwss5V4UznbejAI0qXhXahrU01MysuHOZI9C4U,8116
5
5
  omlish/cached.py,sha256=MLap_p0rdGoDIMVhXVHm1tsbcWobJF0OanoodV03Ju8,542
@@ -9,10 +9,9 @@ omlish/defs.py,sha256=9uUjJuVIbCBL3g14fyzAp-9gH935MFofvlfOGwcBIaM,4913
9
9
  omlish/dynamic.py,sha256=xQ8LlOt_fUPApg-yz7-gNq8JdVgTqJ0_R6vhJq2WbpI,6522
10
10
  omlish/libc.py,sha256=8K4c66YV1ziJerl5poAAYCmsV-VSsHkT3EHhPW04ufg,15639
11
11
  omlish/metadata.py,sha256=q8UG-fpcXhEF7BZnhVikIE_IHyud9-8YT8iv646zU2s,3589
12
- omlish/outcome.py,sha256=ABIE0zjjTyTNtn-ZqQ_9_mUzLiBQ3sDAyqc9JVD8N2k,7852
13
12
  omlish/runmodule.py,sha256=PWvuAaJ9wQQn6bx9ftEL3_d04DyotNn8dR_twm2pgw0,700
14
13
  omlish/shlex.py,sha256=bsW2XUD8GiMTUTDefJejZ5AyqT1pTgWMPD0BMoF02jE,248
15
- omlish/sync.py,sha256=QJ79kxmIqDP9SeHDoZAf--DpFIhDQe1jACy8H4N0yZI,2928
14
+ omlish/sync.py,sha256=-2gVJZFl8hvp7jvrnX8GcZVOecqAym6AcyK1QtMR9Ic,2979
16
15
  omlish/_antlr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
16
  omlish/algorithm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
17
  omlish/algorithm/all.py,sha256=FudUHwoaRLNNmqYM3jhP2Yd2BpmYhNBRPaVZzARMoSc,194
@@ -92,12 +91,18 @@ omlish/argparse/all.py,sha256=NeeMM5MIebY7XDAHaCxUzeesEoUYwsf5i9PrBUcO1cI,1057
92
91
  omlish/argparse/cli.py,sha256=vVLlhJPt0PKaNfIBrXTzz9cHyy2dFEY8hlQ3GvtKbwc,8704
93
92
  omlish/asyncs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
93
  omlish/asyncs/all.py,sha256=uUz9ziKh4_QrgmdhKFMgq6j7mFbiZd3LiogguDCQsGI,587
95
- omlish/asyncs/anyio.py,sha256=gfpx-D8QGmUfhnQxHEaHXcAP8zSMQjcGw4COFTGNnHI,8021
96
94
  omlish/asyncs/asyncs.py,sha256=x72xDJenumWV5a_myJOdWlaTdBNZPCwJ_u7_6yhZyBk,2034
97
95
  omlish/asyncs/bridge.py,sha256=zVAhbFVDvw3qJjcvOKKY2mI8AwrmcmddKsW9KIzPdLI,9740
98
96
  omlish/asyncs/flavors.py,sha256=1mNxGNRVmjUHzA13K5ht8vdJv4CLEmzYTQ6BZXr1520,4866
99
97
  omlish/asyncs/trio.py,sha256=fmZ5b_lKdVV8NQ3euCUutWgnkqTFzSnOjvJSA_jvmrE,367
100
98
  omlish/asyncs/trio_asyncio.py,sha256=oqdOHy0slj9PjVxaDf3gJkq9AAgg7wYZbB469jOftVw,1327
99
+ omlish/asyncs/anyio/__init__.py,sha256=sX7bciyRquaPeDAz16phkg_Lnw_AbJgUkayy5Aw8o2M,1695
100
+ omlish/asyncs/anyio/backends.py,sha256=jJIymWoiedaEJJm82gvKiJ41EWLQZ-bcyNHpbDpKKi4,1584
101
+ omlish/asyncs/anyio/futures.py,sha256=3dmb9DqxSWP2gRtzujqiJcfpbNIVhyEv5KBRInRs388,2052
102
+ omlish/asyncs/anyio/signals.py,sha256=ySSut5prdnoy0-5Ws5V1M4cC2ON_vY550vU10d2NHk8,893
103
+ omlish/asyncs/anyio/streams.py,sha256=gNRAcHR0L8OtNioqKFbq0Z_apYAWKHFipZ2MUBp8Vg0,2228
104
+ omlish/asyncs/anyio/sync.py,sha256=maggE0mH-TxmefX3vfa27DuDEaE5-yQKn84Mj3mOSVU,1569
105
+ omlish/asyncs/anyio/utils.py,sha256=BRThj9AVV1CAe4tkSYXQvNBHqJRbEpP4utzu-AImk08,1086
101
106
  omlish/asyncs/asyncio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
102
107
  omlish/asyncs/asyncio/all.py,sha256=EksCHjRQKobiGrxuDW72IaH53WJMs7rdj_ZDBI3iKcg,315
103
108
  omlish/asyncs/asyncio/asyncio.py,sha256=mDjYNm1cylUhQ8slWXwdPoXasuWfafjzu78GHt2Mdig,2437
@@ -238,7 +243,7 @@ omlish/dispatch/_dispatch2.py,sha256=70k1tKKvuhxtAu6v4skECfHKIKVWrmlt7G_JKLUsKEs
238
243
  omlish/dispatch/_dispatch3.py,sha256=9Zjd7bINAC3keiaBdssc4v5dY0-8OI6XooV2DR9U7Z0,2818
239
244
  omlish/dispatch/dispatch.py,sha256=KA5l49AiGLRjp4J7RDJW9RiDp9WUD1ewR1AOPEF8g38,3062
240
245
  omlish/dispatch/functions.py,sha256=8Qvj62XKn9SKfiqoVQdBD3wVRE4JUWpZDqs0oouuDIw,1519
241
- omlish/dispatch/impls.py,sha256=0t1N3EZUHi-V3kzgOVUezE7ghevZt1G3r0eo2q_do7c,2151
246
+ omlish/dispatch/impls.py,sha256=JP67zSvDWG4XFOmKPrhWHxRV9WnyAPAsjQHvbmEJh4c,2136
242
247
  omlish/dispatch/methods.py,sha256=dr8xQo-zVRckIo_V2Wp8Reqor3NE6APuzomUfsSBGdk,5498
243
248
  omlish/docker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
244
249
  omlish/docker/all.py,sha256=xXRgJgLGPwAtr7bDMJ_Dp9jTfOwfGvohNhc6LsoELJc,514
@@ -401,7 +406,7 @@ omlish/iterators/iterators.py,sha256=iTQQwBE6Wzoy36dnbPIws17zbjE3zNN4KwVw4Fzh-gY
401
406
  omlish/iterators/recipes.py,sha256=53mkexitMhkwXQZbL6DrhpT0WePQ_56uXd5Jaw3DfzI,467
402
407
  omlish/iterators/tools.py,sha256=Pi4ybXytUXVZ3xwK89xpPImQfYYId9p1vIFQvVqVLqA,2551
403
408
  omlish/iterators/unique.py,sha256=0jAX3kwzVfRNhe0Tmh7kVP_Q2WBIn8POo_O-rgFV0rQ,1390
404
- omlish/lang/__init__.py,sha256=TKxKq0L7Q34kdV0_UcxC81Umx64Uz_TPUgH6cy7Uzck,4892
409
+ omlish/lang/__init__.py,sha256=oscoxTO7_oMaTcLxOX_NvHfWsfmQ28G6UcWeqXR0d90,5035
405
410
  omlish/lang/attrs.py,sha256=fofCKN0X8TMu1yGqHpLpNLih9r9HWl3D3Vn3b6O791w,3891
406
411
  omlish/lang/clsdct.py,sha256=sJYadm-fwzti-gsi98knR5qQUxriBmOqQE_qz3RopNk,1743
407
412
  omlish/lang/cmp.py,sha256=5vbzWWbqdzDmNKAGL19z6ZfUKe5Ci49e-Oegf9f4BsE,1346
@@ -416,6 +421,7 @@ omlish/lang/imports.py,sha256=Gdl6xCF89xiMOE1yDmdvKWamLq8HX-XPianO58Jdpmw,9218
416
421
  omlish/lang/iterables.py,sha256=HOjcxOwyI5bBApDLsxRAGGhTTmw7fdZl2kEckxRVl-0,1994
417
422
  omlish/lang/maybes.py,sha256=dAgrUoAhCgyrHRqa73CkaGnpXwGc-o9n-NIThrNXnbU,3416
418
423
  omlish/lang/objects.py,sha256=ih3z47DysrW11Vf3vF8rdALsnhK19Afp6wTU8AHAPWM,4982
424
+ omlish/lang/outcomes.py,sha256=yuNstlFj36gN9s_wcigcSXn7F08a2XTmwmNMgzGeMjM,8432
419
425
  omlish/lang/params.py,sha256=QmNVBfJsfxjDG5ilDPgHV7sK4UwRztkSQdLTo0umb8I,6648
420
426
  omlish/lang/resolving.py,sha256=OuN2mDTPNyBUbcrswtvFKtj4xgH4H4WglgqSKv3MTy0,1606
421
427
  omlish/lang/resources.py,sha256=WKkAddC3ctMK1bvGw-elGe8ZxAj2IaUTKVSu2nfgHTo,2839
@@ -532,7 +538,7 @@ omlish/os/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
532
538
  omlish/os/atomics.py,sha256=KhWNeh4mzU3M-TF0v8uR6hUqMfZJW42MeyIK9Jl6R0k,5246
533
539
  omlish/os/deathsig.py,sha256=hk9Yq2kyDdI-cI7OQH7mOfpRbOKzY_TfPKEqgrjVYbA,641
534
540
  omlish/os/fcntl.py,sha256=riQf9iEEEIC28lJp8ud06MU56w2XJHJ9nBFtck_hdhc,1501
535
- omlish/os/filemodes.py,sha256=eVT60kokup40-N31r2acHJ2ip3d9HmqY8jCGIsKpKqc,4576
541
+ omlish/os/filemodes.py,sha256=ZIk6XpPw2oyoytSsuVmBXQ6fvMDHzctNEDIA2uHTBC4,4575
536
542
  omlish/os/files.py,sha256=WJ_42vsZIZukQURN3TTccp-n74ZNhbux_ps3TLbHj18,1106
537
543
  omlish/os/forkhooks.py,sha256=yjodOvs90ClXskv5oBIJbHn0Y7dzajLmZmOpRMKbyxM,5656
538
544
  omlish/os/journald.py,sha256=2nI8Res1poXkbLc31--MPUlzYMESnCcPUkIxDOCjZW0,3903
@@ -612,10 +618,10 @@ omlish/specs/jmespath/lexer.py,sha256=hlPGCXPzGhd9ySj-z2cGTbyC9z3e0Io78IMYJZSEwN
612
618
  omlish/specs/jmespath/parser.py,sha256=IPJ0fCv1Aj2MhsDx5XuddtM2LnnLrynuGs4g7PYCmf0,24453
613
619
  omlish/specs/jmespath/scope.py,sha256=UyDsl9rv_c8DCjJBuVIA2ESu1jrgYvuwEKiaJDQKnT0,1590
614
620
  omlish/specs/jmespath/visitor.py,sha256=yneRMO4qf3k2Mdcm2cPC0ozRgOaudzlxRVRGatztJzs,16569
615
- omlish/specs/jsonrpc/__init__.py,sha256=E0EogYSKmbj1D-V57tBgPDTyVuD8HosHqVg0Vh1CVwM,416
621
+ omlish/specs/jsonrpc/__init__.py,sha256=QQwr-jkgvwr1ZMlNwl5W1TuHcxx8RuzQVFwWwNhp5sM,515
616
622
  omlish/specs/jsonrpc/errors.py,sha256=-Zgmlo6bV6J8w5f8h9axQgLquIFBHDgIwcpufEH5NsE,707
617
623
  omlish/specs/jsonrpc/marshal.py,sha256=hM1rPZddoha_87qcQtBWkyaZshCXlPoHPJg6J_nBi9k,1915
618
- omlish/specs/jsonrpc/types.py,sha256=50aARffC_FdxAaRxEJMNhydygj9sP8L3Kb2fx5vQGm4,2164
624
+ omlish/specs/jsonrpc/types.py,sha256=Hf6GQHJhqdSUXE0kWw67HhSH_Fu2fuOeS-MYTgEbXwA,2753
619
625
  omlish/specs/jsonschema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
620
626
  omlish/specs/jsonschema/types.py,sha256=qoxExgKfrI-UZXdk3qcVZIEyp1WckFbb85_eGInEoAY,467
621
627
  omlish/specs/jsonschema/keywords/__init__.py,sha256=kZNJCujSpflCOrPNeJT8C1a5sfStn6cwiXXzbu9YPyg,753
@@ -670,7 +676,7 @@ omlish/sql/api/errors.py,sha256=YtC2gz5DqRTT3uCJniUOufVH1GEnFIc5ElkYLK3BHwM,230
670
676
  omlish/sql/api/funcs.py,sha256=-H6V-o9JPSHFXsxdHtutB4mP2LwJfCzlLbRrPHunmB4,990
671
677
  omlish/sql/api/queries.py,sha256=IgB8_sDe40-mKE-ByTmZ4GVOCdLLJDzJGJCevMd8R5s,1207
672
678
  omlish/sql/api/rows.py,sha256=MEK9LNYEe8vLEJXQJD63MpnSOiE22cawJL-dUWQD6sU,1246
673
- omlish/sql/parsing/Minisql.g4,sha256=DlriPFcnGT4QYG7O7VH2EmDVJQZq5zewoQ-tpXsSbIY,4748
679
+ omlish/sql/parsing/Minisql.g4,sha256=Jw8xT-8UI6ySHAgStyCg5QX9NTCinvTenLJReWiZIJU,4578
674
680
  omlish/sql/parsing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
675
681
  omlish/sql/parsing/parsing.py,sha256=hYIZdEKik4q22aEHHOX6lCpMa1jvgUk2aC1Llx10NMI,3343
676
682
  omlish/sql/parsing/_antlr/MinisqlLexer.py,sha256=f4WzRrwqM7tW6sNn01035hRWPZL7xtuvba9EMR06j2E,17611
@@ -736,7 +742,7 @@ omlish/testing/pytest/plugins/switches.py,sha256=U8tDP-WSI2yjxwp4hocgZNJEmEv8UO8
736
742
  omlish/testing/pytest/plugins/utils.py,sha256=L5C622UXcA_AUKDcvyh5IMiRfqSGGz0McdhwZWvfMlU,261
737
743
  omlish/testing/pytest/plugins/asyncs/__init__.py,sha256=TTNhFmP_krug1973sq_bpWBTIvg68-1nbuVLSs92Z6k,41
738
744
  omlish/testing/pytest/plugins/asyncs/consts.py,sha256=0NOCkzV43dOu3u97BqYMQ4mPG8JuFncpWibkOZpCqX4,55
739
- omlish/testing/pytest/plugins/asyncs/fixtures.py,sha256=HyhtZLq5Qai7pS9Z4Ejl0f0NyVtDjJJL9fhbUKVUx2M,11299
745
+ omlish/testing/pytest/plugins/asyncs/fixtures.py,sha256=O0gT4jVH-4t1WYpY2j51QgsbdK8LKt4R9hOxnf74eTg,11264
740
746
  omlish/testing/pytest/plugins/asyncs/plugin.py,sha256=-gVLHZb78nEfMOnmWKY0gdT3BOHjY3bp-GnBGshOvPo,6021
741
747
  omlish/testing/pytest/plugins/asyncs/utils.py,sha256=K-nQxSJQL-3N_xtLqfCX11KSLYCG_gPQ6hZqLQZIHNQ,294
742
748
  omlish/testing/pytest/plugins/asyncs/backends/__init__.py,sha256=DpJGt5KA2N2pNXy59raVyJH1969M1AP80pJAqIlNEAs,359
@@ -754,11 +760,13 @@ omlish/text/indent.py,sha256=YjtJEBYWuk8--b9JU_T6q4yxV85_TR7VEVr5ViRCFwk,1336
754
760
  omlish/text/linecache.py,sha256=hRYlEhD63ZfA6_ZOTkQIcnON-3W56QMAhcG3vEJqj9M,1858
755
761
  omlish/text/mangle.py,sha256=kfzFLfvepH-chl1P89_mdc5vC4FSqyPA2aVtgzuB8IY,1133
756
762
  omlish/text/minja.py,sha256=jZC-fp3Xuhx48ppqsf2Sf1pHbC0t8XBB7UpUUoOk2Qw,5751
757
- omlish/text/parts.py,sha256=JkNZpyR2tv2CNcTaWJJhpQ9E4F0yPR8P_YfDbZfMtwQ,6182
763
+ omlish/text/parts.py,sha256=Q9NvoyEGQKIWgiPD4D_Qc66cWAuyEKE033dT9m7c3Wk,6662
758
764
  omlish/text/random.py,sha256=jNWpqiaKjKyTdMXC-pWAsSC10AAP-cmRRPVhm59ZWLk,194
759
- omlish-0.0.0.dev254.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
760
- omlish-0.0.0.dev254.dist-info/METADATA,sha256=-Mvy0_hjjJoMNilZrvKn9X-FWgQvLcItEjlbdvLO2vE,4176
761
- omlish-0.0.0.dev254.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
762
- omlish-0.0.0.dev254.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
763
- omlish-0.0.0.dev254.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
764
- omlish-0.0.0.dev254.dist-info/RECORD,,
765
+ omlish/text/go/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
766
+ omlish/text/go/quoting.py,sha256=N9EYdnFdEX_A8fOviH-1w4jwV3XOQ7VU2WsoUNubYVY,9137
767
+ omlish-0.0.0.dev256.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
768
+ omlish-0.0.0.dev256.dist-info/METADATA,sha256=zL7YX2rpkMFfh9x-gH60SU4EE1a0EuKuaT4Nn97JIjA,4176
769
+ omlish-0.0.0.dev256.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
770
+ omlish-0.0.0.dev256.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
771
+ omlish-0.0.0.dev256.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
772
+ omlish-0.0.0.dev256.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (76.0.0)
2
+ Generator: setuptools (76.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
omlish/asyncs/anyio.py DELETED
@@ -1,273 +0,0 @@
1
- """
2
- TODO:
3
- - bane
4
- - owned lock
5
- - async once
6
-
7
- See:
8
- - https://github.com/davidbrochart/sqlite-anyio/blob/a3ba4c6ef0535b14a5a60071fcd6ed565a514963/sqlite_anyio/sqlite.py
9
- - https://github.com/rafalkrupinski/ratelimit-anyio/blob/2910a8a3d6fa54ed17ee6ba457686c9f7a4c4beb/src/ratelimit_anyio/__init__.py
10
- - https://github.com/nekitdev/async-extensions/tree/main/async_extensions
11
- - https://github.com/kinnay/anynet/tree/master/anynet
12
- - https://github.com/M-o-a-T/asyncscope
13
- - https://github.com/M-o-a-T/aevent
14
- - https://github.com/florimondmanca/aiometer
15
- - https://github.com/sanitizers/octomachinery/blob/b36c3d3d49da813ac46e361424132955a4e99ac8/octomachinery/utils/asynctools.py
16
-
17
- ==
18
-
19
- async def killer(shutdown: anyio.Event, sleep_s: float) -> None:
20
- log.warning('Killing in %d seconds', sleep_s)
21
- await anyio.sleep(sleep_s)
22
- log.warning('Killing')
23
- shutdown.set()
24
-
25
- """ # noqa
26
- import dataclasses as dc
27
- import signal
28
- import typing as ta
29
-
30
- import anyio.abc
31
- import anyio.streams.memory
32
- import anyio.streams.stapled
33
- import sniffio
34
-
35
- from .. import check
36
- from .. import lang
37
-
38
-
39
- T = ta.TypeVar('T')
40
-
41
- MemoryObjectReceiveStream: ta.TypeAlias = anyio.streams.memory.MemoryObjectReceiveStream
42
- MemoryObjectSendStream: ta.TypeAlias = anyio.streams.memory.MemoryObjectSendStream
43
-
44
- StapledByteStream: ta.TypeAlias = anyio.streams.stapled.StapledByteStream
45
- StapledObjectStream: ta.TypeAlias = anyio.streams.stapled.StapledObjectStream
46
-
47
-
48
- @dc.dataclass(eq=False)
49
- class MemoryStapledObjectStream(StapledObjectStream[T]):
50
- send_stream: MemoryObjectSendStream[T]
51
- receive_stream: MemoryObjectReceiveStream[T]
52
-
53
-
54
- ##
55
-
56
-
57
- async def anyio_eof_to_empty(fn: ta.Callable[..., ta.Awaitable[T]], *args: ta.Any, **kwargs: ta.Any) -> T | bytes:
58
- try:
59
- return await fn(*args, **kwargs)
60
- except anyio.EndOfStream:
61
- return b''
62
-
63
-
64
- async def gather(*fns: ta.Callable[..., ta.Awaitable[T]], take_first: bool = False) -> list[lang.Maybe[T]]:
65
- results: list[lang.Maybe[T]] = [lang.empty()] * len(fns)
66
-
67
- async def inner(fn, i):
68
- results[i] = lang.just(await fn())
69
- if take_first:
70
- tg.cancel_scope.cancel()
71
-
72
- async with anyio.create_task_group() as tg:
73
- for i, fn in enumerate(fns):
74
- tg.start_soon(inner, fn, i)
75
-
76
- return results
77
-
78
-
79
- async def first(*fns: ta.Callable[..., ta.Awaitable[T]], **kwargs: ta.Any) -> list[lang.Maybe[T]]:
80
- return await gather(*fns, take_first=True, **kwargs)
81
-
82
-
83
- ##
84
-
85
-
86
- def get_current_task() -> anyio.TaskInfo | None:
87
- try:
88
- return anyio.get_current_task()
89
- except sniffio.AsyncLibraryNotFoundError:
90
- return None
91
-
92
-
93
- #
94
-
95
-
96
- BackendTask: ta.TypeAlias = ta.Union[ # noqa
97
- # asyncio.tasks.Task,
98
- # trio.lowlevel.Task,
99
- ta.Any,
100
- ]
101
-
102
-
103
- def _is_class_named(obj: ta.Any, m: str, n: str) -> bool:
104
- cls = obj.__class__
105
- return cls.__module__ == m and cls.__name__ == n
106
-
107
-
108
- def get_backend_task(at: anyio.TaskInfo) -> BackendTask | None:
109
- if _is_class_named(at, 'anyio._backends._asyncio', 'AsyncIOTaskInfo'):
110
- # https://github.com/agronholm/anyio/blob/8907964926a24461840eee0925d3f355e729f15d/src/anyio/_backends/_asyncio.py#L1846 # noqa
111
- # weakref.ref
112
- obj = at._task() # type: ignore # noqa
113
- if obj is not None and not (
114
- _is_class_named(obj, '_asyncio', 'Task') or
115
- _is_class_named(obj, 'asyncio.tasks', 'Task')
116
- ):
117
- raise TypeError(obj)
118
- return obj
119
-
120
- elif _is_class_named(at, 'anyio._backends._trio', 'TrioTaskInfo'):
121
- # https://github.com/agronholm/anyio/blob/8907964926a24461840eee0925d3f355e729f15d/src/anyio/_backends/_trio.py#L850 # noqa
122
- # weakref.proxy
123
- # https://stackoverflow.com/a/62144308 :|
124
- obj = at._task.__repr__.__self__ # type: ignore # noqa
125
- if obj is not None and not _is_class_named(obj, 'trio.lowlevel', 'Task'):
126
- raise TypeError(obj)
127
- return obj
128
-
129
- else:
130
- raise TypeError(at)
131
-
132
-
133
- def get_current_backend_task() -> BackendTask | None:
134
- if (at := get_current_task()) is not None:
135
- return get_backend_task(at)
136
- else:
137
- return None
138
-
139
-
140
- ##
141
-
142
-
143
- def split_memory_object_streams(
144
- *args: anyio.create_memory_object_stream[T],
145
- ) -> tuple[
146
- MemoryObjectSendStream[T],
147
- MemoryObjectReceiveStream[T],
148
- ]:
149
- [tup] = args
150
- return tup
151
-
152
-
153
- def create_stapled_memory_object_stream(max_buffer_size: float = 0) -> MemoryStapledObjectStream:
154
- return MemoryStapledObjectStream(*anyio.create_memory_object_stream(max_buffer_size))
155
-
156
-
157
- # FIXME: https://github.com/python/mypy/issues/15238
158
- # FIXME: https://youtrack.jetbrains.com/issues?q=tag:%20%7BPEP%20695%7D
159
- def create_memory_object_stream[T](max_buffer_size: float = 0) -> tuple[
160
- MemoryObjectSendStream[T],
161
- MemoryObjectReceiveStream[T],
162
- ]:
163
- return anyio.create_memory_object_stream[T](max_buffer_size) # noqa
164
-
165
-
166
- def staple_memory_object_stream(
167
- *args: anyio.create_memory_object_stream[T],
168
- ) -> MemoryStapledObjectStream[T]:
169
- send, receive = args
170
- return MemoryStapledObjectStream(
171
- check.isinstance(send, MemoryObjectSendStream), # type: ignore
172
- check.isinstance(receive, MemoryObjectReceiveStream), # type: ignore
173
- )
174
-
175
-
176
- # FIXME: https://github.com/python/mypy/issues/15238
177
- # FIXME: https://youtrack.jetbrains.com/issues?q=tag:%20%7BPEP%20695%7D
178
- def staple_memory_object_stream2[T](max_buffer_size: float = 0) -> MemoryStapledObjectStream[T]:
179
- send, receive = anyio.create_memory_object_stream[T](max_buffer_size)
180
- return MemoryStapledObjectStream(
181
- check.isinstance(send, MemoryObjectSendStream), # type: ignore
182
- check.isinstance(receive, MemoryObjectReceiveStream), # type: ignore
183
- )
184
-
185
-
186
- ##
187
-
188
-
189
- class Once:
190
- def __init__(self) -> None:
191
- super().__init__()
192
- self._done = False
193
- self._lock = anyio.Lock()
194
-
195
- async def do(self, fn: ta.Callable[[], ta.Awaitable[None]]) -> bool:
196
- if self._done:
197
- return False
198
- async with self._lock:
199
- if self._done:
200
- return False # type: ignore
201
- try:
202
- await fn()
203
- finally:
204
- self._done = True
205
- return True
206
-
207
-
208
- class Lazy(ta.Generic[T]):
209
- def __init__(self) -> None:
210
- super().__init__()
211
- self._once = Once()
212
- self._v: lang.Maybe[T] = lang.empty()
213
-
214
- def peek(self) -> lang.Maybe[T]:
215
- return self._v
216
-
217
- def set(self, v: T) -> None:
218
- self._v = lang.just(v)
219
-
220
- async def get(self, fn: ta.Callable[[], ta.Awaitable[T]]) -> T:
221
- async def do():
222
- self._v = lang.just(await fn())
223
- await self._once.do(do)
224
- return self._v.must()
225
-
226
-
227
- class LazyFn(ta.Generic[T]):
228
- def __init__(self, fn: ta.Callable[[], ta.Awaitable[T]]) -> None:
229
- super().__init__()
230
- self._fn = fn
231
- self._once = Once()
232
- self._v: lang.Maybe[T] = lang.empty()
233
-
234
- def peek(self) -> lang.Maybe[T]:
235
- return self._v
236
-
237
- def set(self, v: T) -> None:
238
- self._v = lang.just(v)
239
-
240
- async def get(self) -> T:
241
- async def do():
242
- self._v = lang.just(await self._fn())
243
- await self._once.do(do)
244
- return self._v.must()
245
-
246
-
247
- ##
248
-
249
-
250
- async def install_shutdown_signal_handler(
251
- tg: anyio.abc.TaskGroup,
252
- event: anyio.Event | None = None,
253
- *,
254
- signals: ta.Iterable[int] = (signal.SIGINT, signal.SIGTERM),
255
- echo: bool = False,
256
- ) -> ta.Callable[..., ta.Awaitable[None]] | None:
257
- if event is None:
258
- event = anyio.Event()
259
-
260
- async def _handler(*, task_status=anyio.TASK_STATUS_IGNORED):
261
- with anyio.open_signal_receiver(*signals) as it: # type: ignore
262
- task_status.started()
263
- async for signum in it:
264
- if echo:
265
- if signum == signal.SIGINT:
266
- print('Ctrl+C pressed!')
267
- else:
268
- print('Terminated!')
269
- event.set()
270
- return
271
-
272
- await tg.start(_handler)
273
- return event.wait