ominfra 0.0.0.dev103__py3-none-any.whl → 0.0.0.dev105__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
File without changes
@@ -0,0 +1,48 @@
1
+ import json
2
+ import time
3
+ import typing as ta
4
+
5
+ from omlish import check
6
+ from omlish import http
7
+ from omlish.http import jwt
8
+
9
+
10
+ DEFAULT_JWT_SCOPE = 'https://www.googleapis.com/auth/cloud-platform'
11
+
12
+
13
+ def generate_gcp_jwt(
14
+ creds_dct: ta.Mapping[str, ta.Any],
15
+ *,
16
+ issued_at: int | None = None,
17
+ lifetime_s: int = 3600,
18
+ scope: str = DEFAULT_JWT_SCOPE,
19
+ ) -> str:
20
+ return jwt.generate_jwt(
21
+ issuer=creds_dct['client_email'],
22
+ subject=creds_dct['client_email'],
23
+ audience=creds_dct['token_uri'],
24
+ issued_at=(issued_at := int(issued_at if issued_at is not None else time.time())),
25
+ expires_at=issued_at + lifetime_s,
26
+ scope=scope,
27
+ key=creds_dct['private_key'],
28
+ algorithm='RS256',
29
+ )
30
+
31
+
32
+ def get_gcp_access_token(
33
+ creds_dct: ta.Mapping[str, ta.Any],
34
+ *,
35
+ client: http.HttpClient | None = None,
36
+ ) -> str:
37
+ signed_jwt = generate_gcp_jwt(creds_dct)
38
+ resp = http.request(
39
+ creds_dct['token_uri'],
40
+ 'POST',
41
+ data=jwt.build_get_token_body(signed_jwt).encode('utf-8'),
42
+ headers={
43
+ http.consts.HEADER_CONTENT_TYPE: http.consts.CONTENT_TYPE_FORM_URLENCODED,
44
+ },
45
+ client=client,
46
+ )
47
+ resp_dct = json.loads(check.not_none(resp.data).decode('utf-8'))
48
+ return resp_dct['access_token']
@@ -725,7 +725,10 @@ class UuidObjMarshaler(ObjMarshaler):
725
725
  return uuid.UUID(o)
726
726
 
727
727
 
728
- _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
728
+ ##
729
+
730
+
731
+ _DEFAULT_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
729
732
  **{t: NopObjMarshaler() for t in (type(None),)},
730
733
  **{t: CastObjMarshaler(t) for t in (int, float, str, bool)},
731
734
  **{t: Base64ObjMarshaler(t) for t in (bytes, bytearray)},
@@ -754,20 +757,19 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
754
757
  }
755
758
 
756
759
 
757
- def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
758
- if ty in _OBJ_MARSHALERS:
759
- raise KeyError(ty)
760
- _OBJ_MARSHALERS[ty] = m
761
-
762
-
763
- def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
760
+ def _make_obj_marshaler(
761
+ ty: ta.Any,
762
+ rec: ta.Callable[[ta.Any], ObjMarshaler],
763
+ *,
764
+ nonstrict_dataclasses: bool = False,
765
+ ) -> ObjMarshaler:
764
766
  if isinstance(ty, type):
765
767
  if abc.ABC in ty.__bases__:
