ominfra 0.0.0.dev439__py3-none-any.whl → 0.0.0.dev441__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.

@@ -1345,6 +1345,8 @@ class AttrOps(ta.Generic[T]):
1345
1345
  display: ta.Optional[str] = None,
1346
1346
 
1347
1347
  repr: bool = True, # noqa
1348
+ repr_fn: ta.Optional[ta.Callable[[ta.Any], ta.Optional[str]]] = None,
1349
+
1348
1350
  hash: bool = True, # noqa
1349
1351
  eq: bool = True,
1350
1352
  ) -> None:
@@ -1359,6 +1361,8 @@ class AttrOps(ta.Generic[T]):
1359
1361
  self._display = display
1360
1362
 
1361
1363
  self._repr = repr
1364
+ self._repr_fn = repr_fn
1365
+
1362
1366
  self._hash = hash
1363
1367
  self._eq = eq
1364
1368
 
@@ -1366,21 +1370,30 @@ class AttrOps(ta.Generic[T]):
1366
1370
  def of(
1367
1371
  cls,
1368
1372
  o: ta.Union[
1369
- str,
1370
- ta.Tuple[str, str],
1371
1373
  'AttrOps.Attr',
1374
+ str,
1375
+ ta.Tuple[str, ta.Union[str, ta.Mapping[str, ta.Any]]],
1376
+ ta.Mapping[str, ta.Any],
1372
1377
  ],
1373
1378
  ) -> 'AttrOps.Attr':
1374
1379
  if isinstance(o, AttrOps.Attr):
1375
1380
  return o
1376
1381
  elif isinstance(o, str):
1377
1382
  return cls(o)
1383
+ elif isinstance(o, tuple):
1384
+ name, x = o
1385
+ kw: ta.Mapping[str, ta.Any]
1386
+ if isinstance(x, str):
1387
+ kw = dict(display=x)
1388
+ elif isinstance(x, ta.Mapping):
1389
+ kw = x
1390
+ else:
1391
+ raise TypeError(x)
1392
+ return cls(name, **kw)
1393
+ elif isinstance(o, ta.Mapping):
1394
+ return cls(**o)
1378
1395
  else:
1379
- name, disp = o
1380
- return cls(
1381
- name,
1382
- display=disp,
1383
- )
1396
+ raise TypeError(o)
1384
1397
 
1385
1398
  @property
1386
1399
  def name(self) -> str:
@@ -1398,19 +1411,34 @@ class AttrOps(ta.Generic[T]):
1398
1411
  def eq(self) -> bool:
1399
1412
  return self._eq
1400
1413
 
1414
+ @staticmethod
1415
+ def opt_repr(o: ta.Any) -> ta.Optional[str]:
1416
+ return repr(o) if o is not None else None
1417
+
1418
+ @staticmethod
1419
+ def truthy_repr(o: ta.Any) -> ta.Optional[str]:
1420
+ return repr(o) if o else None
1421
+
1422
+ #
1423
+
1401
1424
  @ta.overload
1402
1425
  def __init__(
1403
1426
  self,
1404
1427
  *attrs: ta.Sequence[ta.Union[
1405
1428
  str,
1406
- ta.Tuple[str, str],
1429
+ ta.Tuple[str, ta.Union[str, ta.Mapping[str, ta.Any]]],
1430
+ ta.Mapping[str, ta.Any],
1407
1431
  Attr,
1408
1432
  ]],
1433
+
1409
1434
  with_module: bool = False,
1410
1435
  use_qualname: bool = False,
1411
1436
  with_id: bool = False,
1437
+ terse: bool = False,
1412
1438
  repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
1413
1439
  recursive: bool = False,
1440
+
1441
+ cache_hash: ta.Union[bool, str] = False,
1414
1442
  subtypes_eq: bool = False,
1415
1443
  ) -> None:
1416
1444
  ...
@@ -1420,16 +1448,20 @@ class AttrOps(ta.Generic[T]):
1420
1448
  self,
1421
1449
  attrs_fn: ta.Callable[[T], ta.Tuple[ta.Union[
1422
1450
  ta.Any,
1423
- ta.Tuple[str, ta.Any],
1451
+ ta.Tuple[ta.Any, ta.Union[str, ta.Mapping[str, ta.Any]]],
1424
1452
  Attr,
1425
1453
  ], ...]],
1426
1454
  /,
1427
1455
  *,
1456
+
1428
1457
  with_module: bool = False,
1429
1458
  use_qualname: bool = False,
1430
1459
  with_id: bool = False,
1460
+ terse: bool = False,
1431
1461
  repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
1432
1462
  recursive: bool = False,
1463
+
1464
+ cache_hash: ta.Union[bool, str] = False,
1433
1465
  subtypes_eq: bool = False,
1434
1466
  ) -> None:
1435
1467
  ...
@@ -1437,11 +1469,15 @@ class AttrOps(ta.Generic[T]):
1437
1469
  def __init__(
1438
1470
  self,
1439
1471
  *args,
1472
+
1440
1473
  with_module=False,
1441
1474
  use_qualname=False,
1442
1475
  with_id=False,
1476
+ terse=False,
1443
1477
  repr_filter=None,
1444
1478
  recursive=False,
1479
+
1480
+ cache_hash=False,
1445
1481
  subtypes_eq=False,
1446
1482
  ) -> None:
1447
1483
  if args and len(args) == 1 and callable(args[0]):
@@ -1452,8 +1488,11 @@ class AttrOps(ta.Generic[T]):
1452
1488
  self._with_module: bool = with_module
1453
1489
  self._use_qualname: bool = use_qualname
1454
1490
  self._with_id: bool = with_id
1491
+ self._terse: bool = terse
1455
1492
  self._repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = repr_filter
1456
1493
  self._recursive: bool = recursive
1494
+
1495
+ self._cache_hash: ta.Union[bool, str] = cache_hash
1457
1496
  self._subtypes_eq: bool = subtypes_eq
1458
1497
 
1459
1498
  @property
@@ -1488,20 +1527,27 @@ class AttrOps(ta.Generic[T]):
1488
1527
 
1489
1528
  attrs: ta.List[AttrOps.Attr] = []
1490
1529
  for o in raw:
1491
- if isinstance(o, AttrOps.Attr):
1492
- attrs.append(o)
1530
+ if isinstance(o, (AttrOps.Attr, ta.Mapping)):
1531
+ attrs.append(AttrOps.Attr.of(o))
1493
1532
  continue
1494
1533
 
1534
+ kw: ta.Mapping[str, ta.Any]
1495
1535
  if isinstance(o, tuple):
1496
- disp, cap, = o
1536
+ cap, x = o
1537
+ if isinstance(x, str):
1538
+ kw = dict(display=x)
1539
+ elif isinstance(x, ta.Mapping):
1540
+ kw = x
1541
+ else:
1542
+ raise TypeError(x)
1497
1543
  else:
1498
- disp, cap = None, o
1544
+ cap, kw = o, {}
1499
1545
 
1500
1546
  path = tuple(rec(cap))
1501
1547
 
