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 enum import Enum, auto
|
||||||
from functools import cache
|
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.App import App as Base
|
||||||
from .lib.Distro import Distro
|
from .lib.Distro import Distro
|
||||||
|
|
@ -40,7 +40,7 @@ class ResultCache(object):
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.__cache: dict[str, Any] = {}
|
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
|
d = self.__cache
|
||||||
depth = 0
|
depth = 0
|
||||||
keys = [func.__name__] + args
|
keys = [func.__name__] + args
|
||||||
|
|
@ -137,21 +137,21 @@ class App(Base):
|
||||||
if search_absdirs is None:
|
if search_absdirs is None:
|
||||||
search_absdirs = []
|
search_absdirs = []
|
||||||
|
|
||||||
def __format_relpath(path: str):
|
def __format_relpath(path: str) -> str:
|
||||||
if path.startswith('./'):
|
if path.startswith('./'):
|
||||||
return path[2:]
|
return path[2:]
|
||||||
if path.endswith('/.'):
|
if path.endswith('/.'):
|
||||||
return path[:-2]
|
return path[:-2]
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def __relpath(target: str, base: str):
|
def __relpath(target: str, base: str) -> str:
|
||||||
return __format_relpath(os.path.relpath(target, base))
|
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:
|
if not pretty:
|
||||||
return pd
|
return pd
|
||||||
if self.__topdir_fmt == 'absolute':
|
if self.__topdir_fmt == 'absolute':
|
||||||
return os.path.abspath(pd)
|
return str(os.path.abspath(pd))
|
||||||
if self.__topdir_fmt == 'unaltered':
|
if self.__topdir_fmt == 'unaltered':
|
||||||
return pd
|
return pd
|
||||||
if self.__topdir_fmt == 'relative':
|
if self.__topdir_fmt == 'relative':
|
||||||
|
|
@ -175,6 +175,7 @@ class App(Base):
|
||||||
path = pd + '/' + sd
|
path = pd + '/' + sd
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path):
|
||||||
ret = __format_pd(name, pd, pretty)
|
ret = __format_pd(name, pd, pretty)
|
||||||
|
assert ret is not None
|
||||||
if sd and sd[0] != '/':
|
if sd and sd[0] != '/':
|
||||||
if ret == '.':
|
if ret == '.':
|
||||||
ret = ''
|
ret = ''
|
||||||
|
|
@ -210,10 +211,13 @@ class App(Base):
|
||||||
add_self: bool,
|
add_self: bool,
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
names_only: bool,
|
names_only: bool,
|
||||||
):
|
) -> list[str]:
|
||||||
return self.__res_cache.run(
|
return cast(
|
||||||
self.__get_project_refs,
|
'list[str]',
|
||||||
[buf, visited, spec, section, key, add_self, scope, names_only],
|
self.__res_cache.run(
|
||||||
|
self.__get_project_refs,
|
||||||
|
[buf, visited, spec, section, key, add_self, scope, names_only],
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
def __get_project_refs(
|
def __get_project_refs(
|
||||||
|
|
@ -292,7 +296,7 @@ class App(Base):
|
||||||
for dep in deps:
|
for dep in deps:
|
||||||
self.__read_dep_graph([dep], sections, graph)
|
self.__read_dep_graph([dep], sections, graph)
|
||||||
|
|
||||||
def __flip_dep_graph(self, graph: Graph):
|
def __flip_dep_graph(self, graph: Graph) -> Graph:
|
||||||
ret: Graph = {}
|
ret: Graph = {}
|
||||||
for project, deps in graph.items():
|
for project, deps in graph.items():
|
||||||
for d in deps:
|
for d in deps:
|
||||||
|
|
@ -384,7 +388,7 @@ class App(Base):
|
||||||
)
|
)
|
||||||
|
|
||||||
@override
|
@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:
|
if self.__exec_context is not None:
|
||||||
await self.__exec_context.close()
|
await self.__exec_context.close()
|
||||||
self.__exec_context = None
|
self.__exec_context = None
|
||||||
|
|
@ -494,7 +498,7 @@ class App(Base):
|
||||||
return self.__exec_context
|
return self.__exec_context
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def top_name(self):
|
def top_name(self) -> str | None:
|
||||||
return self.__top_name
|
return self.__top_name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
@ -581,7 +585,7 @@ class App(Base):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@cache
|
@cache
|
||||||
def get_version(self, project) -> str:
|
def get_version(self, project: str) -> str:
|
||||||
ret = self.get_value(project, 'version', '')
|
ret = self.get_value(project, 'version', '')
|
||||||
if ret is None:
|
if ret is None:
|
||||||
raise Exception(f"Can't get version of project {project}")
|
raise Exception(f"Can't get version of project {project}")
|
||||||
|
|
@ -610,9 +614,9 @@ class App(Base):
|
||||||
projects: list[str],
|
projects: list[str],
|
||||||
sections: list[str],
|
sections: list[str],
|
||||||
keys: str | list[str],
|
keys: str | list[str],
|
||||||
add_self: bool,
|
scope: Scope = Scope.One,
|
||||||
scope: Scope,
|
add_self: bool = False,
|
||||||
names_only = True,
|
names_only: bool = False,
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
if isinstance(keys, str):
|
if isinstance(keys, str):
|
||||||
keys = [keys]
|
keys = [keys]
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ from ..App import App as Parent
|
||||||
from ..CmdBase import CmdBase as Base
|
from ..CmdBase import CmdBase as Base
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from argparse import Namespace
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
from ..lib.Distro import Distro
|
from ..lib.Distro import Distro
|
||||||
|
|
||||||
|
|
@ -21,7 +22,7 @@ class Cmd(Base): # export
|
||||||
super().__init__(parent, name, help, aliases = aliases)
|
super().__init__(parent, name, help, aliases = aliases)
|
||||||
|
|
||||||
@override
|
@override
|
||||||
async def _run(self, args):
|
async def _run(self, args: 'Namespace') -> None:
|
||||||
# Missing subcommand
|
# Missing subcommand
|
||||||
self.print_help(1)
|
self.print_help(1)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, override
|
||||||
from .Cmd import Cmd, Parent
|
from .Cmd import Cmd, Parent
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser, Namespace
|
||||||
|
|
||||||
class CmdPkg(Cmd): # export
|
class CmdPkg(Cmd): # export
|
||||||
|
|
||||||
|
|
@ -19,7 +19,7 @@ class CmdPkg(Cmd): # export
|
||||||
self.load_subcommands()
|
self.load_subcommands()
|
||||||
|
|
||||||
@override
|
@override
|
||||||
async def _run(self, args):
|
async def _run(self, args: Namespace) -> None:
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Missing subcommand
|
# Missing subcommand
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, override
|
||||||
from .Cmd import Cmd, Parent
|
from .Cmd import Cmd, Parent
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser, Namespace
|
||||||
|
|
||||||
class CmdPlatform(Cmd): # export
|
class CmdPlatform(Cmd): # export
|
||||||
|
|
||||||
|
|
@ -16,7 +16,7 @@ class CmdPlatform(Cmd): # export
|
||||||
self.load_subcommands()
|
self.load_subcommands()
|
||||||
|
|
||||||
@override
|
@override
|
||||||
async def _run(self, args):
|
async def _run(self, args: Namespace) -> None:
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Missing subcommand
|
# Missing subcommand
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, override
|
||||||
from .Cmd import Cmd, Parent
|
from .Cmd import Cmd, Parent
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser, Namespace
|
||||||
|
|
||||||
class CmdPosix(Cmd): # export
|
class CmdPosix(Cmd): # export
|
||||||
|
|
||||||
|
|
@ -21,7 +21,7 @@ class CmdPosix(Cmd): # export
|
||||||
self.load_subcommands()
|
self.load_subcommands()
|
||||||
|
|
||||||
@override
|
@override
|
||||||
async def _run(self, args):
|
async def _run(self, args: Namespace) -> None:
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Missing subcommand
|
# Missing subcommand
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, override
|
||||||
from .Cmd import Cmd, Parent
|
from .Cmd import Cmd, Parent
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser, Namespace
|
||||||
|
|
||||||
class CmdProjects(Cmd): # export
|
class CmdProjects(Cmd): # export
|
||||||
|
|
||||||
|
|
@ -18,7 +18,7 @@ class CmdProjects(Cmd): # export
|
||||||
self.load_subcommands()
|
self.load_subcommands()
|
||||||
|
|
||||||
@override
|
@override
|
||||||
async def _run(self, args):
|
async def _run(self, args: Namespace) -> None:
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Missing subcommand
|
# Missing subcommand
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, override
|
||||||
from .Cmd import Cmd, Parent
|
from .Cmd import Cmd, Parent
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser, Namespace
|
||||||
|
|
||||||
class CmdSecrets(Cmd): # export
|
class CmdSecrets(Cmd): # export
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@ class CmdSecrets(Cmd): # export
|
||||||
self.load_subcommands()
|
self.load_subcommands()
|
||||||
|
|
||||||
@override
|
@override
|
||||||
async def _run(self, args):
|
async def _run(self, args: Namespace) -> None:
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Missing subcommand
|
# Missing subcommand
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, override
|
||||||
from .Cmd import Cmd, Parent
|
from .Cmd import Cmd, Parent
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser, Namespace
|
||||||
|
|
||||||
class CmdTar(Cmd): # export
|
class CmdTar(Cmd): # export
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@ class CmdTar(Cmd): # export
|
||||||
self.load_subcommands()
|
self.load_subcommands()
|
||||||
|
|
||||||
@override
|
@override
|
||||||
async def _run(self, args):
|
async def _run(self, args: Namespace) -> None:
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Missing subcommand
|
# Missing subcommand
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from typing import override, TYPE_CHECKING
|
from typing import Any, override, TYPE_CHECKING
|
||||||
|
|
||||||
from ....CmdBase import CmdBase as Base
|
from ....CmdBase import CmdBase as Base
|
||||||
from ....lib.FileContext import FileContext
|
from ....lib.FileContext import FileContext
|
||||||
|
|
@ -20,7 +20,7 @@ class Cmd(Base): # export
|
||||||
self.__tar_io: None = None
|
self.__tar_io: None = None
|
||||||
|
|
||||||
@asynccontextmanager
|
@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:
|
async with TarIo.create(src = self.app.args.archive_path, **kwargs) as ret:
|
||||||
ret.src.add_proc_filter(
|
ret.src.add_proc_filter(
|
||||||
FileContext.Direction.In, ProcFilterGpg(ec = self.app.exec_context)
|
FileContext.Direction.In, ProcFilterGpg(ec = self.app.exec_context)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, override
|
from typing import TYPE_CHECKING, cast, override
|
||||||
|
|
||||||
from .Cmd import Cmd, Parent
|
from .Cmd import Cmd, Parent
|
||||||
from .lib.pkg_relations import VersionSyntax
|
from .lib.pkg_relations import VersionSyntax
|
||||||
|
|
@ -17,7 +17,7 @@ class BaseCmdPkgRelations(Cmd):
|
||||||
|
|
||||||
def pkg_relations(self, rel_type: str, args: Namespace) -> str:
|
def pkg_relations(self, rel_type: str, args: Namespace) -> str:
|
||||||
|
|
||||||
return args.delimiter.join(
|
return cast('str', args.delimiter).join(
|
||||||
pkg_relations_list(
|
pkg_relations_list(
|
||||||
self.app,
|
self.app,
|
||||||
rel_type = rel_type,
|
rel_type = rel_type,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ class CmdCanonicalizeRemotes(Cmd): # export
|
||||||
@override
|
@override
|
||||||
async def _run(self, args: Namespace) -> None:
|
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]
|
cmd = ['/usr/bin/git', *cmd]
|
||||||
log(NOTICE, f'-- {" ".join(cmd)}')
|
log(NOTICE, f'-- {" ".join(cmd)}')
|
||||||
if ro or not args.dry_run:
|
if ro or not args.dry_run:
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ from .Cmd import Cmd, Parent
|
||||||
from typing import TYPE_CHECKING, override
|
from typing import TYPE_CHECKING, override
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser, Namespace
|
||||||
|
|
||||||
class CmdCheck(Cmd): # export
|
class CmdCheck(Cmd): # export
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@ class CmdCheck(Cmd): # export
|
||||||
self.load_subcommands()
|
self.load_subcommands()
|
||||||
|
|
||||||
@override
|
@override
|
||||||
async def _run(self, args):
|
async def _run(self, args: Namespace) -> None:
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Missing subcommand
|
# Missing subcommand
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ from .Cmd import Cmd, Parent
|
||||||
from .lib.pkg_relations import VersionSyntax, pkg_relations
|
from .lib.pkg_relations import VersionSyntax, pkg_relations
|
||||||
from .lib.templates import ListDict, RenderValues, tmpl_render
|
from .lib.templates import ListDict, RenderValues, tmpl_render
|
||||||
|
|
||||||
def key_value(s):
|
def key_value(s: str) -> tuple[str, str]:
|
||||||
try:
|
try:
|
||||||
key, value = s.split('=', 1)
|
key, value = s.split('=', 1)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
|
@ -51,8 +51,8 @@ class CmdCreateFile(Cmd): # export
|
||||||
self,
|
self,
|
||||||
template_name: str,
|
template_name: str,
|
||||||
values: list[RenderValues],
|
values: list[RenderValues],
|
||||||
li_quote = False,
|
li_quote: bool = False,
|
||||||
li_delimiter = '\n',
|
li_delimiter: str = '\n',
|
||||||
) -> str:
|
) -> str:
|
||||||
return tmpl_render(
|
return tmpl_render(
|
||||||
template_name,
|
template_name,
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ def pkg_relations(
|
||||||
ignore: set[str] = set(),
|
ignore: set[str] = set(),
|
||||||
quote: bool = False,
|
quote: bool = False,
|
||||||
skip_excluded: bool = False,
|
skip_excluded: bool = False,
|
||||||
hide_self = False,
|
hide_self: bool = False,
|
||||||
hide_jw_pkg = False,
|
hide_jw_pkg: bool = False,
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
|
|
||||||
if subsections is None:
|
if subsections is None:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import textwrap
|
import textwrap
|
||||||
from typing import Iterable, TypeAlias, TypeGuard
|
from typing import Any, Iterable, TypeAlias, TypeGuard
|
||||||
|
|
||||||
TupleList: TypeAlias = Iterable[tuple[str, str]]
|
TupleList: TypeAlias = Iterable[tuple[str, str]]
|
||||||
ListDict: TypeAlias = dict[str, list[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
|
template: str, values: ListDict | dict[str, str], li_quote: bool, li_delimiter: str
|
||||||
) -> str:
|
) -> str:
|
||||||
|
|
||||||
def __format_value(val):
|
def __format_value(val: Any) -> str:
|
||||||
if not li_quote:
|
if not li_quote:
|
||||||
return str(val)
|
return str(val)
|
||||||
return f'"{val}"'
|
return f'"{val}"'
|
||||||
|
|
@ -144,9 +144,9 @@ _templates = {
|
||||||
def tmpl_render(
|
def tmpl_render(
|
||||||
template_name: str,
|
template_name: str,
|
||||||
values: list[RenderValues],
|
values: list[RenderValues],
|
||||||
li_quote = False,
|
li_quote: bool = False,
|
||||||
li_delimiter = '\n',
|
li_delimiter: str = '\n',
|
||||||
search_path: list[str] = []
|
search_path: list[str] | None = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
|
|
||||||
def __format(template: str) -> str:
|
def __format(template: str) -> str:
|
||||||
|
|
@ -157,7 +157,7 @@ def tmpl_render(
|
||||||
li_delimiter = li_delimiter,
|
li_delimiter = li_delimiter,
|
||||||
)
|
)
|
||||||
|
|
||||||
for d in search_path:
|
for d in search_path if search_path else []:
|
||||||
path = d + '/' + template_name
|
path = d + '/' + template_name
|
||||||
try:
|
try:
|
||||||
with open(path, 'r') as f:
|
with open(path, 'r') as f:
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,11 @@ class FilesContext:
|
||||||
def ctx(self) -> FileContext:
|
def ctx(self) -> FileContext:
|
||||||
return self.__ctx
|
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] = {}
|
ret: dict[str, str] = {}
|
||||||
try:
|
try:
|
||||||
result = await self.ctx.get(path)
|
result = await self.ctx.get(path)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser, Namespace
|
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 .AsyncRunner import AsyncRunner
|
||||||
from .log import DEBUG, ERR, NOTICE, log, log_m, set_log_flags, set_log_level
|
from .log import DEBUG, ERR, NOTICE, log, log_m, set_log_flags, set_log_level
|
||||||
|
|
@ -52,12 +52,15 @@ class App: # export
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
def add_cmd_to_parser(cmd: AbstractCmd, parsers: Any) -> ArgumentParser:
|
def add_cmd_to_parser(cmd: AbstractCmd, parsers: Any) -> ArgumentParser:
|
||||||
parser = parsers.add_parser(
|
parser = cast(
|
||||||
cmd.name,
|
'ArgumentParser',
|
||||||
help = cmd.help,
|
parsers.add_parser(
|
||||||
description = cmd.description,
|
cmd.name,
|
||||||
aliases = cmd.aliases,
|
help = cmd.help,
|
||||||
formatter_class = ArgumentDefaultsHelpFormatter,
|
description = cmd.description,
|
||||||
|
aliases = cmd.aliases,
|
||||||
|
formatter_class = ArgumentDefaultsHelpFormatter,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
parser.set_defaults(func = cmd.run)
|
parser.set_defaults(func = cmd.run)
|
||||||
cmd.add_arguments(parser)
|
cmd.add_arguments(parser)
|
||||||
|
|
@ -68,7 +71,7 @@ class App: # export
|
||||||
parent: AbstractCmd | App,
|
parent: AbstractCmd | App,
|
||||||
parser: ArgumentParser,
|
parser: ArgumentParser,
|
||||||
cmds: Collection[AbstractCmd],
|
cmds: Collection[AbstractCmd],
|
||||||
all = False
|
all: bool = False
|
||||||
) -> None:
|
) -> None:
|
||||||
if not cmds:
|
if not cmds:
|
||||||
return
|
return
|
||||||
|
|
@ -168,7 +171,7 @@ class App: # export
|
||||||
'-h', '--help', action = 'help', help = 'Show this help message and exit'
|
'-h', '--help', action = 'help', help = 'Show this help message and exit'
|
||||||
)
|
)
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self) -> None:
|
||||||
if self.__own_eloop:
|
if self.__own_eloop:
|
||||||
if self.__eloop is not None:
|
if self.__eloop is not None:
|
||||||
self.__eloop.close()
|
self.__eloop.close()
|
||||||
|
|
@ -178,10 +181,10 @@ class App: # export
|
||||||
async def __aenter__(self) -> None:
|
async def __aenter__(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc, tb) -> None:
|
async def __aexit__(self, exc_type: Any, exc: Any, tb: Any) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def __run(self, argv = None) -> None:
|
async def __run(self, argv: list[str] | None = None) -> None:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Import argcomplete only here to not require it to be compatible
|
# Import argcomplete only here to not require it to be compatible
|
||||||
|
|
@ -194,8 +197,8 @@ class App: # export
|
||||||
|
|
||||||
@override
|
@override
|
||||||
def __call__( # pyright: ignore[reportGeneralTypeIssues]
|
def __call__( # pyright: ignore[reportGeneralTypeIssues]
|
||||||
self, *args, **kwargs
|
self, *args: Any, **kwargs: Any
|
||||||
):
|
) -> None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
import argcomplete # type: ignore[import-not-found, unused-ignore]
|
import argcomplete # type: ignore[import-not-found, unused-ignore]
|
||||||
|
|
@ -249,7 +252,7 @@ class App: # export
|
||||||
self.__parser.print_help()
|
self.__parser.print_help()
|
||||||
return None
|
return None
|
||||||
# Run sub-command. Overwrite if you want to do anything before or after
|
# 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:
|
def call_async(self, awaitable: Awaitable[T], timeout: float | None = None) -> T:
|
||||||
return self.async_runner.call(awaitable, timeout)
|
return self.async_runner.call(awaitable, timeout)
|
||||||
|
|
@ -286,7 +289,7 @@ class App: # export
|
||||||
def parser(self) -> ArgumentParser:
|
def parser(self) -> ArgumentParser:
|
||||||
return self.__parser
|
return self.__parser
|
||||||
|
|
||||||
def run(self, argv = None) -> None:
|
def run(self, argv: list[str] | None = None) -> None:
|
||||||
try:
|
try:
|
||||||
ret = self.eloop.run_until_complete(self.__run(argv))
|
ret = self.eloop.run_until_complete(self.__run(argv))
|
||||||
finally:
|
finally:
|
||||||
|
|
@ -296,7 +299,10 @@ class App: # export
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def run_sub_commands( # export
|
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)
|
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 concurrent.futures
|
||||||
import contextlib
|
import contextlib
|
||||||
|
|
||||||
from typing import TypeVar, TYPE_CHECKING
|
from typing import Any, TypeVar, TYPE_CHECKING, cast
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from collections.abc import Awaitable, Generator
|
from collections.abc import Awaitable, Generator
|
||||||
|
|
@ -48,7 +48,7 @@ class AsyncRunner:
|
||||||
awaitable, # type: ignore[arg-type, var-annotated]
|
awaitable, # type: ignore[arg-type, var-annotated]
|
||||||
self._loop,
|
self._loop,
|
||||||
)
|
)
|
||||||
return fut.result(timeout)
|
return cast('T', fut.result(timeout))
|
||||||
|
|
||||||
def close(self) -> None:
|
def close(self) -> None:
|
||||||
self._cm.__exit__(None, None, None)
|
self._cm.__exit__(None, None, None)
|
||||||
|
|
@ -56,5 +56,5 @@ class AsyncRunner:
|
||||||
def __enter__(self) -> AsyncRunner:
|
def __enter__(self) -> AsyncRunner:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc, tb) -> None:
|
def __exit__(self, exc_type: Any, exc: Any, tb: Any) -> None:
|
||||||
self.close()
|
self.close()
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ from .log import ERR
|
||||||
from .Types import LoadTypes, Types
|
from .Types import LoadTypes, Types
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser, Namespace
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
|
||||||
from .App import App
|
from .App import App
|
||||||
|
|
@ -26,7 +26,7 @@ class AbstractCmd(abc.ABC):
|
||||||
self.__child_classes: list[type[Cmd]] = []
|
self.__child_classes: list[type[Cmd]] = []
|
||||||
self.__parser: ArgumentParser | None = None
|
self.__parser: ArgumentParser | None = None
|
||||||
|
|
||||||
def set_parent(self, parent: Any | Cmd):
|
def set_parent(self, parent: Any | Cmd) -> None:
|
||||||
self.__parent = parent
|
self.__parent = parent
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
@ -76,7 +76,7 @@ class AbstractCmd(abc.ABC):
|
||||||
return self.__parser
|
return self.__parser
|
||||||
|
|
||||||
# Don't use a setter decorator to force using a grepable method
|
# 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
|
self.__parser = parser
|
||||||
|
|
||||||
def print_help(self, exit_status: int | None = None) -> None:
|
def print_help(self, exit_status: int | None = None) -> None:
|
||||||
|
|
@ -129,11 +129,11 @@ class AbstractCmd(abc.ABC):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abc.abstractmethod
|
@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
|
if isinstance(self.__parent, Cmd): # Calling App.run() would loop
|
||||||
return await self.__parent._run(args)
|
return await self.__parent._run(args)
|
||||||
|
|
||||||
async def run(self, args):
|
async def run(self, args: Namespace) -> None:
|
||||||
return await self._run(args)
|
return await self._run(args)
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import Self
|
from typing import Any, Self
|
||||||
|
|
||||||
from .FileContext import FileContext
|
from .FileContext import FileContext
|
||||||
from .Uri import Uri
|
from .Uri import Uri
|
||||||
|
|
@ -9,7 +9,7 @@ class CopyContext:
|
||||||
self,
|
self,
|
||||||
src: Uri | str | FileContext,
|
src: Uri | str | FileContext,
|
||||||
dst: Uri | str | FileContext,
|
dst: Uri | str | FileContext,
|
||||||
chroot = False
|
chroot: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
def __uri(ctx: FileContext | Uri | str) -> Uri | str:
|
def __uri(ctx: FileContext | Uri | str) -> Uri | str:
|
||||||
|
|
@ -43,7 +43,7 @@ class CopyContext:
|
||||||
await self.__dst.open()
|
await self.__dst.open()
|
||||||
return self
|
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:
|
if self.__src is not None:
|
||||||
await self.__src.close()
|
await self.__src.close()
|
||||||
self.__src = None
|
self.__src = None
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue