ominfra 0.0.0.dev148__py3-none-any.whl → 0.0.0.dev149__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/cli.py +1 -1
- ominfra/journald/messages.py +1 -1
- ominfra/manage/deploy/paths.py +2 -2
- ominfra/scripts/journald2aws.py +68 -63
- ominfra/scripts/manage.py +6 -1
- ominfra/scripts/supervisor.py +491 -486
- ominfra/supervisor/dispatchers.py +1 -1
- ominfra/supervisor/http.py +2 -2
- ominfra/supervisor/inject.py +4 -4
- ominfra/supervisor/io.py +1 -1
- ominfra/supervisor/spawningimpl.py +1 -1
- ominfra/supervisor/supervisor.py +1 -1
- ominfra/supervisor/types.py +1 -1
- ominfra/tailscale/cli.py +1 -1
- {ominfra-0.0.0.dev148.dist-info → ominfra-0.0.0.dev149.dist-info}/METADATA +3 -3
- {ominfra-0.0.0.dev148.dist-info → ominfra-0.0.0.dev149.dist-info}/RECORD +20 -20
- {ominfra-0.0.0.dev148.dist-info → ominfra-0.0.0.dev149.dist-info}/LICENSE +0 -0
- {ominfra-0.0.0.dev148.dist-info → ominfra-0.0.0.dev149.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev148.dist-info → ominfra-0.0.0.dev149.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev148.dist-info → ominfra-0.0.0.dev149.dist-info}/top_level.txt +0 -0
    
        ominfra/scripts/supervisor.py
    CHANGED
    
    | @@ -1431,160 +1431,7 @@ def parse_octal(arg: ta.Union[str, int]) -> int: | |
| 1431 1431 |  | 
| 1432 1432 |  | 
| 1433 1433 | 
             
            ########################################
         | 
| 1434 | 
            -
            # ../../../omlish/ | 
| 1435 | 
            -
             | 
| 1436 | 
            -
             | 
| 1437 | 
            -
            ##
         | 
| 1438 | 
            -
             | 
| 1439 | 
            -
             | 
| 1440 | 
            -
            class _AbstractCachedNullary:
         | 
| 1441 | 
            -
                def __init__(self, fn):
         | 
| 1442 | 
            -
                    super().__init__()
         | 
| 1443 | 
            -
                    self._fn = fn
         | 
| 1444 | 
            -
                    self._value = self._missing = object()
         | 
| 1445 | 
            -
                    functools.update_wrapper(self, fn)
         | 
| 1446 | 
            -
             | 
| 1447 | 
            -
                def __call__(self, *args, **kwargs):  # noqa
         | 
| 1448 | 
            -
                    raise TypeError
         | 
| 1449 | 
            -
             | 
| 1450 | 
            -
                def __get__(self, instance, owner):  # noqa
         | 
| 1451 | 
            -
                    bound = instance.__dict__[self._fn.__name__] = self.__class__(self._fn.__get__(instance, owner))
         | 
| 1452 | 
            -
                    return bound
         | 
| 1453 | 
            -
             | 
| 1454 | 
            -
             | 
| 1455 | 
            -
            ##
         | 
| 1456 | 
            -
             | 
| 1457 | 
            -
             | 
| 1458 | 
            -
            class _CachedNullary(_AbstractCachedNullary):
         | 
| 1459 | 
            -
                def __call__(self, *args, **kwargs):  # noqa
         | 
| 1460 | 
            -
                    if self._value is self._missing:
         | 
| 1461 | 
            -
                        self._value = self._fn()
         | 
| 1462 | 
            -
                    return self._value
         | 
| 1463 | 
            -
             | 
| 1464 | 
            -
             | 
| 1465 | 
            -
            def cached_nullary(fn):  # ta.Callable[..., T]) -> ta.Callable[..., T]:
         | 
| 1466 | 
            -
                return _CachedNullary(fn)
         | 
| 1467 | 
            -
             | 
| 1468 | 
            -
             | 
| 1469 | 
            -
            def static_init(fn: CallableT) -> CallableT:
         | 
| 1470 | 
            -
                fn = cached_nullary(fn)
         | 
| 1471 | 
            -
                fn()
         | 
| 1472 | 
            -
                return fn
         | 
| 1473 | 
            -
             | 
| 1474 | 
            -
             | 
| 1475 | 
            -
            ##
         | 
| 1476 | 
            -
             | 
| 1477 | 
            -
             | 
| 1478 | 
            -
            class _AsyncCachedNullary(_AbstractCachedNullary):
         | 
| 1479 | 
            -
                async def __call__(self, *args, **kwargs):
         | 
| 1480 | 
            -
                    if self._value is self._missing:
         | 
| 1481 | 
            -
                        self._value = await self._fn()
         | 
| 1482 | 
            -
                    return self._value
         | 
| 1483 | 
            -
             | 
| 1484 | 
            -
             | 
| 1485 | 
            -
            def async_cached_nullary(fn):  # ta.Callable[..., T]) -> ta.Callable[..., T]:
         | 
| 1486 | 
            -
                return _AsyncCachedNullary(fn)
         | 
| 1487 | 
            -
             | 
| 1488 | 
            -
             | 
| 1489 | 
            -
            ########################################
         | 
| 1490 | 
            -
            # ../../../omlish/lite/check.py
         | 
| 1491 | 
            -
             | 
| 1492 | 
            -
             | 
| 1493 | 
            -
            def check_isinstance(v: ta.Any, spec: ta.Union[ta.Type[T], tuple]) -> T:
         | 
| 1494 | 
            -
                if not isinstance(v, spec):
         | 
| 1495 | 
            -
                    raise TypeError(v)
         | 
| 1496 | 
            -
                return v
         | 
| 1497 | 
            -
             | 
| 1498 | 
            -
             | 
| 1499 | 
            -
            def check_not_isinstance(v: T, spec: ta.Union[type, tuple]) -> T:
         | 
| 1500 | 
            -
                if isinstance(v, spec):
         | 
| 1501 | 
            -
                    raise TypeError(v)
         | 
| 1502 | 
            -
                return v
         | 
| 1503 | 
            -
             | 
| 1504 | 
            -
             | 
| 1505 | 
            -
            def check_none(v: T) -> None:
         | 
| 1506 | 
            -
                if v is not None:
         | 
| 1507 | 
            -
                    raise ValueError(v)
         | 
| 1508 | 
            -
             | 
| 1509 | 
            -
             | 
| 1510 | 
            -
            def check_not_none(v: ta.Optional[T]) -> T:
         | 
| 1511 | 
            -
                if v is None:
         | 
| 1512 | 
            -
                    raise ValueError
         | 
| 1513 | 
            -
                return v
         | 
| 1514 | 
            -
             | 
| 1515 | 
            -
             | 
| 1516 | 
            -
            def check_not(v: ta.Any) -> None:
         | 
| 1517 | 
            -
                if v:
         | 
| 1518 | 
            -
                    raise ValueError(v)
         | 
| 1519 | 
            -
                return v
         | 
| 1520 | 
            -
             | 
| 1521 | 
            -
             | 
| 1522 | 
            -
            def check_non_empty_str(v: ta.Optional[str]) -> str:
         | 
| 1523 | 
            -
                if not v:
         | 
| 1524 | 
            -
                    raise ValueError
         | 
| 1525 | 
            -
                return v
         | 
| 1526 | 
            -
             | 
| 1527 | 
            -
             | 
| 1528 | 
            -
            def check_state(v: bool, msg: str = 'Illegal state') -> None:
         | 
| 1529 | 
            -
                if not v:
         | 
| 1530 | 
            -
                    raise ValueError(msg)
         | 
| 1531 | 
            -
             | 
| 1532 | 
            -
             | 
| 1533 | 
            -
            def check_equal(l: T, r: T) -> T:
         | 
| 1534 | 
            -
                if l != r:
         | 
| 1535 | 
            -
                    raise ValueError(l, r)
         | 
| 1536 | 
            -
                return l
         | 
| 1537 | 
            -
             | 
| 1538 | 
            -
             | 
| 1539 | 
            -
            def check_not_equal(l: T, r: T) -> T:
         | 
| 1540 | 
            -
                if l == r:
         | 
| 1541 | 
            -
                    raise ValueError(l, r)
         | 