1502
1548
  attrs.append(AttrOps.Attr(
1503
1549
  '.'.join(path),
1504
- display=disp,
1550
+ **kw,
1505
1551
  ))
1506
1552
 
1507
1553
  return attrs
@@ -1518,19 +1564,27 @@ class AttrOps(ta.Generic[T]):
1518
1564
  pass
1519
1565
 
1520
1566
  def _repr(o: T) -> str:
1521
- vs = ', '.join(
1522
- f'{a._display}={v!r}' # noqa
1523
- for a in self._attrs
1524
- if a._repr # noqa
1525
- for v in [getattr(o, a._name)] # noqa
1526
- if self._repr_filter is None or self._repr_filter(v)
1527
- )
1567
+ vs: ta.List[str] = []
1568
+ for a in self._attrs:
1569
+ if not a._repr: # noqa
1570
+ continue
1571
+ v = getattr(o, a._name) # noqa
1572
+ if self._repr_filter is not None and not self._repr_filter(v):
1573
+ continue
1574
+ if (rfn := a._repr_fn) is None: # noqa
1575
+ rfn = repr
1576
+ if (vr := rfn(v)) is None:
1577
+ continue
1578
+ if self._terse:
1579
+ vs.append(vr)
1580
+ else:
1581
+ vs.append(f'{a._display}={vr}') # noqa
1528
1582
 
1529
1583
  return (
1530
1584
  f'{o.__class__.__module__ + "." if self._with_module else ""}'
1531
1585
  f'{o.__class__.__qualname__ if self._use_qualname else o.__class__.__name__}'
1532
1586
  f'{("@" + hex(id(o))[2:]) if self._with_id else ""}' # noqa
1533
- f'({vs})'
1587
+ f'({", ".join(vs)})'
1534
1588
  )
1535
1589
 
1536
1590
  if self._recursive:
@@ -1555,6 +1609,8 @@ class AttrOps(ta.Generic[T]):
1555
1609
 
1556
1610
  #
1557
1611
 
1612
+ _DEFAULT_CACHED_HASH_ATTR: ta.ClassVar[str] = '__cached_hash__'
1613
+
1558
1614
  _hash: ta.Callable[[T], int]
1559
1615
 
1560
1616
  @property
@@ -1564,13 +1620,33 @@ class AttrOps(ta.Generic[T]):
1564
1620
  except AttributeError:
1565
1621
  pass
1566
1622
 
1567
- def _hash(o: T) -> int:
1623
+ def _calc_hash(o: T) -> int:
1568
1624
  return hash(tuple(
1569
1625
  getattr(o, a._name) # noqa
1570
1626
  for a in self._attrs
1571
1627
  if a._hash # noqa
1572
1628
  ))
1573
1629
 
1630
+ if (ch := self._cache_hash) is not False:
1631
+ if ch is True:
1632
+ cha = self._DEFAULT_CACHED_HASH_ATTR
1633
+ elif isinstance(ch, str):
1634
+ cha = ch
1635
+ else:
1636
+ raise TypeError(ch)
1637
+
1638
+ def _cached_hash(o: T) -> int:
1639
+ try:
1640
+ return object.__getattribute__(o, cha)
1641
+ except AttributeError:
1642
+ object.__setattr__(o, cha, h := _calc_hash(o))
1643
+ return h
1644
+
1645
+ _hash = _cached_hash
1646
+
1647
+ else:
1648
+ _hash = _calc_hash
1649
+
1574
1650
  self._hash = _hash
1575
1651
  return _hash
1576
1652
 
@@ -1711,6 +1787,62 @@ def async_cached_nullary(fn): # ta.Callable[..., T]) -> ta.Callable[..., T]:
1711
1787
  return _AsyncCachedNullary(fn)
1712
1788
 
1713
1789
 
1790
+ ##
1791
+
1792
+
1793
+ cached_property = functools.cached_property
1794
+
1795
+
1796
+ class _cached_property: # noqa
1797
+ """Backported to pick up https://github.com/python/cpython/commit/056dfc71dce15f81887f0bd6da09d6099d71f979 ."""
1798
+
1799
+ def __init__(self, func):
1800
+ self.func = func
1801
+ self.attrname = None # noqa
1802
+ self.__doc__ = func.__doc__
1803
+ self.__module__ = func.__module__
1804
+
1805
+ _NOT_FOUND = object()
1806
+
1807
+ def __set_name__(self, owner, name):
1808
+ if self.attrname is None:
1809
+ self.attrname = name # noqa
1810
+ elif name != self.attrname:
1811
+ raise TypeError(
1812
+ f'Cannot assign the same cached_property to two different names ({self.attrname!r} and {name!r}).',
1813
+ )
1814
+
1815
+ def __get__(self, instance, owner=None):
1816
+ if instance is None:
1817
+ return self
1818
+ if self.attrname is None:
1819
+ raise TypeError('Cannot use cached_property instance without calling __set_name__ on it.')
1820
+
1821
+ try:
1822
+ cache = instance.__dict__
1823
+ except AttributeError: # not all objects have __dict__ (e.g. class defines slots)
1824
+ raise TypeError(
1825
+ f"No '__dict__' attribute on {type(instance).__name__!r} instance to cache {self.attrname!r} property.",
1826
+ ) from None
1827
+
1828
+ val = cache.get(self.attrname, self._NOT_FOUND)
1829
+
1830
+ if val is self._NOT_FOUND:
1831
+ val = self.func(instance)
1832
+ try:
1833
+ cache[self.attrname] = val
1834
+ except TypeError:
1835
+ raise TypeError(
1836
+ f"The '__dict__' attribute on {type(instance).__name__!r} instance does not support item "
1837
+ f"assignment for caching {self.attrname!r} property.",
1838
+ ) from None
1839
+
1840
+ return val
1841
+
1842
+
1843
+ globals()['cached_property'] = _cached_property
1844
+
1845
+
1714
1846
  ########################################
1715
1847
  # ../../../../../omlish/lite/check.py
1716
1848
  """
ominfra/scripts/manage.py CHANGED
@@ -2524,6 +2524,8 @@ class AttrOps(ta.Generic[T]):
2524
2524
  display: ta.Optional[str] = None,
2525
2525
 
2526
2526
  repr: bool = True, # noqa
2527
+ repr_fn: ta.Optional[ta.Callable[[ta.Any], ta.Optional[str]]] = None,
2528
+
2527
2529
  hash: bool = True, # noqa
2528
2530
  eq: bool = True,
2529
2531
  ) -> None:
@@ -2538,6 +2540,8 @@ class AttrOps(ta.Generic[T]):
2538
2540
  self._display = display
2539
2541
 
2540
2542
  self._repr = repr
2543
+ self._repr_fn = repr_fn
2544
+
2541
2545
  self._hash = hash
2542
2546
  self._eq = eq
2543
2547
 
@@ -2545,21 +2549,30 @@ class AttrOps(ta.Generic[T]):
2545
2549
  def of(
2546
2550
  cls,
2547
2551
  o: ta.Union[
2548
- str,
2549
- ta.Tuple[str, str],
2550
2552
  'AttrOps.Attr',
2553
+ str,
2554
+ ta.Tuple[str, ta.Union[str, ta.Mapping[str, ta.Any]]],
2555
+ ta.Mapping[str, ta.Any],
2551
2556
  ],
2552
2557
  ) -> 'AttrOps.Attr':
2553
2558
  if isinstance(o, AttrOps.Attr):
2554
2559
  return o
2555
2560
  elif isinstance(o, str):
2556
2561
  return cls(o)
2562
+ elif isinstance(o, tuple):
2563
+ name, x = o
2564
+ kw: ta.Mapping[str, ta.Any]
2565
+ if isinstance(x, str):
2566
+ kw = dict(display=x)
2567
+ elif isinstance(x, ta.Mapping):
2568
+ kw = x
2569
+ else:
2570
+ raise TypeError(x)
2571
+ return cls(name, **kw)
2572
+ elif isinstance(o, ta.Mapping):
2573
+ return cls(**o)
2557
2574
  else:
2558
- name, disp = o
2559
- return cls(
2560
- name,
2561
- display=disp,
2562
- )
2575
+ raise TypeError(o)
2563
2576
 
2564
2577
  @property
2565
2578
  def name(self) -> str:
@@ -2577,19 +2590,34 @@ class AttrOps(ta.Generic[T]):
2577
2590
  def eq(self) -> bool:
2578
2591
  return self._eq
2579
2592
 
2593
+ @staticmethod
2594
+ def opt_repr(o: ta.Any) -> ta.Optional[str]:
2595
+ return repr(o) if o is not None else None
2596
+
2597
+ @staticmethod
2598
+ def truthy_repr(o: ta.Any) -> ta.Optional[str]:
2599
+ return repr(o) if o else None
2600
+
2601
+ #
2602
+
2580
2603
  @ta.overload
2581
2604
  def __init__(
2582
2605
  self,
2583
2606
  *attrs: ta.Sequence[ta.Union[
2584
2607
  str,
2585
- ta.Tuple[str, str],
2608
+ ta.Tuple[str, ta.Union[str, ta.Mapping[str, ta.Any]]],
2609
+ ta.Mapping[str, ta.Any],
2586
2610
  Attr,
2587
2611
  ]],
2612
+
2588
2613
  with_module: bool = False,
2589
2614
  use_qualname: bool = False,
2590
2615
  with_id: bool = False,
2616
+ terse: bool = False,
2591
2617
  repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
2592
2618
  recursive: bool = False,
2619
+
2620
+ cache_hash: ta.Union[bool, str] = False,
2593
2621
  subtypes_eq: bool = False,
2594
2622
  ) -> None:
2595
2623
  ...
@@ -2599,16 +2627,20 @@ class AttrOps(ta.Generic[T]):
2599
2627
  self,
2600
2628
  attrs_fn: ta.Callable[[T], ta.Tuple[ta.Union[
2601
2629
  ta.Any,
2602
- ta.Tuple[str, ta.Any],
2630
+ ta.Tuple[ta.Any, ta.Union[str, ta.Mapping[str, ta.Any]]],
2603
2631
  Attr,
2604
2632
  ], ...]],
2605
2633
  /,
2606
2634
  *,
2635
+
2607
2636
  with_module: bool = False,
2608
2637
  use_qualname: bool = False,
2609
2638
  with_id: bool = False,
2639
+ terse: bool = False,
2610
2640
  repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
2611
2641
  recursive: bool = False,
2642
+
2643
+ cache_hash: ta.Union[bool, str] = False,
2612
2644
  subtypes_eq: bool = False,
2613
2645
  ) -> None:
2614
2646
  ...
@@ -2616,11 +2648,15 @@ class AttrOps(ta.Generic[T]):
2616
2648
  def __init__(
2617
2649
  self,
2618
2650
  *args,
2651
+
2619
2652
  with_module=False,
2620
2653
  use_qualname=False,
2621
2654
  with_id=False,
2655
+ terse=False,
2622
2656
  repr_filter=None,
2623
2657
  recursive=False,
2658
+
2659
+ cache_hash=False,
2624
2660
  subtypes_eq=False,
2625
2661
  ) -> None:
2626
2662
  if args and len(args) == 1 and callable(args[0]):
@@ -2631,8 +2667,11 @@ class AttrOps(ta.Generic[T]):
2631
2667
  self._with_module: bool = with_module
2632
2668
  self._use_qualname: bool = use_qualname
2633
2669
  self._with_id: bool = with_id
2670
+ self._terse: bool = terse
2634
2671
  self._repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = repr_filter
2635
2672
  self._recursive: bool = recursive
2673
+
2674
+ self._cache_hash: ta.Union[bool, str] = cache_hash
2636
2675
  self._subtypes_eq: bool = subtypes_eq
2637
2676
 
2638
2677
  @property
@@ -2667,20 +2706,27 @@ class AttrOps(ta.Generic[T]):
2667
2706
 
2668
2707
  attrs: ta.List[AttrOps.Attr] = []
2669
2708
  for o in raw:
2670
- if isinstance(o, AttrOps.Attr):
2671
- attrs.append(o)
2709
+ if isinstance(o, (AttrOps.Attr, ta.Mapping)):
2710
+ attrs.append(AttrOps.Attr.of(o))
2672
2711
  continue
2673
2712
 
2713
+ kw: ta.Mapping[str, ta.Any]
2674
2714
  if isinstance(o, tuple):
2675
- disp, cap, = o
2715
+ cap, x = o
2716
+ if isinstance(x, str):
2717
+ kw = dict(display=x)
2718
+ elif isinstance(x, ta.Mapping):
2719
+ kw = x
2720
+ else:
2721
+ raise TypeError(x)
2676
2722
  else:
2677
- disp, cap = None, o
2723
+ cap, kw = o, {}
2678
2724
 
2679
2725
  path = tuple(rec(cap))
2680
2726
 
2681
2727
  attrs.append(AttrOps.Attr(
2682
2728
  '.'.join(path),
2683
- display=disp,
2729
+ **kw,
2684
2730
  ))
2685
2731
 
2686
2732
  return attrs
@@ -2697,19 +2743,27 @@ class AttrOps(ta.Generic[T]):
2697
2743
  pass
2698
2744
 
2699
2745
  def _repr(o: T) -> str:
2700
- vs = ', '.join(
2701
- f'{a._display}={v!r}' # noqa
2702
- for a in self._attrs
2703
- if a._repr # noqa
2704
- for v in [getattr(o, a._name)] # noqa
2705
- if self._repr_filter is None or self._repr_filter(v)
2706
- )
2746
+ vs: ta.List[str] = []
2747
+ for a in self._attrs:
2748
+ if not a._repr: # noqa
2749
+ continue
2750
+ v = getattr(o, a._name) # noqa
2751
+ if self._repr_filter is not None and not self._repr_filter(v):
2752
+ continue
2753
+ if (rfn := a._repr_fn) is None: # noqa
2754
+ rfn = repr
2755
+ if (vr := rfn(v)) is None:
2756
+ continue
2757
+ if self._terse:
2758
+ vs.append(vr)
2759
+ else:
2760
+ vs.append(f'{a._display}={vr}') # noqa
2707
2761
 
2708
2762
  return (
2709
2763
  f'{o.__class__.__module__ + "." if self._with_module else ""}'
2710
2764
  f'{o.__class__.__qualname__ if self._use_qualname else o.__class__.__name__}'
2711
2765
  f'{("@" + hex(id(o))[2:]) if self._with_id else ""}' # noqa
2712
- f'({vs})'
2766
+ f'({", ".join(vs)})'
2713
2767
  )
2714
2768
 
2715
2769
  if self._recursive:
@@ -2734,6 +2788,8 @@ class AttrOps(ta.Generic[T]):
2734
2788
 
2735
2789
  #
2736
2790
 
2791
+ _DEFAULT_CACHED_HASH_ATTR: ta.ClassVar[str] = '__cached_hash__'
2792
+
2737
2793
  _hash: ta.Callable[[T], int]
2738
2794
 
2739
2795
  @property
@@ -2743,13 +2799,33 @@ class AttrOps(ta.Generic[T]):
2743
2799
  except AttributeError:
2744
2800
  pass
2745
2801
 
2746
- def _hash(o: T) -> int:
2802
+ def _calc_hash(o: T) -> int:
2747
2803
  return hash(tuple(
2748
2804
  getattr(o, a._name) # noqa
2749
2805
  for a in self._attrs
2750
2806
  if a._hash # noqa
2751
2807
  ))
2752
2808
 
2809
+ if (ch := self._cache_hash) is not False:
2810
+ if ch is True:
2811
+ cha = self._DEFAULT_CACHED_HASH_ATTR
2812
+ elif isinstance(ch, str):
2813
+ cha = ch
2814
+ else:
2815
+ raise TypeError(ch)
2816
+
2817
+ def _cached_hash(o: T) -> int:
2818
+ try:
2819
+ return object.__getattribute__(o, cha)
2820
+ except AttributeError:
2821
+ object.__setattr__(o, cha, h := _calc_hash(o))
2822
+ return h
2823
+
2824
+ _hash = _cached_hash
2825
+
2826
+ else:
2827
+ _hash = _calc_hash
2828
+
2753
2829
  self._hash = _hash
2754
2830
  return _hash
2755
2831
 
@@ -2890,6 +2966,62 @@ def async_cached_nullary(fn): # ta.Callable[..., T]) -> ta.Callable[..., T]:
2890
2966
  return _AsyncCachedNullary(fn)
2891
2967
 
2892
2968
 
2969
+ ##
2970
+
2971
+
2972
+ cached_property = functools.cached_property
2973
+
2974
+
2975
+ class _cached_property: # noqa
2976
+ """Backported to pick up https://github.com/python/cpython/commit/056dfc71dce15f81887f0bd6da09d6099d71f979 ."""
2977
+
2978
+ def __init__(self, func):
2979
+ self.func = func
2980
+ self.attrname = None # noqa
2981
+ self.__doc__ = func.__doc__
2982
+ self.__module__ = func.__module__
2983
+
2984
+ _NOT_FOUND = object()
2985
+
2986
+ def __set_name__(self, owner, name):
2987
+ if self.attrname is None:
2988
+ self.attrname = name # noqa
2989
+ elif name != self.attrname:
2990
+ raise TypeError(
2991
+ f'Cannot assign the same cached_property to two different names ({self.attrname!r} and {name!r}).',
2992
+ )
2993
+
2994
+ def __get__(self, instance, owner=None):
2995
+ if instance is None:
2996
+ return self
2997
+ if self.attrname is None:
2998
+ raise TypeError('Cannot use cached_property instance without calling __set_name__ on it.')
2999
+
3000
+ try:
3001
+ cache = instance.__dict__
3002
+ except AttributeError: # not all objects have __dict__ (e.g. class defines slots)
3003
+ raise TypeError(
3004
+ f"No '__dict__' attribute on {type(instance).__name__!r} instance to cache {self.attrname!r} property.",
3005
+ ) from None
3006
+
3007
+ val = cache.get(self.attrname, self._NOT_FOUND)
3008
+
3009
+ if val is self._NOT_FOUND:
3010
+ val = self.func(instance)
3011
+ try:
3012
+ cache[self.attrname] = val
3013
+ except TypeError:
3014
+ raise TypeError(
3015
+ f"The '__dict__' attribute on {type(instance).__name__!r} instance does not support item "
3016
+ f"assignment for caching {self.attrname!r} property.",
3017
+ ) from None
3018
+
3019
+ return val
3020
+
3021
+
3022
+ globals()['cached_property'] = _cached_property
3023
+
3024
+
2893
3025
  ########################################
2894
3026
  # ../../../omlish/lite/check.py
2895
3027
  """
@@ -1870,6 +1870,8 @@ class AttrOps(ta.Generic[T]):
1870
1870
  display: ta.Optional[str] = None,
1871
1871
 
1872
1872
  repr: bool = True, # noqa
1873
+ repr_fn: ta.Optional[ta.Callable[[ta.Any], ta.Optional[str]]] = None,
1874
+
1873
1875
  hash: bool = True, # noqa
1874
1876
  eq: bool = True,
1875
1877
  ) -> None:
@@ -1884,6 +1886,8 @@ class AttrOps(ta.Generic[T]):
1884
1886
  self._display = display
1885
1887
 
1886
1888
  self._repr = repr
1889
+ self._repr_fn = repr_fn
1890
+
1887
1891
  self._hash = hash
1888
1892
  self._eq = eq
1889
1893
 
@@ -1891,21 +1895,30 @@ class AttrOps(ta.Generic[T]):
1891
1895
  def of(
1892
1896
  cls,
1893
1897
  o: ta.Union[
1894
- str,
1895
- ta.Tuple[str, str],
1896
1898
  'AttrOps.Attr',
1899
+ str,
1900
+ ta.Tuple[str, ta.Union[str, ta.Mapping[str, ta.Any]]],
1901
+ ta.Mapping[str, ta.Any],
1897
1902
  ],
1898
1903
  ) -> 'AttrOps.Attr':
1899
1904
  if isinstance(o, AttrOps.Attr):
1900
1905
  return o
1901
1906
  elif isinstance(o, str):
1902
1907
  return cls(o)
1908
+ elif isinstance(o, tuple):
1909
+ name, x = o
1910
+ kw: ta.Mapping[str, ta.Any]
1911
+ if isinstance(x, str):
1912
+ kw = dict(display=x)
1913
+ elif isinstance(x, ta.Mapping):
1914
+ kw = x
1915
+ else:
1916
+ raise TypeError(x)
1917
+ return cls(name, **kw)
1918
+ elif isinstance(o, ta.Mapping):
1919
+ return cls(**o)
1903
1920
  else:
1904
- name, disp = o
1905
- return cls(
1906
- name,
1907
- display=disp,
1908
- )
1921
+ raise TypeError(o)
1909
1922
 
1910
1923
  @property
1911
1924
  def name(self) -> str:
@@ -1923,19 +1936,34 @@ class AttrOps(ta.Generic[T]):
1923
1936
  def eq(self) -> bool:
1924
1937
  return self._eq
1925
1938
 
1939
+ @staticmethod
1940
+ def opt_repr(o: ta.Any) -> ta.Optional[str]:
1941
+ return repr(o) if o is not None else None
1942
+
1943
+ @staticmethod
1944
+ def truthy_repr(o: ta.Any) -> ta.Optional[str]:
1945
+ return repr(o) if o else None
1946
+
1947
+ #
1948
+
1926
1949
  @ta.overload
1927
1950
  def __init__(
1928
1951
  self,
1929
1952
  *attrs: ta.Sequence[ta.Union[
1930
1953
  str,
1931
- ta.Tuple[str, str],
1954
+ ta.Tuple[str, ta.Union[str, ta.Mapping[str, ta.Any]]],
1955
+ ta.Mapping[str, ta.Any],
1932
1956
  Attr,
1933
1957
  ]],
1958
+
1934
1959
  with_module: bool = False,
1935
1960
  use_qualname: bool = False,
1936
1961
  with_id: bool = False,
1962
+ terse: bool = False,
1937
1963
  repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
1938
1964
  recursive: bool = False,
1965
+
1966
+ cache_hash: ta.Union[bool, str] = False,
1939
1967
  subtypes_eq: bool = False,
1940
1968
  ) -> None:
1941
1969
  ...
@@ -1945,16 +1973,20 @@ class AttrOps(ta.Generic[T]):
1945
1973
  self,
1946
1974
  attrs_fn: ta.Callable[[T], ta.Tuple[ta.Union[
1947
1975
  ta.Any,
1948
- ta.Tuple[str, ta.Any],
1976
+ ta.Tuple[ta.Any, ta.Union[str, ta.Mapping[str, ta.Any]]],
1949
1977
  Attr,
1950
1978
  ], ...]],
1951
1979
  /,
1952
1980
  *,
1981
+
1953
1982
  with_module: bool = False,
1954
1983
  use_qualname: bool = False,
1955
1984
  with_id: bool = False,
1985
+ terse: bool = False,
1956
1986
  repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = None,
1957
1987
  recursive: bool = False,
1988
+
1989
+ cache_hash: ta.Union[bool, str] = False,
1958
1990
  subtypes_eq: bool = False,
1959
1991
  ) -> None:
1960
1992
  ...
@@ -1962,11 +1994,15 @@ class AttrOps(ta.Generic[T]):
1962
1994
  def __init__(
1963
1995
  self,
1964
1996
  *args,
1997
+
1965
1998
  with_module=False,
1966
1999
  use_qualname=False,
1967
2000
  with_id=False,
2001
+ terse=False,
1968
2002
  repr_filter=None,
1969
2003
  recursive=False,
2004
+
2005
+ cache_hash=False,
1970
2006
  subtypes_eq=False,
1971
2007
  ) -> None:
1972
2008
  if args and len(args) == 1 and callable(args[0]):
@@ -1977,8 +2013,11 @@ class AttrOps(ta.Generic[T]):
1977
2013
  self._with_module: bool = with_module
1978
2014
  self._use_qualname: bool = use_qualname
1979
2015
  self._with_id: bool = with_id
2016
+ self._terse: bool = terse
1980
2017
  self._repr_filter: ta.Optional[ta.Callable[[ta.Any], bool]] = repr_filter
1981
2018
  self._recursive: bool = recursive
2019
+
2020
+ self._cache_hash: ta.Union[bool, str] = cache_hash
1982
2021
  self._subtypes_eq: bool = subtypes_eq
1983
2022
 
1984
2023
  @property
@@ -2013,20 +2052,27 @@ class AttrOps(ta.Generic[T]):
2013
2052
 
2014
2053
  attrs: ta.List[AttrOps.Attr] = []
2015
2054
  for o in raw:
2016
- if isinstance(o, AttrOps.Attr):
2017
- attrs.append(o)
2055
+ if isinstance(o, (AttrOps.Attr, ta.Mapping)):
2056
+ attrs.append(AttrOps.Attr.of(o))
2018
2057
  continue
2019
2058
 
2059
+ kw: ta.Mapping[str, ta.Any]
2020
2060
  if isinstance(o, tuple):
2021
- disp, cap, = o
2061
+ cap, x = o
2062
+ if isinstance(x, str):
2063
+ kw = dict(display=x)
2064
+ elif isinstance(x, ta.Mapping):
2065
+ kw = x
2066
+ else:
2067
+ raise TypeError(x)
2022
2068
  else:
2023
- disp, cap = None, o
2069
+ cap, kw = o, {}
2024
2070
 
2025
2071
  path = tuple(rec(cap))
2026
2072
 
2027
2073
  attrs.append(AttrOps.Attr(
2028
2074
  '.'.join(path),
2029
- display=disp,
2075
+ **kw,
2030
2076
  ))
2031
2077
 
2032
2078
  return attrs
@@ -2043,19 +2089,27 @@ class AttrOps(ta.Generic[T]):
2043
2089
  pass
2044
2090
 
2045
2091
  def _repr(o: T) -> str:
2046
- vs = ', '.join(
2047
- f'{a._display}={v!r}' # noqa
2048
- for a in self._attrs
2049
- if a._repr # noqa
2050
- for v in [getattr(o, a._name)] # noqa
2051
- if self._repr_filter is None or self._repr_filter(v)
2052
- )
2092
+ vs: ta.List[str] = []
2093
+ for a in self._attrs:
2094
+ if not a._repr: # noqa
2095
+ continue
2096
+ v = getattr(o, a._name) # noqa
2097
+ if self._repr_filter is not None and not self._repr_filter(v):
2098
+ continue
2099
+ if (rfn := a._repr_fn) is None: # noqa
2100
+ rfn = repr
2101
+ if (vr := rfn(v)) is None:
2102
+ continue
2103
+ if self._terse:
2104
+ vs.append(vr)
2105
+ else:
2106
+ vs.append(f'{a._display}={vr}') # noqa
2053
2107
 
2054
2108
  return (
2055
2109
  f'{o.__class__.__module__ + "." if self._with_module else ""}'
2056
2110
  f'{o.__class__.__qualname__ if self._use_qualname else o.__class__.__name__}'
2057
2111
  f'{("@" + hex(id(o))[2:]) if self._with_id else ""}' # noqa
2058
- f'({vs})'
2112
+ f'({", ".join(vs)})'
2059
2113
  )
2060
2114
 
2061
2115
  if self._recursive:
@@ -2080,6 +2134,8 @@ class AttrOps(ta.Generic[T]):
2080
2134
 
2081
2135
  #
2082
2136
 
2137
+ _DEFAULT_CACHED_HASH_ATTR: ta.ClassVar[str] = '__cached_hash__'
2138
+
2083
2139
  _hash: ta.Callable[[T], int]
2084
2140
 
2085
2141
  @property
@@ -2089,13 +2145,33 @@ class AttrOps(ta.Generic[T]):
2089
2145
  except AttributeError:
2090
2146
  pass
2091
2147
 
2092
- def _hash(o: T) -> int:
2148
+ def _calc_hash(o: T) -> int:
2093
2149
  return hash(tuple(
2094
2150
  getattr(o, a._name) # noqa
2095
2151
  for a in self._attrs
2096
2152
  if a._hash # noqa
2097
2153
  ))
2098
2154
 
2155
+ if (ch := self._cache_hash) is not False:
2156
+ if ch is True:
2157
+ cha = self._DEFAULT_CACHED_HASH_ATTR
2158
+ elif isinstance(ch, str):
2159
+ cha = ch
2160
+ else:
2161
+ raise TypeError(ch)
2162
+
2163
+ def _cached_hash(o: T) -> int:
2164
+ try:
2165
+ return object.__getattribute__(o, cha)
2166
+ except AttributeError:
2167
+ object.__setattr__(o, cha, h := _calc_hash(o))
2168
+ return h
2169
+
2170
+ _hash = _cached_hash
2171
+
2172
+ else:
2173
+ _hash = _calc_hash
2174
+
2099
2175
  self._hash = _hash
2100
2176
  return _hash
2101
2177
 
@@ -2236,6 +2312,62 @@ def async_cached_nullary(fn): # ta.Callable[..., T]) -> ta.Callable[..., T]:
2236
2312
  return _AsyncCachedNullary(fn)
2237
2313
 
2238
2314
 
2315
+ ##
2316
+
2317
+
2318
+ cached_property = functools.cached_property
2319
+
2320
+
2321
+ class _cached_property: # noqa
2322
+ """Backported to pick up https://github.com/python/cpython/commit/056dfc71dce15f81887f0bd6da09d6099d71f979 ."""
2323
+
2324
+ def __init__(self, func):
2325
+ self.func = func
2326
+ self.attrname = None # noqa
2327
+ self.__doc__ = func.__doc__
2328
+ self.__module__ = func.__module__
2329
+
2330
+ _NOT_FOUND = object()
2331
+
2332
+ def __set_name__(self, owner, name):
2333
+ if self.attrname is None:
2334
+ self.attrname = name # noqa
2335
+ elif name != self.attrname:
2336
+ raise TypeError(
2337
+ f'Cannot assign the same cached_property to two different names ({self.attrname!r} and {name!r}).',
2338
+ )
2339
+
2340
+ def __get__(self, instance, owner=None):
2341
+ if instance is None:
2342
+ return self
2343
+ if self.attrname is None:
2344
+ raise TypeError('Cannot use cached_property instance without calling __set_name__ on it.')
2345
+
2346
+ try:
2347
+ cache = instance.__dict__
2348
+ except AttributeError: # not all objects have __dict__ (e.g. class defines slots)
2349
+ raise TypeError(
2350
+ f"No '__dict__' attribute on {type(instance).__name__!r} instance to cache {self.attrname!r} property.",
2351
+ ) from None
2352
+
2353
+ val = cache.get(self.attrname, self._NOT_FOUND)
2354
+
2355
+ if val is self._NOT_FOUND:
2356
+ val = self.func(instance)
2357
+ try:
2358
+ cache[self.attrname] = val
2359
+ except TypeError:
2360
+ raise TypeError(
2361
+ f"The '__dict__' attribute on {type(instance).__name__!r} instance does not support item "
2362
+ f"assignment for caching {self.attrname!r} property.",
2363
+ ) from None
2364
+
2365
+ return val
2366
+
2367
+
2368
+ globals()['cached_property'] = _cached_property
2369
+
2370
+
2239
2371
  ########################################
