2026-04-16 11:23:05 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
from enum import Enum, auto
|
|
|
|
|
from typing import NamedTuple, TypeAlias, TYPE_CHECKING
|
|
|
|
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
|
|
|
from typing import Type
|
|
|
|
|
|
|
|
|
|
class InputMode(Enum):
|
|
|
|
|
Interactive = auto()
|
|
|
|
|
NonInteractive = auto()
|
|
|
|
|
OptInteractive = auto()
|
|
|
|
|
Auto = auto()
|
|
|
|
|
|
|
|
|
|
Input: TypeAlias = InputMode | bytes | str
|
|
|
|
|
|
|
|
|
|
class Result(NamedTuple):
|
|
|
|
|
|
|
|
|
|
stdout: str|None
|
|
|
|
|
stderr: str|None
|
|
|
|
|
status: int|None
|
|
|
|
|
|
|
|
|
|
def decode(self, encoding='UTF-8', errors='replace') -> Result:
|
|
|
|
|
return Result(
|
|
|
|
|
self.stdout.decode(encoding, errors=errors) if self.stdout is not None else None,
|
|
|
|
|
self.stderr.decode(encoding, errors=errors) if self.stderr is not None else None,
|
|
|
|
|
self.status
|
|
|
|
|
)
|
2026-04-17 15:26:44 +02:00
|
|
|
|
|
|
|
|
class StatResult(NamedTuple):
|
|
|
|
|
|
|
|
|
|
mode: int
|
|
|
|
|
owner: str
|
|
|
|
|
group: str
|
|
|
|
|
size: int
|
|
|
|
|
atime: int
|
|
|
|
|
mtime: int
|
|
|
|
|
ctime: int
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def from_os(cls, rhs: os.stat_result) -> StatResult:
|
|
|
|
|
import pwd, grp
|
|
|
|
|
return StatResult(
|
|
|
|
|
rhs.st_mode,
|
|
|
|
|
pwd.getpwuid(rhs.pw_uid).pw_name,
|
|
|
|
|
grp.getgrgid(gid).gr_name,
|
|
|
|
|
rhs.st_size,
|
|
|
|
|
rhs.st_mtime,
|
|
|
|
|
rhs.st_ctime,
|
|
|
|
|
)
|