| 1542 | 
            -
                return l
         | 
| 1543 | 
            -
             | 
| 1544 | 
            -
             | 
| 1545 | 
            -
            def check_is(l: T, r: T) -> T:
         | 
| 1546 | 
            -
                if l is not r:
         | 
| 1547 | 
            -
                    raise ValueError(l, r)
         | 
| 1548 | 
            -
                return l
         | 
| 1549 | 
            -
             | 
| 1550 | 
            -
             | 
| 1551 | 
            -
            def check_is_not(l: T, r: ta.Any) -> T:
         | 
| 1552 | 
            -
                if l is r:
         | 
| 1553 | 
            -
                    raise ValueError(l, r)
         | 
| 1554 | 
            -
                return l
         | 
| 1555 | 
            -
             | 
| 1556 | 
            -
             | 
| 1557 | 
            -
            def check_in(v: T, c: ta.Container[T]) -> T:
         | 
| 1558 | 
            -
                if v not in c:
         | 
| 1559 | 
            -
                    raise ValueError(v, c)
         | 
| 1560 | 
            -
                return v
         | 
| 1561 | 
            -
             | 
| 1562 | 
            -
             | 
| 1563 | 
            -
            def check_not_in(v: T, c: ta.Container[T]) -> T:
         | 
| 1564 | 
            -
                if v in c:
         | 
| 1565 | 
            -
                    raise ValueError(v, c)
         | 
| 1566 | 
            -
                return v
         | 
| 1567 | 
            -
             | 
| 1568 | 
            -
             | 
| 1569 | 
            -
            def check_single(vs: ta.Iterable[T]) -> T:
         | 
| 1570 | 
            -
                [v] = vs
         | 
| 1571 | 
            -
                return v
         | 
| 1572 | 
            -
             | 
| 1573 | 
            -
             | 
| 1574 | 
            -
            def check_empty(v: SizedT) -> SizedT:
         | 
| 1575 | 
            -
                if len(v):
         | 
| 1576 | 
            -
                    raise ValueError(v)
         | 
| 1577 | 
            -
                return v
         | 
| 1578 | 
            -
             | 
| 1579 | 
            -
             | 
| 1580 | 
            -
            def check_non_empty(v: SizedT) -> SizedT:
         | 
| 1581 | 
            -
                if not len(v):
         | 
| 1582 | 
            -
                    raise ValueError(v)
         | 
| 1583 | 
            -
                return v
         | 
| 1584 | 
            -
             | 
| 1585 | 
            -
             | 
| 1586 | 
            -
            ########################################
         | 
| 1587 | 
            -
            # ../../../omlish/lite/fdio/pollers.py
         | 
| 1434 | 
            +
            # ../../../omlish/io/fdio/pollers.py
         | 
| 1588 1435 |  | 
| 1589 1436 |  | 
| 1590 1437 | 
             
            ##
         | 
| @@ -1794,91 +1641,249 @@ else: | |
| 1794 1641 |  | 
| 1795 1642 |  | 
| 1796 1643 | 
             
            ########################################
         | 
| 1797 | 
            -
            # ../../../omlish/lite/ | 
| 1798 | 
            -
             | 
| 1644 | 
            +
            # ../../../omlish/lite/cached.py
         | 
| 1799 1645 |  | 
| 1800 | 
            -
            class HttpProtocolVersion(ta.NamedTuple):
         | 
| 1801 | 
            -
                major: int
         | 
| 1802 | 
            -
                minor: int
         | 
| 1803 1646 |  | 
| 1804 | 
            -
             | 
| 1805 | 
            -
                    return f'HTTP/{self.major}.{self.minor}'
         | 
| 1647 | 
            +
            ##
         | 
| 1806 1648 |  | 
| 1807 1649 |  | 
| 1808 | 
            -
            class  | 
| 1809 | 
            -
                 | 
| 1810 | 
            -
             | 
| 1811 | 
            -
             | 
| 1812 | 
            -
             | 
| 1650 | 
            +
            class _AbstractCachedNullary:
         | 
| 1651 | 
            +
                def __init__(self, fn):
         | 
| 1652 | 
            +
                    super().__init__()
         | 
| 1653 | 
            +
                    self._fn = fn
         | 
| 1654 | 
            +
                    self._value = self._missing = object()
         | 
| 1655 | 
            +
                    functools.update_wrapper(self, fn)
         | 
| 1813 1656 |  | 
| 1657 | 
            +
                def __call__(self, *args, **kwargs):  # noqa
         | 
| 1658 | 
            +
                    raise TypeError
         | 
| 1814 1659 |  | 
| 1815 | 
            -
             | 
| 1816 | 
            -
             | 
| 1660 | 
            +
                def __get__(self, instance, owner):  # noqa
         | 
| 1661 | 
            +
                    bound = instance.__dict__[self._fn.__name__] = self.__class__(self._fn.__get__(instance, owner))
         | 
| 1662 | 
            +
                    return bound
         | 
| 1817 1663 |  | 
| 1818 1664 |  | 
| 1819 1665 | 
             
            ##
         | 
| 1820 1666 |  | 
| 1821 1667 |  | 
| 1822 | 
            -
             | 
| 1668 | 
            +
            class _CachedNullary(_AbstractCachedNullary):
         | 
| 1669 | 
            +
                def __call__(self, *args, **kwargs):  # noqa
         | 
| 1670 | 
            +
                    if self._value is self._missing:
         | 
| 1671 | 
            +
                        self._value = self._fn()
         | 
| 1672 | 
            +
                    return self._value
         | 
| 1823 1673 |  | 
| 1824 | 
            -
            JSON_PRETTY_KWARGS: ta.Mapping[str, ta.Any] = dict(
         | 
| 1825 | 
            -
                indent=JSON_PRETTY_INDENT,
         | 
| 1826 | 
            -
            )
         | 
| 1827 1674 |  | 
| 1828 | 
            -
             | 
| 1829 | 
            -
             | 
| 1675 | 
            +
            def cached_nullary(fn):  # ta.Callable[..., T]) -> ta.Callable[..., T]:
         | 
| 1676 | 
            +
                return _CachedNullary(fn)
         | 
| 1677 | 
            +
             | 
| 1678 | 
            +
             | 
| 1679 | 
            +
            def static_init(fn: CallableT) -> CallableT:
         | 
| 1680 | 
            +
                fn = cached_nullary(fn)
         | 
| 1681 | 
            +
                fn()
         | 
| 1682 | 
            +
                return fn
         | 
| 1830 1683 |  | 
| 1831 1684 |  | 
| 1832 1685 | 
             
            ##
         | 
| 1833 1686 |  | 
| 1834 1687 |  | 
| 1835 | 
            -
             | 
| 1688 | 
            +
            class _AsyncCachedNullary(_AbstractCachedNullary):
         | 
| 1689 | 
            +
                async def __call__(self, *args, **kwargs):
         | 
| 1690 | 
            +
                    if self._value is self._missing:
         | 
| 1691 | 
            +
                        self._value = await self._fn()
         | 
| 1692 | 
            +
                    return self._value
         | 
| 1836 1693 |  | 
| 1837 | 
            -
            JSON_COMPACT_KWARGS: ta.Mapping[str, ta.Any] = dict(
         | 
| 1838 | 
            -
                indent=None,
         | 
| 1839 | 
            -
                separators=JSON_COMPACT_SEPARATORS,
         | 
| 1840 | 
            -
            )
         | 
| 1841 1694 |  | 
| 1842 | 
            -
             | 
| 1843 | 
            -
             | 
| 1695 | 
            +
            def async_cached_nullary(fn):  # ta.Callable[..., T]) -> ta.Callable[..., T]:
         | 
| 1696 | 
            +
                return _AsyncCachedNullary(fn)
         | 
| 1844 1697 |  | 
| 1845 1698 |  | 
| 1846 1699 | 
             
            ########################################
         | 
| 1847 | 
            -
            # ../../../omlish/lite/ | 
| 1700 | 
            +
            # ../../../omlish/lite/check.py
         | 
| 1848 1701 |  | 
| 1849 1702 |  | 
| 1850 | 
            -
             | 
| 1851 | 
            -
                 | 
| 1852 | 
            -
             | 
| 1853 | 
            -
                 | 