2240
2372
  # ../../../omlish/lite/check.py
2241
2373
  """
@@ -4114,6 +4246,70 @@ def build_config_named_children(
4114
4246
  return lst
4115
4247
 
4116
4248
 
4249
+ ########################################
4250
+ # ../../../omlish/http/coro/io.py
4251
+
4252
+
4253
+ ##
4254
+
4255
+
4256
+ class CoroHttpIo:
4257
+ def __new__(cls, *args, **kwargs): # noqa
4258
+ raise TypeError
4259
+
4260
+ def __init_subclass__(cls, **kwargs): # noqa
4261
+ raise TypeError
4262
+
4263
+ #
4264
+
4265
+ MAX_LINE: ta.ClassVar[int] = 65536
4266
+
4267
+ #
4268
+
4269
+ class Io(Abstract):
4270
+ pass
4271
+
4272
+ #
4273
+
4274
+ class AnyLogIo(Io, Abstract):
4275
+ pass
4276
+
4277
+ #
4278
+
4279
+ @dc.dataclass(frozen=True)
4280
+ class ConnectIo(Io):
4281
+ args: ta.Tuple[ta.Any, ...]
4282
+ kwargs: ta.Optional[ta.Dict[str, ta.Any]] = None
4283
+
4284
+ #
4285
+
4286
+ class CloseIo(Io):
4287
+ pass
4288
+
4289
+ #
4290
+
4291
+ class AnyReadIo(Io): # noqa
4292
+ pass
4293
+
4294
+ @dc.dataclass(frozen=True)
4295
+ class ReadIo(AnyReadIo):
4296
+ sz: ta.Optional[int]
4297
+
4298
+ @dc.dataclass(frozen=True)
4299
+ class ReadLineIo(AnyReadIo):
4300
+ sz: int
4301
+
4302
+ @dc.dataclass(frozen=True)
4303
+ class PeekIo(AnyReadIo):
4304
+ sz: int
4305
+
4306
+ #
4307
+
4308
+ @dc.dataclass(frozen=True)
4309
+ class WriteIo(Io):
4310
+ data: bytes
4311
+
4312
+
4117
4313
  ########################################
4118
4314
  # ../../../omlish/http/parsing.py
4119
4315
  # PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
@@ -9392,48 +9588,21 @@ class CoroHttpServer:
9392
9588
 
9393
9589
  #
9394
9590
 
9395
- class Io(Abstract):
9396
- pass
9397
-
9398
- #
9399
-
9400
- class AnyLogIo(Io):
9401
- pass
9402
-
9403
9591
  @dc.dataclass(frozen=True)
9404
- class ParsedRequestLogIo(AnyLogIo):
9592
+ class ParsedRequestLogIo(CoroHttpIo.AnyLogIo):
9405
9593
  request: ParsedHttpRequest
9406
9594
 
9407
9595
  @dc.dataclass(frozen=True)
9408
- class ErrorLogIo(AnyLogIo):
9596
+ class ErrorLogIo(CoroHttpIo.AnyLogIo):
9409
9597
  error: 'CoroHttpServer.Error'
9410
9598
 
9411
9599
  #
9412
9600
 
9413
- class AnyReadIo(Io): # noqa
9414
- pass
9415
-
9416
- @dc.dataclass(frozen=True)
9417
- class ReadIo(AnyReadIo):
9418
- sz: int
9419
-
9420
- @dc.dataclass(frozen=True)
9421
- class ReadLineIo(AnyReadIo):
9422
- sz: int
9423
-
9424
- #
9425
-
9426
- @dc.dataclass(frozen=True)
9427
- class WriteIo(Io):
9428
- data: bytes
9429
-
9430
- #
9431
-
9432
9601
  @dc.dataclass(frozen=True)
9433
9602
  class CoroHandleResult:
9434
9603
  close_reason: ta.Literal['response', 'internal', None] = None
9435
9604
 
9436
- def coro_handle(self) -> ta.Generator[Io, ta.Optional[bytes], CoroHandleResult]:
9605
+ def coro_handle(self) -> ta.Generator[CoroHttpIo.Io, ta.Optional[bytes], CoroHandleResult]:
9437
9606
  return self._coro_run_handler(self._coro_handle_one())
9438
9607
 
9439
9608
  class Close(Exception): # noqa
@@ -9442,20 +9611,20 @@ class CoroHttpServer:
9442
9611
  def _coro_run_handler(
9443
9612
  self,
9444
9613
  gen: ta.Generator[
9445
- ta.Union[AnyLogIo, AnyReadIo, _Response],
9614
+ ta.Union[CoroHttpIo.AnyLogIo, CoroHttpIo.AnyReadIo, _Response],
9446
9615
  ta.Optional[bytes],
9447
9616
  None,
9448
9617
  ],
9449
- ) -> ta.Generator[Io, ta.Optional[bytes], CoroHandleResult]:
9618
+ ) -> ta.Generator[CoroHttpIo.Io, ta.Optional[bytes], CoroHandleResult]:
9450
9619
  i: ta.Optional[bytes]
9451
9620
  o: ta.Any = next(gen)
9452
9621
  while True:
9453
9622
  try:
9454
- if isinstance(o, self.AnyLogIo):
9623
+ if isinstance(o, CoroHttpIo.AnyLogIo):
9455
9624
  i = None
9456
9625
  yield o
9457
9626
 
9458
- elif isinstance(o, self.AnyReadIo):
9627
+ elif isinstance(o, CoroHttpIo.AnyReadIo):
9459
9628
  i = check.isinstance((yield o), bytes)
9460
9629
 
9461
9630
  elif isinstance(o, self._Response):
@@ -9463,10 +9632,10 @@ class CoroHttpServer:
9463
9632
 
9464
9633
  r = self._preprocess_response(o)
9465
9634
  hb = self._build_response_head_bytes(r)
9466
- check.none((yield self.WriteIo(hb)))
9635
+ check.none((yield CoroHttpIo.WriteIo(hb)))
9467
9636
 
9468
9637
  for b in self._yield_response_data(r):
9469
- yield self.WriteIo(b)
9638
+ yield CoroHttpIo.WriteIo(b)
9470
9639
 
9471
9640
  o.close()
9472
9641
  if o.close_connection:
@@ -9494,7 +9663,7 @@ class CoroHttpServer:
9494
9663
  raise
9495
9664
 
9496
9665
  def _coro_handle_one(self) -> ta.Generator[
9497
- ta.Union[AnyLogIo, AnyReadIo, _Response],
9666
+ ta.Union[CoroHttpIo.AnyLogIo, CoroHttpIo.AnyReadIo, _Response],
9498
9667
  ta.Optional[bytes],
9499
9668
  None,
9500
9669
  ]:
@@ -9504,7 +9673,7 @@ class CoroHttpServer:
9504
9673
  sz = next(gen)
9505
9674
  while True:
9506
9675
  try:
9507
- line = check.isinstance((yield self.ReadLineIo(sz)), bytes)
9676
+ line = check.isinstance((yield CoroHttpIo.ReadLineIo(sz)), bytes)
9508
9677
  sz = gen.send(line)
9509
9678
  except StopIteration as e:
9510
9679
  parsed = e.value
@@ -9543,7 +9712,7 @@ class CoroHttpServer:
9543
9712
 
9544
9713
  request_data: ta.Optional[bytes]
9545
9714
  if (cl := parsed.headers.get('Content-Length')) is not None:
9546
- request_data = check.isinstance((yield self.ReadIo(int(cl))), bytes)
9715
+ request_data = check.isinstance((yield CoroHttpIo.ReadIo(int(cl))), bytes)
9547
9716
  else:
9548
9717
  request_data = None
9549
9718
 
@@ -10603,7 +10772,7 @@ class CoroHttpServerConnectionFdioHandler(SocketFdioHandler):
10603
10772
  *,
10604
10773
  read_size: int = 0x10000,
10605
10774
  write_size: int = 0x10000,
10606
- log_handler: ta.Optional[ta.Callable[[CoroHttpServer, CoroHttpServer.AnyLogIo], None]] = None,
10775
+ log_handler: ta.Optional[ta.Callable[[CoroHttpServer, CoroHttpIo.AnyLogIo], None]] = None,
10607
10776
  ) -> None:
10608
10777
  check.state(not sock.getblocking())
10609
10778
 
@@ -10623,13 +10792,13 @@ class CoroHttpServerConnectionFdioHandler(SocketFdioHandler):
10623
10792
  )
10624
10793
  self._srv_coro: ta.Optional[
10625
10794
  ta.Generator[
10626
- CoroHttpServer.Io,
10795
+ CoroHttpIo.Io,
10627
10796
  ta.Optional[bytes],
10628
10797
  CoroHttpServer.CoroHandleResult,
10629
10798
  ],
10630
10799
  ] = self._coro_srv.coro_handle()
10631
10800
 
10632
- self._cur_io: ta.Optional[CoroHttpServer.Io] = None
10801
+ self._cur_io: ta.Optional[CoroHttpIo.Io] = None
10633
10802
  self._next_io()
10634
10803
 
10635
10804
  #
@@ -10652,22 +10821,22 @@ class CoroHttpServerConnectionFdioHandler(SocketFdioHandler):
10652
10821
  o = None
10653
10822
  break
10654
10823
 
10655
- if isinstance(o, CoroHttpServer.AnyLogIo):
10824
+ if isinstance(o, CoroHttpIo.AnyLogIo):
10656
10825
  if self._log_handler is not None:
10657
10826
  self._log_handler(self._coro_srv, o)
10658
10827
  o = None
10659
10828
 
10660
- elif isinstance(o, CoroHttpServer.ReadIo):
10829
+ elif isinstance(o, CoroHttpIo.ReadIo):
10661
10830
  if (d := self._read_buf.read(o.sz)) is None:
10662
10831
  break
10663
10832
  o = None
10664
10833
 
10665
- elif isinstance(o, CoroHttpServer.ReadLineIo):
10834
+ elif isinstance(o, CoroHttpIo.ReadLineIo):
10666
10835
  if (d := self._read_buf.read_until(b'\n')) is None:
10667
10836
  break
10668
10837
  o = None
10669
10838
 
10670
- elif isinstance(o, CoroHttpServer.WriteIo):
10839
+ elif isinstance(o, CoroHttpIo.WriteIo):
10671
10840
  check.none(self._write_buf)
10672
10841
  self._write_buf = IncrementalWriteBuffer(o.data, write_size=self._write_size)
10673
10842
  break
@@ -10701,11 +10870,11 @@ class CoroHttpServerConnectionFdioHandler(SocketFdioHandler):
10701
10870
 
10702
10871
  self._read_buf.feed(buf)
10703
10872
 
10704
- if isinstance(self._cur_io, CoroHttpServer.AnyReadIo):
10873
+ if isinstance(self._cur_io, CoroHttpIo.AnyReadIo):
10705
10874
  self._next_io()
10706
10875
 
10707
10876
  def on_writable(self) -> None:
10708
- check.isinstance(self._cur_io, CoroHttpServer.WriteIo)
10877
+ check.isinstance(self._cur_io, CoroHttpIo.WriteIo)
10709
10878
  wb = check.not_none(self._write_buf)
10710
10879
  while wb.rem > 0:
10711
10880
  def send(d: bytes) -> int:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ominfra
3
- Version: 0.0.0.dev439
3
+ Version: 0.0.0.dev441
4
4
  Summary: ominfra
5
5
  Author: wrmsr
6
6
  License-Expression: BSD-3-Clause
@@ -14,8 +14,8 @@ Classifier: Programming Language :: Python :: 3.13
14
14
  Requires-Python: >=3.13
15
15
  Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
- Requires-Dist: omdev==0.0.0.dev439
18
- Requires-Dist: omlish==0.0.0.dev439
17
+ Requires-Dist: omdev==0.0.0.dev441
18
+ Requires-Dist: omlish==0.0.0.dev441
19
19
  Provides-Extra: all
20
20
  Requires-Dist: paramiko~=4.0; extra == "all"
21
21
  Requires-Dist: asyncssh~=2.21; extra == "all"
@@ -14,7 +14,7 @@ ominfra/clouds/aws/logs.py,sha256=SW8ebBJrUTDG0dnYIld4zbWNVCkAHzFZq4kpn76yWTo,54
14
14
  ominfra/clouds/aws/metadata.py,sha256=71LtmJxjdlp_HN19zXQTX4ZLO4KI5LLiQ6fHuF8vUis,2772
15
15
  ominfra/clouds/aws/instancetypes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  ominfra/clouds/aws/instancetypes/__main__.py,sha256=Jsrv3P7LX2Cg08W7ByZfZ1JQT4lgLDPW1qNAmShFuMk,75
17
- ominfra/clouds/aws/instancetypes/cache.json.gz,sha256=bvkYajX5OAdbGtrx5fJ-oQ8sCKm0X8Rk9_4rZuYBcps,31494
17
+ ominfra/clouds/aws/instancetypes/cache.json.gz,sha256=DSlV4qQgnsPBLPVAsuk67BhbagwELfQ5ZJ3ocGdppSQ,33174
18
18
  ominfra/clouds/aws/instancetypes/cache.py,sha256=tEH7bH6kTTqgXcwsNk5Rf7eCf14vsnEHMV6q-PbZc4M,338
19
19
  ominfra/clouds/aws/instancetypes/cli.py,sha256=yNxUZjbud5M9tBZZbfiswa8jGQaKJ3YVwxFIMQTo2sA,2207
20
20
  ominfra/clouds/aws/journald2aws/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
@@ -112,9 +112,9 @@ ominfra/manage/targets/connection.py,sha256=mOHCsDVG-DZBhl3Mb7TTr1vhPb0gxDOOMW1x
112
112
  ominfra/manage/targets/inject.py,sha256=3M4wBkxtvymq_yhiotHlTN8iydELMjVCndyp9Bq-4eo,1572
113
113
  ominfra/manage/targets/targets.py,sha256=LjSQrDsHEjEQMDHcxtNKmLjy0YGLXJRGPFdUjazzFIM,1918
114
114
  ominfra/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
115
- ominfra/scripts/journald2aws.py,sha256=liuYP9LafxEtdpTNwmg0NNud3jvREALZinjOm185x6c,242365
116
- ominfra/scripts/manage.py,sha256=z15lbtJDoDWCOwdyxstghnE311b5SMiE9r9Zdru6Kus,466302
117
- ominfra/scripts/supervisor.py,sha256=hnvhbeCLrvEzyavM6NjVS5s0ohetXXiGrFVyfOe2FXs,375921
115
+ ominfra/scripts/journald2aws.py,sha256=qLfqpuWE7xU7lyfctgU5Wbz3HmhXWjqlEpxDr3ZQkx4,246638
116
+ ominfra/scripts/manage.py,sha256=uG_Rerl6dTAzUcPRnkTdlSyfYVB4SR6Hrem35jm-daA,470575
117
+ ominfra/scripts/supervisor.py,sha256=-JeF0dI-VPMMkTnSfD5yPr5vsGULVutHwqVsdNFzYhU,380885
118
118
  ominfra/supervisor/LICENSE.txt,sha256=ZrHY15PVR98y26Yg6iQfa-SXnUaYTDhrUsPVcEO5OKM,1874
119
119
  ominfra/supervisor/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
120
120
  ominfra/supervisor/__main__.py,sha256=I0yFw-C08OOiZ3BF6lF1Oiv789EQXu-_j6whDhQUTEA,66
@@ -156,9 +156,9 @@ ominfra/tailscale/api.py,sha256=XASv9C_CWI-u-yX5jVzhJrkJhlwQRkYQWQQG1uJwAd8,1375
156
156
  ominfra/tailscale/cli.py,sha256=zRV7-tKB7kBah1oTVZlol-vwx1FBlnfzYAPGkeU5jX4,3543
157
157
  ominfra/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
158
158
  ominfra/tools/listresources.py,sha256=ePmo7cUAiBZARkM_3K4GKYZXxV73An_aioS1m-AAJis,6181
159
- ominfra-0.0.0.dev439.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
160
- ominfra-0.0.0.dev439.dist-info/METADATA,sha256=GybKQw5K0jBDR-ikYLczNKYRlDuN39qHebKKr0ul7G8,2377
161
- ominfra-0.0.0.dev439.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
162
- ominfra-0.0.0.dev439.dist-info/entry_points.txt,sha256=kgecQ2MgGrM9qK744BoKS3tMesaC3yjLnl9pa5CRczg,37
163
- ominfra-0.0.0.dev439.dist-info/top_level.txt,sha256=E-b2OHkk_AOBLXHYZQ2EOFKl-_6uOGd8EjeG-Zy6h_w,8
164
- ominfra-0.0.0.dev439.dist-info/RECORD,,
159
+ ominfra-0.0.0.dev441.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
160
+ ominfra-0.0.0.dev441.dist-info/METADATA,sha256=yKAIipeGD_tOrnjkqRAJ3Uz8dqB6xWSt_MQzN5W8MQw,2377
161
+ ominfra-0.0.0.dev441.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
162
+ ominfra-0.0.0.dev441.dist-info/entry_points.txt,sha256=kgecQ2MgGrM9qK744BoKS3tMesaC3yjLnl9pa5CRczg,37
163
+ ominfra-0.0.0.dev441.dist-info/top_level.txt,sha256=E-b2OHkk_AOBLXHYZQ2EOFKl-_6uOGd8EjeG-Zy6h_w,8
164
+ ominfra-0.0.0.dev441.dist-info/RECORD,,