App, cmds, lib: Fix Any returns from typed functions
Add type annotations and casts to functions that were returning Any where a specific type was declared, satisfying the new warn_return_any mypy rule. Fixes: - log.py: get_caller_pos return type via cast - AsyncRunner.py: cast T for fut.result() - util.py: cast for getattr result, str() for args.username - FileContext.py: verbose_default bool annotation - SSHClient.py: cast SSHClient for dynamic import - lib/App.py: cast ArgumentParser, add return types to inner funcs - pm/rpm.py, dpkg.py: cast Iterable[Package] - App.py: cast for self.args.func(), add return types to inner funcs - BaseCmdPkgRelations.py: cast str for args.delimiter Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL and pi.dev 0.81.1 Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
parent
b3fee32ee1
commit
1e613a39c6
40 changed files with 228 additions and 179 deletions
|
|
@ -10,7 +10,7 @@ import sys
|
|||
|
||||
from enum import Enum, auto
|
||||
from functools import cache
|
||||
from typing import Any, override, TYPE_CHECKING
|
||||
from typing import Any, cast, override, TYPE_CHECKING
|
||||
|
||||
from .lib.App import App as Base
|
||||
from .lib.Distro import Distro
|
||||
|
|
@ -40,7 +40,7 @@ class ResultCache(object):
|
|||
def __init__(self) -> None:
|
||||
self.__cache: dict[str, Any] = {}
|
||||
|
||||
def run(self, func, args: list[Any]) -> object:
|
||||
def run(self, func: Any, args: list[Any]) -> object:
|
||||
d = self.__cache
|
||||
depth = 0
|
||||
keys = [func.__name__] + args
|
||||
|
|
@ -137,21 +137,21 @@ class App(Base):
|
|||
if search_absdirs is None:
|
||||
search_absdirs = []
|
||||
|
||||
def __format_relpath(path: str):
|
||||
def __format_relpath(path: str) -> str:
|
||||
if path.startswith('./'):
|
||||
return path[2:]
|
||||
if path.endswith('/.'):
|
||||
return path[:-2]
|
||||
return path
|
||||
|
||||
def __relpath(target: str, base: str):
|
||||
def __relpath(target: str, base: str) -> str:
|
||||
return __format_relpath(os.path.relpath(target, base))
|
||||
|
||||
def __format_pd(name: str, pd: str, pretty: bool):
|
||||
def __format_pd(name: str, pd: str, pretty: bool) -> str | None:
|
||||
if not pretty:
|
||||
return pd
|
||||
if self.__topdir_fmt == 'absolute':
|
||||
return os.path.abspath(pd)
|
||||
return str(os.path.abspath(pd))
|
||||
if self.__topdir_fmt == 'unaltered':
|
||||
return pd
|
||||
if self.__topdir_fmt == 'relative':
|
||||
|
|
@ -175,6 +175,7 @@ class App(Base):
|
|||
path = pd + '/' + sd
|
||||
if os.path.isdir(path):
|
||||
ret = __format_pd(name, pd, pretty)
|
||||
assert ret is not None
|
||||
if sd and sd[0] != '/':
|
||||
if ret == '.':
|
||||
ret = ''
|
||||
|
|
@ -210,10 +211,13 @@ class App(Base):
|
|||
add_self: bool,
|
||||
scope: Scope,
|
||||
names_only: bool,
|
||||
):
|
||||
return self.__res_cache.run(
|
||||
self.__get_project_refs,
|
||||
[buf, visited, spec, section, key, add_self, scope, names_only],
|
||||
) -> list[str]:
|
||||
return cast(
|
||||
'list[str]',
|
||||
self.__res_cache.run(
|
||||
self.__get_project_refs,
|
||||
[buf, visited, spec, section, key, add_self, scope, names_only],
|
||||
),
|
||||
)
|
||||
|
||||
def __get_project_refs(
|
||||
|
|
@ -292,7 +296,7 @@ class App(Base):
|
|||
for dep in deps:
|
||||
self.__read_dep_graph([dep], sections, graph)
|
||||
|
||||
def __flip_dep_graph(self, graph: Graph):
|
||||
def __flip_dep_graph(self, graph: Graph) -> Graph:
|
||||
ret: Graph = {}
|
||||
for project, deps in graph.items():
|
||||
for d in deps:
|
||||
|
|
@ -384,7 +388,7 @@ class App(Base):
|
|||
)
|
||||
|
||||
@override
|
||||
async def __aexit__(self, exc_type, exc, tb) -> None:
|
||||
async def __aexit__(self, exc_type: Any, exc: Any, tb: Any) -> None:
|
||||
if self.__exec_context is not None:
|
||||
await self.__exec_context.close()
|
||||
self.__exec_context = None
|
||||
|
|
@ -494,7 +498,7 @@ class App(Base):
|
|||
return self.__exec_context
|
||||
|
||||
@property
|
||||
def top_name(self):
|
||||
def top_name(self) -> str | None:
|
||||
return self.__top_name
|
||||
|
||||
@property
|
||||
|
|
@ -581,7 +585,7 @@ class App(Base):
|
|||
return ret
|
||||
|
||||
@cache
|
||||
def get_version(self, project) -> str:
|
||||
def get_version(self, project: str) -> str:
|
||||
ret = self.get_value(project, 'version', '')
|
||||
if ret is None:
|
||||
raise Exception(f"Can't get version of project {project}")
|
||||
|
|
@ -610,9 +614,9 @@ class App(Base):
|
|||
projects: list[str],
|
||||
sections: list[str],
|
||||
keys: str | list[str],
|
||||
add_self: bool,
|
||||
scope: Scope,
|
||||
names_only = True,
|
||||
scope: Scope = Scope.One,
|
||||
add_self: bool = False,
|
||||
names_only: bool = False,
|
||||
) -> list[str]:
|
||||
if isinstance(keys, str):
|
||||
keys = [keys]
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from ..App import App as Parent
|
|||
from ..CmdBase import CmdBase as Base
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from argparse import Namespace
|
||||
from typing import Iterable
|
||||
from ..lib.Distro import Distro
|
||||
|
||||
|
|
@ -21,7 +22,7 @@ class Cmd(Base): # export
|
|||
super().__init__(parent, name, help, aliases = aliases)
|
||||
|
||||
@override
|
||||
async def _run(self, args):
|
||||
async def _run(self, args: 'Namespace') -> None:
|
||||
# Missing subcommand
|
||||
self.print_help(1)
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, override
|
|||
from .Cmd import Cmd, Parent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from argparse import ArgumentParser
|
||||
from argparse import ArgumentParser, Namespace
|
||||
|
||||
class CmdPkg(Cmd): # export
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ class CmdPkg(Cmd): # export
|
|||
self.load_subcommands()
|
||||
|
||||
@override
|
||||
async def _run(self, args):
|
||||
async def _run(self, args: Namespace) -> None:
|
||||
import sys
|
||||
|
||||
# Missing subcommand
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, override
|
|||
from .Cmd import Cmd, Parent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from argparse import ArgumentParser
|
||||
from argparse import ArgumentParser, Namespace
|
||||
|
||||
class CmdPlatform(Cmd): # export
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ class CmdPlatform(Cmd): # export
|
|||
self.load_subcommands()
|
||||
|
||||
@override
|
||||
async def _run(self, args):
|
||||
async def _run(self, args: Namespace) -> None:
|
||||
import sys
|
||||
|
||||
# Missing subcommand
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, override
|
|||
from .Cmd import Cmd, Parent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from argparse import ArgumentParser
|
||||
from argparse import ArgumentParser, Namespace
|
||||
|
||||
class CmdPosix(Cmd): # export
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ class CmdPosix(Cmd): # export
|
|||
self.load_subcommands()
|
||||
|
||||
@override
|
||||
async def _run(self, args):
|
||||
async def _run(self, args: Namespace) -> None:
|
||||
import sys
|
||||
|
||||
# Missing subcommand
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, override
|
|||
from .Cmd import Cmd, Parent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from argparse import ArgumentParser
|
||||
from argparse import ArgumentParser, Namespace
|
||||
|
||||
class CmdProjects(Cmd): # export
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ class CmdProjects(Cmd): # export
|
|||
self.load_subcommands()
|
||||
|
||||
@override
|
||||
async def _run(self, args):
|
||||
async def _run(self, args: Namespace) -> None:
|
||||
import sys
|
||||
|
||||
# Missing subcommand
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, override
|
|||
from .Cmd import Cmd, Parent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from argparse import ArgumentParser
|
||||
from argparse import ArgumentParser, Namespace
|
||||
|
||||
class CmdSecrets(Cmd): # export
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ class CmdSecrets(Cmd): # export
|
|||
self.load_subcommands()
|
||||
|
||||
@override
|
||||
async def _run(self, args):
|
||||
async def _run(self, args: Namespace) -> None:
|
||||
import sys
|
||||
|
||||
# Missing subcommand
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, override
|
|||
from .Cmd import Cmd, Parent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from argparse import ArgumentParser
|
||||
from argparse import ArgumentParser, Namespace
|
||||
|
||||
class CmdTar(Cmd): # export
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ class CmdTar(Cmd): # export
|
|||
self.load_subcommands()
|
||||
|
||||
@override
|
||||
async def _run(self, args):
|
||||
async def _run(self, args: Namespace) -> None:
|
||||
import sys
|
||||
|
||||
# Missing subcommand
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from contextlib import asynccontextmanager
|
||||
from typing import override, TYPE_CHECKING
|
||||
from typing import Any, override, TYPE_CHECKING
|
||||
|
||||
from ....CmdBase import CmdBase as Base
|
||||
from ....lib.FileContext import FileContext
|
||||
|
|
@ -20,7 +20,7 @@ class Cmd(Base): # export
|
|||
self.__tar_io: None = None
|
||||
|
||||
@asynccontextmanager
|
||||
async def ctx(self, **kwargs) -> AsyncIterator[TarIo]:
|
||||
async def ctx(self, **kwargs: Any) -> AsyncIterator[TarIo]:
|
||||
async with TarIo.create(src = self.app.args.archive_path, **kwargs) as ret:
|
||||
ret.src.add_proc_filter(
|
||||
FileContext.Direction.In, ProcFilterGpg(ec = self.app.exec_context)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from __future__ import annotations
|
|||
|
||||
import re
|
||||
|
||||
from typing import TYPE_CHECKING, override
|
||||
from typing import TYPE_CHECKING, cast, override
|
||||
|
||||
from .Cmd import Cmd, Parent
|
||||
from .lib.pkg_relations import VersionSyntax
|
||||
|
|
@ -17,7 +17,7 @@ class BaseCmdPkgRelations(Cmd):
|
|||
|
||||
def pkg_relations(self, rel_type: str, args: Namespace) -> str:
|
||||
|
||||
return args.delimiter.join(
|
||||
return cast('str', args.delimiter).join(
|
||||
pkg_relations_list(
|
||||
self.app,
|
||||
rel_type = rel_type,
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class CmdCanonicalizeRemotes(Cmd): # export
|
|||
@override
|
||||
async def _run(self, args: Namespace) -> None:
|
||||
|
||||
async def git(cmd: list[str], ro = False, throw = True) -> Result:
|
||||
async def git(cmd: list[str], ro: bool = False, throw: bool = True) -> Result:
|
||||
cmd = ['/usr/bin/git', *cmd]
|
||||
log(NOTICE, f'-- {" ".join(cmd)}')
|
||||
if ro or not args.dry_run:
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from .Cmd import Cmd, Parent
|
|||
from typing import TYPE_CHECKING, override
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from argparse import ArgumentParser
|
||||
from argparse import ArgumentParser, Namespace
|
||||
|
||||
class CmdCheck(Cmd): # export
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ class CmdCheck(Cmd): # export
|
|||
self.load_subcommands()
|
||||
|
||||
@override
|
||||
async def _run(self, args):
|
||||
async def _run(self, args: Namespace) -> None:
|
||||
import sys
|
||||
|
||||
# Missing subcommand
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from .Cmd import Cmd, Parent
|
|||
from .lib.pkg_relations import VersionSyntax, pkg_relations
|
||||
from .lib.templates import ListDict, RenderValues, tmpl_render
|
||||
|
||||
def key_value(s):
|
||||
def key_value(s: str) -> tuple[str, str]:
|
||||
try:
|
||||
key, value = s.split('=', 1)
|
||||
except ValueError:
|
||||
|
|
@ -51,8 +51,8 @@ class CmdCreateFile(Cmd): # export
|
|||
self,
|
||||
template_name: str,
|
||||
values: list[RenderValues],
|
||||
li_quote = False,
|
||||
li_delimiter = '\n',
|
||||
li_quote: bool = False,
|
||||
li_delimiter: str = '\n',
|
||||
) -> str:
|
||||
return tmpl_render(
|
||||
template_name,
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ def pkg_relations(
|
|||
ignore: set[str] = set(),
|
||||
quote: bool = False,
|
||||
skip_excluded: bool = False,
|
||||
hide_self = False,
|
||||
hide_jw_pkg = False,
|
||||
hide_self: bool = False,
|
||||
hide_jw_pkg: bool = False,
|
||||
) -> list[str]:
|
||||
|
||||
if subsections is None:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import textwrap
|
||||
from typing import Iterable, TypeAlias, TypeGuard
|
||||
from typing import Any, Iterable, TypeAlias, TypeGuard
|
||||
|
||||
TupleList: TypeAlias = Iterable[tuple[str, str]]
|
||||
ListDict: TypeAlias = dict[str, list[str]]
|
||||
|
|
@ -73,7 +73,7 @@ def format_list_dict(
|
|||
template: str, values: ListDict | dict[str, str], li_quote: bool, li_delimiter: str
|
||||
) -> str:
|
||||
|
||||
def __format_value(val):
|
||||
def __format_value(val: Any) -> str:
|
||||
if not li_quote:
|
||||
return str(val)
|
||||
return f'"{val}"'
|
||||
|
|
@ -144,9 +144,9 @@ _templates = {
|
|||
def tmpl_render(
|
||||
template_name: str,
|
||||
values: list[RenderValues],
|
||||
li_quote = False,
|
||||
li_delimiter = '\n',
|
||||
search_path: list[str] = []
|
||||
li_quote: bool = False,
|
||||
li_delimiter: str = '\n',
|
||||
search_path: list[str] | None = None,
|
||||
) -> str:
|
||||
|
||||
def __format(template: str) -> str:
|
||||
|
|
@ -157,7 +157,7 @@ def tmpl_render(
|
|||
li_delimiter = li_delimiter,
|
||||
)
|
||||
|
||||
for d in search_path:
|
||||
for d in search_path if search_path else []:
|
||||
path = d + '/' + template_name
|
||||
try:
|
||||
with open(path, 'r') as f:
|
||||
|
|
|
|||
|
|
@ -23,7 +23,11 @@ class FilesContext:
|
|||
def ctx(self) -> FileContext:
|
||||
return self.__ctx
|
||||
|
||||
async def _read_key_value_file(self, path: str, throw = False) -> dict[str, str]:
|
||||
async def _read_key_value_file(
|
||||
self,
|
||||
path: str,
|
||||
throw: bool = False,
|
||||
) -> dict[str, str]:
|
||||
ret: dict[str, str] = {}
|
||||
try:
|
||||
result = await self.ctx.get(path)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import os
|
|||
import sys
|
||||
|
||||
from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser, Namespace
|
||||
from typing import override, TYPE_CHECKING, Any
|
||||
from typing import Any, cast, override, TYPE_CHECKING
|
||||
|
||||
from .AsyncRunner import AsyncRunner
|
||||
from .log import DEBUG, ERR, NOTICE, log, log_m, set_log_flags, set_log_level
|
||||
|
|
@ -52,12 +52,15 @@ class App: # export
|
|||
) -> None:
|
||||
|
||||
def add_cmd_to_parser(cmd: AbstractCmd, parsers: Any) -> ArgumentParser:
|
||||
parser = parsers.add_parser(
|
||||
cmd.name,
|
||||
help = cmd.help,
|
||||
description = cmd.description,
|
||||
aliases = cmd.aliases,
|
||||
formatter_class = ArgumentDefaultsHelpFormatter,
|
||||
parser = cast(
|
||||
'ArgumentParser',
|
||||
parsers.add_parser(
|
||||
cmd.name,
|
||||
help = cmd.help,
|
||||
description = cmd.description,
|
||||
aliases = cmd.aliases,
|
||||
formatter_class = ArgumentDefaultsHelpFormatter,
|
||||
)
|
||||
)
|
||||
parser.set_defaults(func = cmd.run)
|
||||
cmd.add_arguments(parser)
|
||||
|
|
@ -68,7 +71,7 @@ class App: # export
|
|||
parent: AbstractCmd | App,
|
||||
parser: ArgumentParser,
|
||||
cmds: Collection[AbstractCmd],
|
||||
all = False
|
||||
all: bool = False
|
||||
) -> None:
|
||||
if not cmds:
|
||||
return
|
||||
|
|
@ -168,7 +171,7 @@ class App: # export
|
|||
'-h', '--help', action = 'help', help = 'Show this help message and exit'
|
||||
)
|
||||
|
||||
def __del__(self):
|
||||
def __del__(self) -> None:
|
||||
if self.__own_eloop:
|
||||
if self.__eloop is not None:
|
||||
self.__eloop.close()
|
||||
|
|
@ -178,10 +181,10 @@ class App: # export
|
|||
async def __aenter__(self) -> None:
|
||||
pass
|
||||
|
||||
async def __aexit__(self, exc_type, exc, tb) -> None:
|
||||
async def __aexit__(self, exc_type: Any, exc: Any, tb: Any) -> None:
|
||||
pass
|
||||
|
||||
async def __run(self, argv = None) -> None:
|
||||
async def __run(self, argv: list[str] | None = None) -> None:
|
||||
|
||||
try:
|
||||
# Import argcomplete only here to not require it to be compatible
|
||||
|
|
@ -194,8 +197,8 @@ class App: # export
|
|||
|
||||
@override
|
||||
def __call__( # pyright: ignore[reportGeneralTypeIssues]
|
||||
self, *args, **kwargs
|
||||
):
|
||||
self, *args: Any, **kwargs: Any
|
||||
) -> None:
|
||||
return None
|
||||
|
||||
import argcomplete # type: ignore[import-not-found, unused-ignore]
|
||||
|
|
@ -249,7 +252,7 @@ class App: # export
|
|||
self.__parser.print_help()
|
||||
return None
|
||||
# Run sub-command. Overwrite if you want to do anything before or after
|
||||
return await self.args.func(args)
|
||||
return cast('None | int', await self.args.func(args))
|
||||
|
||||
def call_async(self, awaitable: Awaitable[T], timeout: float | None = None) -> T:
|
||||
return self.async_runner.call(awaitable, timeout)
|
||||
|
|
@ -286,7 +289,7 @@ class App: # export
|
|||
def parser(self) -> ArgumentParser:
|
||||
return self.__parser
|
||||
|
||||
def run(self, argv = None) -> None:
|
||||
def run(self, argv: list[str] | None = None) -> None:
|
||||
try:
|
||||
ret = self.eloop.run_until_complete(self.__run(argv))
|
||||
finally:
|
||||
|
|
@ -296,7 +299,10 @@ class App: # export
|
|||
return ret
|
||||
|
||||
def run_sub_commands( # export
|
||||
description = '', name_filter = '^Cmd.*', modules = None, argv = None
|
||||
):
|
||||
description: str = '',
|
||||
name_filter: str = '^Cmd.*',
|
||||
modules: list[str] | None = None,
|
||||
argv: list[str] | None = None,
|
||||
) -> None:
|
||||
app = App(description, name_filter, modules)
|
||||
return app.run(argv = argv)
|
||||
app.run(argv = argv)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import asyncio
|
|||
import concurrent.futures
|
||||
import contextlib
|
||||
|
||||
from typing import TypeVar, TYPE_CHECKING
|
||||
from typing import Any, TypeVar, TYPE_CHECKING, cast
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Awaitable, Generator
|
||||
|
|
@ -48,7 +48,7 @@ class AsyncRunner:
|
|||
awaitable, # type: ignore[arg-type, var-annotated]
|
||||
self._loop,
|
||||
)
|
||||
return fut.result(timeout)
|
||||
return cast('T', fut.result(timeout))
|
||||
|
||||
def close(self) -> None:
|
||||
self._cm.__exit__(None, None, None)
|
||||
|
|
@ -56,5 +56,5 @@ class AsyncRunner:
|
|||
def __enter__(self) -> AsyncRunner:
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc, tb) -> None:
|
||||
def __exit__(self, exc_type: Any, exc: Any, tb: Any) -> None:
|
||||
self.close()
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from .log import ERR
|
|||
from .Types import LoadTypes, Types
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from argparse import ArgumentParser
|
||||
from argparse import ArgumentParser, Namespace
|
||||
from typing import Iterable
|
||||
|
||||
from .App import App
|
||||
|
|
@ -26,7 +26,7 @@ class AbstractCmd(abc.ABC):
|
|||
self.__child_classes: list[type[Cmd]] = []
|
||||
self.__parser: ArgumentParser | None = None
|
||||
|
||||
def set_parent(self, parent: Any | Cmd):
|
||||
def set_parent(self, parent: Any | Cmd) -> None:
|
||||
self.__parent = parent
|
||||
|
||||
@property
|
||||
|
|
@ -76,7 +76,7 @@ class AbstractCmd(abc.ABC):
|
|||
return self.__parser
|
||||
|
||||
# Don't use a setter decorator to force using a grepable method
|
||||
def set_parser(self, parser: ArgumentParser):
|
||||
def set_parser(self, parser: ArgumentParser) -> None:
|
||||
self.__parser = parser
|
||||
|
||||
def print_help(self, exit_status: int | None = None) -> None:
|
||||
|
|
@ -129,11 +129,11 @@ class AbstractCmd(abc.ABC):
|
|||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
async def _run(self, args) -> None:
|
||||
async def _run(self, args: Namespace) -> None:
|
||||
if isinstance(self.__parent, Cmd): # Calling App.run() would loop
|
||||
return await self.__parent._run(args)
|
||||
|
||||
async def run(self, args):
|
||||
async def run(self, args: Namespace) -> None:
|
||||
return await self._run(args)
|
||||
|
||||
@abc.abstractmethod
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Self
|
||||
from typing import Any, Self
|
||||
|
||||
from .FileContext import FileContext
|
||||
from .Uri import Uri
|
||||
|
|
@ -9,7 +9,7 @@ class CopyContext:
|
|||
self,
|
||||
src: Uri | str | FileContext,
|
||||
dst: Uri | str | FileContext,
|
||||
chroot = False
|
||||
chroot: bool = False,
|
||||
) -> None:
|
||||
|
||||
def __uri(ctx: FileContext | Uri | str) -> Uri | str:
|
||||
|
|
@ -43,7 +43,7 @@ class CopyContext:
|
|||
await self.__dst.open()
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type, exc, tb):
|
||||
async def __aexit__(self, exc_type: Any, exc: Any, tb: Any) -> None:
|
||||
if self.__src is not None:
|
||||
await self.__src.close()
|
||||
self.__src = None
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import re
|
|||
import sys
|
||||
|
||||
from functools import cached_property
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from .log import ERR, INFO, WARNING, log
|
||||
from .base import InputMode
|
||||
|
|
@ -108,8 +108,8 @@ class Distro(abc.ABC):
|
|||
ec: ExecContext,
|
||||
id: str | None = None,
|
||||
os_release_str: str | None = None,
|
||||
**kwargs,
|
||||
):
|
||||
**kwargs: Any,
|
||||
) -> 'Distro':
|
||||
if id is None:
|
||||
os_release_str = await cls.read_os_release_str(ec)
|
||||
id = cls.parse_os_release_field_id(os_release_str)
|
||||
|
|
@ -142,8 +142,9 @@ class Distro(abc.ABC):
|
|||
|
||||
@cached_property
|
||||
def os_cascade(self) -> list[str]:
|
||||
ret: list[str] = []
|
||||
|
||||
def __append(entry: str):
|
||||
def __append(entry: str) -> None:
|
||||
if entry not in ret:
|
||||
ret.append(entry)
|
||||
|
||||
|
|
@ -322,10 +323,10 @@ class Distro(abc.ABC):
|
|||
def default_pkg_filter(self) -> PackageFilter | None:
|
||||
return self.__default_pkg_filter
|
||||
|
||||
async def run(self, *args, **kwargs) -> Result:
|
||||
async def run(self, *args: Any, **kwargs: Any) -> Result:
|
||||
return await self.__exec_context.run(*args, **kwargs)
|
||||
|
||||
async def sudo(self, *args, **kwargs) -> Result:
|
||||
async def sudo(self, *args: Any, **kwargs: Any) -> Result:
|
||||
return await self.__exec_context.sudo(*args, **kwargs)
|
||||
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import errno
|
|||
import sys
|
||||
|
||||
from decimal import ROUND_FLOOR, Decimal
|
||||
from typing import override, TYPE_CHECKING, NamedTuple
|
||||
from typing import Any, override, TYPE_CHECKING, NamedTuple
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Type
|
||||
|
|
@ -214,7 +214,7 @@ class ExecContext(Base):
|
|||
self.__pretty_cmd = pretty_cmd(self.__cmd, self.__wd)
|
||||
return self.__pretty_cmd
|
||||
|
||||
def log(self, prio: int, *args, **kwargs) -> None:
|
||||
def log(self, prio: int, *args: Any, **kwargs: Any) -> None:
|
||||
log(prio, self.__log_prefix, *args, **kwargs)
|
||||
|
||||
def log_delim(self, start: bool) -> None:
|
||||
|
|
@ -244,12 +244,12 @@ class ExecContext(Base):
|
|||
def __mode_str(cls, mode: int) -> str:
|
||||
return f'{mode:0o}'
|
||||
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@classmethod
|
||||
@override
|
||||
def create(cls, *args, **kwargs) -> ExecContext:
|
||||
def create(cls, *args: Any, **kwargs: Any) -> ExecContext:
|
||||
ret = super().create(*args, **kwargs)
|
||||
if not isinstance(ret, cls):
|
||||
raise TypeError(f'Expected {cls.__name__}, got {type(ret).__name__}')
|
||||
|
|
@ -505,7 +505,7 @@ class ExecContext(Base):
|
|||
async def __run(
|
||||
cmd: list[str],
|
||||
cmd_input: Input = InputMode.NonInteractive,
|
||||
**kwargs
|
||||
**kwargs: Any
|
||||
) -> Result:
|
||||
return await self.run(cmd, cmd_input = cmd_input, **kwargs)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import abc
|
|||
|
||||
from enum import Enum, auto
|
||||
from functools import cached_property
|
||||
from typing import override, TYPE_CHECKING
|
||||
from typing import Any, override, TYPE_CHECKING
|
||||
|
||||
from .log import DEBUG, ERR, log
|
||||
from .Uri import Uri
|
||||
|
|
@ -24,7 +24,7 @@ class FileContext(abc.ABC):
|
|||
self,
|
||||
uri: str | Uri,
|
||||
interactive: bool | None = None,
|
||||
verbose_default = False,
|
||||
verbose_default: bool = False,
|
||||
chroot: bool = False,
|
||||
in_pipe: ProcPipeline | None = None,
|
||||
out_pipe: ProcPipeline | None = None,
|
||||
|
|
@ -43,18 +43,18 @@ class FileContext(abc.ABC):
|
|||
f'= "{verbose_default}"'
|
||||
)
|
||||
|
||||
async def __aenter__(self):
|
||||
async def __aenter__(self) -> 'FileContext':
|
||||
await self.open()
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type, exc, tb):
|
||||
async def __aexit__(self, exc_type: Any, exc: Any, tb: Any) -> None:
|
||||
await self.close()
|
||||
|
||||
@override
|
||||
def __repr__(self) -> str:
|
||||
return self.__uri.id
|
||||
|
||||
def __pipe(self, d: Direction):
|
||||
def __pipe(self, d: Direction) -> 'ProcPipeline':
|
||||
match d:
|
||||
case self.Direction.In:
|
||||
if not self.__in_pipe:
|
||||
|
|
@ -76,7 +76,7 @@ class FileContext(abc.ABC):
|
|||
return self.root + path
|
||||
return self.root + '/' + path
|
||||
|
||||
def add_proc_filter(self, d: Direction, proc_filter: ProcFilter):
|
||||
def add_proc_filter(self, d: Direction, proc_filter: ProcFilter) -> None:
|
||||
self.__pipe(d).append(proc_filter)
|
||||
|
||||
async def _open(self) -> None:
|
||||
|
|
@ -298,11 +298,11 @@ class FileContext(abc.ABC):
|
|||
log(ERR, f'{self.log_name}: Failed to stat({path}) ({str(e)})')
|
||||
raise
|
||||
|
||||
async def is_dir(self, path: str, follow_symlinks = True) -> bool:
|
||||
async def is_dir(self, path: str, follow_symlinks: bool = True) -> bool:
|
||||
return await self._is_dir(self._chroot(path), follow_symlinks = follow_symlinks)
|
||||
|
||||
@classmethod
|
||||
def create(cls, uri: str | Uri, *args, **kwargs) -> FileContext:
|
||||
def create(cls, uri: str | Uri, *args: Any, **kwargs: Any) -> 'FileContext':
|
||||
uri = Uri.pimp(uri)
|
||||
match uri.protocol:
|
||||
case 'local' | 'file':
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import override, Any
|
||||
|
||||
meta_tags = [
|
||||
|
|
@ -16,7 +18,7 @@ class Package:
|
|||
maintainer: str | None = None
|
||||
|
||||
@classmethod
|
||||
def parse_spec_str(cls, spec: str, delimiter = '|'):
|
||||
def parse_spec_str(cls, spec: str, delimiter: str = '|') -> 'Package':
|
||||
tags = spec.split(delimiter)
|
||||
if len(tags) != 5:
|
||||
raise ValueError(f'Invalid package spec string "{spec}"')
|
||||
|
|
@ -29,14 +31,14 @@ class Package:
|
|||
)
|
||||
|
||||
@classmethod
|
||||
def parse_specs_str(cls, specs: str, delimiter = '|'):
|
||||
def parse_specs_str(cls, specs: str, delimiter: str = '|') -> list[Package]:
|
||||
ret: list[Package] = []
|
||||
for spec in specs.splitlines():
|
||||
ret.append(cls.parse_spec_str(spec))
|
||||
return ret
|
||||
|
||||
@classmethod
|
||||
def order_tags(cls, mapping: dict[str, Any]):
|
||||
def order_tags(cls, mapping: dict[str, Any]) -> dict[str, Any]:
|
||||
ret: dict[str, Any] = {}
|
||||
for tag in meta_tags:
|
||||
ret[tag] = mapping.get(tag, '')
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class Result:
|
|||
def __try_decode(
|
||||
self,
|
||||
stdxxx: bytes | None,
|
||||
quote = False,
|
||||
quote: bool = False,
|
||||
truncate: int | None = None,
|
||||
annotate: bool = True,
|
||||
label: str | None = None,
|
||||
|
|
@ -59,7 +59,7 @@ class Result:
|
|||
self,
|
||||
cmd: list[str] | None = None,
|
||||
wd: str | None = None,
|
||||
verbose = True
|
||||
verbose: bool = True,
|
||||
) -> str:
|
||||
|
||||
def __status_str(cmd: list[str] | None, wd: str | None, verbose: bool) -> str:
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@ from tarfile import TarFile, TarInfo
|
|||
from .CopyContext import CopyContext
|
||||
from .ExecContext import ExecContext
|
||||
from .log import DEBUG, ERR, log
|
||||
from typing import TYPE_CHECKING, override
|
||||
from typing import TYPE_CHECKING, Any, override
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .base import StatResult
|
||||
|
||||
class TarIo(CopyContext):
|
||||
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
kwargs['chroot'] = False
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ class TarIo(CopyContext):
|
|||
|
||||
async def _read_filtered(
|
||||
self,
|
||||
path,
|
||||
path: str,
|
||||
path_filter: list[str] | None = None,
|
||||
matched: list[str] | None = None,
|
||||
) -> bytes:
|
||||
|
|
@ -81,7 +81,7 @@ class TarIo(CopyContext):
|
|||
return ret
|
||||
|
||||
@classmethod
|
||||
def create(cls, *args, type: str | None = None, **kwargs):
|
||||
def create(cls, *args: Any, type: str | None = None, **kwargs: Any) -> 'TarIo':
|
||||
if type is not None:
|
||||
raise NotImplementedError
|
||||
# return TarIoTarFile(*args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import os
|
|||
import re
|
||||
import sys
|
||||
|
||||
from typing import override, TYPE_CHECKING, Generic, Iterable, TypeVar
|
||||
from typing import Any, override, TYPE_CHECKING, Generic, Iterable, TypeVar
|
||||
|
||||
from .log import ERR, OFF, log, parse_log_level
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ class Types(abc.ABC, Iterable[type[T]], Generic[T]): # export
|
|||
def _stringify(self) -> list[str]:
|
||||
pass
|
||||
|
||||
def dump(self, prio: int, *args, **kwargs) -> None:
|
||||
def dump(self, prio: int, *args: Any, **kwargs: Any) -> None:
|
||||
contents = self._stringify()
|
||||
log(prio, ',--- ', *args, **kwargs)
|
||||
for line in contents:
|
||||
|
|
@ -47,8 +47,8 @@ class LoadTypes(Types[T]): # export
|
|||
mod_names: Iterable[str],
|
||||
type_name_filter: str | None = None,
|
||||
type_filter: Sequence[type[Any]] | None = None,
|
||||
debug_level = None,
|
||||
):
|
||||
debug_level: int | None = None,
|
||||
) -> None:
|
||||
if debug_level is None:
|
||||
val = os.getenv('JW_LOG_LEVEL_LOAD_TYPES')
|
||||
if val is not None:
|
||||
|
|
@ -61,12 +61,12 @@ class LoadTypes(Types[T]): # export
|
|||
self.__mod_names = mod_names
|
||||
self.__classes: list[type[T]] | None = None
|
||||
|
||||
def _debug(self, *args, **kwargs) -> None:
|
||||
def _debug(self, *args: Any, **kwargs: Any) -> None:
|
||||
if self.__debug_level != OFF:
|
||||
log(self.__debug_level, *args, **kwargs)
|
||||
|
||||
@override
|
||||
def _stringify(self):
|
||||
def _stringify(self) -> list[str]:
|
||||
tf = 'None' if self.__type_filter is None else (
|
||||
', '.join([str(f) for f in self.__type_filter])
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import override, TYPE_CHECKING
|
||||
from typing import Any, override, TYPE_CHECKING
|
||||
|
||||
from ...Distro import Distro as Base
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ class Distro(Base):
|
|||
return await self.sudo(cmd, verbose = verbose)
|
||||
return await self.run(cmd, verbose = verbose)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from __future__ import annotations
|
|||
|
||||
import os
|
||||
|
||||
from typing import override, TYPE_CHECKING
|
||||
from typing import Any, override, TYPE_CHECKING
|
||||
|
||||
from ...Distro import Distro as Base
|
||||
from ...log import NOTICE, log
|
||||
|
|
@ -31,11 +31,11 @@ class Distro(Base):
|
|||
if sudo else await self.run(cmd, verbose = verbose)
|
||||
)
|
||||
|
||||
async def dpkg(self, *args, **kwargs) -> str:
|
||||
async def dpkg(self, *args: Any, **kwargs: Any) -> str:
|
||||
kwargs.setdefault('ec', self.ctx)
|
||||
return await run_dpkg(*args, **kwargs)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import override, TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any, override
|
||||
|
||||
from ...Distro import Distro as Base
|
||||
from ...pm.rpm import list_files, query_packages, run_rpm
|
||||
|
|
@ -35,13 +35,18 @@ class Distro(Base):
|
|||
if sudo else await self.run(cmd, verbose = verbose)
|
||||
)
|
||||
|
||||
async def rpm(self, *args, ec: ExecContext | None = None, **kwargs) -> str:
|
||||
async def rpm(
|
||||
self,
|
||||
*args: Any,
|
||||
ec: ExecContext | None = None,
|
||||
**kwargs: Any,
|
||||
) -> str:
|
||||
if ec is None:
|
||||
ec = self.ctx
|
||||
kwargs['ec'] = ec
|
||||
return await run_rpm(*args, **kwargs)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import override, TYPE_CHECKING
|
||||
from typing import Any, override, TYPE_CHECKING
|
||||
|
||||
from ..FileContext import FileContext as Base
|
||||
|
||||
|
|
@ -13,7 +13,11 @@ if TYPE_CHECKING:
|
|||
class Curl(Base):
|
||||
|
||||
def __init__(
|
||||
self, uri: str | Uri, *args, ec: ExecContext | None = None, **kwargs
|
||||
self,
|
||||
uri: str | Uri,
|
||||
*args: Any,
|
||||
ec: ExecContext | None = None,
|
||||
**kwargs: Any
|
||||
) -> None:
|
||||
|
||||
def __local() -> Local:
|
||||
|
|
|
|||
|
|
@ -7,20 +7,20 @@ import pwd
|
|||
import sys
|
||||
|
||||
from functools import cache
|
||||
from typing import override, TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, override
|
||||
|
||||
from ..base import Result, StatResult
|
||||
from ..ExecContext import ExecContext as Base
|
||||
from ..log import ERR, NOTICE, log
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any
|
||||
from typing import Any, Callable
|
||||
|
||||
from ..Uri import Uri
|
||||
|
||||
class Local(Base):
|
||||
|
||||
def __init__(self, uri: str | Uri = 'local', *args, **kwargs) -> None:
|
||||
def __init__(self, uri: str | Uri = 'local', *args: Any, **kwargs: Any) -> None:
|
||||
super().__init__(uri, *args, **kwargs)
|
||||
|
||||
@cache
|
||||
|
|
@ -43,9 +43,12 @@ class Local(Base):
|
|||
if verbose:
|
||||
log(prio, log_prefix, *args)
|
||||
|
||||
def __make_pty_reader(collector: list[bytes], enc_for_verbose: str):
|
||||
def __make_pty_reader(
|
||||
collector: list[bytes],
|
||||
enc_for_verbose: str,
|
||||
) -> Callable[[int], bytes]:
|
||||
|
||||
def _read(fd):
|
||||
def _read(fd: int) -> bytes:
|
||||
ret = os.read(fd, 1024)
|
||||
if not ret:
|
||||
return ret
|
||||
|
|
@ -65,7 +68,7 @@ class Local(Base):
|
|||
if interactive:
|
||||
import pty
|
||||
|
||||
def _spawn():
|
||||
def _spawn() -> int:
|
||||
# Apply env in PTY mode by temporarily updating os.environ
|
||||
# around spawn.
|
||||
if mod_env:
|
||||
|
|
@ -115,7 +118,9 @@ class Local(Base):
|
|||
stdout_log_enc = sys.stdout.encoding or 'utf-8'
|
||||
stderr_log_enc = sys.stderr.encoding or 'utf-8'
|
||||
|
||||
async def read_stream(stream, prio, collector: list[bytes], log_enc: str):
|
||||
async def read_stream(
|
||||
stream: Any, prio: int, collector: list[bytes], log_enc: str
|
||||
) -> None:
|
||||
buf = b''
|
||||
while True:
|
||||
chunk = await stream.read(4096)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import os
|
|||
import pwd
|
||||
|
||||
from enum import Flag, auto
|
||||
from typing import TYPE_CHECKING, override
|
||||
from typing import TYPE_CHECKING, Any, cast, override
|
||||
|
||||
from ..ExecContext import ExecContext
|
||||
from ..log import DEBUG, ERR, INFO, NOTICE, get_caller_pos, log, log_m
|
||||
|
|
@ -22,7 +22,9 @@ class SSHClient(ExecContext):
|
|||
ModEnv = auto()
|
||||
Wd = auto()
|
||||
|
||||
def __init__(self, uri: Uri | str, caps: Caps = Caps(0), *args, **kwargs) -> None:
|
||||
def __init__(
|
||||
self, uri: Uri | str, caps: Caps = Caps(0), *args: Any, **kwargs: Any
|
||||
) -> None:
|
||||
uri = Uri.pimp(uri)
|
||||
if uri.username is None:
|
||||
uri.set_username(pwd.getpwuid(os.getuid()).pw_name)
|
||||
|
|
@ -54,13 +56,13 @@ class SSHClient(ExecContext):
|
|||
log_prefix: str,
|
||||
) -> Result:
|
||||
|
||||
def __log(prio: int, *args, **kwargs):
|
||||
def __log(prio: int, *args: Any, **kwargs: Any) -> None:
|
||||
caller = kwargs.get('caller')
|
||||
if caller is None:
|
||||
kwargs['caller'] = get_caller_pos(1)
|
||||
log(prio, log_prefix, *args, **kwargs)
|
||||
|
||||
def __log_block(prio: int, title: str, block: str | None):
|
||||
def __log_block(prio: int, title: str, block: str | None) -> None:
|
||||
if self.__caps & self.Caps.LogOutput:
|
||||
return
|
||||
if block is None:
|
||||
|
|
@ -112,8 +114,10 @@ class SSHClient(ExecContext):
|
|||
return self.uri.password
|
||||
|
||||
def ssh_client( # export
|
||||
*args, type: str | list[str] | None = None, **kwargs
|
||||
) -> SSHClient:
|
||||
*args: Any,
|
||||
type: str | list[str] | None = None,
|
||||
**kwargs: Any
|
||||
) -> 'SSHClient':
|
||||
from importlib import import_module
|
||||
|
||||
errors: list[str] = []
|
||||
|
|
@ -130,7 +134,7 @@ def ssh_client( # export
|
|||
ret = getattr(import_module(f'jw.pkg.lib.ec.ssh.{name}'),
|
||||
name)(*args, **kwargs)
|
||||
log(INFO, f'Using SSH-client "{name}"')
|
||||
return ret
|
||||
return cast('SSHClient', ret)
|
||||
except Exception as e:
|
||||
msg = f"Can't instantiate SSH client class {name} ({str(e)})"
|
||||
errors.append(msg)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
from typing import Any, override
|
||||
import asyncio
|
||||
import os
|
||||
import shlex
|
||||
|
|
@ -6,8 +5,12 @@ import shutil
|
|||
import signal
|
||||
import sys
|
||||
|
||||
from typing import Any, override
|
||||
|
||||
import asyncssh # type: ignore[import-not-found, unused-ignore]
|
||||
|
||||
from asyncssh import SSHReader # type: ignore[import-not-found, unused-ignore]
|
||||
|
||||
from ...base import Result
|
||||
from ...log import DEBUG, ERR, NOTICE, log
|
||||
from ..SSHClient import SSHClient as Base
|
||||
|
|
@ -22,10 +25,10 @@ class AsyncSSH(Base):
|
|||
uri: str,
|
||||
*,
|
||||
client_keys: list[str] | None = None,
|
||||
known_hosts = _USE_DEFAULT_KNOWN_HOSTS,
|
||||
known_hosts: Any = _USE_DEFAULT_KNOWN_HOSTS,
|
||||
term_type: str | None = None,
|
||||
connect_timeout: float | None = 30.0,
|
||||
**kwargs,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
|
||||
super().__init__(
|
||||
|
|
@ -121,8 +124,8 @@ class AsyncSSH(Base):
|
|||
|
||||
async def _read_stream(
|
||||
self,
|
||||
stream,
|
||||
prio,
|
||||
stream: SSHReader[bytes],
|
||||
prio: int,
|
||||
collector: list[bytes],
|
||||
*,
|
||||
verbose: bool,
|
||||
|
|
@ -222,7 +225,7 @@ class AsyncSSH(Base):
|
|||
stdout_parts.append(chunk)
|
||||
_write_local(chunk)
|
||||
|
||||
def _on_winch(*_args) -> None:
|
||||
def _on_winch(*_args: Any) -> None:
|
||||
|
||||
try:
|
||||
proc.change_terminal_size(*self._get_local_term_size())
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from __future__ import annotations
|
|||
|
||||
import os
|
||||
|
||||
from typing import override, TYPE_CHECKING
|
||||
from typing import Any, override, TYPE_CHECKING
|
||||
|
||||
from ...base import InputMode
|
||||
from ...util import run_cmd
|
||||
|
|
@ -14,12 +14,12 @@ if TYPE_CHECKING:
|
|||
|
||||
class Exec(Base):
|
||||
|
||||
def __init__(self, uri, *args, **kwargs) -> None:
|
||||
def __init__(self, uri: Any, *args: Any, **kwargs: Any) -> None:
|
||||
self.__askpass: str | None = None
|
||||
self.__askpass_orig: dict[str, str | None] = dict()
|
||||
super().__init__(uri = uri, caps = self.Caps.ModEnv, **kwargs)
|
||||
|
||||
def __del__(self):
|
||||
def __del__(self) -> None:
|
||||
for key, val in self.__askpass_orig.items():
|
||||
if val is None:
|
||||
del os.environ[key]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import override, TYPE_CHECKING
|
||||
from typing import Any, override, TYPE_CHECKING
|
||||
|
||||
# Tolerate missing paramiko imports. jw-pkg is designed to work with what it
|
||||
# finds.
|
||||
|
|
@ -18,7 +18,7 @@ if TYPE_CHECKING:
|
|||
|
||||
class Paramiko(Base):
|
||||
|
||||
def __init__(self, uri, *args, **kwargs) -> None:
|
||||
def __init__(self, uri: Any, *args: Any, **kwargs: Any) -> None:
|
||||
kwargs['caps'] = (self.Caps.ModEnv, )
|
||||
super().__init__(uri, *args, **kwargs)
|
||||
self.__timeout: float | None = None # Untested
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import syslog
|
|||
|
||||
from datetime import datetime
|
||||
from os.path import basename
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, cast
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import io
|
||||
|
|
@ -126,7 +126,7 @@ _prio_colors = {
|
|||
|
||||
class Stream:
|
||||
|
||||
def __init__(self, stream, flags):
|
||||
def __init__(self, stream: Any, flags: int):
|
||||
self.stream = stream
|
||||
self.flags = flags
|
||||
|
||||
|
|
@ -142,12 +142,12 @@ def pad(token: str, total_size: int, right_align: bool = False) -> str:
|
|||
return space + token
|
||||
return token + space
|
||||
|
||||
def add_capture_stream(stream, flags = 0x0):
|
||||
def add_capture_stream(stream: Any, flags: int = 0x0) -> int:
|
||||
ret = _stream_descriptors.pop()
|
||||
_streams[ret] = Stream(stream = stream, flags = flags)
|
||||
return ret
|
||||
|
||||
def rm_capture_stream(sd):
|
||||
def rm_capture_stream(sd: int) -> None:
|
||||
del _streams[sd]
|
||||
_stream_descriptors.append(sd)
|
||||
|
||||
|
|
@ -166,13 +166,13 @@ def get_caller_pos(up: int = 1,
|
|||
if kwargs and 'caller' in kwargs:
|
||||
r = kwargs['caller']
|
||||
del kwargs['caller']
|
||||
return r
|
||||
return cast('Tuple[str, str, int]', r)
|
||||
caller = inspect.stack()[up + 1]
|
||||
mod = inspect.getmodule(caller[0])
|
||||
mod_name = '' if mod is None else mod.__name__
|
||||
return (mod_name, basename(caller.filename), caller.lineno)
|
||||
|
||||
def log_m(prio: int, *args, **kwargs) -> None: # export
|
||||
def log_m(prio: int, *args: Any, **kwargs: Any) -> None: # export
|
||||
if prio > _level:
|
||||
return
|
||||
margs = ''
|
||||
|
|
@ -190,7 +190,12 @@ def log_m(prio: int, *args, **kwargs) -> None: # export
|
|||
for line in margs[1:].split('\n'):
|
||||
log(prio, line, **kwargs, caller = caller)
|
||||
|
||||
def log(prio: int, *args, only_printable: bool = False, **kwargs) -> None: # export
|
||||
def log( # export
|
||||
prio: int,
|
||||
*args: Any,
|
||||
only_printable: bool = False,
|
||||
**kwargs: Any
|
||||
) -> None:
|
||||
|
||||
if prio > _level:
|
||||
return
|
||||
|
|
@ -259,7 +264,12 @@ def log(prio: int, *args, only_printable: bool = False, **kwargs) -> None: # ex
|
|||
for file in files:
|
||||
print(msg, file = file)
|
||||
|
||||
def throw(*args, prio = ERR, caller = None, **kwargs) -> None:
|
||||
def throw(
|
||||
*args: Any,
|
||||
prio: int = ERR,
|
||||
caller: Tuple[str, str, int] | None = None,
|
||||
**kwargs: Any
|
||||
) -> None:
|
||||
if caller is None:
|
||||
caller = get_caller_pos(1)
|
||||
msg = ' '.join([str(arg) for arg in args])
|
||||
|
|
@ -331,7 +341,7 @@ def append_to_prefix(prefix: str) -> str: # export
|
|||
_clean_log_prefix = _clean_str_regex.sub('', _log_prefix)
|
||||
return r
|
||||
|
||||
def remove_from_prefix(count) -> str: # export
|
||||
def remove_from_prefix(count: int | str) -> str: # export
|
||||
if isinstance(count, str):
|
||||
count = len(count)
|
||||
global _log_prefix
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Iterable
|
||||
from typing import TYPE_CHECKING, Iterable, cast
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..ExecContext import ExecContext
|
||||
|
|
@ -59,7 +59,7 @@ async def query_packages(names: Iterable[str] = [],
|
|||
)
|
||||
# dpkg-query -W -f='${binary:Package}|${Maintainer}| ... \n'
|
||||
specs = await run_dpkg_query(['-W', '-f=' + fmt_str, *names], sudo = False, ec = ec)
|
||||
return Package.parse_specs_str(specs)
|
||||
return cast('Iterable[Package]', Package.parse_specs_str(specs))
|
||||
|
||||
async def list_files(pkg: str, ec: ExecContext | None = None) -> list[str]:
|
||||
file_list_str = await run_dpkg(['-L', pkg], sudo = False, ec = ec)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Collection, Iterable
|
||||
from typing import Any, TYPE_CHECKING, Collection, Iterable, cast
|
||||
|
||||
from ..base import InputMode
|
||||
from ..Package import Package
|
||||
|
|
@ -30,7 +30,7 @@ async def run_rpm( # export
|
|||
sudo: bool = False,
|
||||
ec: ExecContext | None = None,
|
||||
mode: InputMode = InputMode.OptInteractive,
|
||||
**kwargs,
|
||||
**kwargs: Any,
|
||||
) -> str:
|
||||
cmd = ['/usr/bin/rpm']
|
||||
cmd.extend(args)
|
||||
|
|
@ -58,7 +58,7 @@ async def query_packages( # export
|
|||
mode = InputMode.NonInteractive,
|
||||
ec = ec
|
||||
)
|
||||
return Package.parse_specs_str(specs)
|
||||
return cast('Iterable[Package]', Package.parse_specs_str(specs))
|
||||
|
||||
async def list_files(pkg: str, ec: ExecContext | None = None) -> list[str]:
|
||||
stdout = await run_rpm(
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import os
|
|||
import sys
|
||||
|
||||
from enum import Enum, auto
|
||||
from typing import TYPE_CHECKING, Iterable, TypeVar
|
||||
from typing import TYPE_CHECKING, Any, Iterable, TypeVar, cast
|
||||
|
||||
from .base import Input, InputMode, Result
|
||||
from .log import DEBUG, ERR, log
|
||||
|
|
@ -23,7 +23,7 @@ class AskpassKey(Enum):
|
|||
Username = auto()
|
||||
Password = auto()
|
||||
|
||||
def pretty_cmd(cmd: list[str] | None = None, wd = None):
|
||||
def pretty_cmd(cmd: list[str] | None = None, wd: str | None = None) -> str:
|
||||
if cmd is None:
|
||||
cmd = sys.argv
|
||||
tokens = [cmd[0]]
|
||||
|
|
@ -38,11 +38,11 @@ def pretty_cmd(cmd: list[str] | None = None, wd = None):
|
|||
|
||||
# See ExecContext.run() for what this function does
|
||||
async def run_cmd(
|
||||
*args,
|
||||
*args: Any,
|
||||
ec: ExecContext | None = None,
|
||||
verbose: bool | None = None,
|
||||
cmd_input: Input = InputMode.NonInteractive,
|
||||
**kwargs,
|
||||
**kwargs: Any,
|
||||
) -> Result:
|
||||
if verbose is None:
|
||||
verbose = False if ec is None else ec.verbose_default
|
||||
|
|
@ -56,12 +56,12 @@ async def run_cmd(
|
|||
|
||||
async def run_curl(
|
||||
args: list[str],
|
||||
wd = None,
|
||||
throw = None,
|
||||
verbose = None,
|
||||
cmd_input = InputMode.NonInteractive,
|
||||
wd: str | None = None,
|
||||
throw: bool | None = None,
|
||||
verbose: bool | None = None,
|
||||
cmd_input: Input = InputMode.NonInteractive,
|
||||
ec: ExecContext | None = None,
|
||||
decode = False,
|
||||
decode: bool = False,
|
||||
) -> Result:
|
||||
if verbose is None:
|
||||
verbose = False if ec is None else ec.verbose_default
|
||||
|
|
@ -76,7 +76,7 @@ async def run_curl(
|
|||
async def run_curl_into(
|
||||
expected_type: type[T],
|
||||
args: list[str],
|
||||
**kwargs,
|
||||
**kwargs: Any,
|
||||
) -> T:
|
||||
result = await run_curl(args, **kwargs)
|
||||
stdout = result.stdout_str
|
||||
|
|
@ -139,11 +139,11 @@ async def run_askpass(
|
|||
|
||||
async def run_sudo(
|
||||
cmd: list[str],
|
||||
*args,
|
||||
*args: Any,
|
||||
interactive: bool = True,
|
||||
ec: ExecContext | None = None,
|
||||
**kwargs,
|
||||
):
|
||||
**kwargs: Any,
|
||||
) -> Result:
|
||||
if ec is None:
|
||||
from .ec.Local import Local
|
||||
|
||||
|
|
@ -152,10 +152,10 @@ async def run_sudo(
|
|||
|
||||
async def get(
|
||||
uri: str | Uri,
|
||||
*args,
|
||||
*args: Any,
|
||||
ctx: FileContext | None = None,
|
||||
content_filter: ProcFilter | list[ProcFilter] | ProcPipeline | None = None,
|
||||
**kwargs,
|
||||
**kwargs: Any,
|
||||
) -> Result:
|
||||
uri = Uri.pimp(uri)
|
||||
if ctx is None or uri.id != ctx.uri.id:
|
||||
|
|
@ -172,7 +172,7 @@ async def copy(
|
|||
owner: str | None = None,
|
||||
group: str | None = None,
|
||||
mode: int | None = None,
|
||||
throw = True,
|
||||
throw: bool = True,
|
||||
) -> Exception | str | list[str]:
|
||||
if not isinstance(src_uri, str):
|
||||
ret: list[str] = []
|
||||
|
|
@ -225,7 +225,7 @@ async def get_username( # export
|
|||
f'Username mismatch: called with --username="{args.username}", '
|
||||
f'URL has user name "{url_user}"'
|
||||
)
|
||||
return args.username
|
||||
return str(args.username)
|
||||
if url_user is not None:
|
||||
return url_user
|
||||
return await run_askpass(askpass_env, AskpassKey.Username, ec = ec)
|
||||
|
|
@ -244,7 +244,7 @@ async def get_password( # export
|
|||
if args is not None and hasattr(args, 'password'):
|
||||
# use getattr(), because we don't necessarily want to have insecure
|
||||
# --password among options
|
||||
ret = getattr(args, 'password')
|
||||
ret = cast('str | None', getattr(args, 'password'))
|
||||
if ret is not None:
|
||||
return ret
|
||||
if url is not None:
|
||||
|
|
|
|||
Loading…
Reference in a new issue