766
768
  impls = [ # type: ignore
767
769
  PolymorphicObjMarshaler.Impl(
768
770
  ity,
769
771
  ity.__qualname__,
770
- get_obj_marshaler(ity),
772
+ rec(ity),
771
773
  )
772
774
  for ity in deep_subclasses(ty)
773
775
  if abc.ABC not in ity.__bases__
@@ -783,7 +785,8 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
783
785
  if dc.is_dataclass(ty):
784
786
  return DataclassObjMarshaler(
785
787
  ty,
786
- {f.name: get_obj_marshaler(f.type) for f in dc.fields(ty)},
788
+ {f.name: rec(f.type) for f in dc.fields(ty)},
789
+ nonstrict=nonstrict_dataclasses,
787
790
  )
788
791
 
789
792
  if is_generic_alias(ty):
@@ -793,7 +796,7 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
793
796
  pass
794
797
  else:
795
798
  k, v = ta.get_args(ty)
796
- return MappingObjMarshaler(mt, get_obj_marshaler(k), get_obj_marshaler(v))
799
+ return MappingObjMarshaler(mt, rec(k), rec(v))
797
800
 
798
801
  try:
799
802
  st = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES[ta.get_origin(ty)]
@@ -801,33 +804,71 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
801
804
  pass
802
805
  else:
803
806
  [e] = ta.get_args(ty)
804
- return IterableObjMarshaler(st, get_obj_marshaler(e))
807
+ return IterableObjMarshaler(st, rec(e))
805
808
 
806
809
  if is_union_alias(ty):
807
- return OptionalObjMarshaler(get_obj_marshaler(get_optional_alias_arg(ty)))
810
+ return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
808
811
 
809
812
  raise TypeError(ty)
810
813
 
811
814
 
812
- def get_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
813
- try:
814
- return _OBJ_MARSHALERS[ty]
815
- except KeyError:
816
- pass
815
+ ##
817
816
 
818
- p = ProxyObjMarshaler()
819
- _OBJ_MARSHALERS[ty] = p
820
- try:
821
- m = _make_obj_marshaler(ty)
822
- except Exception:
823
- del _OBJ_MARSHALERS[ty]
824
- raise
825
- else:
826
- p.m = m
817
+
818
+ _OBJ_MARSHALERS_LOCK = threading.RLock()
819
+
820
+ _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
821
+
822
+ _OBJ_MARSHALER_PROXIES: ta.Dict[ta.Any, ProxyObjMarshaler] = {}
823
+
824
+
825
+ def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
826
+ with _OBJ_MARSHALERS_LOCK:
827
+ if ty in _OBJ_MARSHALERS:
828
+ raise KeyError(ty)
827
829
  _OBJ_MARSHALERS[ty] = m
830
+
831
+
832
+ def get_obj_marshaler(
833
+ ty: ta.Any,
834
+ *,
835
+ no_cache: bool = False,
836
+ **kwargs: ta.Any,
837
+ ) -> ObjMarshaler:
838
+ with _OBJ_MARSHALERS_LOCK:
839
+ if not no_cache:
840
+ try:
841
+ return _OBJ_MARSHALERS[ty]
842
+ except KeyError:
843
+ pass
844
+
845
+ try:
846
+ return _OBJ_MARSHALER_PROXIES[ty]
847
+ except KeyError:
848
+ pass
849
+
850
+ rec = functools.partial(
851
+ get_obj_marshaler,
852
+ no_cache=no_cache,
853
+ **kwargs,
854
+ )
855
+
856
+ p = ProxyObjMarshaler()
857
+ _OBJ_MARSHALER_PROXIES[ty] = p
858
+ try:
859
+ m = _make_obj_marshaler(ty, rec, **kwargs)
860
+ finally:
861
+ del _OBJ_MARSHALER_PROXIES[ty]
862
+ p.m = m
863
+
864
+ if not no_cache:
865
+ _OBJ_MARSHALERS[ty] = m
828
866
  return m
829
867
 
830
868
 
869
+ ##
870
+
871
+
831
872
  def marshal_obj(o: ta.Any, ty: ta.Any = None) -> ta.Any:
832
873
  return get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
833
874
 
@@ -808,7 +808,10 @@ class UuidObjMarshaler(ObjMarshaler):
808
808
  return uuid.UUID(o)
809
809
 
810
810
 
811
- _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
811
+ ##
812
+
813
+
814
+ _DEFAULT_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
812
815
  **{t: NopObjMarshaler() for t in (type(None),)},
813
816
  **{t: CastObjMarshaler(t) for t in (int, float, str, bool)},
814
817
  **{t: Base64ObjMarshaler(t) for t in (bytes, bytearray)},
@@ -837,20 +840,19 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
837
840
  }