| 1854 | 
            -
                    raise NotImplementedError
         | 
| 1703 | 
            +
            def check_isinstance(v: ta.Any, spec: ta.Union[ta.Type[T], tuple]) -> T:
         | 
| 1704 | 
            +
                if not isinstance(v, spec):
         | 
| 1705 | 
            +
                    raise TypeError(v)
         | 
| 1706 | 
            +
                return v
         | 
| 1855 1707 |  | 
| 1856 | 
            -
                @abc.abstractmethod
         | 
| 1857 | 
            -
                def must(self) -> T:
         | 
| 1858 | 
            -
                    raise NotImplementedError
         | 
| 1859 1708 |  | 
| 1860 | 
            -
             | 
| 1861 | 
            -
                 | 
| 1862 | 
            -
                     | 
| 1709 | 
            +
            def check_not_isinstance(v: T, spec: ta.Union[type, tuple]) -> T:
         | 
| 1710 | 
            +
                if isinstance(v, spec):
         | 
| 1711 | 
            +
                    raise TypeError(v)
         | 
| 1712 | 
            +
                return v
         | 
| 1863 1713 |  | 
| 1864 | 
            -
                _empty: ta.ClassVar['Maybe']
         | 
| 1865 1714 |  | 
| 1866 | 
            -
             | 
| 1867 | 
            -
                 | 
| 1868 | 
            -
                     | 
| 1715 | 
            +
            def check_none(v: T) -> None:
         | 
| 1716 | 
            +
                if v is not None:
         | 
| 1717 | 
            +
                    raise ValueError(v)
         | 
| 1869 1718 |  | 
| 1870 1719 |  | 
| 1871 | 
            -
             | 
| 1872 | 
            -
                 | 
| 1720 | 
            +
            def check_not_none(v: ta.Optional[T]) -> T:
         | 
| 1721 | 
            +
                if v is None:
         | 
| 1722 | 
            +
                    raise ValueError
         | 
| 1723 | 
            +
                return v
         | 
| 1873 1724 |  | 
| 1874 | 
            -
                def __init_subclass__(cls, **kwargs):
         | 
| 1875 | 
            -
                    raise TypeError
         | 
| 1876 1725 |  | 
| 1877 | 
            -
             | 
| 1878 | 
            -
                 | 
| 1879 | 
            -
                     | 
| 1726 | 
            +
            def check_not(v: ta.Any) -> None:
         | 
| 1727 | 
            +
                if v:
         | 
| 1728 | 
            +
                    raise ValueError(v)
         | 
| 1729 | 
            +
                return v
         | 
| 1880 1730 |  | 
| 1881 | 
            -
             | 
| 1731 | 
            +
             | 
| 1732 | 
            +
            def check_non_empty_str(v: ta.Optional[str]) -> str:
         | 
| 1733 | 
            +
                if not v:
         | 
| 1734 | 
            +
                    raise ValueError
         | 
| 1735 | 
            +
                return v
         | 
| 1736 | 
            +
             | 
| 1737 | 
            +
             | 
| 1738 | 
            +
            def check_arg(v: bool, msg: str = 'Illegal argument') -> None:
         | 
| 1739 | 
            +
                if not v:
         | 
| 1740 | 
            +
                    raise ValueError(msg)
         | 
| 1741 | 
            +
             | 
| 1742 | 
            +
             | 
| 1743 | 
            +
            def check_state(v: bool, msg: str = 'Illegal state') -> None:
         | 
| 1744 | 
            +
                if not v:
         | 
| 1745 | 
            +
                    raise ValueError(msg)
         | 
| 1746 | 
            +
             | 
| 1747 | 
            +
             | 
| 1748 | 
            +
            def check_equal(l: T, r: T) -> T:
         | 
| 1749 | 
            +
                if l != r:
         | 
| 1750 | 
            +
                    raise ValueError(l, r)
         | 
| 1751 | 
            +
                return l
         | 
| 1752 | 
            +
             | 
| 1753 | 
            +
             | 
| 1754 | 
            +
            def check_not_equal(l: T, r: T) -> T:
         | 
| 1755 | 
            +
                if l == r:
         | 
| 1756 | 
            +
                    raise ValueError(l, r)
         | 
| 1757 | 
            +
                return l
         | 
| 1758 | 
            +
             | 
| 1759 | 
            +
             | 
| 1760 | 
            +
            def check_is(l: T, r: T) -> T:
         | 
| 1761 | 
            +
                if l is not r:
         | 
| 1762 | 
            +
                    raise ValueError(l, r)
         | 
| 1763 | 
            +
                return l
         | 
| 1764 | 
            +
             | 
| 1765 | 
            +
             | 
| 1766 | 
            +
            def check_is_not(l: T, r: ta.Any) -> T:
         | 
| 1767 | 
            +
                if l is r:
         | 
| 1768 | 
            +
                    raise ValueError(l, r)
         | 
| 1769 | 
            +
                return l
         | 
| 1770 | 
            +
             | 
| 1771 | 
            +
             | 
| 1772 | 
            +
            def check_in(v: T, c: ta.Container[T]) -> T:
         | 
| 1773 | 
            +
                if v not in c:
         | 
| 1774 | 
            +
                    raise ValueError(v, c)
         | 
| 1775 | 
            +
                return v
         | 
| 1776 | 
            +
             | 
| 1777 | 
            +
             | 
| 1778 | 
            +
            def check_not_in(v: T, c: ta.Container[T]) -> T:
         | 
| 1779 | 
            +
                if v in c:
         | 
| 1780 | 
            +
                    raise ValueError(v, c)
         | 
| 1781 | 
            +
                return v
         | 
| 1782 | 
            +
             | 
| 1783 | 
            +
             | 
| 1784 | 
            +
            def check_single(vs: ta.Iterable[T]) -> T:
         | 
| 1785 | 
            +
                [v] = vs
         | 
| 1786 | 
            +
                return v
         | 
| 1787 | 
            +
             | 
| 1788 | 
            +
             | 
| 1789 | 
            +
            def check_empty(v: SizedT) -> SizedT:
         | 
| 1790 | 
            +
                if len(v):
         | 
| 1791 | 
            +
                    raise ValueError(v)
         | 
| 1792 | 
            +
                return v
         | 
| 1793 | 
            +
             | 
| 1794 | 
            +
             | 
| 1795 | 
            +
            def check_not_empty(v: SizedT) -> SizedT:
         | 
| 1796 | 
            +
                if not len(v):
         | 
| 1797 | 
            +
                    raise ValueError(v)
         | 
| 1798 | 
            +
                return v
         | 
| 1799 | 
            +
             | 
| 1800 | 
            +
             | 
| 1801 | 
            +
            ########################################
         | 
| 1802 | 
            +
            # ../../../omlish/lite/http/versions.py
         | 
| 1803 | 
            +
             | 
| 1804 | 
            +
             | 
| 1805 | 
            +
            class HttpProtocolVersion(ta.NamedTuple):
         | 
| 1806 | 
            +
                major: int
         | 
| 1807 | 
            +
                minor: int
         | 
| 1808 | 
            +
             | 
| 1809 | 
            +
                def __str__(self) -> str:
         | 
| 1810 | 
            +
                    return f'HTTP/{self.major}.{self.minor}'
         | 
| 1811 | 
            +
             | 
| 1812 | 
            +
             | 
| 1813 | 
            +
            class HttpProtocolVersions:
         | 
| 1814 | 
            +
                HTTP_0_9 = HttpProtocolVersion(0, 9)
         | 
| 1815 | 
            +
                HTTP_1_0 = HttpProtocolVersion(1, 0)
         | 
| 1816 | 
            +
                HTTP_1_1 = HttpProtocolVersion(1, 1)
         | 
| 1817 | 
            +
                HTTP_2_0 = HttpProtocolVersion(2, 0)
         | 
| 1818 | 
            +
             | 
| 1819 | 
            +
             | 
| 1820 | 
            +
            ########################################
         | 
| 1821 | 
            +
            # ../../../omlish/lite/json.py
         | 
| 1822 | 
            +
             | 
| 1823 | 
            +
             | 
| 1824 | 
            +
            ##
         | 
| 1825 | 
            +
             | 
| 1826 | 
            +
             | 
