ominfra 0.0.0.dev420__py3-none-any.whl → 0.0.0.dev421__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.
- ominfra/clouds/aws/models/base.py +1 -2
- ominfra/clouds/aws/models/services/ec2.py +45 -0
- ominfra/clouds/aws/models/services/rds.py +10 -0
- ominfra/manage/commands/base.py +5 -4
- ominfra/manage/deploy/conf/specs.py +2 -2
- ominfra/manage/deploy/paths/owners.py +3 -2
- ominfra/manage/deploy/paths/paths.py +4 -3
- ominfra/manage/deploy/tags.py +8 -8
- ominfra/manage/inject.py +2 -1
- ominfra/manage/remote/channel.py +2 -1
- ominfra/manage/remote/execution.py +4 -4
- ominfra/manage/remote/spawning.py +2 -1
- ominfra/manage/system/packages.py +2 -1
- ominfra/manage/system/platforms.py +3 -3
- ominfra/manage/targets/connection.py +2 -1
- ominfra/manage/targets/targets.py +5 -5
- ominfra/scripts/journald2aws.py +436 -133
- ominfra/scripts/manage.py +2957 -2655
- ominfra/scripts/supervisor.py +2806 -2468
- ominfra/supervisor/dispatchers.py +3 -0
- ominfra/supervisor/dispatchersimpl.py +5 -2
- ominfra/supervisor/events.py +6 -6
- ominfra/supervisor/groups.py +3 -0
- ominfra/supervisor/groupsimpl.py +3 -0
- ominfra/supervisor/inject.py +3 -0
- ominfra/supervisor/pipes.py +3 -0
- ominfra/supervisor/privileges.py +3 -0
- ominfra/supervisor/setup.py +4 -2
- ominfra/supervisor/signals.py +3 -0
- ominfra/supervisor/spawning.py +3 -0
- ominfra/supervisor/types.py +9 -8
- ominfra/supervisor/utils/collections.py +7 -2
- ominfra/supervisor/utils/diag.py +3 -0
- ominfra/supervisor/utils/fds.py +3 -0
- ominfra/supervisor/utils/fs.py +3 -0
- ominfra/threadworkers.py +2 -1
- {ominfra-0.0.0.dev420.dist-info → ominfra-0.0.0.dev421.dist-info}/METADATA +3 -3
- {ominfra-0.0.0.dev420.dist-info → ominfra-0.0.0.dev421.dist-info}/RECORD +42 -42
- {ominfra-0.0.0.dev420.dist-info → ominfra-0.0.0.dev421.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev420.dist-info → ominfra-0.0.0.dev421.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev420.dist-info → ominfra-0.0.0.dev421.dist-info}/licenses/LICENSE +0 -0
- {ominfra-0.0.0.dev420.dist-info → ominfra-0.0.0.dev421.dist-info}/top_level.txt +0 -0
ominfra/scripts/journald2aws.py
CHANGED
@@ -1184,6 +1184,126 @@ class TomlWriter:
|
|
1184
1184
|
return out.getvalue()
|
1185
1185
|
|
1186
1186
|
|
1187
|
+
########################################
|
1188
|
+
# ../../../../../omlish/lite/abstract.py
|
1189
|
+
|
1190
|
+
|
1191
|
+
##
|
1192
|
+
|
1193
|
+
|
1194
|
+
_ABSTRACT_METHODS_ATTR = '__abstractmethods__'
|
1195
|
+
_IS_ABSTRACT_METHOD_ATTR = '__isabstractmethod__'
|
1196
|
+
|
1197
|
+
|
1198
|
+
def is_abstract_method(obj: ta.Any) -> bool:
|
1199
|
+
return bool(getattr(obj, _IS_ABSTRACT_METHOD_ATTR, False))
|
1200
|
+
|
1201
|
+
|
1202
|
+
def update_abstracts(cls, *, force=False):
|
1203
|
+
if not force and not hasattr(cls, _ABSTRACT_METHODS_ATTR):
|
1204
|
+
# Per stdlib: We check for __abstractmethods__ here because cls might by a C implementation or a python
|
1205
|
+
# implementation (especially during testing), and we want to handle both cases.
|
1206
|
+
return cls
|
1207
|
+
|
1208
|
+
abstracts: ta.Set[str] = set()
|
1209
|
+
|
1210
|
+
for scls in cls.__bases__:
|
1211
|
+
for name in getattr(scls, _ABSTRACT_METHODS_ATTR, ()):
|
1212
|
+
value = getattr(cls, name, None)
|
1213
|
+
if getattr(value, _IS_ABSTRACT_METHOD_ATTR, False):
|
1214
|
+
abstracts.add(name)
|
1215
|
+
|
1216
|
+
for name, value in cls.__dict__.items():
|
1217
|
+
if getattr(value, _IS_ABSTRACT_METHOD_ATTR, False):
|
1218
|
+
abstracts.add(name)
|
1219
|
+
|
1220
|
+
setattr(cls, _ABSTRACT_METHODS_ATTR, frozenset(abstracts))
|
1221
|
+
return cls
|
1222
|
+
|
1223
|
+
|
1224
|
+
#
|
1225
|
+
|
1226
|
+
|
1227
|
+
class AbstractTypeError(TypeError):
|
1228
|
+
pass
|
1229
|
+
|
1230
|
+
|
1231
|
+
_FORCE_ABSTRACT_ATTR = '__forceabstract__'
|
1232
|
+
|
1233
|
+
|
1234
|
+
class Abstract:
|
1235
|
+
"""
|
1236
|
+
Different from, but interoperable with, abc.ABC / abc.ABCMeta:
|
1237
|
+
|
1238
|
+
- This raises AbstractTypeError during class creation, not instance instantiation - unless Abstract or abc.ABC are
|
1239
|
+
explicitly present in the class's direct bases.
|
1240
|
+
- This will forbid instantiation of classes with Abstract in their direct bases even if there are no
|
1241
|
+
abstractmethods left on the class.
|
1242
|
+
- This is a mixin, not a metaclass.
|
1243
|
+
- As it is not an ABCMeta, this does not support virtual base classes. As a result, operations like `isinstance`
|
1244
|
+
and `issubclass` are ~7x faster.
|
1245
|
+
- It additionally enforces a base class order of (Abstract, abc.ABC) to preemptively prevent common mro conflicts.
|
1246
|
+
|
1247
|
+
If not mixed-in with an ABCMeta, it will update __abstractmethods__ itself.
|
1248
|
+
"""
|
1249
|
+
|
1250
|
+
__slots__ = ()
|
1251
|
+
|
1252
|
+
__abstractmethods__: ta.ClassVar[ta.FrozenSet[str]] = frozenset()
|
1253
|
+
|
1254
|
+
#
|
1255
|
+
|
1256
|
+
def __forceabstract__(self):
|
1257
|
+
raise TypeError
|
1258
|
+
|
1259
|
+
# This is done manually, rather than through @abc.abstractmethod, to mask it from static analysis.
|
1260
|
+
setattr(__forceabstract__, _IS_ABSTRACT_METHOD_ATTR, True)
|
1261
|
+
|
1262
|
+
#
|
1263
|
+
|
1264
|
+
def __init_subclass__(cls, **kwargs: ta.Any) -> None:
|
1265
|
+
setattr(
|
1266
|
+
cls,
|
1267
|
+
_FORCE_ABSTRACT_ATTR,
|
1268
|
+
getattr(Abstract, _FORCE_ABSTRACT_ATTR) if Abstract in cls.__bases__ else False,
|
1269
|
+
)
|
1270
|
+
|
1271
|
+
super().__init_subclass__(**kwargs)
|
1272
|
+
|
1273
|
+
if not (Abstract in cls.__bases__ or abc.ABC in cls.__bases__):
|
1274
|
+
ams = {a: cls for a, o in cls.__dict__.items() if is_abstract_method(o)}
|
1275
|
+
|
1276
|
+
seen = set(cls.__dict__)
|
1277
|
+
for b in cls.__bases__:
|
1278
|
+
ams.update({a: b for a in set(getattr(b, _ABSTRACT_METHODS_ATTR, [])) - seen}) # noqa
|
1279
|
+
seen.update(dir(b))
|
1280
|
+
|
1281
|
+
if ams:
|
1282
|
+
raise AbstractTypeError(
|
1283
|
+
f'Cannot subclass abstract class {cls.__name__} with abstract methods: ' +
|
1284
|
+
', '.join(sorted([
|
1285
|
+
'.'.join([
|
1286
|
+
*([m] if (m := getattr(c, '__module__')) else []),
|
1287
|
+
getattr(c, '__qualname__', getattr(c, '__name__')),
|
1288
|
+
a,
|
1289
|
+
])
|
1290
|
+
for a, c in ams.items()
|
1291
|
+
])),
|
1292
|
+
)
|
1293
|
+
|
1294
|
+
xbi = (Abstract, abc.ABC) # , ta.Generic ?
|
1295
|
+
bis = [(cls.__bases__.index(b), b) for b in xbi if b in cls.__bases__]
|
1296
|
+
if bis != sorted(bis):
|
1297
|
+
raise TypeError(
|
1298
|
+
f'Abstract subclass {cls.__name__} must have proper base class order of '
|
1299
|
+
f'({", ".join(getattr(b, "__name__") for b in xbi)}), got: '
|
1300
|
+
f'({", ".join(getattr(b, "__name__") for _, b in sorted(bis))})',
|
1301
|
+
)
|
1302
|
+
|
1303
|
+
if not isinstance(cls, abc.ABCMeta):
|
1304
|
+
update_abstracts(cls, force=True)
|
1305
|
+
|
1306
|
+
|
1187
1307
|
########################################
|
1188
1308
|
# ../../../../../omlish/lite/cached.py
|
1189
1309
|
|
@@ -1916,7 +2036,7 @@ def attr_setting(obj, attr, val, *, default=None): # noqa
|
|
1916
2036
|
##
|
1917
2037
|
|
1918
2038
|
|
1919
|
-
class
|
2039
|
+
class AsyncClosingManager(contextlib.AbstractAsyncContextManager):
|
1920
2040
|
def __init__(self, thing):
|
1921
2041
|
self.thing = thing
|
1922
2042
|
|
@@ -1927,6 +2047,9 @@ class aclosing(contextlib.AbstractAsyncContextManager): # noqa
|
|
1927
2047
|
await self.thing.aclose()
|
1928
2048
|
|
1929
2049
|
|
2050
|
+
aclosing = AsyncClosingManager
|
2051
|
+
|
2052
|
+
|
1930
2053
|
########################################
|
1931
2054
|
# ../../../../../omlish/lite/json.py
|
1932
2055
|
|
@@ -1965,6 +2088,86 @@ json_dumps_compact: ta.Callable[..., str] = functools.partial(json.dumps, **JSON
|
|
1965
2088
|
log = logging.getLogger(__name__)
|
1966
2089
|
|
1967
2090
|
|
2091
|
+
########################################
|
2092
|
+
# ../../../../../omlish/lite/objects.py
|
2093
|
+
|
2094
|
+
|
2095
|
+
##
|
2096
|
+
|
2097
|
+
|
2098
|
+
def deep_subclasses(cls: ta.Type[T]) -> ta.Iterator[ta.Type[T]]:
|
2099
|
+
seen = set()
|
2100
|
+
todo = list(reversed(cls.__subclasses__()))
|
2101
|
+
while todo:
|
2102
|
+
cur = todo.pop()
|
2103
|
+
if cur in seen:
|
2104
|
+
continue
|
2105
|
+
seen.add(cur)
|
2106
|
+
yield cur
|
2107
|
+
todo.extend(reversed(cur.__subclasses__()))
|
2108
|
+
|
2109
|
+
|
2110
|
+
##
|
2111
|
+
|
2112
|
+
|
2113
|
+
def mro_owner_dict(
|
2114
|
+
instance_cls: type,
|
2115
|
+
owner_cls: ta.Optional[type] = None,
|
2116
|
+
*,
|
2117
|
+
bottom_up_key_order: bool = False,
|
2118
|
+
sort_keys: bool = False,
|
2119
|
+
) -> ta.Mapping[str, ta.Tuple[type, ta.Any]]:
|
2120
|
+
if owner_cls is None:
|
2121
|
+
owner_cls = instance_cls
|
2122
|
+
|
2123
|
+
mro = instance_cls.__mro__[-2::-1]
|
2124
|
+
try:
|
2125
|
+
pos = mro.index(owner_cls)
|
2126
|
+
except ValueError:
|
2127
|
+
raise TypeError(f'Owner class {owner_cls} not in mro of instance class {instance_cls}') from None
|
2128
|
+
|
2129
|
+
dct: ta.Dict[str, ta.Tuple[type, ta.Any]] = {}
|
2130
|
+
if not bottom_up_key_order:
|
2131
|
+
for cur_cls in mro[:pos + 1][::-1]:
|
2132
|
+
for k, v in cur_cls.__dict__.items():
|
2133
|
+
if k not in dct:
|
2134
|
+
dct[k] = (cur_cls, v)
|
2135
|
+
|
2136
|
+
else:
|
2137
|
+
for cur_cls in mro[:pos + 1]:
|
2138
|
+
dct.update({k: (cur_cls, v) for k, v in cur_cls.__dict__.items()})
|
2139
|
+
|
2140
|
+
if sort_keys:
|
2141
|
+
dct = dict(sorted(dct.items(), key=lambda t: t[0]))
|
2142
|
+
|
2143
|
+
return dct
|
2144
|
+
|
2145
|
+
|
2146
|
+
def mro_dict(
|
2147
|
+
instance_cls: type,
|
2148
|
+
owner_cls: ta.Optional[type] = None,
|
2149
|
+
*,
|
2150
|
+
bottom_up_key_order: bool = False,
|
2151
|
+
sort_keys: bool = False,
|
2152
|
+
) -> ta.Mapping[str, ta.Any]:
|
2153
|
+
return {
|
2154
|
+
k: v
|
2155
|
+
for k, (o, v) in mro_owner_dict(
|
2156
|
+
instance_cls,
|
2157
|
+
owner_cls,
|
2158
|
+
bottom_up_key_order=bottom_up_key_order,
|
2159
|
+
sort_keys=sort_keys,
|
2160
|
+
).items()
|
2161
|
+
}
|
2162
|
+
|
2163
|
+
|
2164
|
+
def dir_dict(o: ta.Any) -> ta.Dict[str, ta.Any]:
|
2165
|
+
return {
|
2166
|
+
a: getattr(o, a)
|
2167
|
+
for a in dir(o)
|
2168
|
+
}
|
2169
|
+
|
2170
|
+
|
1968
2171
|
########################################
|
1969
2172
|
# ../../../../../omlish/lite/reflect.py
|
1970
2173
|
|
@@ -2054,21 +2257,6 @@ def get_literal_type_args(spec: ta.Any) -> ta.Iterable[ta.Any]:
|
|
2054
2257
|
return spec.__args__
|
2055
2258
|
|
2056
2259
|
|
2057
|
-
##
|
2058
|
-
|
2059
|
-
|
2060
|
-
def deep_subclasses(cls: ta.Type[T]) -> ta.Iterator[ta.Type[T]]:
|
2061
|
-
seen = set()
|
2062
|
-
todo = list(reversed(cls.__subclasses__()))
|
2063
|
-
while todo:
|
2064
|
-
cur = todo.pop()
|
2065
|
-
if cur in seen:
|
2066
|
-
continue
|
2067
|
-
seen.add(cur)
|
2068
|
-
yield cur
|
2069
|
-
todo.extend(reversed(cur.__subclasses__()))
|
2070
|
-
|
2071
|
-
|
2072
2260
|
########################################
|
2073
2261
|
# ../../../../../omlish/lite/strings.py
|
2074
2262
|
|
@@ -2942,7 +3130,7 @@ TODO:
|
|
2942
3130
|
##
|
2943
3131
|
|
2944
3132
|
|
2945
|
-
class ThreadWorker(ExitStacked,
|
3133
|
+
class ThreadWorker(ExitStacked, Abstract):
|
2946
3134
|
def __init__(
|
2947
3135
|
self,
|
2948
3136
|
*,
|
@@ -3131,7 +3319,7 @@ TODO:
|
|
3131
3319
|
|
3132
3320
|
|
3133
3321
|
@dc.dataclass(frozen=True)
|
3134
|
-
class ConfigData(
|
3322
|
+
class ConfigData(Abstract):
|
3135
3323
|
@abc.abstractmethod
|
3136
3324
|
def as_map(self) -> ConfigMap:
|
3137
3325
|
raise NotImplementedError
|
@@ -3140,7 +3328,7 @@ class ConfigData(abc.ABC): # noqa
|
|
3140
3328
|
#
|
3141
3329
|
|
3142
3330
|
|
3143
|
-
class ConfigLoader(
|
3331
|
+
class ConfigLoader(Abstract, ta.Generic[ConfigDataT]):
|
3144
3332
|
@property
|
3145
3333
|
def file_exts(self) -> ta.Sequence[str]:
|
3146
3334
|
return ()
|
@@ -3162,7 +3350,7 @@ class ConfigLoader(abc.ABC, ta.Generic[ConfigDataT]):
|
|
3162
3350
|
#
|
3163
3351
|
|
3164
3352
|
|
3165
|
-
class ConfigRenderer(
|
3353
|
+
class ConfigRenderer(Abstract, ta.Generic[ConfigDataT]):
|
3166
3354
|
@property
|
3167
3355
|
@abc.abstractmethod
|
3168
3356
|
def data_cls(self) -> ta.Type[ConfigDataT]:
|
@@ -3182,7 +3370,7 @@ class ConfigRenderer(abc.ABC, ta.Generic[ConfigDataT]):
|
|
3182
3370
|
|
3183
3371
|
|
3184
3372
|
@dc.dataclass(frozen=True)
|
3185
|
-
class ObjConfigData(ConfigData,
|
3373
|
+
class ObjConfigData(ConfigData, Abstract):
|
3186
3374
|
obj: ta.Any
|
3187
3375
|
|
3188
3376
|
def as_map(self) -> ConfigMap:
|
@@ -3654,7 +3842,7 @@ class ObjMarshalOptions:
|
|
3654
3842
|
non_strict_fields: bool = False
|
3655
3843
|
|
3656
3844
|
|
3657
|
-
class ObjMarshaler(
|
3845
|
+
class ObjMarshaler(Abstract):
|
3658
3846
|
@abc.abstractmethod
|
3659
3847
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3660
3848
|
raise NotImplementedError
|
@@ -3672,26 +3860,30 @@ class NopObjMarshaler(ObjMarshaler):
|
|
3672
3860
|
return o
|
3673
3861
|
|
3674
3862
|
|
3675
|
-
@dc.dataclass()
|
3676
3863
|
class ProxyObjMarshaler(ObjMarshaler):
|
3677
|
-
m: ta.Optional[ObjMarshaler] = None
|
3864
|
+
def __init__(self, m: ta.Optional[ObjMarshaler] = None) -> None:
|
3865
|
+
super().__init__()
|
3866
|
+
|
3867
|
+
self._m = m
|
3678
3868
|
|
3679
3869
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3680
|
-
return check.not_none(self.
|
3870
|
+
return check.not_none(self._m).marshal(o, ctx)
|
3681
3871
|
|
3682
3872
|
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3683
|
-
return check.not_none(self.
|
3873
|
+
return check.not_none(self._m).unmarshal(o, ctx)
|
3684
3874
|
|
3685
3875
|
|
3686
|
-
@dc.dataclass(frozen=True)
|
3687
3876
|
class CastObjMarshaler(ObjMarshaler):
|
3688
|
-
ty: type
|
3877
|
+
def __init__(self, ty: type) -> None:
|
3878
|
+
super().__init__()
|
3879
|
+
|
3880
|
+
self._ty = ty
|
3689
3881
|
|
3690
3882
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3691
3883
|
return o
|
3692
3884
|
|
3693
3885
|
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3694
|
-
return self.
|
3886
|
+
return self._ty(o)
|
3695
3887
|
|
3696
3888
|
|
3697
3889
|
class DynamicObjMarshaler(ObjMarshaler):
|
@@ -3702,121 +3894,151 @@ class DynamicObjMarshaler(ObjMarshaler):
|
|
3702
3894
|
return o
|
3703
3895
|
|
3704
3896
|
|
3705
|
-
@dc.dataclass(frozen=True)
|
3706
3897
|
class Base64ObjMarshaler(ObjMarshaler):
|
3707
|
-
ty: type
|
3898
|
+
def __init__(self, ty: type) -> None:
|
3899
|
+
super().__init__()
|
3900
|
+
|
3901
|
+
self._ty = ty
|
3708
3902
|
|
3709
3903
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3710
3904
|
return base64.b64encode(o).decode('ascii')
|
3711
3905
|
|
3712
3906
|
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3713
|
-
return self.
|
3907
|
+
return self._ty(base64.b64decode(o))
|
3714
3908
|
|
3715
3909
|
|
3716
|
-
@dc.dataclass(frozen=True)
|
3717
3910
|
class BytesSwitchedObjMarshaler(ObjMarshaler):
|
3718
|
-
m: ObjMarshaler
|
3911
|
+
def __init__(self, m: ObjMarshaler) -> None:
|
3912
|
+
super().__init__()
|
3913
|
+
|
3914
|
+
self._m = m
|
3719
3915
|
|
3720
3916
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3721
3917
|
if ctx.options.raw_bytes:
|
3722
3918
|
return o
|
3723
|
-
return self.
|
3919
|
+
return self._m.marshal(o, ctx)
|
3724
3920
|
|
3725
3921
|
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3726
3922
|
if ctx.options.raw_bytes:
|
3727
3923
|
return o
|
3728
|
-
return self.
|
3924
|
+
return self._m.unmarshal(o, ctx)
|
3729
3925
|
|
3730
3926
|
|
3731
|
-
@dc.dataclass(frozen=True)
|
3732
3927
|
class EnumObjMarshaler(ObjMarshaler):
|
3733
|
-
ty: type
|
3928
|
+
def __init__(self, ty: type) -> None:
|
3929
|
+
super().__init__()
|
3930
|
+
|
3931
|
+
self._ty = ty
|
3734
3932
|
|
3735
3933
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3736
3934
|
return o.name
|
3737
3935
|
|
3738
3936
|
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3739
|
-
return self.
|
3937
|
+
return self._ty.__members__[o] # type: ignore
|
3740
3938
|
|
3741
3939
|
|
3742
|
-
@dc.dataclass(frozen=True)
|
3743
3940
|
class OptionalObjMarshaler(ObjMarshaler):
|
3744
|
-
item: ObjMarshaler
|
3941
|
+
def __init__(self, item: ObjMarshaler) -> None:
|
3942
|
+
super().__init__()
|
3943
|
+
|
3944
|
+
self._item = item
|
3745
3945
|
|
3746
3946
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3747
3947
|
if o is None:
|
3748
3948
|
return None
|
3749
|
-
return self.
|
3949
|
+
return self._item.marshal(o, ctx)
|
3750
3950
|
|
3751
3951
|
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3752
3952
|
if o is None:
|
3753
3953
|
return None
|
3754
|
-
return self.
|
3954
|
+
return self._item.unmarshal(o, ctx)
|
3755
3955
|
|
3756
3956
|
|
3757
|
-
@dc.dataclass(frozen=True)
|
3758
3957
|
class PrimitiveUnionObjMarshaler(ObjMarshaler):
|
3759
|
-
|
3760
|
-
|
3958
|
+
def __init__(
|
3959
|
+
self,
|
3960
|
+
pt: ta.Tuple[type, ...],
|
3961
|
+
x: ta.Optional[ObjMarshaler] = None,
|
3962
|
+
) -> None:
|
3963
|
+
super().__init__()
|
3964
|
+
|
3965
|
+
self._pt = pt
|
3966
|
+
self._x = x
|
3761
3967
|
|
3762
3968
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3763
|
-
if isinstance(o, self.
|
3969
|
+
if isinstance(o, self._pt):
|
3764
3970
|
return o
|
3765
|
-
elif self.
|
3766
|
-
return self.
|
3971
|
+
elif self._x is not None:
|
3972
|
+
return self._x.marshal(o, ctx)
|
3767
3973
|
else:
|
3768
3974
|
raise TypeError(o)
|
3769
3975
|
|
3770
3976
|
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3771
|
-
if isinstance(o, self.
|
3977
|
+
if isinstance(o, self._pt):
|
3772
3978
|
return o
|
3773
|
-
elif self.
|
3774
|
-
return self.
|
3979
|
+
elif self._x is not None:
|
3980
|
+
return self._x.unmarshal(o, ctx)
|
3775
3981
|
else:
|
3776
3982
|
raise TypeError(o)
|
3777
3983
|
|
3778
3984
|
|
3779
|
-
@dc.dataclass(frozen=True)
|
3780
3985
|
class LiteralObjMarshaler(ObjMarshaler):
|
3781
|
-
|
3782
|
-
|
3986
|
+
def __init__(
|
3987
|
+
self,
|
3988
|
+
item: ObjMarshaler,
|
3989
|
+
vs: frozenset,
|
3990
|
+
) -> None:
|
3991
|
+
super().__init__()
|
3992
|
+
|
3993
|
+
self._item = item
|
3994
|
+
self._vs = vs
|
3783
3995
|
|
3784
3996
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3785
|
-
return self.
|
3997
|
+
return self._item.marshal(check.in_(o, self._vs), ctx)
|
3786
3998
|
|
3787
3999
|
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3788
|
-
return check.in_(self.
|
4000
|
+
return check.in_(self._item.unmarshal(o, ctx), self._vs)
|
3789
4001
|
|
3790
4002
|
|
3791
|
-
@dc.dataclass(frozen=True)
|
3792
4003
|
class MappingObjMarshaler(ObjMarshaler):
|
3793
|
-
|
3794
|
-
|
3795
|
-
|
4004
|
+
def __init__(
|
4005
|
+
self,
|
4006
|
+
ty: type,
|
4007
|
+
km: ObjMarshaler,
|
4008
|
+
vm: ObjMarshaler,
|
4009
|
+
) -> None:
|
4010
|
+
super().__init__()
|
4011
|
+
|
4012
|
+
self._ty = ty
|
4013
|
+
self._km = km
|
4014
|
+
self._vm = vm
|
3796
4015
|
|
3797
4016
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3798
|
-
return {self.
|
4017
|
+
return {self._km.marshal(k, ctx): self._vm.marshal(v, ctx) for k, v in o.items()}
|
3799
4018
|
|
3800
4019
|
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3801
|
-
return self.
|
4020
|
+
return self._ty((self._km.unmarshal(k, ctx), self._vm.unmarshal(v, ctx)) for k, v in o.items())
|
3802
4021
|
|
3803
4022
|
|
3804
|
-
@dc.dataclass(frozen=True)
|
3805
4023
|
class IterableObjMarshaler(ObjMarshaler):
|
3806
|
-
|
3807
|
-
|
4024
|
+
def __init__(
|
4025
|
+
self,
|
4026
|
+
ty: type,
|
4027
|
+
item: ObjMarshaler,
|
4028
|
+
) -> None:
|
4029
|
+
super().__init__()
|
4030
|
+
|
4031
|
+
self._ty = ty
|
4032
|
+
self._item = item
|
3808
4033
|
|
3809
4034
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3810
|
-
return [self.
|
4035
|
+
return [self._item.marshal(e, ctx) for e in o]
|
3811
4036
|
|
3812
4037
|
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3813
|
-
return self.
|
4038
|
+
return self._ty(self._item.unmarshal(e, ctx) for e in o)
|
3814
4039
|
|
3815
4040
|
|
3816
|
-
@dc.dataclass(frozen=True)
|
3817
4041
|
class FieldsObjMarshaler(ObjMarshaler):
|
3818
|
-
ty: type
|
3819
|
-
|
3820
4042
|
@dc.dataclass(frozen=True)
|
3821
4043
|
class Field:
|
3822
4044
|
att: str
|
@@ -3825,31 +4047,43 @@ class FieldsObjMarshaler(ObjMarshaler):
|
|
3825
4047
|
|
3826
4048
|
omit_if_none: bool = False
|
3827
4049
|
|
3828
|
-
|
3829
|
-
|
3830
|
-
|
3831
|
-
|
3832
|
-
|
4050
|
+
def __init__(
|
4051
|
+
self,
|
4052
|
+
ty: type,
|
4053
|
+
fs: ta.Sequence[Field],
|
4054
|
+
*,
|
4055
|
+
non_strict: bool = False,
|
4056
|
+
) -> None:
|
4057
|
+
super().__init__()
|
3833
4058
|
|
3834
|
-
|
3835
|
-
|
4059
|
+
self._ty = ty
|
4060
|
+
self._fs = fs
|
4061
|
+
self._non_strict = non_strict
|
3836
4062
|
|
3837
|
-
def __post_init__(self) -> None:
|
3838
4063
|
fs_by_att: dict = {}
|
3839
4064
|
fs_by_key: dict = {}
|
3840
|
-
for f in self.
|
4065
|
+
for f in self._fs:
|
3841
4066
|
check.not_in(check.non_empty_str(f.att), fs_by_att)
|
3842
4067
|
check.not_in(check.non_empty_str(f.key), fs_by_key)
|
3843
4068
|
fs_by_att[f.att] = f
|
3844
4069
|
fs_by_key[f.key] = f
|
3845
|
-
|
3846
|
-
self.
|
4070
|
+
|
4071
|
+
self._fs_by_att: ta.Mapping[str, FieldsObjMarshaler.Field] = fs_by_att
|
4072
|
+
self._fs_by_key: ta.Mapping[str, FieldsObjMarshaler.Field] = fs_by_key
|
4073
|
+
|
4074
|
+
@property
|
4075
|
+
def ty(self) -> type:
|
4076
|
+
return self._ty
|
4077
|
+
|
4078
|
+
@property
|
4079
|
+
def fs(self) -> ta.Sequence[Field]:
|
4080
|
+
return self._fs
|
3847
4081
|
|
3848
4082
|
#
|
3849
4083
|
|
3850
4084
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3851
4085
|
d = {}
|
3852
|
-
for f in self.
|
4086
|
+
for f in self._fs:
|
3853
4087
|
mv = f.m.marshal(getattr(o, f.att), ctx)
|
3854
4088
|
if mv is None and f.omit_if_none:
|
3855
4089
|
continue
|
@@ -3860,34 +4094,46 @@ class FieldsObjMarshaler(ObjMarshaler):
|
|
3860
4094
|
kw = {}
|
3861
4095
|
for k, v in o.items():
|
3862
4096
|
if (f := self._fs_by_key.get(k)) is None:
|
3863
|
-
if not (self.
|
4097
|
+
if not (self._non_strict or ctx.options.non_strict_fields):
|
3864
4098
|
raise KeyError(k)
|
3865
4099
|
continue
|
3866
4100
|
kw[f.att] = f.m.unmarshal(v, ctx)
|
3867
|
-
return self.
|
4101
|
+
return self._ty(**kw)
|
3868
4102
|
|
3869
4103
|
|
3870
|
-
@dc.dataclass(frozen=True)
|
3871
4104
|
class SingleFieldObjMarshaler(ObjMarshaler):
|
3872
|
-
|
3873
|
-
|
4105
|
+
def __init__(
|
4106
|
+
self,
|
4107
|
+
ty: type,
|
4108
|
+
fld: str,
|
4109
|
+
) -> None:
|
4110
|
+
super().__init__()
|
4111
|
+
|
4112
|
+
self._ty = ty
|
4113
|
+
self._fld = fld
|
3874
4114
|
|
3875
4115
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3876
|
-
return getattr(o, self.
|
4116
|
+
return getattr(o, self._fld)
|
3877
4117
|
|
3878
4118
|
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3879
|
-
return self.
|
4119
|
+
return self._ty(**{self._fld: o})
|
3880
4120
|
|
3881
4121
|
|
3882
|
-
@dc.dataclass(frozen=True)
|
3883
4122
|
class PolymorphicObjMarshaler(ObjMarshaler):
|
3884
4123
|
class Impl(ta.NamedTuple):
|
3885
4124
|
ty: type
|
3886
4125
|
tag: str
|
3887
4126
|
m: ObjMarshaler
|
3888
4127
|
|
3889
|
-
|
3890
|
-
|
4128
|
+
def __init__(
|
4129
|
+
self,
|
4130
|
+
impls_by_ty: ta.Mapping[type, Impl],
|
4131
|
+
impls_by_tag: ta.Mapping[str, Impl],
|
4132
|
+
) -> None:
|
4133
|
+
super().__init__()
|
4134
|
+
|
4135
|
+
self._impls_by_ty = impls_by_ty
|
4136
|
+
self._impls_by_tag = impls_by_tag
|
3891
4137
|
|
3892
4138
|
@classmethod
|
3893
4139
|
def of(cls, impls: ta.Iterable[Impl]) -> 'PolymorphicObjMarshaler':
|
@@ -3897,24 +4143,29 @@ class PolymorphicObjMarshaler(ObjMarshaler):
|
|
3897
4143
|
)
|
3898
4144
|
|
3899
4145
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3900
|
-
impl = self.
|
4146
|
+
impl = self._impls_by_ty[type(o)]
|
3901
4147
|
return {impl.tag: impl.m.marshal(o, ctx)}
|
3902
4148
|
|
3903
4149
|
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3904
4150
|
[(t, v)] = o.items()
|
3905
|
-
impl = self.
|
4151
|
+
impl = self._impls_by_tag[t]
|
3906
4152
|
return impl.m.unmarshal(v, ctx)
|
3907
4153
|
|
3908
4154
|
|
3909
|
-
@dc.dataclass(frozen=True)
|
3910
4155
|
class DatetimeObjMarshaler(ObjMarshaler):
|
3911
|
-
|
4156
|
+
def __init__(
|
4157
|
+
self,
|
4158
|
+
ty: type,
|
4159
|
+
) -> None:
|
4160
|
+
super().__init__()
|
4161
|
+
|
4162
|
+
self._ty = ty
|
3912
4163
|
|
3913
4164
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3914
4165
|
return o.isoformat()
|
3915
4166
|
|
3916
4167
|
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
3917
|
-
return self.
|
4168
|
+
return self._ty.fromisoformat(o) # type: ignore
|
3918
4169
|
|
3919
4170
|
|
3920
4171
|
class DecimalObjMarshaler(ObjMarshaler):
|
@@ -4022,7 +4273,78 @@ class OBJ_MARSHALER_OMIT_IF_NONE(ObjMarshalerFieldMetadata): # noqa
|
|
4022
4273
|
##
|
4023
4274
|
|
4024
4275
|
|
4025
|
-
class ObjMarshalerManager:
|
4276
|
+
class ObjMarshalerManager(Abstract):
|
4277
|
+
@abc.abstractmethod
|
4278
|
+
def make_obj_marshaler(
|
4279
|
+
self,
|
4280
|
+
ty: ta.Any,
|
4281
|
+
rec: ta.Callable[[ta.Any], ObjMarshaler],
|
4282
|
+
*,
|
4283
|
+
non_strict_fields: bool = False,
|
4284
|
+
) -> ObjMarshaler:
|
4285
|
+
raise NotImplementedError
|
4286
|
+
|
4287
|
+
@abc.abstractmethod
|
4288
|
+
def set_obj_marshaler(
|
4289
|
+
self,
|
4290
|
+
ty: ta.Any,
|
4291
|
+
m: ObjMarshaler,
|
4292
|
+
*,
|
4293
|
+
override: bool = False,
|
4294
|
+
) -> None:
|
4295
|
+
raise NotImplementedError
|
4296
|
+
|
4297
|
+
@abc.abstractmethod
|
4298
|
+
def get_obj_marshaler(
|
4299
|
+
self,
|
4300
|
+
ty: ta.Any,
|
4301
|
+
*,
|
4302
|
+
no_cache: bool = False,
|
4303
|
+
**kwargs: ta.Any,
|
4304
|
+
) -> ObjMarshaler:
|
4305
|
+
raise NotImplementedError
|
4306
|
+
|
4307
|
+
@abc.abstractmethod
|
4308
|
+
def make_context(self, opts: ta.Optional[ObjMarshalOptions]) -> 'ObjMarshalContext':
|
4309
|
+
raise NotImplementedError
|
4310
|
+
|
4311
|
+
#
|
4312
|
+
|
4313
|
+
def marshal_obj(
|
4314
|
+
self,
|
4315
|
+
o: ta.Any,
|
4316
|
+
ty: ta.Any = None,
|
4317
|
+
opts: ta.Optional[ObjMarshalOptions] = None,
|
4318
|
+
) -> ta.Any:
|
4319
|
+
m = self.get_obj_marshaler(ty if ty is not None else type(o))
|
4320
|
+
return m.marshal(o, self.make_context(opts))
|
4321
|
+
|
4322
|
+
def unmarshal_obj(
|
4323
|
+
self,
|
4324
|
+
o: ta.Any,
|
4325
|
+
ty: ta.Union[ta.Type[T], ta.Any],
|
4326
|
+
opts: ta.Optional[ObjMarshalOptions] = None,
|
4327
|
+
) -> T:
|
4328
|
+
m = self.get_obj_marshaler(ty)
|
4329
|
+
return m.unmarshal(o, self.make_context(opts))
|
4330
|
+
|
4331
|
+
def roundtrip_obj(
|
4332
|
+
self,
|
4333
|
+
o: ta.Any,
|
4334
|
+
ty: ta.Any = None,
|
4335
|
+
opts: ta.Optional[ObjMarshalOptions] = None,
|
4336
|
+
) -> ta.Any:
|
4337
|
+
if ty is None:
|
4338
|
+
ty = type(o)
|
4339
|
+
m: ta.Any = self.marshal_obj(o, ty, opts)
|
4340
|
+
u: ta.Any = self.unmarshal_obj(m, ty, opts)
|
4341
|
+
return u
|
4342
|
+
|
4343
|
+
|
4344
|
+
#
|
4345
|
+
|
4346
|
+
|
4347
|
+
class ObjMarshalerManagerImpl(ObjMarshalerManager):
|
4026
4348
|
def __init__(
|
4027
4349
|
self,
|
4028
4350
|
*,
|
@@ -4049,6 +4371,12 @@ class ObjMarshalerManager:
|
|
4049
4371
|
|
4050
4372
|
#
|
4051
4373
|
|
4374
|
+
@classmethod
|
4375
|
+
def _is_abstract(cls, ty: type) -> bool:
|
4376
|
+
return abc.ABC in ty.__bases__ or Abstract in ty.__bases__
|
4377
|
+
|
4378
|
+
#
|
4379
|
+
|
4052
4380
|
def make_obj_marshaler(
|
4053
4381
|
self,
|
4054
4382
|
ty: ta.Any,
|
@@ -4060,12 +4388,12 @@ class ObjMarshalerManager:
|
|
4060
4388
|
if (reg := self._registered_obj_marshalers.get(ty)) is not None:
|
4061
4389
|
return reg
|
4062
4390
|
|
4063
|
-
if
|
4391
|
+
if self._is_abstract(ty):
|
4064
4392
|
tn = ty.__name__
|
4065
4393
|
impls: ta.List[ta.Tuple[type, str]] = [ # type: ignore[var-annotated]
|
4066
4394
|
(ity, ity.__name__)
|
4067
4395
|
for ity in deep_subclasses(ty)
|
4068
|
-
if
|
4396
|
+
if not self._is_abstract(ity)
|
4069
4397
|
]
|
4070
4398
|
|
4071
4399
|
if all(itn.endswith(tn) for _, itn in impls):
|
@@ -4231,49 +4559,24 @@ class ObjMarshalerManager:
|
|
4231
4559
|
m = self.make_obj_marshaler(ty, rec, **kwargs)
|
4232
4560
|
finally:
|
4233
4561
|
del self._proxies[ty]
|
4234
|
-
p.
|
4562
|
+
p._m = m # noqa
|
4235
4563
|
|
4236
4564
|
if not no_cache:
|
4237
4565
|
self._obj_marshalers[ty] = m
|
4238
4566
|
return m
|
4239
4567
|
|
4240
|
-
|
4241
|
-
|
4242
|
-
def _make_context(self, opts: ta.Optional[ObjMarshalOptions]) -> 'ObjMarshalContext':
|
4568
|
+
def make_context(self, opts: ta.Optional[ObjMarshalOptions]) -> 'ObjMarshalContext':
|
4243
4569
|
return ObjMarshalContext(
|
4244
4570
|
options=opts or self._default_options,
|
4245
4571
|
manager=self,
|
4246
4572
|
)
|
4247
4573
|
|
4248
|
-
def marshal_obj(
|
4249
|
-
self,
|
4250
|
-
o: ta.Any,
|
4251
|
-
ty: ta.Any = None,
|
4252
|
-
opts: ta.Optional[ObjMarshalOptions] = None,
|
4253
|
-
) -> ta.Any:
|
4254
|
-
m = self.get_obj_marshaler(ty if ty is not None else type(o))
|
4255
|
-
return m.marshal(o, self._make_context(opts))
|
4256
4574
|
|
4257
|
-
|
4258
|
-
|
4259
|
-
o: ta.Any,
|
4260
|
-
ty: ta.Union[ta.Type[T], ta.Any],
|
4261
|
-
opts: ta.Optional[ObjMarshalOptions] = None,
|
4262
|
-
) -> T:
|
4263
|
-
m = self.get_obj_marshaler(ty)
|
4264
|
-
return m.unmarshal(o, self._make_context(opts))
|
4575
|
+
def new_obj_marshaler_manager(**kwargs: ta.Any) -> ObjMarshalerManager:
|
4576
|
+
return ObjMarshalerManagerImpl(**kwargs)
|
4265
4577
|
|
4266
|
-
|
4267
|
-
|
4268
|
-
o: ta.Any,
|
4269
|
-
ty: ta.Any = None,
|
4270
|
-
opts: ta.Optional[ObjMarshalOptions] = None,
|
4271
|
-
) -> ta.Any:
|
4272
|
-
if ty is None:
|
4273
|
-
ty = type(o)
|
4274
|
-
m: ta.Any = self.marshal_obj(o, ty, opts)
|
4275
|
-
u: ta.Any = self.unmarshal_obj(m, ty, opts)
|
4276
|
-
return u
|
4578
|
+
|
4579
|
+
##
|
4277
4580
|
|
4278
4581
|
|
4279
4582
|
@dc.dataclass(frozen=True)
|
@@ -4285,7 +4588,7 @@ class ObjMarshalContext:
|
|
4285
4588
|
##
|
4286
4589
|
|
4287
4590
|
|
4288
|
-
OBJ_MARSHALER_MANAGER =
|
4591
|
+
OBJ_MARSHALER_MANAGER = new_obj_marshaler_manager()
|
4289
4592
|
|
4290
4593
|
set_obj_marshaler = OBJ_MARSHALER_MANAGER.set_obj_marshaler
|
4291
4594
|
get_obj_marshaler = OBJ_MARSHALER_MANAGER.get_obj_marshaler
|