838
841
 
839
842
 
840
- def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
841
- if ty in _OBJ_MARSHALERS:
842
- raise KeyError(ty)
843
- _OBJ_MARSHALERS[ty] = m
844
-
845
-
846
- def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
843
+ def _make_obj_marshaler(
844
+ ty: ta.Any,
845
+ rec: ta.Callable[[ta.Any], ObjMarshaler],
846
+ *,
847
+ nonstrict_dataclasses: bool = False,
848
+ ) -> ObjMarshaler:
847
849
  if isinstance(ty, type):
848
850
  if abc.ABC in ty.__bases__:
849
851
  impls = [ # type: ignore
850
852
  PolymorphicObjMarshaler.Impl(
851
853
  ity,
852
854
  ity.__qualname__,
853
- get_obj_marshaler(ity),
855
+ rec(ity),
854
856
  )
855
857
  for ity in deep_subclasses(ty)
856
858
  if abc.ABC not in ity.__bases__
@@ -866,7 +868,8 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
866
868
  if dc.is_dataclass(ty):
867
869
  return DataclassObjMarshaler(
868
870
  ty,
869
- {f.name: get_obj_marshaler(f.type) for f in dc.fields(ty)},
871
+ {f.name: rec(f.type) for f in dc.fields(ty)},
872
+ nonstrict=nonstrict_dataclasses,
870
873
  )
871
874
 
872
875
  if is_generic_alias(ty):
@@ -876,7 +879,7 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
876
879
  pass
877
880
  else:
878
881
  k, v = ta.get_args(ty)
879
- return MappingObjMarshaler(mt, get_obj_marshaler(k), get_obj_marshaler(v))
882
+ return MappingObjMarshaler(mt, rec(k), rec(v))
880
883
 
881
884
  try:
882
885
  st = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES[ta.get_origin(ty)]
@@ -884,33 +887,71 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
884
887
  pass
885
888
  else:
886
889
  [e] = ta.get_args(ty)
887
- return IterableObjMarshaler(st, get_obj_marshaler(e))
890
+ return IterableObjMarshaler(st, rec(e))
888
891
 
889
892
  if is_union_alias(ty):
890
- return OptionalObjMarshaler(get_obj_marshaler(get_optional_alias_arg(ty)))
893
+ return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
891
894
 
892
895
  raise TypeError(ty)
893
896
 
894
897
 
895
- def get_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
896
- try:
897
- return _OBJ_MARSHALERS[ty]
898
- except KeyError:
899
- pass
898
+ ##
900
899
 
901
- p = ProxyObjMarshaler()
902
- _OBJ_MARSHALERS[ty] = p
903
- try:
904
- m = _make_obj_marshaler(ty)
905
- except Exception:
906
- del _OBJ_MARSHALERS[ty]
907
- raise
908
- else:
909
- p.m = m
900
+
901
+ _OBJ_MARSHALERS_LOCK = threading.RLock()
902
+
903
+ _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
904
+
905
+ _OBJ_MARSHALER_PROXIES: ta.Dict[ta.Any, ProxyObjMarshaler] = {}
906
+
907
+
908
+ def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
909
+ with _OBJ_MARSHALERS_LOCK:
910
+ if ty in _OBJ_MARSHALERS:
911
+ raise KeyError(ty)
910
912
  _OBJ_MARSHALERS[ty] = m
913
+
914
+
915
+ def get_obj_marshaler(
916
+ ty: ta.Any,
917
+ *,
918
+ no_cache: bool = False,
919
+ **kwargs: ta.Any,
920
+ ) -> ObjMarshaler:
921
+ with _OBJ_MARSHALERS_LOCK:
922
+ if not no_cache:
923
+ try:
924
+ return _OBJ_MARSHALERS[ty]
925
+ except KeyError:
926
+ pass
927
+
928
+ try:
929
+ return _OBJ_MARSHALER_PROXIES[ty]
930
+ except KeyError:
931
+ pass
932
+
933
+ rec = functools.partial(
934
+ get_obj_marshaler,
935
+ no_cache=no_cache,
936
+ **kwargs,
937
+ )
938
+
939
+ p = ProxyObjMarshaler()
940
+ _OBJ_MARSHALER_PROXIES[ty] = p
941
+ try:
942
+ m = _make_obj_marshaler(ty, rec, **kwargs)
943
+ finally:
944
+ del _OBJ_MARSHALER_PROXIES[ty]
945
+ p.m = m
946
+
947
+ if not no_cache:
948
+ _OBJ_MARSHALERS[ty] = m
911
949
  return m
912
950
 
913
951
 
952
+ ##
953
+
954
+
914
955
  def marshal_obj(o: ta.Any, ty: ta.Any = None) -> ta.Any:
915
956
  return get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
916
957
 
@@ -1343,7 +1343,10 @@ class UuidObjMarshaler(ObjMarshaler):
1343
1343
  return uuid.UUID(o)
1344
1344
 
1345
1345
 
1346
- _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
1346
+ ##
1347
+
1348
+
1349
+ _DEFAULT_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
1347
1350
  **{t: NopObjMarshaler() for t in (type(None),)},
1348
1351
  **{t: CastObjMarshaler(t) for t in (int, float, str, bool)},
1349
1352
  **{t: Base64ObjMarshaler(t) for t in (bytes, bytearray)},
@@ -1372,20 +1375,19 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
1372
1375
  }