| 1827 | 
            +
            JSON_PRETTY_INDENT = 2
         | 
| 1828 | 
            +
             | 
| 1829 | 
            +
            JSON_PRETTY_KWARGS: ta.Mapping[str, ta.Any] = dict(
         | 
| 1830 | 
            +
                indent=JSON_PRETTY_INDENT,
         | 
| 1831 | 
            +
            )
         | 
| 1832 | 
            +
             | 
| 1833 | 
            +
            json_dump_pretty: ta.Callable[..., bytes] = functools.partial(json.dump, **JSON_PRETTY_KWARGS)  # type: ignore
         | 
| 1834 | 
            +
            json_dumps_pretty: ta.Callable[..., str] = functools.partial(json.dumps, **JSON_PRETTY_KWARGS)
         | 
| 1835 | 
            +
             | 
| 1836 | 
            +
             | 
| 1837 | 
            +
            ##
         | 
| 1838 | 
            +
             | 
| 1839 | 
            +
             | 
| 1840 | 
            +
            JSON_COMPACT_SEPARATORS = (',', ':')
         | 
| 1841 | 
            +
             | 
| 1842 | 
            +
            JSON_COMPACT_KWARGS: ta.Mapping[str, ta.Any] = dict(
         | 
| 1843 | 
            +
                indent=None,
         | 
| 1844 | 
            +
                separators=JSON_COMPACT_SEPARATORS,
         | 
| 1845 | 
            +
            )
         | 
| 1846 | 
            +
             | 
| 1847 | 
            +
            json_dump_compact: ta.Callable[..., bytes] = functools.partial(json.dump, **JSON_COMPACT_KWARGS)  # type: ignore
         | 
| 1848 | 
            +
            json_dumps_compact: ta.Callable[..., str] = functools.partial(json.dumps, **JSON_COMPACT_KWARGS)
         | 
| 1849 | 
            +
             | 
| 1850 | 
            +
             | 
| 1851 | 
            +
            ########################################
         | 
| 1852 | 
            +
            # ../../../omlish/lite/maybes.py
         | 
| 1853 | 
            +
             | 
| 1854 | 
            +
             | 
| 1855 | 
            +
            class Maybe(ta.Generic[T]):
         | 
| 1856 | 
            +
                @property
         | 
| 1857 | 
            +
                @abc.abstractmethod
         | 
| 1858 | 
            +
                def present(self) -> bool:
         | 
| 1859 | 
            +
                    raise NotImplementedError
         | 
| 1860 | 
            +
             | 
| 1861 | 
            +
                @abc.abstractmethod
         | 
| 1862 | 
            +
                def must(self) -> T:
         | 
| 1863 | 
            +
                    raise NotImplementedError
         | 
| 1864 | 
            +
             | 
| 1865 | 
            +
                @classmethod
         | 
| 1866 | 
            +
                def just(cls, v: T) -> 'Maybe[T]':
         | 
| 1867 | 
            +
                    return tuple.__new__(_Maybe, (v,))  # noqa
         | 
| 1868 | 
            +
             | 
| 1869 | 
            +
                _empty: ta.ClassVar['Maybe']
         | 
| 1870 | 
            +
             | 
| 1871 | 
            +
                @classmethod
         | 
| 1872 | 
            +
                def empty(cls) -> 'Maybe[T]':
         | 
| 1873 | 
            +
                    return Maybe._empty
         | 
| 1874 | 
            +
             | 
| 1875 | 
            +
             | 
| 1876 | 
            +
            class _Maybe(Maybe[T], tuple):
         | 
| 1877 | 
            +
                __slots__ = ()
         | 
| 1878 | 
            +
             | 
| 1879 | 
            +
                def __init_subclass__(cls, **kwargs):
         | 
| 1880 | 
            +
                    raise TypeError
         | 
| 1881 | 
            +
             | 
| 1882 | 
            +
                @property
         | 
| 1883 | 
            +
                def present(self) -> bool:
         | 
| 1884 | 
            +
                    return bool(self)
         | 
| 1885 | 
            +
             | 
| 1886 | 
            +
                def must(self) -> T:
         | 
| 1882 1887 | 
             
                    if not self:
         | 
| 1883 1888 | 
             
                        raise ValueError
         | 
| 1884 1889 | 
             
                    return self[0]
         | 
| @@ -2564,65 +2569,229 @@ def get_user(name: str) -> User: | |
| 2564 2569 |  | 
| 2565 2570 |  | 
| 2566 2571 | 
             
            ########################################
         | 
| 2567 | 
            -
            # ../../../omlish/ | 
| 2572 | 
            +
            # ../../../omlish/io/buffers.py
         | 
| 2568 2573 |  | 
| 2569 2574 |  | 
| 2570 | 
            -
             | 
| 2575 | 
            +
            class DelimitingBuffer:
         | 
| 2576 | 
            +
                """
         | 
| 2577 | 
            +
                https://github.com/python-trio/trio/issues/796 :|
         | 
| 2578 | 
            +
                """
         | 
| 2571 2579 |  | 
| 2580 | 
            +
                #
         | 
| 2572 2581 |  | 
| 2573 | 
            -
            class  | 
| 2574 | 
            -
             | 
| 2582 | 
            +
                class Error(Exception):
         | 
| 2583 | 
            +
                    def __init__(self, buffer: 'DelimitingBuffer') -> None:
         | 
| 2584 | 
            +
                        super().__init__(buffer)
         | 
| 2585 | 
            +
                        self.buffer = buffer
         | 
| 2575 2586 |  | 
| 2576 | 
            -
             | 
| 2577 | 
            -
             | 
| 2578 | 
            -
                    es = self._exit_stack = contextlib.ExitStack()
         | 
| 2579 | 
            -
                    es.__enter__()
         | 
| 2580 | 
            -
                    return self
         | 
| 2587 | 
            +
                    def __repr__(self) -> str:
         | 
| 2588 | 
            +
                        return attr_repr(self, 'buffer')
         | 
| 2581 2589 |  | 
| 2582 | 
            -
                 | 
| 2583 | 
            -
                     | 
| 2590 | 
            +
                class ClosedError(Error):
         | 
| 2591 | 
            +
                    pass
         | 
| 2592 | 
            +
             | 
| 2593 | 
            +
                #
         | 
| 2594 | 
            +
             | 
| 2595 | 
            +
                DEFAULT_DELIMITERS: bytes = b'\n'
         | 
| 2596 | 
            +
             | 
| 2597 | 
            +
                def __init__(
         | 
| 2598 | 
            +
                        self,
         | 
| 2599 | 
            +
                        delimiters: ta.Iterable[int] = DEFAULT_DELIMITERS,
         | 
| 2600 | 
            +
                        *,
         | 
| 2601 | 
            +
                        keep_ends: bool = False,
         | 
| 2602 | 
            +
                        max_size: ta.Optional[int] = None,
         | 
| 2603 | 
            +
                ) -> None:
         | 
| 2604 | 
            +
                    super().__init__()
         | 
| 2605 | 
            +
             | 
| 2606 | 
            +
                    self._delimiters = frozenset(check_isinstance(d, int) for d in delimiters)
         | 
| 2607 | 
            +
                    self._keep_ends = keep_ends
         | 
| 2608 | 
            +
                    self._max_size = max_size
         | 
| 2609 | 
            +
             | 
| 2610 | 
            +
                    self._buf: ta.Optional[io.BytesIO] = io.BytesIO()
         | 
| 2611 | 
            +
             | 
| 2612 | 
            +
                #
         | 
| 2613 | 
            +
             | 
| 2614 | 
            +
                @property
         | 
| 2615 | 
            +
                def is_closed(self) -> bool:
         | 
| 2616 | 
            +
                    return self._buf is None
         | 
| 2617 | 
            +
             | 
| 2618 | 
            +
                def tell(self) -> int:
         | 
| 2619 | 
            +
                    if (buf := self._buf) is None:
         | 
| 2620 | 
            +
                        raise self.ClosedError(self)
         | 
| 2621 | 
            +
                    return buf.tell()
         | 
| 2622 | 
            +
             | 
| 2623 | 
            +
                def peek(self) -> bytes:
         | 
| 2624 | 
            +
                    if (buf := self._buf) is None:
         | 
| 2625 | 
            +
                        raise self.ClosedError(self)
         | 
