ominfra 0.0.0.dev102__py3-none-any.whl → 0.0.0.dev104__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.
@@ -41,7 +41,7 @@ if sys.version_info < (3, 8):
41
41
  ########################################
42
42
 
43
43
 
44
- # ../../../omlish/lite/check.py
44
+ # ../../../omlish/lite/cached.py
45
45
  T = ta.TypeVar('T')
46
46
 
47
47
 
@@ -195,7 +195,7 @@ def post_boostrap() -> PostBoostrap:
195
195
  # ../../../omlish/lite/cached.py
196
196
 
197
197
 
198
- class cached_nullary: # noqa
198
+ class _cached_nullary: # noqa
199
199
  def __init__(self, fn):
200
200
  super().__init__()
201
201
  self._fn = fn
@@ -212,6 +212,10 @@ class cached_nullary: # noqa
212
212
  return bound
213
213
 
214
214
 
215
+ def cached_nullary(fn: ta.Callable[..., T]) -> ta.Callable[..., T]:
216
+ return _cached_nullary(fn)
217
+
218
+
215
219
  ########################################
216
220
  # ../../../omlish/lite/check.py
217
221
 
@@ -744,7 +748,7 @@ class DataclassObjMarshaler(ObjMarshaler):
744
748
  return {k: m.marshal(getattr(o, k)) for k, m in self.fs.items()}
745
749
 
746
750
  def unmarshal(self, o: ta.Any) -> ta.Any:
747
- return self.ty(**{k: self.fs[k].unmarshal(v) for k, v in o.items() if self.nonstrict or k in self.fs})
751
+ return self.ty(**{k: self.fs[k].unmarshal(v) for k, v in o.items() if not self.nonstrict or k in self.fs})
748
752
 
749
753
 
750
754
  @dc.dataclass(frozen=True)
@@ -804,7 +808,10 @@ class UuidObjMarshaler(ObjMarshaler):
804
808
  return uuid.UUID(o)
805
809
 
806
810
 
807
- _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
811
+ ##
812
+
813
+
814
+ _DEFAULT_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
808
815
  **{t: NopObjMarshaler() for t in (type(None),)},
809
816
  **{t: CastObjMarshaler(t) for t in (int, float, str, bool)},
810
817
  **{t: Base64ObjMarshaler(t) for t in (bytes, bytearray)},
@@ -833,20 +840,19 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
833
840
  }
834
841
 
835
842
 
836
- def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
837
- if ty in _OBJ_MARSHALERS:
838
- raise KeyError(ty)
839
- _OBJ_MARSHALERS[ty] = m
840
-
841
-
842
- 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:
843
849
  if isinstance(ty, type):
844
850
  if abc.ABC in ty.__bases__:
845
851
  impls = [ # type: ignore
846
852
  PolymorphicObjMarshaler.Impl(
847
853
  ity,
848
854
  ity.__qualname__,
849
- get_obj_marshaler(ity),
855
+ rec(ity),
850
856
  )
851
857
  for ity in deep_subclasses(ty)
852
858
  if abc.ABC not in ity.__bases__
@@ -862,7 +868,8 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
862
868
  if dc.is_dataclass(ty):
863
869
  return DataclassObjMarshaler(
864
870
  ty,
865
- {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,
866
873
  )
867
874
 
868
875
  if is_generic_alias(ty):
@@ -872,7 +879,7 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
872
879
  pass
873
880
  else:
874
881
  k, v = ta.get_args(ty)
875
- return MappingObjMarshaler(mt, get_obj_marshaler(k), get_obj_marshaler(v))
882
+ return MappingObjMarshaler(mt, rec(k), rec(v))
876
883
 
877
884
  try:
878
885
  st = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES[ta.get_origin(ty)]
@@ -880,33 +887,71 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
880
887
  pass
881
888
  else:
882
889
  [e] = ta.get_args(ty)
883
- return IterableObjMarshaler(st, get_obj_marshaler(e))
890
+ return IterableObjMarshaler(st, rec(e))
884
891
 
885
892
  if is_union_alias(ty):
886
- return OptionalObjMarshaler(get_obj_marshaler(get_optional_alias_arg(ty)))
893
+ return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
887
894
 
888
895
  raise TypeError(ty)
889
896
 
890
897
 
891
- def get_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
892
- try:
893
- return _OBJ_MARSHALERS[ty]
894
- except KeyError:
895
- pass
898
+ ##
896
899
 
897
- p = ProxyObjMarshaler()
898
- _OBJ_MARSHALERS[ty] = p
899
- try:
900
- m = _make_obj_marshaler(ty)
901
- except Exception:
902
- del _OBJ_MARSHALERS[ty]
903
- raise
904
- else:
905
- 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)
906
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
907
949
  return m
908
950
 
909
951
 
952
+ ##
953
+
954
+
910
955
  def marshal_obj(o: ta.Any, ty: ta.Any = None) -> ta.Any:
911
956
  return get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
912
957
 
@@ -1039,6 +1084,24 @@ def subprocess_try_output_str(*args: str, **kwargs: ta.Any) -> ta.Optional[str]:
1039
1084
  return out.decode().strip() if out is not None else None
1040
1085
 
1041
1086
 
1087
+ ##
1088
+
1089
+
1090
+ def subprocess_close(
1091
+ proc: subprocess.Popen,
1092
+ timeout: ta.Optional[float] = None,
1093
+ ) -> None:
1094
+ # TODO: terminate, sleep, kill
1095
+ if proc.stdout:
1096
+ proc.stdout.close()
1097
+ if proc.stderr:
1098
+ proc.stderr.close()
1099
+ if proc.stdin:
1100
+ proc.stdin.close()
1101
+
1102
+ proc.wait(timeout)
1103
+
1104
+
1042
1105
  ########################################
1043
1106
  # runcommands.py
1044
1107