ominfra 0.0.0.dev103__py3-none-any.whl → 0.0.0.dev105__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.
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,,