ominfra 0.0.0.dev438__py3-none-any.whl → 0.0.0.dev483__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.
Potentially problematic release.
This version of ominfra might be problematic. Click here for more details.
- ominfra/clouds/aws/instancetypes/cache.json.gz +0 -0
- ominfra/clouds/aws/models/gen/gen.py +8 -5
- ominfra/clouds/aws/models/services/__init__.py +7 -0
- ominfra/clouds/aws/models/services/_dataclasses.py +47718 -0
- ominfra/clouds/aws/models/services/ec2.py +103 -0
- ominfra/clouds/aws/models/services/lambda_.py +129 -0
- ominfra/clouds/aws/models/services/rds.py +210 -77
- ominfra/clouds/aws/models/services/s3.py +2 -0
- ominfra/manage/main.py +1 -2
- ominfra/scripts/journald2aws.py +408 -52
- ominfra/scripts/manage.py +391 -64
- ominfra/scripts/supervisor.py +539 -98
- {ominfra-0.0.0.dev438.dist-info → ominfra-0.0.0.dev483.dist-info}/METADATA +3 -3
- {ominfra-0.0.0.dev438.dist-info → ominfra-0.0.0.dev483.dist-info}/RECORD +18 -17
- {ominfra-0.0.0.dev438.dist-info → ominfra-0.0.0.dev483.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev438.dist-info → ominfra-0.0.0.dev483.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev438.dist-info → ominfra-0.0.0.dev483.dist-info}/licenses/LICENSE +0 -0
- {ominfra-0.0.0.dev438.dist-info → ominfra-0.0.0.dev483.dist-info}/top_level.txt +0 -0
ominfra/scripts/journald2aws.py
CHANGED
|
@@ -54,6 +54,57 @@ if sys.version_info < (3, 8):
|
|
|
54
54
|
raise OSError(f'Requires python (3, 8), got {sys.version_info} from {sys.executable}') # noqa
|
|
55
55
|
|
|
56
56
|
|
|
57
|
+
def __omlish_amalg__(): # noqa
|
|
58
|
+
return dict(
|
|
59
|
+
src_files=[
|
|
60
|
+
dict(path='../../../../omlish/configs/types.py', sha1='f7a5584cd6eccb77d18d729796072a162e9a8790'),
|
|
61
|
+
dict(path='../../../../omlish/formats/ini/sections.py', sha1='731c92cce82e183d1d4bdc23fc781fad62187394'),
|
|
62
|
+
dict(path='../../../../omlish/formats/toml/parser.py', sha1='73dac82289350ab951c4bcdbfe61167fa221f26f'),
|
|
63
|
+
dict(path='../../../../omlish/formats/toml/writer.py', sha1='6ea41d7e724bb1dcf6bd84b88993ff4e8798e021'),
|
|
64
|
+
dict(path='../../../../omlish/io/readers.py', sha1='4b19ab4a87f2fa2a6f6c3cad7e1f3892b7cbd3a4'),
|
|
65
|
+
dict(path='../../../../omlish/lite/abstract.py', sha1='a2fc3f3697fa8de5247761e9d554e70176f37aac'),
|
|
66
|
+
dict(path='../../../../omlish/lite/attrops.py', sha1='c1ebfb8573d766d34593c452a2377208d02726dc'),
|
|
67
|
+
dict(path='../../../../omlish/lite/cached.py', sha1='0c33cf961ac8f0727284303c7a30c5ea98f714f2'),
|
|
68
|
+
dict(path='../../../../omlish/lite/check.py', sha1='bb6b6b63333699b84462951a854d99ae83195b94'),
|
|
69
|
+
dict(path='../../../../omlish/lite/contextmanagers.py', sha1='993f5ed96d3410f739a20363f55670d5e5267fa3'),
|
|
70
|
+
dict(path='../../../../omlish/lite/json.py', sha1='57eeddc4d23a17931e00284ffa5cb6e3ce089486'),
|
|
71
|
+
dict(path='../../../../omlish/lite/objects.py', sha1='9566bbf3530fd71fcc56321485216b592fae21e9'),
|
|
72
|
+
dict(path='../../../../omlish/lite/reflect.py', sha1='c4fec44bf144e9d93293c996af06f6c65fc5e63d'),
|
|
73
|
+
dict(path='../../../../omlish/lite/strings.py', sha1='89831ecbc34ad80e118a865eceb390ed399dc4d6'),
|
|
74
|
+
dict(path='../../../../omlish/logs/levels.py', sha1='91405563d082a5eba874da82aac89d83ce7b6152'),
|
|
75
|
+
dict(path='../../../../omlish/logs/std/filters.py', sha1='f36aab646d84d31e295b33aaaaa6f8b67ff38b3d'),
|
|
76
|
+
dict(path='../../../../omlish/logs/std/proxy.py', sha1='3e7301a2aa351127f9c85f61b2f85dcc3f15aafb'),
|
|
77
|
+
dict(path='../../../../omlish/logs/warnings.py', sha1='c4eb694b24773351107fcc058f3620f1dbfb6799'),
|
|
78
|
+
dict(path='../../../../omlish/os/pidfiles/pidfile.py', sha1='7c3c6d4674855bfc4f1d7fd77b8fa40f36581535'),
|
|
79
|
+
dict(path='../../../../omlish/subprocesses/utils.py', sha1='2210d90ab1bfc75642aa2f4caad662368900aa1c'),
|
|
80
|
+
dict(path='../auth.py', sha1='b1ac1a5e03d4e9e38957a54e346943c6dcc964a1'),
|
|
81
|
+
dict(path='../dataclasses.py', sha1='8e950d7815904588fed284889392cbb0b1002605'),
|
|
82
|
+
dict(path='../../../../omlish/configs/formats.py', sha1='9bc4f953b4b8700f6f109e6f49e2d70f8e48ce7c'),
|
|
83
|
+
dict(path='../../../../omlish/io/buffers.py', sha1='45a5f79c6d71f02ab82082a48d63ebbd10959031'),
|
|
84
|
+
dict(path='../../../../omlish/lite/marshal.py', sha1='96348f5f2a26dc27d842d33cc3927e9da163436b'),
|
|
85
|
+
dict(path='../../../../omlish/lite/runtime.py', sha1='2e752a27ae2bf89b1bb79b4a2da522a3ec360c70'),
|
|
86
|
+
dict(path='../../../../omlish/logs/infos.py', sha1='4dd104bd468a8c438601dd0bbda619b47d2f1620'),
|
|
87
|
+
dict(path='../../../../omlish/logs/std/json.py', sha1='2a75553131e4d5331bb0cedde42aa183f403fc3b'),
|
|
88
|
+
dict(path='../logs.py', sha1='5a4fad522508bdc1b790f1d5234a87f319c9da2d'),
|
|
89
|
+
dict(path='../../../../omlish/lite/configs.py', sha1='c8602e0e197ef1133e7e8e248935ac745bfd46cb'),
|
|
90
|
+
dict(path='../../../../omlish/logs/contexts.py', sha1='7456964ade9ac66460e9ade4e242dbdc24b39501'),
|
|
91
|
+
dict(path='../../../../omlish/logs/standard.py', sha1='818b674f7d15012f25b79f52f6e8e7368b633038'),
|
|
92
|
+
dict(path='../../../../omlish/subprocesses/wrap.py', sha1='8a9b7d2255481fae15c05f5624b0cdc0766f4b3f'),
|
|
93
|
+
dict(path='../../../../omlish/logs/base.py', sha1='a376460b11b9dc0555fd4ead5437af62c2109a4b'),
|
|
94
|
+
dict(path='../../../../omlish/logs/std/records.py', sha1='8bbf6ef9eccb3a012c6ca416ddf3969450fd8fc9'),
|
|
95
|
+
dict(path='../../../../omlish/logs/std/loggers.py', sha1='daa35bdc4adea5006e442688017f0de3392579b7'),
|
|
96
|
+
dict(path='../../../../omlish/logs/modules.py', sha1='99e73cde6872fd5eda6af3dbf0fc9322bdeb641a'),
|
|
97
|
+
dict(path='cursor.py', sha1='00f1c62e16e4c85b20658eaf33c0bedf22c9e18f'),
|
|
98
|
+
dict(path='../../../journald/messages.py', sha1='6f2d2eeedb71723b1c6631ad2e634b473b297696'),
|
|
99
|
+
dict(path='../../../threadworkers.py', sha1='e3413436070b66faeb3e6974dc9a75cd8a949ad7'),
|
|
100
|
+
dict(path='poster.py', sha1='275770a4e60ea5777053c9044e37d71397c3ed20'),
|
|
101
|
+
dict(path='../../../journald/tailer.py', sha1='1c37a6bbde32e8556d26b94b439f14869731ac01'),
|
|
102
|
+
dict(path='driver.py', sha1='a9353a417fc4e57f29e7f04038c3bf4668f36dbd'),
|
|
103
|
+
dict(path='main.py', sha1='e051dbef37e026f887b6084cfaa811ccfa543ee7'),
|
|
104
|
+
],
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
|
|
57
108
|
########################################
|
|
58
109
|
|
|
59
110
|
|
|
@@ -68,7 +119,7 @@ TomlParseFloat = ta.Callable[[str], ta.Any] # ta.TypeAlias
|
|
|
68
119
|
TomlKey = ta.Tuple[str, ...] # ta.TypeAlias
|
|
69
120
|
TomlPos = int # ta.TypeAlias
|
|
70
121
|
|
|
71
|
-
# ../../../../omlish/lite/
|
|
122
|
+
# ../../../../omlish/lite/abstract.py
|
|
72
123
|
T = ta.TypeVar('T')
|
|
73
124
|
|
|
74
125
|
# ../../../../omlish/lite/cached.py
|
|
@@ -1200,6 +1251,36 @@ class TomlWriter:
|
|
|
1200
1251
|
return out.getvalue()
|
|
1201
1252
|
|
|
1202
1253
|
|
|
1254
|
+
########################################
|
|
1255
|
+
# ../../../../../omlish/io/readers.py
|
|
1256
|
+
|
|
1257
|
+
|
|
1258
|
+
##
|
|
1259
|
+
|
|
1260
|
+
|
|
1261
|
+
class RawBytesReader(ta.Protocol):
|
|
1262
|
+
def read1(self, n: int = -1, /) -> bytes: ...
|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
class BufferedBytesReader(RawBytesReader, ta.Protocol):
|
|
1266
|
+
def read(self, n: int = -1, /) -> bytes: ...
|
|
1267
|
+
|
|
1268
|
+
def readall(self) -> bytes: ...
|
|
1269
|
+
|
|
1270
|
+
|
|
1271
|
+
#
|
|
1272
|
+
|
|
1273
|
+
|
|
1274
|
+
class AsyncRawBytesReader(ta.Protocol):
|
|
1275
|
+
def read1(self, n: int = -1, /) -> ta.Awaitable[bytes]: ...
|
|
1276
|
+
|
|
1277
|
+
|
|
1278
|
+
class AsyncBufferedBytesReader(AsyncRawBytesReader, ta.Protocol):
|
|
1279
|
+
def read(self, n: int = -1, /) -> ta.Awaitable[bytes]: ...
|
|
1280
|
+
|
|
1281
|
+
def readall(self) -> ta.Awaitable[bytes]: ...
|
|
1282
|
+
|
|
1283
|
+
|
|
1203
1284
|
########################################
|
|
1204
1285
|
# ../../../../../omlish/lite/abstract.py
|
|
1205
1286
|
|
|
@@ -1215,25 +1296,49 @@ def is_abstract_method(obj: ta.Any) -> bool:
|
|
|
1215
1296
|
return bool(getattr(obj, _IS_ABSTRACT_METHOD_ATTR, False))
|
|
1216
1297
|
|
|
1217
1298
|
|
|
1218
|
-
def
|
|
1299
|
+
def compute_abstract_methods(cls: type) -> ta.FrozenSet[str]:
|
|
1300
|
+
# ~> https://github.com/python/cpython/blob/f3476c6507381ca860eec0989f53647b13517423/Modules/_abc.c#L358
|
|
1301
|
+
|
|
1302
|
+
# Stage 1: direct abstract methods
|
|
1303
|
+
|
|
1304
|
+
abstracts = {
|
|
1305
|
+
a
|
|
1306
|
+
# Get items as a list to avoid mutation issues during iteration
|
|
1307
|
+
for a, v in list(cls.__dict__.items())
|
|
1308
|
+
if is_abstract_method(v)
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
# Stage 2: inherited abstract methods
|
|
1312
|
+
|
|
1313
|
+
for base in cls.__bases__:
|
|
1314
|
+
# Get __abstractmethods__ from base if it exists
|
|
1315
|
+
if (base_abstracts := getattr(base, _ABSTRACT_METHODS_ATTR, None)) is None:
|
|
1316
|
+
continue
|
|
1317
|
+
|
|
1318
|
+
# Iterate over abstract methods in base
|
|
1319
|
+
for key in base_abstracts:
|
|
1320
|
+
# Check if this class has an attribute with this name
|
|
1321
|
+
try:
|
|
1322
|
+
value = getattr(cls, key)
|
|
1323
|
+
except AttributeError:
|
|
1324
|
+
# Attribute not found in this class, skip
|
|
1325
|
+
continue
|
|
1326
|
+
|
|
1327
|
+
# Check if it's still abstract
|
|
1328
|
+
if is_abstract_method(value):
|
|
1329
|
+
abstracts.add(key)
|
|
1330
|
+
|
|
1331
|
+
return frozenset(abstracts)
|
|
1332
|
+
|
|
1333
|
+
|
|
1334
|
+
def update_abstracts(cls: ta.Type[T], *, force: bool = False) -> ta.Type[T]:
|
|
1219
1335
|
if not force and not hasattr(cls, _ABSTRACT_METHODS_ATTR):
|
|
1220
1336
|
# Per stdlib: We check for __abstractmethods__ here because cls might by a C implementation or a python
|
|
1221
1337
|
# implementation (especially during testing), and we want to handle both cases.
|
|
1222
1338
|
return cls
|
|
1223
1339
|
|
|
1224
|
-
abstracts
|
|
1225
|
-
|
|
1226
|
-
for scls in cls.__bases__:
|
|
1227
|
-
for name in getattr(scls, _ABSTRACT_METHODS_ATTR, ()):
|
|
1228
|
-
value = getattr(cls, name, None)
|
|
1229
|
-
if getattr(value, _IS_ABSTRACT_METHOD_ATTR, False):
|
|
1230
|
-
abstracts.add(name)
|
|
1231
|
-
|
|
1232
|
-
for name, value in cls.__dict__.items():
|
|
1233
|
-
if getattr(value, _IS_ABSTRACT_METHOD_ATTR, False):
|
|
1234
|
-
abstracts.add(name)
|
|
1235
|
-
|
|
1236
|
-
setattr(cls, _ABSTRACT_METHODS_ATTR, frozenset(abstracts))
|
|
1340
|
+
abstracts = compute_abstract_methods(cls)
|
|
1341
|
+
setattr(cls, _ABSTRACT_METHODS_ATTR, abstracts)
|
|
1237
1342
|
return cls
|
|
1238
1343
|
|
|
1239
1344
|
|
|
@@ -1287,23 +1392,26 @@ class Abstract:
|
|
|
1287
1392
|
super().__init_subclass__(**kwargs)
|
|
1288
1393
|
|
|
1289
1394
|
if not (Abstract in cls.__bases__ or abc.ABC in cls.__bases__):
|
|
1290
|
-
ams
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1395
|
+
if ams := compute_abstract_methods(cls):
|
|
1396
|
+
amd = {
|
|
1397
|
+
a: mcls
|
|
1398
|
+
for mcls in cls.__mro__[::-1]
|
|
1399
|
+
for a in ams
|
|
1400
|
+
if a in mcls.__dict__
|
|
1401
|
+
}
|
|
1296
1402
|
|
|
1297
|
-
if ams:
|
|
1298
1403
|
raise AbstractTypeError(
|
|
1299
1404
|
f'Cannot subclass abstract class {cls.__name__} with abstract methods: ' +
|
|
1300
1405
|
', '.join(sorted([
|
|
1301
1406
|
'.'.join([
|
|
1302
|
-
*([
|
|
1303
|
-
|
|
1407
|
+
*([
|
|
1408
|
+
*([m] if (m := getattr(c, '__module__')) else []),
|
|
1409
|
+
getattr(c, '__qualname__', getattr(c, '__name__')),
|
|
1410
|
+
] if c is not None else '?'),
|
|
1304
1411
|
a,
|
|
1305
1412
|
])
|
|
1306
|
-
for a
|
|
1413
|
+
for a in ams
|
|
1414
|
+
for c in [amd.get(a)]
|
|
1307
1415
|
])),
|
|
1308
1416
|
)
|
|
1309
1417
|
|
|
@@ -1328,6 +1436,8 @@ TODO:
|
|
|
1328
1436
|
- per-attr repr transform / filter
|
|
1329
1437
|
- __ne__ ? cases where it still matters
|
|
1330
1438
|
- ordering ?
|
|
1439
|
+
- repr_filter: ta.Union[ta.Callable[[ta.Any], ta.Optional[str]], ta.Literal['not_none', 'truthy']]] ?
|
|
1440
|
+
- unify repr/repr_fn/repr_filter
|
|
1331
1441
|
"""
|
|
1332
1442
|
|
|
1333
1443
|
|
|
@@ -1345,6 +1455,8 @@ class AttrOps(ta.Generic[T]):
|
|
|
1345
1455
|
display: ta.Optional[str] = None,
|
|
1346
1456
|
|
|
1347
1457
|
repr: bool = True, # noqa
|
|
1458
|
+
repr_fn: ta.Optional[ta.Callable[[ta.Any], ta.Optional[str]]] = None,
|
|
1459
|
+
|
|
1348
1460
|
hash: bool = True, # noqa
|
|
1349
1461
|
eq: bool = True,
|
|
1350
1462
|
) -> None:
|
|
@@ -1359,6 +1471,8 @@ class AttrOps(ta.Generic[T]):
|
|
|
1359
1471
|
self._display = display
|
|
1360
1472
|
|
|
1361
1473
|
self._repr = repr
|
|
1474
|
+
self._repr_fn = repr_fn
|
|
1475
|
+
|
|
1362
1476
|
self._hash = hash
|
|
1363
1477
|
self._eq = eq
|
|
1364
1478
|
|
|
@@ -1366,21 +1480,30 @@ class AttrOps(ta.Generic[T]):
|
|
|
1366
1480
|
def of(
|
|
1367
1481
|
cls,
|
|
1368
1482
|
o: ta.Union[
|
|
1369
|
-
str,
|
|
1370
|
-
ta.Tuple[str, str],
|
|
1371
1483
|
'AttrOps.Attr',
|
|
1484
|
+
str,
|
|
1485
|
+
ta.Tuple[str, ta.Union[str, ta.Mapping[str, ta.Any]]],
|
|
1486
|
+
ta.Mapping[str, ta.Any],
|
|
1372
1487
|
],
|
|
1373
1488
|
) -> 'AttrOps.Attr':
|
|
1374
1489
|
if isinstance(o, AttrOps.Attr):
|
|
1375
1490
|
return o
|
|
1376
1491
|
elif isinstance(o, str):
|
|
1377
1492
|
return cls(o)
|
|
1493
|
+
elif isinstance(o, tuple):
|
|
1494
|
+
name, x = o
|
|
1495
|
+
kw: ta.Mapping[str, ta.Any]
|
|
1496
|
+
if isinstance(x, str):
|
|
1497
|
+
kw = dict(display=x)
|
|
1498
|
+
elif isinstance(x, ta.Mapping):
|
|
1499
|
+
kw = x
|
|
1500
|
+
else:
|
|
1501
|
+
raise TypeError(x)
|
|
1502
|
+
return cls(name, **kw)
|
|
1503
|
+
elif isinstance(o, ta.Mapping):
|
|
1504
|
+
return cls(**o)
|
|
1378
1505
|
else:
|
|
1379
|
-
|
|
1380
|
-
return cls(
|
|
1381
|
-
name,
|
|
1382
|
-
display=disp,
|
|
1383
|
-
)
|
|
1506
|
+
raise TypeError(o)
|
|
1384
1507
|
|
|
1385
1508
|
@property
|
|
1386
1509
|
def name(self) -> str:
|
|
@@ -1398,19 +1521,34 @@ class AttrOps(ta.Generic[T]):
|
|
|
1398
1521
|
def eq(self) -> bool:
|
|
1399
1522
|
return self._eq
|
|
1400
1523
|
|
|
1524
|
+
@staticmethod
|
|
1525
|
+
def opt_repr(o: ta.Any) -> ta.Optional[str]:
|
|
1526
|
+
return repr(o) if o is not None else None
|
|
1527
|
+
|
|
1528
|
+
@staticmethod
|
|
1529
|
+
def truthy_repr(o: ta.Any) -> ta.Optional[str]:
|
|
1530
|
+
return repr(o) if o else None
|
|
1531
|
+
|
|
1532
|
+
#
|
|
1533
|
+
|
|
1401
1534
|
@ta.overload
|
|
1402
1535
|
def __init__(
|
|
1403
1536
|
self,
|
|
1404
1537
|
*attrs: ta.Sequence[ta.Union[
|
|
1405
1538
|
str,
|
|
1406
|
-
ta.Tuple[str, str],
|
|
1539
|
+
ta.Tuple[str, ta.Union[str, ta.Mapping[str, ta.Any]]],
|
|
1540
|
+
ta.Mapping[str, ta.Any],
|
|
1407
1541
|
Attr,
|
|
1408
1542
|
]],
|
|
1543
|
+
|
|
1409
1544
|
with_module: bool = False,
|
|
1410
1545
|
use_qualname: bool = False,
|
|
1411
1546
|
with_id: bool = False,
|
|
1547
|
+
terse: bool = False,
|
|
1412
1548
|
repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
|
|
1413
1549
|
recursive: bool = False,
|
|
1550
|
+
|
|
1551
|
+
cache_hash: ta.Union[bool, str] = False,
|
|
1414
1552
|
subtypes_eq: bool = False,
|
|
1415
1553
|
) -> None:
|
|
1416
1554
|
...
|
|
@@ -1420,16 +1558,20 @@ class AttrOps(ta.Generic[T]):
|
|
|
1420
1558
|
self,
|
|
1421
1559
|
attrs_fn: ta.Callable[[T], ta.Tuple[ta.Union[
|
|
1422
1560
|
ta.Any,
|
|
1423
|
-
ta.Tuple[str, ta.Any],
|
|
1561
|
+
ta.Tuple[ta.Any, ta.Union[str, ta.Mapping[str, ta.Any]]],
|
|
1424
1562
|
Attr,
|
|
1425
1563
|
], ...]],
|
|
1426
1564
|
/,
|
|
1427
1565
|
*,
|
|
1566
|
+
|
|
1428
1567
|
with_module: bool = False,
|
|
1429
1568
|
use_qualname: bool = False,
|
|
1430
1569
|
with_id: bool = False,
|
|
1570
|
+
terse: bool = False,
|
|
1431
1571
|
repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
|
|
1432
1572
|
recursive: bool = False,
|
|
1573
|
+
|
|
1574
|
+
cache_hash: ta.Union[bool, str] = False,
|
|
1433
1575
|
subtypes_eq: bool = False,
|
|
1434
1576
|
) -> None:
|
|
1435
1577
|
...
|
|
@@ -1437,11 +1579,15 @@ class AttrOps(ta.Generic[T]):
|
|
|
1437
1579
|
def __init__(
|
|
1438
1580
|
self,
|
|
1439
1581
|
*args,
|
|
1582
|
+
|
|
1440
1583
|
with_module=False,
|
|
1441
1584
|
use_qualname=False,
|
|
1442
1585
|
with_id=False,
|
|
1586
|
+
terse=False,
|
|
1443
1587
|
repr_filter=None,
|
|
1444
1588
|
recursive=False,
|
|
1589
|
+
|
|
1590
|
+
cache_hash=False,
|
|
1445
1591
|
subtypes_eq=False,
|
|
1446
1592
|
) -> None:
|
|
1447
1593
|
if args and len(args) == 1 and callable(args[0]):
|
|
@@ -1452,8 +1598,11 @@ class AttrOps(ta.Generic[T]):
|
|
|
1452
1598
|
self._with_module: bool = with_module
|
|
1453
1599
|
self._use_qualname: bool = use_qualname
|
|
1454
1600
|
self._with_id: bool = with_id
|
|
1601
|
+
self._terse: bool = terse
|
|
1455
1602
|
self._repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = repr_filter
|
|
1456
1603
|
self._recursive: bool = recursive
|
|
1604
|
+
|
|
1605
|
+
self._cache_hash: ta.Union[bool, str] = cache_hash
|
|
1457
1606
|
self._subtypes_eq: bool = subtypes_eq
|
|
1458
1607
|
|
|
1459
1608
|
@property
|
|
@@ -1488,20 +1637,27 @@ class AttrOps(ta.Generic[T]):
|
|
|
1488
1637
|
|
|
1489
1638
|
attrs: ta.List[AttrOps.Attr] = []
|
|
1490
1639
|
for o in raw:
|
|
1491
|
-
if isinstance(o, AttrOps.Attr):
|
|
1492
|
-
attrs.append(o)
|
|
1640
|
+
if isinstance(o, (AttrOps.Attr, ta.Mapping)):
|
|
1641
|
+
attrs.append(AttrOps.Attr.of(o))
|
|
1493
1642
|
continue
|
|
1494
1643
|
|
|
1644
|
+
kw: ta.Mapping[str, ta.Any]
|
|
1495
1645
|
if isinstance(o, tuple):
|
|
1496
|
-
|
|
1646
|
+
cap, x = o
|
|
1647
|
+
if isinstance(x, str):
|
|
1648
|
+
kw = dict(display=x)
|
|
1649
|
+
elif isinstance(x, ta.Mapping):
|
|
1650
|
+
kw = x
|
|
1651
|
+
else:
|
|
1652
|
+
raise TypeError(x)
|
|
1497
1653
|
else:
|
|
1498
|
-
|
|
1654
|
+
cap, kw = o, {}
|
|
1499
1655
|
|
|
1500
1656
|
path = tuple(rec(cap))
|
|
1501
1657
|
|
|
1502
1658
|
attrs.append(AttrOps.Attr(
|
|
1503
1659
|
'.'.join(path),
|
|
1504
|
-
|
|
1660
|
+
**kw,
|
|
1505
1661
|
))
|
|
1506
1662
|
|
|
1507
1663
|
return attrs
|
|
@@ -1518,19 +1674,27 @@ class AttrOps(ta.Generic[T]):
|
|
|
1518
1674
|
pass
|
|
1519
1675
|
|
|
1520
1676
|
def _repr(o: T) -> str:
|
|
1521
|
-
vs =
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
if self._repr_filter is None
|
|
1527
|
-
|
|
1677
|
+
vs: ta.List[str] = []
|
|
1678
|
+
for a in self._attrs:
|
|
1679
|
+
if not a._repr: # noqa
|
|
1680
|
+
continue
|
|
1681
|
+
v = getattr(o, a._name) # noqa
|
|
1682
|
+
if self._repr_filter is not None and not self._repr_filter(v):
|
|
1683
|
+
continue
|
|
1684
|
+
if (rfn := a._repr_fn) is None: # noqa
|
|
1685
|
+
rfn = repr
|
|
1686
|
+
if (vr := rfn(v)) is None:
|
|
1687
|
+
continue
|
|
1688
|
+
if self._terse:
|
|
1689
|
+
vs.append(vr)
|
|
1690
|
+
else:
|
|
1691
|
+
vs.append(f'{a._display}={vr}') # noqa
|
|
1528
1692
|
|
|
1529
1693
|
return (
|
|
1530
1694
|
f'{o.__class__.__module__ + "." if self._with_module else ""}'
|
|
1531
1695
|
f'{o.__class__.__qualname__ if self._use_qualname else o.__class__.__name__}'
|
|
1532
1696
|
f'{("@" + hex(id(o))[2:]) if self._with_id else ""}' # noqa
|
|
1533
|
-
f'({vs})'
|
|
1697
|
+
f'({", ".join(vs)})'
|
|
1534
1698
|
)
|
|
1535
1699
|
|
|
1536
1700
|
if self._recursive:
|
|
@@ -1555,6 +1719,8 @@ class AttrOps(ta.Generic[T]):
|
|
|
1555
1719
|
|
|
1556
1720
|
#
|
|
1557
1721
|
|
|
1722
|
+
_DEFAULT_CACHED_HASH_ATTR: ta.ClassVar[str] = '__cached_hash__'
|
|
1723
|
+
|
|
1558
1724
|
_hash: ta.Callable[[T], int]
|
|
1559
1725
|
|
|
1560
1726
|
@property
|
|
@@ -1564,13 +1730,33 @@ class AttrOps(ta.Generic[T]):
|
|
|
1564
1730
|
except AttributeError:
|
|
1565
1731
|
pass
|
|
1566
1732
|
|
|
1567
|
-
def
|
|
1733
|
+
def _calc_hash(o: T) -> int:
|
|
1568
1734
|
return hash(tuple(
|
|
1569
1735
|
getattr(o, a._name) # noqa
|
|
1570
1736
|
for a in self._attrs
|
|
1571
1737
|
if a._hash # noqa
|
|
1572
1738
|
))
|
|
1573
1739
|
|
|
1740
|
+
if (ch := self._cache_hash) is not False:
|
|
1741
|
+
if ch is True:
|
|
1742
|
+
cha = self._DEFAULT_CACHED_HASH_ATTR
|
|
1743
|
+
elif isinstance(ch, str):
|
|
1744
|
+
cha = ch
|
|
1745
|
+
else:
|
|
1746
|
+
raise TypeError(ch)
|
|
1747
|
+
|
|
1748
|
+
def _cached_hash(o: T) -> int:
|
|
1749
|
+
try:
|
|
1750
|
+
return object.__getattribute__(o, cha)
|
|
1751
|
+
except AttributeError:
|
|
1752
|
+
object.__setattr__(o, cha, h := _calc_hash(o))
|
|
1753
|
+
return h
|
|
1754
|
+
|
|
1755
|
+
_hash = _cached_hash
|
|
1756
|
+
|
|
1757
|
+
else:
|
|
1758
|
+
_hash = _calc_hash
|
|
1759
|
+
|
|
1574
1760
|
self._hash = _hash
|
|
1575
1761
|
return _hash
|
|
1576
1762
|
|
|
@@ -1711,6 +1897,62 @@ def async_cached_nullary(fn): # ta.Callable[..., T]) -> ta.Callable[..., T]:
|
|
|
1711
1897
|
return _AsyncCachedNullary(fn)
|
|
1712
1898
|
|
|
1713
1899
|
|
|
1900
|
+
##
|
|
1901
|
+
|
|
1902
|
+
|
|
1903
|
+
cached_property = functools.cached_property
|
|
1904
|
+
|
|
1905
|
+
|
|
1906
|
+
class _cached_property: # noqa
|
|
1907
|
+
"""Backported to pick up https://github.com/python/cpython/commit/056dfc71dce15f81887f0bd6da09d6099d71f979 ."""
|
|
1908
|
+
|
|
1909
|
+
def __init__(self, func):
|
|
1910
|
+
self.func = func
|
|
1911
|
+
self.attrname = None # noqa
|
|
1912
|
+
self.__doc__ = func.__doc__
|
|
1913
|
+
self.__module__ = func.__module__
|
|
1914
|
+
|
|
1915
|
+
_NOT_FOUND = object()
|
|
1916
|
+
|
|
1917
|
+
def __set_name__(self, owner, name):
|
|
1918
|
+
if self.attrname is None:
|
|
1919
|
+
self.attrname = name # noqa
|
|
1920
|
+
elif name != self.attrname:
|
|
1921
|
+
raise TypeError(
|
|
1922
|
+
f'Cannot assign the same cached_property to two different names ({self.attrname!r} and {name!r}).',
|
|
1923
|
+
)
|
|
1924
|
+
|
|
1925
|
+
def __get__(self, instance, owner=None):
|
|
1926
|
+
if instance is None:
|
|
1927
|
+
return self
|
|
1928
|
+
if self.attrname is None:
|
|
1929
|
+
raise TypeError('Cannot use cached_property instance without calling __set_name__ on it.')
|
|
1930
|
+
|
|
1931
|
+
try:
|
|
1932
|
+
cache = instance.__dict__
|
|
1933
|
+
except AttributeError: # not all objects have __dict__ (e.g. class defines slots)
|
|
1934
|
+
raise TypeError(
|
|
1935
|
+
f"No '__dict__' attribute on {type(instance).__name__!r} instance to cache {self.attrname!r} property.",
|
|
1936
|
+
) from None
|
|
1937
|
+
|
|
1938
|
+
val = cache.get(self.attrname, self._NOT_FOUND)
|
|
1939
|
+
|
|
1940
|
+
if val is self._NOT_FOUND:
|
|
1941
|
+
val = self.func(instance)
|
|
1942
|
+
try:
|
|
1943
|
+
cache[self.attrname] = val
|
|
1944
|
+
except TypeError:
|
|
1945
|
+
raise TypeError(
|
|
1946
|
+
f"The '__dict__' attribute on {type(instance).__name__!r} instance does not support item "
|
|
1947
|
+
f"assignment for caching {self.attrname!r} property.",
|
|
1948
|
+
) from None
|
|
1949
|
+
|
|
1950
|
+
return val
|
|
1951
|
+
|
|
1952
|
+
|
|
1953
|
+
globals()['cached_property'] = _cached_property
|
|
1954
|
+
|
|
1955
|
+
|
|
1714
1956
|
########################################
|
|
1715
1957
|
# ../../../../../omlish/lite/check.py
|
|
1716
1958
|
"""
|
|
@@ -2250,7 +2492,7 @@ class ExitStacked:
|
|
|
2250
2492
|
es.__enter__()
|
|
2251
2493
|
try:
|
|
2252
2494
|
self._enter_contexts()
|
|
2253
|
-
except
|
|
2495
|
+
except BaseException: # noqa
|
|
2254
2496
|
es.__exit__(*sys.exc_info())
|
|
2255
2497
|
raise
|
|
2256
2498
|
return self
|
|
@@ -2261,7 +2503,7 @@ class ExitStacked:
|
|
|
2261
2503
|
return None
|
|
2262
2504
|
try:
|
|
2263
2505
|
self._exit_contexts()
|
|
2264
|
-
except
|
|
2506
|
+
except BaseException: # noqa
|
|
2265
2507
|
es.__exit__(*sys.exc_info())
|
|
2266
2508
|
raise
|
|
2267
2509
|
return es.__exit__(exc_type, exc_val, exc_tb)
|
|
@@ -2309,7 +2551,7 @@ class AsyncExitStacked:
|
|
|
2309
2551
|
await es.__aenter__()
|
|
2310
2552
|
try:
|
|
2311
2553
|
await self._async_enter_contexts()
|
|
2312
|
-
except
|
|
2554
|
+
except BaseException: # noqa
|
|
2313
2555
|
await es.__aexit__(*sys.exc_info())
|
|
2314
2556
|
raise
|
|
2315
2557
|
return self
|
|
@@ -2320,7 +2562,7 @@ class AsyncExitStacked:
|
|
|
2320
2562
|
return None
|
|
2321
2563
|
try:
|
|
2322
2564
|
await self._async_exit_contexts()
|
|
2323
|
-
except
|
|
2565
|
+
except BaseException: # noqa
|
|
2324
2566
|
await es.__aexit__(*sys.exc_info())
|
|
2325
2567
|
raise
|
|
2326
2568
|
return await es.__aexit__(exc_type, exc_val, exc_tb)
|
|
@@ -3747,6 +3989,10 @@ DEFAULT_CONFIG_RENDERER = SwitchedConfigRenderer(DEFAULT_CONFIG_RENDERERS)
|
|
|
3747
3989
|
|
|
3748
3990
|
########################################
|
|
3749
3991
|
# ../../../../../omlish/io/buffers.py
|
|
3992
|
+
"""
|
|
3993
|
+
TODO:
|
|
3994
|
+
- overhaul and just coro-ify pyio?
|
|
3995
|
+
"""
|
|
3750
3996
|
|
|
3751
3997
|
|
|
3752
3998
|
##
|
|
@@ -3925,6 +4171,9 @@ class ReadableListBuffer:
|
|
|
3925
4171
|
|
|
3926
4172
|
self._lst: list[bytes] = []
|
|
3927
4173
|
|
|
4174
|
+
def __bool__(self) -> ta.NoReturn:
|
|
4175
|
+
raise TypeError("Use 'buf is not None' or 'len(buf)'.")
|
|
4176
|
+
|
|
3928
4177
|
def __len__(self) -> int:
|
|
3929
4178
|
return sum(map(len, self._lst))
|
|
3930
4179
|
|
|
@@ -3950,6 +4199,9 @@ class ReadableListBuffer:
|
|
|
3950
4199
|
|
|
3951
4200
|
def read(self, n: ta.Optional[int] = None) -> ta.Optional[bytes]:
|
|
3952
4201
|
if n is None:
|
|
4202
|
+
if not self._lst:
|
|
4203
|
+
return b''
|
|
4204
|
+
|
|
3953
4205
|
o = b''.join(self._lst)
|
|
3954
4206
|
self._lst = []
|
|
3955
4207
|
return o
|
|
@@ -3988,6 +4240,110 @@ class ReadableListBuffer:
|
|
|
3988
4240
|
r = self.read_until_(delim)
|
|
3989
4241
|
return r if isinstance(r, bytes) else None
|
|
3990
4242
|
|
|
4243
|
+
#
|
|
4244
|
+
|
|
4245
|
+
DEFAULT_BUFFERED_READER_CHUNK_SIZE: ta.ClassVar[int] = -1
|
|
4246
|
+
|
|
4247
|
+
@ta.final
|
|
4248
|
+
class _BufferedBytesReader(BufferedBytesReader):
|
|
4249
|
+
def __init__(
|
|
4250
|
+
self,
|
|
4251
|
+
raw: RawBytesReader,
|
|
4252
|
+
buf: 'ReadableListBuffer',
|
|
4253
|
+
*,
|
|
4254
|
+
chunk_size: ta.Optional[int] = None,
|
|
4255
|
+
) -> None:
|
|
4256
|
+
self._raw = raw
|
|
4257
|
+
self._buf = buf
|
|
4258
|
+
self._chunk_size = chunk_size or ReadableListBuffer.DEFAULT_BUFFERED_READER_CHUNK_SIZE
|
|
4259
|
+
|
|
4260
|
+
def read1(self, n: int = -1, /) -> bytes:
|
|
4261
|
+
if n < 0:
|
|
4262
|
+
n = self._chunk_size
|
|
4263
|
+
if not n:
|
|
4264
|
+
return b''
|
|
4265
|
+
if 0 < n <= len(self._buf):
|
|
4266
|
+
return self._buf.read(n) or b''
|
|
4267
|
+
return self._raw.read1(n)
|
|
4268
|
+
|
|
4269
|
+
def read(self, /, n: int = -1) -> bytes:
|
|
4270
|
+
if n < 0:
|
|
4271
|
+
return self.readall()
|
|
4272
|
+
while len(self._buf) < n:
|
|
4273
|
+
if not (b := self._raw.read1(n)):
|
|
4274
|
+
break
|
|
4275
|
+
self._buf.feed(b)
|
|
4276
|
+
return self._buf.read(n) or b''
|
|
4277
|
+
|
|
4278
|
+
def readall(self) -> bytes:
|
|
4279
|
+
buf = io.BytesIO()
|
|
4280
|
+
buf.write(self._buf.read() or b'')
|
|
4281
|
+
while (b := self._raw.read1(self._chunk_size)):
|
|
4282
|
+
buf.write(b)
|
|
4283
|
+
return buf.getvalue()
|
|
4284
|
+
|
|
4285
|
+
def new_buffered_reader(
|
|
4286
|
+
self,
|
|
4287
|
+
raw: RawBytesReader,
|
|
4288
|
+
*,
|
|
4289
|
+
chunk_size: ta.Optional[int] = None,
|
|
4290
|
+
) -> BufferedBytesReader:
|
|
4291
|
+
return self._BufferedBytesReader(
|
|
4292
|
+
raw,
|
|
4293
|
+
self,
|
|
4294
|
+
chunk_size=chunk_size,
|
|
4295
|
+
)
|
|
4296
|
+
|
|
4297
|
+
@ta.final
|
|
4298
|
+
class _AsyncBufferedBytesReader(AsyncBufferedBytesReader):
|
|
4299
|
+
def __init__(
|
|
4300
|
+
self,
|
|
4301
|
+
raw: AsyncRawBytesReader,
|
|
4302
|
+
buf: 'ReadableListBuffer',
|
|
4303
|
+
*,
|
|
4304
|
+
chunk_size: ta.Optional[int] = None,
|
|
4305
|
+
) -> None:
|
|
4306
|
+
self._raw = raw
|
|
4307
|
+
self._buf = buf
|
|
4308
|
+
self._chunk_size = chunk_size or ReadableListBuffer.DEFAULT_BUFFERED_READER_CHUNK_SIZE
|
|
4309
|
+
|
|
4310
|
+
async def read1(self, n: int = -1, /) -> bytes:
|
|
4311
|
+
if n < 0:
|
|
4312
|
+
n = self._chunk_size
|
|
4313
|
+
if not n:
|
|
4314
|
+
return b''
|
|
4315
|
+
if 0 < n <= len(self._buf):
|
|
4316
|
+
return self._buf.read(n) or b''
|
|
4317
|
+
return await self._raw.read1(n)
|
|
4318
|
+
|
|
4319
|
+
async def read(self, /, n: int = -1) -> bytes:
|
|
4320
|
+
if n < 0:
|
|
4321
|
+
return await self.readall()
|
|
4322
|
+
while len(self._buf) < n:
|
|
4323
|
+
if not (b := await self._raw.read1(n)):
|
|
4324
|
+
break
|
|
4325
|
+
self._buf.feed(b)
|
|
4326
|
+
return self._buf.read(n) or b''
|
|
4327
|
+
|
|
4328
|
+
async def readall(self) -> bytes:
|
|
4329
|
+
buf = io.BytesIO()
|
|
4330
|
+
buf.write(self._buf.read() or b'')
|
|
4331
|
+
while b := await self._raw.read1(self._chunk_size):
|
|
4332
|
+
buf.write(b)
|
|
4333
|
+
return buf.getvalue()
|
|
4334
|
+
|
|
4335
|
+
def new_async_buffered_reader(
|
|
4336
|
+
self,
|
|
4337
|
+
raw: AsyncRawBytesReader,
|
|
4338
|
+
*,
|
|
4339
|
+
chunk_size: ta.Optional[int] = None,
|
|
4340
|
+
) -> AsyncBufferedBytesReader:
|
|
4341
|
+
return self._AsyncBufferedBytesReader(
|
|
4342
|
+
raw,
|
|
4343
|
+
self,
|
|
4344
|
+
chunk_size=chunk_size,
|
|
4345
|
+
)
|
|
4346
|
+
|
|
3991
4347
|
|
|
3992
4348
|
##
|
|
3993
4349
|
|