diff --git a/test/unit/python/jw/pkg/lib/App/test.py b/test/unit/python/jw/pkg/lib/App/test.py index 2b899d4f..402f11c5 100644 --- a/test/unit/python/jw/pkg/lib/App/test.py +++ b/test/unit/python/jw/pkg/lib/App/test.py @@ -1,10 +1,16 @@ -import asyncio +from __future__ import annotations +import asyncio import sys +from typing import TYPE_CHECKING, override + from jw.pkg.lib.App import App from jw.pkg.lib.Cmd import Cmd +if TYPE_CHECKING: + from argparse import ArgumentParser, Namespace + # -- A minimal command tree: a root command hosting one child command. The # root mimics the "run + opts" unit the App can now mount at the top level: # it adds options, sets up, dispatches to the selected child (or runs its own @@ -12,24 +18,26 @@ from jw.pkg.lib.Cmd import Cmd class ChildCmd(Cmd): - def __init__(self, parent): + def __init__(self, parent: App | Cmd) -> None: super().__init__(parent, 'child', 'A child command') self.ran = False self.got_opt = None - def add_arguments(self, parser): + @override + def add_arguments(self, parser: ArgumentParser) -> None: super().add_arguments(parser) parser.add_argument('--child-opt', default = 'child-default') - async def _run(self, args): + @override + async def _run(self, args: Namespace) -> None: self.ran = True self.got_opt = args.child_opt class RootCmd(Cmd): - made = [] + made: list['RootCmd'] = [] - def __init__(self, parent): + def __init__(self, parent: App | Cmd) -> None: super().__init__(parent, 'root', 'Root command') self.child = ChildCmd(self) self.add_subcommands(self.child) @@ -38,11 +46,13 @@ class RootCmd(Cmd): self.default = False RootCmd.made.append(self) - def add_arguments(self, parser): + @override + def add_arguments(self, parser: ArgumentParser) -> None: super().add_arguments(parser) parser.add_argument('--root-opt', default = 'root-default') - async def _run(self, args): + @override + async def _run(self, args: Namespace) -> None: self.setup = True try: if hasattr(args, 'func'): diff --git a/test/unit/python/jw/pkg/lib/ExecApp/test.py b/test/unit/python/jw/pkg/lib/ExecApp/test.py index 3a558946..b0071e56 100644 --- a/test/unit/python/jw/pkg/lib/ExecApp/test.py +++ b/test/unit/python/jw/pkg/lib/ExecApp/test.py @@ -1,18 +1,27 @@ -import asyncio +from __future__ import annotations +import asyncio import sys +from typing import TYPE_CHECKING, override + from jw.pkg.lib.Cmd import Cmd from jw.pkg.lib.ExecApp import ExecApp +if TYPE_CHECKING: + from argparse import Namespace + + from jw.pkg.lib.App import App + # -- A minimal root command so the app can be built without a command tree. class RootCmd(Cmd): - def __init__(self, parent): + def __init__(self, parent: App | Cmd) -> None: super().__init__(parent, 'root', 'Root command') - async def _run(self, args): + @override + async def _run(self, args: Namespace) -> None: pass # -- Counts the close() calls made by App.__aexit__() when the async context @@ -22,7 +31,8 @@ class RecordingExecApp(ExecApp): closed = 0 - def close(self): + @override + def close(self) -> None: RecordingExecApp.closed += 1 super().close() @@ -38,16 +48,14 @@ finally: # -- ExecApp registers the exec-related options on the top-level parser. -opts = [ - o for a in app.parser._actions for o in getattr(a, 'option_strings', ()) -] +opts = [o for a in app.parser._actions for o in getattr(a, 'option_strings', ())] for opt in ('--interactive', '--verbose', '--target'): assert opt in opts, f'{opt} must be registered by ExecApp' # -- Exiting the async context must close the app, through the # App.__aexit__() that ExecApp.__aexit__() chains to. -async def exit_context(): +async def exit_context() -> None: async with app: pass diff --git a/test/unit/python/jw/pkg/lib/ProjectConf/test.py b/test/unit/python/jw/pkg/lib/ProjectConf/test.py index b503a2ec..e2a55cc3 100644 --- a/test/unit/python/jw/pkg/lib/ProjectConf/test.py +++ b/test/unit/python/jw/pkg/lib/ProjectConf/test.py @@ -1,5 +1,6 @@ import os import tempfile + from jw.pkg.lib.ProjectConf import ProjectConf # -- Helper: create temp file and read it -- @@ -13,7 +14,7 @@ def _load(text: str) -> ProjectConf: _tmpfiles.append(f.name) return ProjectConf.read(f.name) -def _cleanup(): +def _cleanup() -> None: for _p in _tmpfiles: os.unlink(_p) del _p diff --git a/test/unit/python/jw/pkg/lib/version/test.py b/test/unit/python/jw/pkg/lib/version/test.py index 07817f87..337219a6 100644 --- a/test/unit/python/jw/pkg/lib/version/test.py +++ b/test/unit/python/jw/pkg/lib/version/test.py @@ -233,16 +233,16 @@ for bad in ['', 'foo =', ' = 1.0']: # Operators outside the supported set are rejected when parsed, # not folded into the package name or deferred to expansion for bad in [ - 'foo ~= 1.0', - 'foo~=1.0', - 'foo ~ 1.0', - 'foo != 1.0', - 'foo!=1.0', - 'foo == 1.0', - 'foo==1.0', - 'foo === 1.0', - 'foo << 1.0', - 'foo >> 1.0', + 'foo ~= 1.0', + 'foo~=1.0', + 'foo ~ 1.0', + 'foo != 1.0', + 'foo!=1.0', + 'foo == 1.0', + 'foo==1.0', + 'foo === 1.0', + 'foo << 1.0', + 'foo >> 1.0', ]: try: Dependency(bad).full_name