1373
1376
 
1374
1377
 
1375
- def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
1376
- if ty in _OBJ_MARSHALERS:
1377
- raise KeyError(ty)
1378
- _OBJ_MARSHALERS[ty] = m
1379
-
1380
-
1381
- def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1378
+ def _make_obj_marshaler(
1379
+ ty: ta.Any,
1380
+ rec: ta.Callable[[ta.Any], ObjMarshaler],
1381
+ *,
1382
+ nonstrict_dataclasses: bool = False,
1383
+ ) -> ObjMarshaler:
1382
1384
  if isinstance(ty, type):
1383
1385
  if abc.ABC in ty.__bases__:
1384
1386
  impls = [ # type: ignore
1385
1387
  PolymorphicObjMarshaler.Impl(
1386
1388
  ity,
1387
1389
  ity.__qualname__,
1388
- get_obj_marshaler(ity),
1390
+ rec(ity),
1389
1391
  )
1390
1392
  for ity in deep_subclasses(ty)
1391
1393
  if abc.ABC not in ity.__bases__
@@ -1401,7 +1403,8 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1401
1403
  if dc.is_dataclass(ty):
1402
1404
  return DataclassObjMarshaler(
1403
1405
  ty,
1404
- {f.name: get_obj_marshaler(f.type) for f in dc.fields(ty)},
1406
+ {f.name: rec(f.type) for f in dc.fields(ty)},
1407
+ nonstrict=nonstrict_dataclasses,
1405
1408
  )
1406
1409
 
1407
1410
  if is_generic_alias(ty):
@@ -1411,7 +1414,7 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1411
1414
  pass
1412
1415
  else:
1413
1416
  k, v = ta.get_args(ty)
1414
- return MappingObjMarshaler(mt, get_obj_marshaler(k), get_obj_marshaler(v))
1417
+ return MappingObjMarshaler(mt, rec(k), rec(v))
1415
1418
 
1416
1419
  try:
1417
1420
  st = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES[ta.get_origin(ty)]
@@ -1419,33 +1422,71 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1419
1422
  pass
1420
1423
  else:
1421
1424
  [e] = ta.get_args(ty)
1422
- return IterableObjMarshaler(st, get_obj_marshaler(e))
1425
+ return IterableObjMarshaler(st, rec(e))
1423
1426
 
1424
1427
  if is_union_alias(ty):
1425
- return OptionalObjMarshaler(get_obj_marshaler(get_optional_alias_arg(ty)))
1428
+ return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
1426
1429
 
1427
1430
  raise TypeError(ty)
1428
1431
 
1429
1432
 
1430
- def get_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1431
- try:
1432
- return _OBJ_MARSHALERS[ty]
1433
- except KeyError:
1434
- pass
1433
+ ##
1435
1434
 
1436
- p = ProxyObjMarshaler()
1437
- _OBJ_MARSHALERS[ty] = p
1438
- try:
1439
- m = _make_obj_marshaler(ty)
1440
- except Exception:
1441
- del _OBJ_MARSHALERS[ty]
1442
- raise
1443
- else:
1444
- p.m = m
1435
+
1436
+ _OBJ_MARSHALERS_LOCK = threading.RLock()
1437
+
1438
+ _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
1439
+
1440
+ _OBJ_MARSHALER_PROXIES: ta.Dict[ta.Any, ProxyObjMarshaler] = {}
1441
+
1442
+
1443
+ def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
1444
+ with _OBJ_MARSHALERS_LOCK:
1445
+ if ty in _OBJ_MARSHALERS:
1446
+ raise KeyError(ty)
1445
1447
  _OBJ_MARSHALERS[ty] = m
1448
+
1449
+
1450
+ def get_obj_marshaler(
1451
+ ty: ta.Any,
1452
+ *,
1453
+ no_cache: bool = False,
1454
+ **kwargs: ta.Any,
1455
+ ) -> ObjMarshaler:
1456
+ with _OBJ_MARSHALERS_LOCK:
1457
+ if not no_cache:
1458
+ try:
1459
+ return _OBJ_MARSHALERS[ty]
1460
+ except KeyError:
1461
+ pass
1462
+
1463
+ try:
1464
+ return _OBJ_MARSHALER_PROXIES[ty]
1465
+ except KeyError:
1466
+ pass
1467
+
1468
+ rec = functools.partial(
1469
+ get_obj_marshaler,
1470
+ no_cache=no_cache,
1471
+ **kwargs,
1472
+ )
1473
+
1474
+ p = ProxyObjMarshaler()
1475
+ _OBJ_MARSHALER_PROXIES[ty] = p
1476
+ try:
1477
+ m = _make_obj_marshaler(ty, rec, **kwargs)
1478
+ finally:
1479
+ del _OBJ_MARSHALER_PROXIES[ty]
1480
+ p.m = m
1481
+
1482
+ if not no_cache:
1483
+ _OBJ_MARSHALERS[ty] = m
1446
1484
  return m
1447
1485
 
1448
1486
 
1487
+ ##
1488
+
1489
+
1449
1490
  def marshal_obj(o: ta.Any, ty: ta.Any = None) -> ta.Any:
1450
1491
  return get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
1451
1492
 
@@ -1470,7 +1470,10 @@ class UuidObjMarshaler(ObjMarshaler):
1470
1470
  return uuid.UUID(o)
1471
1471
 
1472
1472
 
1473
- _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
1473
+ ##
1474
+
1475
+
1476
+ _DEFAULT_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
1474
1477
  **{t: NopObjMarshaler() for t in (type(None),)},
1475
1478
  **{t: CastObjMarshaler(t) for t in (int, float, str, bool)},
1476
1479
  **{t: Base64ObjMarshaler(t) for t in (bytes, bytearray)},
@@ -1499,20 +1502,19 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
1499
1502
  }