| 2626 | 
            +
                    return buf.getvalue()
         | 
| 2627 | 
            +
             | 
| 2628 | 
            +
                def _find_delim(self, data: ta.Union[bytes, bytearray], i: int) -> ta.Optional[int]:
         | 
| 2629 | 
            +
                    r = None  # type: int | None
         | 
| 2630 | 
            +
                    for d in self._delimiters:
         | 
| 2631 | 
            +
                        if (p := data.find(d, i)) >= 0:
         | 
| 2632 | 
            +
                            if r is None or p < r:
         | 
| 2633 | 
            +
                                r = p
         | 
| 2634 | 
            +
                    return r
         | 
| 2635 | 
            +
             | 
| 2636 | 
            +
                def _append_and_reset(self, chunk: bytes) -> bytes:
         | 
| 2637 | 
            +
                    buf = check_not_none(self._buf)
         | 
| 2638 | 
            +
                    if not buf.tell():
         | 
| 2639 | 
            +
                        return chunk
         | 
| 2640 | 
            +
             | 
| 2641 | 
            +
                    buf.write(chunk)
         | 
| 2642 | 
            +
                    ret = buf.getvalue()
         | 
| 2643 | 
            +
                    buf.seek(0)
         | 
| 2644 | 
            +
                    buf.truncate()
         | 
| 2645 | 
            +
                    return ret
         | 
| 2646 | 
            +
             | 
| 2647 | 
            +
                class Incomplete(ta.NamedTuple):
         | 
| 2648 | 
            +
                    b: bytes
         | 
| 2649 | 
            +
             | 
| 2650 | 
            +
                def feed(self, data: ta.Union[bytes, bytearray]) -> ta.Generator[ta.Union[bytes, Incomplete], None, None]:
         | 
| 2651 | 
            +
                    if (buf := self._buf) is None:
         | 
| 2652 | 
            +
                        raise self.ClosedError(self)
         | 
| 2653 | 
            +
             | 
| 2654 | 
            +
                    if not data:
         | 
| 2655 | 
            +
                        self._buf = None
         | 
| 2656 | 
            +
             | 
| 2657 | 
            +
                        if buf.tell():
         | 
| 2658 | 
            +
                            yield self.Incomplete(buf.getvalue())
         | 
| 2659 | 
            +
             | 
| 2660 | 
            +
                        return
         | 
| 2661 | 
            +
             | 
| 2662 | 
            +
                    l = len(data)
         | 
| 2663 | 
            +
                    i = 0
         | 
| 2664 | 
            +
                    while i < l:
         | 
| 2665 | 
            +
                        if (p := self._find_delim(data, i)) is None:
         | 
| 2666 | 
            +
                            break
         | 
| 2667 | 
            +
             | 
| 2668 | 
            +
                        n = p + 1
         | 
| 2669 | 
            +
                        if self._keep_ends:
         | 
| 2670 | 
            +
                            p = n
         | 
| 2671 | 
            +
             | 
| 2672 | 
            +
                        yield self._append_and_reset(data[i:p])
         | 
| 2673 | 
            +
             | 
| 2674 | 
            +
                        i = n
         | 
| 2675 | 
            +
             | 
| 2676 | 
            +
                    if i >= l:
         | 
| 2677 | 
            +
                        return
         | 
| 2678 | 
            +
             | 
| 2679 | 
            +
                    if self._max_size is None:
         | 
| 2680 | 
            +
                        buf.write(data[i:])
         | 
| 2681 | 
            +
                        return
         | 
| 2682 | 
            +
             | 
| 2683 | 
            +
                    while i < l:
         | 
| 2684 | 
            +
                        remaining_data_len = l - i
         | 
| 2685 | 
            +
                        remaining_buf_capacity = self._max_size - buf.tell()
         | 
| 2686 | 
            +
             | 
| 2687 | 
            +
                        if remaining_data_len < remaining_buf_capacity:
         | 
| 2688 | 
            +
                            buf.write(data[i:])
         | 
| 2689 | 
            +
                            return
         | 
| 2690 | 
            +
             | 
| 2691 | 
            +
                        p = i + remaining_buf_capacity
         | 
| 2692 | 
            +
                        yield self.Incomplete(self._append_and_reset(data[i:p]))
         | 
| 2693 | 
            +
                        i = p
         | 
| 2694 | 
            +
             | 
| 2695 | 
            +
             | 
| 2696 | 
            +
            class ReadableListBuffer:
         | 
| 2697 | 
            +
                def __init__(self) -> None:
         | 
| 2698 | 
            +
                    super().__init__()
         | 
| 2699 | 
            +
                    self._lst: list[bytes] = []
         | 
| 2700 | 
            +
             | 
| 2701 | 
            +
                def feed(self, d: bytes) -> None:
         | 
| 2702 | 
            +
                    if d:
         | 
| 2703 | 
            +
                        self._lst.append(d)
         | 
| 2704 | 
            +
             | 
| 2705 | 
            +
                def _chop(self, i: int, e: int) -> bytes:
         | 
| 2706 | 
            +
                    lst = self._lst
         | 
| 2707 | 
            +
                    d = lst[i]
         | 
| 2708 | 
            +
             | 
| 2709 | 
            +
                    o = b''.join([
         | 
| 2710 | 
            +
                        *lst[:i],
         | 
| 2711 | 
            +
                        d[:e],
         | 
| 2712 | 
            +
                    ])
         | 
| 2713 | 
            +
             | 
| 2714 | 
            +
                    self._lst = [
         | 
| 2715 | 
            +
                        *([d[e:]] if e < len(d) else []),
         | 
| 2716 | 
            +
                        *lst[i + 1:],
         | 
| 2717 | 
            +
                    ]
         | 
| 2718 | 
            +
             | 
| 2719 | 
            +
                    return o
         | 
| 2720 | 
            +
             | 
| 2721 | 
            +
                def read(self, n: ta.Optional[int] = None) -> ta.Optional[bytes]:
         | 
| 2722 | 
            +
                    if n is None:
         | 
| 2723 | 
            +
                        o = b''.join(self._lst)
         | 
| 2724 | 
            +
                        self._lst = []
         | 
| 2725 | 
            +
                        return o
         | 
| 2726 | 
            +
             | 
| 2727 | 
            +
                    if not (lst := self._lst):
         | 
| 2584 2728 | 
             
                        return None
         | 
| 2585 | 
            -
                    self._exit_contexts()
         | 
| 2586 | 
            -
                    return es.__exit__(exc_type, exc_val, exc_tb)
         | 
| 2587 2729 |  | 
| 2588 | 
            -
             | 
| 2589 | 
            -
                     | 
| 2730 | 
            +
                    c = 0
         | 
| 2731 | 
            +
                    for i, d in enumerate(lst):
         | 
| 2732 | 
            +
                        r = n - c
         | 
| 2733 | 
            +
                        if (l := len(d)) >= r:
         | 
| 2734 | 
            +
                            return self._chop(i, r)
         | 
| 2735 | 
            +
                        c += l
         | 
| 2590 2736 |  | 
| 2591 | 
            -
             | 
| 2592 | 
            -
                    es = check_not_none(self._exit_stack)
         | 
| 2593 | 
            -
                    return es.enter_context(cm)
         | 
| 2737 | 
            +
                    return None
         | 
| 2594 2738 |  | 
| 2739 | 
            +
                def read_until(self, delim: bytes = b'\n') -> ta.Optional[bytes]:
         | 
| 2740 | 
            +
                    if not (lst := self._lst):
         | 
| 2741 | 
            +
                        return None
         | 
| 2595 2742 |  | 
| 2596 | 
            -
             | 
| 2743 | 
            +
                    for i, d in enumerate(lst):
         | 
| 2744 | 
            +
                        if (p := d.find(delim)) >= 0:
         | 
| 2745 | 
            +
                            return self._chop(i, p + len(delim))
         | 
| 2597 2746 |  | 
| 2747 | 
            +
                    return None
         | 
| 2598 2748 |  | 
| 2599 | 
            -
            @contextlib.contextmanager
         | 
| 2600 | 
            -
            def defer(fn: ta.Callable) -> ta.Generator[ta.Callable, None, None]:
         | 
| 2601 | 
            -
                try:
         | 