1500
1503
 
1501
1504
 
1502
- def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
1503
- if ty in _OBJ_MARSHALERS:
1504
- raise KeyError(ty)
1505
- _OBJ_MARSHALERS[ty] = m
1506
-
1507
-
1508
- def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1505
+ def _make_obj_marshaler(
1506
+ ty: ta.Any,
1507
+ rec: ta.Callable[[ta.Any], ObjMarshaler],
1508
+ *,
1509
+ nonstrict_dataclasses: bool = False,
1510
+ ) -> ObjMarshaler:
1509
1511
  if isinstance(ty, type):
1510
1512
  if abc.ABC in ty.__bases__:
1511
1513
  impls = [ # type: ignore
1512
1514
  PolymorphicObjMarshaler.Impl(
1513
1515
  ity,
1514
1516
  ity.__qualname__,
1515
- get_obj_marshaler(ity),
1517
+ rec(ity),
1516
1518
  )
1517
1519
  for ity in deep_subclasses(ty)
1518
1520
  if abc.ABC not in ity.__bases__
@@ -1528,7 +1530,8 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1528
1530
  if dc.is_dataclass(ty):
1529
1531
  return DataclassObjMarshaler(
1530
1532
  ty,
1531
- {f.name: get_obj_marshaler(f.type) for f in dc.fields(ty)},
1533
+ {f.name: rec(f.type) for f in dc.fields(ty)},
1534
+ nonstrict=nonstrict_dataclasses,
1532
1535
  )
1533
1536
 
1534
1537
  if is_generic_alias(ty):
@@ -1538,7 +1541,7 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1538
1541
  pass
1539
1542
  else:
1540
1543
  k, v = ta.get_args(ty)
1541
- return MappingObjMarshaler(mt, get_obj_marshaler(k), get_obj_marshaler(v))
1544
+ return MappingObjMarshaler(mt, rec(k), rec(v))
1542
1545
 
1543
1546
  try:
1544
1547
  st = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES[ta.get_origin(ty)]
@@ -1546,33 +1549,71 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1546
1549
  pass
1547
1550
  else:
1548
1551
  [e] = ta.get_args(ty)
1549
- return IterableObjMarshaler(st, get_obj_marshaler(e))
1552
+ return IterableObjMarshaler(st, rec(e))
1550
1553
 
1551
1554
  if is_union_alias(ty):
1552
- return OptionalObjMarshaler(get_obj_marshaler(get_optional_alias_arg(ty)))
1555
+ return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
1553
1556
 
1554
1557
  raise TypeError(ty)
1555
1558
 
1556
1559
 
1557
- def get_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
1558
- try:
1559
- return _OBJ_MARSHALERS[ty]
1560
- except KeyError:
1561
- pass
1560
+ ##
1562
1561
 
1563
- p = ProxyObjMarshaler()
1564
- _OBJ_MARSHALERS[ty] = p
1565
- try:
1566
- m = _make_obj_marshaler(ty)
1567
- except Exception:
1568
- del _OBJ_MARSHALERS[ty]
1569
- raise
1570
- else:
1571
- p.m = m
1562
+
1563
+ _OBJ_MARSHALERS_LOCK = threading.RLock()
1564
+
1565
+ _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
1566
+
1567
+ _OBJ_MARSHALER_PROXIES: ta.Dict[ta.Any, ProxyObjMarshaler] = {}
1568
+
1569
+
1570
+ def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
1571
+ with _OBJ_MARSHALERS_LOCK:
1572
+ if ty in _OBJ_MARSHALERS:
1573
+ raise KeyError(ty)
1572
1574
  _OBJ_MARSHALERS[ty] = m
1575
+
1576
+
1577
+ def get_obj_marshaler(
1578
+ ty: ta.Any,
1579
+ *,
1580
+ no_cache: bool = False,
1581
+ **kwargs: ta.Any,
1582
+ ) -> ObjMarshaler:
1583
+ with _OBJ_MARSHALERS_LOCK:
1584
+ if not no_cache:
1585
+ try:
1586
+ return _OBJ_MARSHALERS[ty]
1587
+ except KeyError:
1588
+ pass
1589
+
1590
+ try:
1591
+ return _OBJ_MARSHALER_PROXIES[ty]
1592
+ except KeyError:
1593
+ pass
1594
+
1595
+ rec = functools.partial(
1596
+ get_obj_marshaler,
1597
+ no_cache=no_cache,
1598
+ **kwargs,
1599
+ )
1600
+
1601
+ p = ProxyObjMarshaler()
1602
+ _OBJ_MARSHALER_PROXIES[ty] = p
1603
+ try:
1604
+ m = _make_obj_marshaler(ty, rec, **kwargs)
1605
+ finally:
1606
+ del _OBJ_MARSHALER_PROXIES[ty]
1607
+ p.m = m
1608
+
1609
+ if not no_cache:
1610
+ _OBJ_MARSHALERS[ty] = m
1573
1611
  return m
1574
1612
 
1575
1613
 
1614
+ ##
1615
+
1616
+
1576
1617
  def marshal_obj(o: ta.Any, ty: ta.Any = None) -> ta.Any:
1577
1618
  return get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
1578
1619
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ominfra
3
- Version: 0.0.0.dev103
3
+ Version: 0.0.0.dev105
4
4
  Summary: ominfra
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -12,8 +12,8 @@ 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: omdev ==0.0.0.dev103
16
- Requires-Dist: omlish ==0.0.0.dev103
15
+ Requires-Dist: omdev ==0.0.0.dev105
16
+ Requires-Dist: omlish ==0.0.0.dev105
17
17
  Provides-Extra: all
18
18
  Requires-Dist: paramiko ~=3.5 ; extra == 'all'
19
19
  Requires-Dist: asyncssh ~=2.18 ; extra == 'all'
@@ -17,8 +17,10 @@ ominfra/clouds/aws/journald2aws/cursor.py,sha256=tQ7O6BHlEdaalbiI_Rqagj0aHfdtTQ_
17
17
  ominfra/clouds/aws/journald2aws/driver.py,sha256=8jiuEpOgKFSucpEJBBTBiSVg6L_tA4alUNK-I788HWU,5452
18
18
  ominfra/clouds/aws/journald2aws/main.py,sha256=xFkEhkYKtFfW0XRfY0UaX_gd_FU66WTZOMCyiIaPY3E,2237
19
19
  ominfra/clouds/aws/journald2aws/poster.py,sha256=hz1XuctW8GtLmfjhRvCFY6py52D4BzXHYny5XKFpHSA,2833
20
+ ominfra/clouds/gcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
+ ominfra/clouds/gcp/auth.py,sha256=3PyfRJNgajjMqJFem3SKui0CqGeHEsZlvbRhuxFcZG8,1348
20
22
  ominfra/deploy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
- ominfra/deploy/_executor.py,sha256=w3qpyRtoIfpm9HgygGb4jo1Wx8-Nz8U3CXSuwBcTFl4,33258
23
+ ominfra/deploy/_executor.py,sha256=3_ndcukzPt6Pc-5Cfnxz4OFjOYJefuTYM6ouijRjhTs,34042
22
24
  ominfra/deploy/configs.py,sha256=qi0kwT7G2NH7dXLOQic-u6R3yeadup_QtvrjwWIggbM,435
23
25
  ominfra/deploy/remote.py,sha256=6ACmpXU1uBdyGs3Xsp97ktKFq30cJlzN9LRWNUWlGY4,2144
24
26
  ominfra/deploy/executor/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
@@ -51,12 +53,12 @@ ominfra/journald/tailer.py,sha256=-CTQPkDQUBJJOpQCueFDsF5VmlfPSaSrbrGB505SUuM,36
51
53
  ominfra/manage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
54
  ominfra/manage/manage.py,sha256=BttL8LFEknHZE_h2Pt5dAqbfUkv6qy43WI0raXBZ1a8,151
53
55
  ominfra/pyremote/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
- ominfra/pyremote/_runcommands.py,sha256=xA-wRpLtGha6ZZyatGokL9kyz43GOB_ZB_WLZcd8gFE,27094
56
+ ominfra/pyremote/_runcommands.py,sha256=IGFDDcmXJDmhGv7AFAAjkCJc615YQGUsNvn5vTAYReY,27878
55
57
  ominfra/pyremote/bootstrap.py,sha256=RvMO3YGaN1E4sgUi1JEtiPak8cjvqtc_vRCq1yqbeZg,3370
56
58
  ominfra/pyremote/runcommands.py,sha256=bviS0_TDIoZVAe4h-_iavbvJtVSFu8lnk7fQ5iasCWE,1571
57
59
  ominfra/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
- ominfra/scripts/journald2aws.py,sha256=4DzyNn8KjrBfHNtENgp7EVL569PLqzQnQu6PQXgqPgg,97251
59
- ominfra/scripts/supervisor.py,sha256=2rf7CCgqpYY6Pt7Yq69n4V7CY-Sas_0MyDO3SIv2tPw,115378
60
+ ominfra/scripts/journald2aws.py,sha256=ZI6SppxsDEwnjk0zaBmAmhyi3-3VVbWubDkeGz_DEU8,98035
61
+ ominfra/scripts/supervisor.py,sha256=Qf6WKD_4EkC_5QWimApONAAs3lvcAKK2X7nOaYDex48,116162
60
62
  ominfra/supervisor/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
61
63
  ominfra/supervisor/__main__.py,sha256=usW9jjq5JPe_2SL8H5PrjDdksO75MX85Ir0HFfb35eM,72
62
64
  ominfra/supervisor/compat.py,sha256=Y1d_pk4eN18AbVYjDHAXMMnPwOKTFpc7JDb1uClYMsQ,5064
@@ -76,9 +78,9 @@ ominfra/tailscale/api.py,sha256=C5-t_b6jZXUWcy5k8bXm7CFnk73pSdrlMOgGDeGVrpw,1370
76
78
  ominfra/tailscale/cli.py,sha256=DSGp4hn5xwOW-l_u_InKlSF6kIobxtUtVssf_73STs0,3567
77
79
  ominfra/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
80
  ominfra/tools/listresources.py,sha256=4qVg5txsb10EHhvqXXeM6gJ2jx9LbroEnPydDv1uXs0,6176
79
- ominfra-0.0.0.dev103.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
80
- ominfra-0.0.0.dev103.dist-info/METADATA,sha256=p_SRGaoGDeFXyv_pvHCMjqaDP6umkRhGCsrtly5uJQs,742
81
- ominfra-0.0.0.dev103.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
82
- ominfra-0.0.0.dev103.dist-info/entry_points.txt,sha256=kgecQ2MgGrM9qK744BoKS3tMesaC3yjLnl9pa5CRczg,37
83
- ominfra-0.0.0.dev103.dist-info/top_level.txt,sha256=E-b2OHkk_AOBLXHYZQ2EOFKl-_6uOGd8EjeG-Zy6h_w,8
84
- ominfra-0.0.0.dev103.dist-info/RECORD,,
81
+ ominfra-0.0.0.dev105.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
82
+ ominfra-0.0.0.dev105.dist-info/METADATA,sha256=MJdBtSIcEZd79i2YGFHZTDTZzV_zDtpwRVLNYNcn0cw,742
83
+ ominfra-0.0.0.dev105.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
84
+ ominfra-0.0.0.dev105.dist-info/entry_points.txt,sha256=kgecQ2MgGrM9qK744BoKS3tMesaC3yjLnl9pa5CRczg,37
85
+ ominfra-0.0.0.dev105.dist-info/top_level.txt,sha256=E-b2OHkk_AOBLXHYZQ2EOFKl-_6uOGd8EjeG-Zy6h_w,8
86
+ ominfra-0.0.0.dev105.dist-info/RECORD,,