| 2602 | 
            -
                    yield fn
         | 
| 2603 | 
            -
                finally:
         | 
| 2604 | 
            -
                    fn()
         | 
| 2605 2749 |  | 
| 2750 | 
            +
            class IncrementalWriteBuffer:
         | 
| 2751 | 
            +
                def __init__(
         | 
| 2752 | 
            +
                        self,
         | 
| 2753 | 
            +
                        data: bytes,
         | 
| 2754 | 
            +
                        *,
         | 
| 2755 | 
            +
                        write_size: int = 0x10000,
         | 
| 2756 | 
            +
                ) -> None:
         | 
| 2757 | 
            +
                    super().__init__()
         | 
| 2606 2758 |  | 
| 2607 | 
            -
             | 
| 2608 | 
            -
             | 
| 2609 | 
            -
             | 
| 2610 | 
            -
             | 
| 2611 | 
            -
             | 
| 2612 | 
            -
             | 
| 2613 | 
            -
             | 
| 2614 | 
            -
             | 
| 2615 | 
            -
                     | 
| 2616 | 
            -
             | 
| 2617 | 
            -
                 | 
| 2618 | 
            -
             | 
| 2619 | 
            -
             | 
| 2620 | 
            -
             | 
| 2621 | 
            -
             | 
| 2759 | 
            +
                    check_not_empty(data)
         | 
| 2760 | 
            +
                    self._len = len(data)
         | 
| 2761 | 
            +
                    self._write_size = write_size
         | 
| 2762 | 
            +
             | 
| 2763 | 
            +
                    self._lst = [
         | 
| 2764 | 
            +
                        data[i:i + write_size]
         | 
| 2765 | 
            +
                        for i in range(0, len(data), write_size)
         | 
| 2766 | 
            +
                    ]
         | 
| 2767 | 
            +
                    self._pos = 0
         | 
| 2768 | 
            +
             | 
| 2769 | 
            +
                @property
         | 
| 2770 | 
            +
                def rem(self) -> int:
         | 
| 2771 | 
            +
                    return self._len - self._pos
         | 
| 2772 | 
            +
             | 
| 2773 | 
            +
                def write(self, fn: ta.Callable[[bytes], int]) -> int:
         | 
| 2774 | 
            +
                    lst = check_not_empty(self._lst)
         | 
| 2775 | 
            +
             | 
| 2776 | 
            +
                    t = 0
         | 
| 2777 | 
            +
                    for i, d in enumerate(lst):  # noqa
         | 
| 2778 | 
            +
                        n = fn(check_not_empty(d))
         | 
| 2779 | 
            +
                        if not n:
         | 
| 2780 | 
            +
                            break
         | 
| 2781 | 
            +
                        t += n
         | 
| 2782 | 
            +
             | 
| 2783 | 
            +
                    if t:
         | 
| 2784 | 
            +
                        self._lst = [
         | 
| 2785 | 
            +
                            *([d[n:]] if n < len(d) else []),
         | 
| 2786 | 
            +
                            *lst[i + 1:],
         | 
| 2787 | 
            +
                        ]
         | 
| 2788 | 
            +
                        self._pos += t
         | 
| 2789 | 
            +
             | 
| 2790 | 
            +
                    return t
         | 
| 2622 2791 |  | 
| 2623 2792 |  | 
| 2624 2793 | 
             
            ########################################
         | 
| 2625 | 
            -
            # ../../../omlish/ | 
| 2794 | 
            +
            # ../../../omlish/io/fdio/handlers.py
         | 
| 2626 2795 |  | 
| 2627 2796 |  | 
| 2628 2797 | 
             
            class FdioHandler(abc.ABC):
         | 
| @@ -2686,7 +2855,7 @@ class SocketFdioHandler(FdioHandler, abc.ABC): | |
| 2686 2855 |  | 
| 2687 2856 |  | 
| 2688 2857 | 
             
            ########################################
         | 
| 2689 | 
            -
            # ../../../omlish/ | 
| 2858 | 
            +
            # ../../../omlish/io/fdio/kqueue.py
         | 
| 2690 2859 |  | 
| 2691 2860 |  | 
| 2692 2861 | 
             
            KqueueFdioPoller: ta.Optional[ta.Type[FdioPoller]]
         | 
| @@ -2785,25 +2954,83 @@ if sys.platform == 'darwin' or sys.platform.startswith('freebsd'): | |
| 2785 2954 | 
             
                        try:
         | 
| 2786 2955 | 
             
                            kes = kq.control(None, self._max_events, timeout)
         | 
| 2787 2956 |  | 
| 2788 | 
            -
                        except OSError as exc:
         | 
| 2789 | 
            -
                            if exc.errno == errno.EINTR:
         | 
| 2790 | 
            -
                                return FdioPoller.PollResult(msg='EINTR encountered in poll', exc=exc)
         | 
| 2791 | 
            -
                            else:
         | 
| 2792 | 
            -
                                raise
         | 
| 2957 | 
            +
                        except OSError as exc:
         | 
| 2958 | 
            +
                            if exc.errno == errno.EINTR:
         | 
| 2959 | 
            +
                                return FdioPoller.PollResult(msg='EINTR encountered in poll', exc=exc)
         | 
| 2960 | 
            +
                            else:
         | 
| 2961 | 
            +
                                raise
         | 
| 2962 | 
            +
             | 
| 2963 | 
            +
                        r: ta.List[int] = []
         | 
| 2964 | 
            +
                        w: ta.List[int] = []
         | 
| 2965 | 
            +
                        for ke in kes:
         | 
| 2966 | 
            +
                            if ke.filter == select.KQ_FILTER_READ:
         | 
| 2967 | 
            +
                                r.append(ke.ident)
         | 
| 2968 | 
            +
                            if ke.filter == select.KQ_FILTER_WRITE:
         | 
| 2969 | 
            +
                                w.append(ke.ident)
         | 
| 2970 | 
            +
             | 
| 2971 | 
            +
                        return FdioPoller.PollResult(r, w)
         | 
| 2972 | 
            +
             | 
| 2973 | 
            +
                KqueueFdioPoller = _KqueueFdioPoller
         | 
| 2974 | 
            +
            else:
         | 
| 2975 | 
            +
                KqueueFdioPoller = None
         | 
| 2976 | 
            +
             | 
| 2977 | 
            +
             | 
| 2978 | 
            +
            ########################################
         | 
| 2979 | 
            +
            # ../../../omlish/lite/contextmanagers.py
         | 
| 2980 | 
            +
             | 
| 2981 | 
            +
             | 
| 2982 | 
            +
            ##
         | 
| 2983 | 
            +
             | 
| 2984 | 
            +
             | 
| 2985 | 
            +
            class ExitStacked:
         | 
| 2986 | 
            +
                _exit_stack: ta.Optional[contextlib.ExitStack] = None
         | 
| 2987 | 
            +
             | 
| 2988 | 
            +
                def __enter__(self: ExitStackedT) -> ExitStackedT:
         | 
| 2989 | 
            +
                    check_state(self._exit_stack is None)
         | 
| 2990 | 
            +
                    es = self._exit_stack = contextlib.ExitStack()
         | 
| 2991 | 
            +
                    es.__enter__()
         | 
| 2992 | 
            +
                    return self
         | 
| 2993 | 
            +
             | 
| 2994 | 
            +
                def __exit__(self, exc_type, exc_val, exc_tb):
         | 
| 2995 | 
            +
                    if (es := self._exit_stack) is None:
         | 
| 2996 | 
            +
                        return None
         | 
| 2997 | 
            +
                    self._exit_contexts()
         | 
| 2998 | 
            +
                    return es.__exit__(exc_type, exc_val, exc_tb)
         | 
| 2999 | 
            +
             | 
| 3000 | 
            +
                def _exit_contexts(self) -> None:
         | 
| 3001 | 
            +
                    pass
         | 
| 3002 | 
            +
             | 
| 3003 | 
            +
                def _enter_context(self, cm: ta.ContextManager[T]) -> T:
         | 
| 3004 | 
            +
                    es = check_not_none(self._exit_stack)
         | 
| 3005 | 
            +
                    return es.enter_context(cm)
         | 
| 3006 | 
            +
             | 
| 3007 | 
            +
             | 
| 3008 | 
            +
            ##
         | 
| 3009 | 
            +
             | 
| 2793 3010 |  | 
| 2794 | 
            -
             | 
| 2795 | 
            -
             | 
| 2796 | 
            -
             | 
| 2797 | 
            -
             | 
| 2798 | 
            -
             | 
| 2799 | 
            -
             | 
| 2800 | 
            -
                                w.append(ke.ident)
         | 
| 3011 | 
            +
            @contextlib.contextmanager
         | 
| 3012 | 
            +
            def defer(fn: ta.Callable) -> ta.Generator[ta.Callable, None, None]:
         | 
| 3013 | 
            +
                try:
         | 
| 3014 | 
            +
                    yield fn
         | 
| 3015 | 
            +
                finally:
         | 
| 3016 | 
            +
                    fn()
         | 
| 2801 3017 |  | 
| 2802 | 
            -
                        return FdioPoller.PollResult(r, w)
         | 
| 2803 3018 |  | 
| 2804 | 
            -
             | 
| 2805 | 
            -
             | 
| 2806 | 
            -
                 | 
| 3019 | 
            +
            @contextlib.contextmanager
         | 
| 3020 | 
            +
            def attr_setting(obj, attr, val, *, default=None):  # noqa
         | 
| 3021 | 
            +
                not_set = object()
         | 
| 3022 | 
            +
                orig = getattr(obj, attr, not_set)
         | 
| 3023 | 
            +
                try:
         | 
| 3024 | 
            +
                    setattr(obj, attr, val)
         | 
| 3025 | 
            +
                    if orig is not not_set:
         | 
| 3026 | 
            +
                        yield orig
         | 
| 3027 | 
            +
                    else:
         | 
| 3028 | 
            +
                        yield default
         | 
| 3029 | 
            +
                finally:
         | 
| 3030 | 
            +
                    if orig is not_set:
         | 
| 3031 | 
            +
                        delattr(obj, attr)
         | 
| 3032 | 
            +
                    else:
         | 
| 3033 | 
            +
                        setattr(obj, attr, orig)
         | 
| 2807 3034 |  | 
| 2808 3035 |  | 
| 2809 3036 | 
             
            ########################################
         | 
| @@ -4099,228 +4326,6 @@ class Injection: | |
| 4099 4326 | 
             
            inj = Injection
         | 
| 4100 4327 |  | 
| 4101 4328 |  | 
| 4102 | 
            -
            ########################################
         | 
| 4103 | 
            -
            # ../../../omlish/lite/io.py
         | 
| 4104 | 
            -
             | 
| 4105 | 
            -
             | 
| 4106 | 
            -
            class DelimitingBuffer:
         | 
| 4107 | 
            -
                """
         | 
| 4108 | 
            -
                https://github.com/python-trio/trio/issues/796 :|
         | 
| 4109 | 
            -
                """
         | 
| 4110 | 
            -
             | 
| 4111 | 
            -
                #
         | 
| 4112 | 
            -
             | 
| 4113 | 
            -
                class Error(Exception):
         | 
| 4114 | 
            -
                    def __init__(self, buffer: 'DelimitingBuffer') -> None:
         | 
| 4115 | 
            -
                        super().__init__(buffer)
         | 
| 4116 | 
            -
                        self.buffer = buffer
         | 
| 4117 | 
            -
             | 
| 4118 | 
            -
                    def __repr__(self) -> str:
         | 
| 4119 | 
            -
                        return attr_repr(self, 'buffer')
         | 
| 4120 | 
            -
             | 
| 4121 | 
            -
                class ClosedError(Error):
         | 
| 4122 | 
            -
                    pass
         | 
| 4123 | 
            -
             | 
| 4124 | 
            -
                #
         | 
| 4125 | 
            -
             | 
| 4126 | 
            -
                DEFAULT_DELIMITERS: bytes = b'\n'
         | 
| 4127 | 
            -
             | 
| 4128 | 
            -
                def __init__(
         | 
| 4129 | 
            -
                        self,
         | 
| 4130 | 
            -
                        delimiters: ta.Iterable[int] = DEFAULT_DELIMITERS,
         | 
| 4131 | 
            -
                        *,
         | 
| 4132 | 
            -
                        keep_ends: bool = False,
         | 
| 4133 | 
            -
                        max_size: ta.Optional[int] = None,
         | 
| 4134 | 
            -
                ) -> None:
         | 
| 4135 | 
            -
                    super().__init__()
         | 
| 4136 | 
            -
             | 
| 4137 | 
            -
                    self._delimiters = frozenset(check_isinstance(d, int) for d in delimiters)
         | 
| 4138 | 
            -
                    self._keep_ends = keep_ends
         | 
| 4139 | 
            -
                    self._max_size = max_size
         | 
| 4140 | 
            -
             | 
| 4141 | 
            -
                    self._buf: ta.Optional[io.BytesIO] = io.BytesIO()
         | 
| 4142 | 
            -
             | 
| 4143 | 
            -
                #
         | 
| 4144 | 
            -
             | 
| 4145 | 
            -
                @property
         | 
| 4146 | 
            -
                def is_closed(self) -> bool:
         | 
| 4147 | 
            -
                    return self._buf is None
         | 
| 4148 | 
            -
             | 
| 4149 | 
            -
                def tell(self) -> int:
         | 
| 4150 | 
            -
                    if (buf := self._buf) is None:
         | 
| 4151 | 
            -
                        raise self.ClosedError(self)
         | 
| 4152 | 
            -
                    return buf.tell()
         | 
| 4153 | 
            -
             | 
| 4154 | 
            -
                def peek(self) -> bytes:
         | 
| 4155 | 
            -
                    if (buf := self._buf) is None:
         | 
| 4156 | 
            -
                        raise self.ClosedError(self)
         | 
| 4157 | 
            -
                    return buf.getvalue()
         | 
| 4158 | 
            -
             | 
| 4159 | 
            -
                def _find_delim(self, data: ta.Union[bytes, bytearray], i: int) -> ta.Optional[int]:
         | 
| 4160 | 
            -
                    r = None  # type: int | None
         | 
| 4161 | 
            -
                    for d in self._delimiters:
         | 
| 4162 | 
            -
                        if (p := data.find(d, i)) >= 0:
         | 
| 4163 | 
            -
                            if r is None or p < r:
         | 
| 4164 | 
            -
                                r = p
         | 
| 4165 | 
            -
                    return r
         | 
| 4166 | 
            -
             | 
| 4167 | 
            -
                def _append_and_reset(self, chunk: bytes) -> bytes:
         | 
| 4168 | 
            -
                    buf = check_not_none(self._buf)
         | 
| 4169 | 
            -
                    if not buf.tell():
         | 
| 4170 | 
            -
                        return chunk
         | 
| 4171 | 
            -
             | 
| 4172 | 
            -
                    buf.write(chunk)
         | 
| 4173 | 
            -
                    ret = buf.getvalue()
         | 
| 4174 | 
            -
                    buf.seek(0)
         | 
| 4175 | 
            -
                    buf.truncate()
         | 
| 4176 | 
            -
                    return ret
         | 
| 4177 | 
            -
             | 
| 4178 | 
            -
                class Incomplete(ta.NamedTuple):
         | 
| 4179 | 
            -
                    b: bytes
         | 
| 4180 | 
            -
             | 
| 4181 | 
            -
                def feed(self, data: ta.Union[bytes, bytearray]) -> ta.Generator[ta.Union[bytes, Incomplete], None, None]:
         | 
| 4182 | 
            -
                    if (buf := self._buf) is None:
         | 
| 4183 | 
            -
                        raise self.ClosedError(self)
         | 
| 4184 | 
            -
             | 
| 4185 | 
            -
                    if not data:
         | 
| 4186 | 
            -
                        self._buf = None
         | 
| 4187 | 
            -
             | 
| 4188 | 
            -
                        if buf.tell():
         | 
| 4189 | 
            -
                            yield self.Incomplete(buf.getvalue())
         | 
| 4190 | 
            -
             | 
| 4191 | 
            -
                        return
         | 
| 4192 | 
            -
             | 
| 4193 | 
            -
                    l = len(data)
         | 
| 4194 | 
            -
                    i = 0
         | 
| 4195 | 
            -
                    while i < l:
         | 
| 4196 | 
            -
                        if (p := self._find_delim(data, i)) is None:
         | 
| 4197 | 
            -
                            break
         | 
| 4198 | 
            -
             | 
| 4199 | 
            -
                        n = p + 1
         | 
| 4200 | 
            -
                        if self._keep_ends:
         | 
| 4201 | 
            -
                            p = n
         | 
| 4202 | 
            -
             | 
| 4203 | 
            -
                        yield self._append_and_reset(data[i:p])
         | 
| 4204 | 
            -
             | 
| 4205 | 
            -
                        i = n
         | 
| 4206 | 
            -
             | 
| 4207 | 
            -
                    if i >= l:
         | 
| 4208 | 
            -
                        return
         | 
| 4209 | 
            -
             | 
| 4210 | 
            -
                    if self._max_size is None:
         | 
| 4211 | 
            -
                        buf.write(data[i:])
         | 
| 4212 | 
            -
                        return
         | 
| 4213 | 
            -
             | 
| 4214 | 
            -
                    while i < l:
         | 
| 4215 | 
            -
                        remaining_data_len = l - i
         | 
| 4216 | 
            -
                        remaining_buf_capacity = self._max_size - buf.tell()
         | 
| 4217 | 
            -
             | 
| 4218 | 
            -
                        if remaining_data_len < remaining_buf_capacity:
         | 
| 4219 | 
            -
                            buf.write(data[i:])
         | 
| 4220 | 
            -
                            return
         | 
| 4221 | 
            -
             | 
| 4222 | 
            -
                        p = i + remaining_buf_capacity
         | 
| 4223 | 
            -
                        yield self.Incomplete(self._append_and_reset(data[i:p]))
         | 
| 4224 | 
            -
                        i = p
         | 
| 4225 | 
            -
             | 
| 4226 | 
            -
             | 
| 4227 | 
            -
            class ReadableListBuffer:
         | 
| 4228 | 
            -
                def __init__(self) -> None:
         | 
| 4229 | 
            -
                    super().__init__()
         | 
| 4230 | 
            -
                    self._lst: list[bytes] = []
         | 
| 4231 | 
            -
             | 
| 4232 | 
            -
                def feed(self, d: bytes) -> None:
         | 
| 4233 | 
            -
                    if d:
         | 
| 4234 | 
            -
                        self._lst.append(d)
         | 
| 4235 | 
            -
             | 
| 4236 | 
            -
                def _chop(self, i: int, e: int) -> bytes:
         | 
| 4237 | 
            -
                    lst = self._lst
         | 
| 4238 | 
            -
                    d = lst[i]
         | 
| 4239 | 
            -
             | 
| 4240 | 
            -
                    o = b''.join([
         | 
| 4241 | 
            -
                        *lst[:i],
         | 
| 4242 | 
            -
                        d[:e],
         | 
| 4243 | 
            -
                    ])
         | 
| 4244 | 
            -
             | 
| 4245 | 
            -
                    self._lst = [
         | 
| 4246 | 
            -
                        *([d[e:]] if e < len(d) else []),
         | 
| 4247 | 
            -
                        *lst[i + 1:],
         | 
| 4248 | 
            -
                    ]
         | 
| 4249 | 
            -
             | 
| 4250 | 
            -
                    return o
         | 
| 4251 | 
            -
             | 
| 4252 | 
            -
                def read(self, n: ta.Optional[int] = None) -> ta.Optional[bytes]:
         | 
| 4253 | 
            -
                    if n is None:
         | 
| 4254 | 
            -
                        o = b''.join(self._lst)
         | 
| 4255 | 
            -
                        self._lst = []
         | 
| 4256 | 
            -
                        return o
         | 
| 4257 | 
            -
             | 
| 4258 | 
            -
                    if not (lst := self._lst):
         | 
| 4259 | 
            -
                        return None
         | 
| 4260 | 
            -
             | 
| 4261 | 
            -
                    c = 0
         | 
| 4262 | 
            -
                    for i, d in enumerate(lst):
         | 
| 4263 | 
            -
                        r = n - c
         | 
| 4264 | 
            -
                        if (l := len(d)) >= r:
         | 
| 4265 | 
            -
                            return self._chop(i, r)
         | 
| 4266 | 
            -
                        c += l
         | 
| 4267 | 
            -
             | 
| 4268 | 
            -
                    return None
         | 
| 4269 | 
            -
             | 
| 4270 | 
            -
                def read_until(self, delim: bytes = b'\n') -> ta.Optional[bytes]:
         | 
| 4271 | 
            -
                    if not (lst := self._lst):
         | 
| 4272 | 
            -
                        return None
         | 
| 4273 | 
            -
             | 
| 4274 | 
            -
                    for i, d in enumerate(lst):
         | 
| 4275 | 
            -
                        if (p := d.find(delim)) >= 0:
         | 
| 4276 | 
            -
                            return self._chop(i, p + len(delim))
         | 
| 4277 | 
            -
             | 
| 4278 | 
            -
                    return None
         | 
| 4279 | 
            -
             | 
| 4280 | 
            -
             | 
| 4281 | 
            -
            class IncrementalWriteBuffer:
         | 
| 4282 | 
            -
                def __init__(
         | 
| 4283 | 
            -
                        self,
         | 
| 4284 | 
            -
                        data: bytes,
         | 
| 4285 | 
            -
                        *,
         | 
| 4286 | 
            -
                        write_size: int = 0x10000,
         | 
| 4287 | 
            -
                ) -> None:
         | 
| 4288 | 
            -
                    super().__init__()
         | 
| 4289 | 
            -
             | 
| 4290 | 
            -
                    check_non_empty(data)
         | 
| 4291 | 
            -
                    self._len = len(data)
         | 
| 4292 | 
            -
                    self._write_size = write_size
         | 
| 4293 | 
            -
             | 
| 4294 | 
            -
                    self._lst = [
         | 
| 4295 | 
            -
                        data[i:i + write_size]
         | 
| 4296 | 
            -
                        for i in range(0, len(data), write_size)
         | 
| 4297 | 
            -
                    ]
         | 
| 4298 | 
            -
                    self._pos = 0
         | 
| 4299 | 
            -
             | 
| 4300 | 
            -
                @property
         | 
| 4301 | 
            -
                def rem(self) -> int:
         | 
| 4302 | 
            -
                    return self._len - self._pos
         | 
| 4303 | 
            -
             | 
| 4304 | 
            -
                def write(self, fn: ta.Callable[[bytes], int]) -> int:
         | 
| 4305 | 
            -
                    lst = check_non_empty(self._lst)
         | 
| 4306 | 
            -
             | 
| 4307 | 
            -
                    t = 0
         | 
| 4308 | 
            -
                    for i, d in enumerate(lst):  # noqa
         | 
| 4309 | 
            -
                        n = fn(check_non_empty(d))
         | 
| 4310 | 
            -
                        if not n:
         | 
| 4311 | 
            -
                            break
         | 
| 4312 | 
            -
                        t += n
         | 
| 4313 | 
            -
             | 
| 4314 | 
            -
                    if t:
         | 
| 4315 | 
            -
                        self._lst = [
         | 
| 4316 | 
            -
                            *([d[n:]] if n < len(d) else []),
         | 
| 4317 | 
            -
                            *lst[i + 1:],
         | 
| 4318 | 
            -
                        ]
         | 
| 4319 | 
            -
                        self._pos += t
         | 
| 4320 | 
            -
             | 
| 4321 | 
            -
                    return t
         | 
| 4322 | 
            -
             | 
| 4323 | 
            -
             | 
| 4324 4329 | 
             
            ########################################
         | 
| 4325 4330 | 
             
            # ../../../omlish/lite/journald.py
         | 
| 4326 4331 |  | 
| @@ -6321,7 +6326,7 @@ class ProcessGroup( | |
| 6321 6326 |  | 
| 6322 6327 |  | 
| 6323 6328 | 
             
            ########################################
         | 
| 6324 | 
            -
            # ../../../omlish/ | 
| 6329 | 
            +
            # ../../../omlish/io/fdio/corohttp.py
         | 
| 6325 6330 |  | 
| 6326 6331 |  | 
| 6327 6332 | 
             
            class CoroHttpServerConnectionFdioHandler(SocketFdioHandler):
         |