jw.pkg: Massively tighten linter checks #53
Loading…
Reference in a new issue
No description provided.
Delete branch "jan/feature/20260809-pyrightconfig-json-mirror-strict-mypy-settings"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This PR gradually tightens Mypy's linter rules in
pypropject.toml. After every change,make checkandmake testfallout is fixed, and the fixes committed, to keep the project bisectable over the entire PR. After that, equivalent rules are also configured to Pyright inpyrightconfig.json, in this case with no additional fallout.The fixes have to a large extent been made by AI.
pyrightconfig.json: Mirror strict mypy settings
Follow the changes in the mypy check profile by adding additional checks.
pyproject.toml: Simplify mypy config using strict mode
Remove 8 redundant mypy settings that are already enabled by strict mode: warn_redundant_casts, strict_equality, disallow_any_generics, warn_unused_ignores, disallow_untyped_calls, warn_return_any, disallow_incomplete_defs, disallow_untyped_defs.
Keep warn_unreachable explicitly since it's not part of strict mode. Also remove the duplicate exhaustive-match entry from enable_error_code.
pyproject.toml: Enable mypy.disallow_untyped_defs
Add disallow_untyped_defs = true to the mypy configuration. This requires all function definitions to have complete type annotations for both parameters and return types. Since disallow_incomplete_defs was already satisfied (all functions have partial annotations), this final rule validates that no function is left without any type hints.
pyproject.toml: Enable mypy.disallow_incomplete_defs
Add disallow_incomplete_defs = true to the mypy configuration. This requires all function definitions to have complete parameter and return type annotations, catching partially-annotated function signatures.
App, lib: Fix disallow_incomplete_defs fallout
Add missing type annotations to function parameters and return types to satisfy the disallow_incomplete_defs mypy rule.
Fixes applied across 28 files:
Added return type annotations (Result, str, None, etc.)
Added parameter type annotations (Any, int, str, Namespace, etc.)
Added *args: Any and **kwargs: Any where needed
Added from future import annotations to Package.py
util.py: annotate *args/**kwargs in run_cmd, run_curl_into
Result.py: annotate quote, verbose parameters in private methods
CopyContext.py: annotate chroot parameter
AsyncRunner.py: annotate exc_type, exc, tb in exit
ec/Curl.py: annotate *args/**kwargs in init, add Any import
ec/Local.py: fix __make_pty_reader return type and _read annotation
Types.py: annotate debug_level parameter, add return type
Distro.py: annotate **kwargs in instantiate
distros/suse/Distro.py: annotate *args/**kwargs, add Any import
distros/debian/Distro.py: annotate *args/**kwargs, add Any import
ec/ssh/Paramiko.py: annotate uri parameter, *args/**kwargs
ec/ssh/Exec.py: annotate uri parameter, *args/**kwargs, add Any import
pm/rpm.py: annotate **kwargs in run_rpm, add Any import
cmds/secrets/lib/FilesContext.py: annotate throw parameter
cmds/projects/lib/templates.py: annotate li_quote, li_delimiter parameters, fix search_path None handling
cmds/projects/lib/pkg_relations.py: annotate hide_self, hide_jw_pkg
cmds/projects/CmdCreateFile.py: annotate li_quote, li_delimiter
cmds/projects/CmdCanonicalizeRemotes.py: annotate ro, throw in git
cmds/posix/tar/Cmd.py: annotate **kwargs in ctx, add Any import
App.py: annotate __get_project_refs_cached return type, use cast
pyproject.toml: Enable mypy.warn_return_any
Add warn_return_any = true to the mypy configuration. This detects functions that return Any from contexts where a specific return type is declared, encouraging more precise type annotations.
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:
pyproject.toml: Enable mypy.disallow_untyped_calls
Add disallow_untyped_calls = true to the mypy configuration. This requires all function calls from typed code to target typed functions, ensuring better type safety across the codebase.
App, lib: Add type annotations to untyped functions
Add missing type annotations to functions that are called from typed contexts, satisfying the new disallow_untyped_calls mypy rule.
Fixes:
pyproject.toml: Enable mypy.warn_unreachable
Add warn_unreachable = true to the mypy configuration. This detects statements that mypy proves are unreachable, such as code after an unconditional return or assertions that can never be true.
App, lib, cmds: Remove unreachable code
Remove dead code paths detected by the new warn_unreachable mypy rule. These include:
pyproject.toml: Enable mypy.exhaustive-match
Add the exhaustive-match error code to the mypy configuration. This requires all match statements to be exhaustive, handling all possible values of the matched expression.
The fix is to add 'case _: pass' to each match statement that is intended to be non-exhaustive, making the non-exhaustiveness explicit.
lib, cmds: Add exhaustive match cases
Add 'case _: pass' to match statements that are intentionally non-exhaustive, satisfying the new exhaustive-match mypy rule.
Also replaced 'case '_':' (a string literal) with 'case _: pass' in pkg_relations.py since it was an unreachable case (syntax is a VersionSyntax enum, not a str).
Added 'case VersionSyntax.names_only:' to the match in pkg_relations.py to handle the missing enum value.
Files modified:
pyproject.toml: Enable mypy.truthy-iterable
Add the truthy-iterable error code to the mypy configuration. This detects Iterable parameters that are used in boolean contexts (if not names, etc.) since Iterable values are always truthy.
The fix is to change Iterable[str] parameters to Collection[str] when they are tested for emptiness, since Collection guarantees len.
lib: Change Iterable to Collection for truthy checks
Change parameter types from Iterable[str] to Collection[str] wherever the parameter is tested for emptiness (if not names). This satisfies the new truthy-iterable mypy rule, since bare Iterable values are always truthy even when empty.
Affected files:
pyproject.toml: Enable mypy.warn_unused_ignores
Add warn_unused_ignores = true to the mypy configuration. This warns when a '# type: ignore' comment has no associated error code, ensuring all type ignores are explicit about which error they suppress.
App, AsyncSSH: Remove unused "type: ignore" comments
Remove '# type: ignore' comments that are no longer needed now that warn_unused_ignores is enabled in the mypy configuration. The errors they were suppressing (import-not-found, type-abstract) are no longer triggered, likely due to updated type stubs or changed code paths.
pyproject.toml: Enable mypy.disallow_any_generics
Add disallow_any_generics = true to the mypy configuration. This requires all generic types (dict, list, Iterable, Types, etc.) to have explicit type arguments instead of using bare generic aliases.
Distro, Cmd, AsyncSSH: Fix bare generic types
Add explicit type arguments to all generic type annotations that were previously bare, satisfying the new disallow_any_generics mypy rule.
Fixes:
pyproject.toml: Enable mypy.strict_equality
Set mypy.strict_equality = true, forcing type-equal equality.
Distro._reboot_required(): Fix comparison
The comparison ret != 0 is comparing a Result object against the integer 0, which is always True since Result has no eq defined.
This commit fixes the bug by comparing ret.status instead, which is the actual exit code we care about. This satisfies the new strict_equality mypy rule which enables the comparison-overlap check.
pyproject.toml: Enable mypy.warn_redundant_casts
Add warn_redundant_casts = true to the mypy configuration template. This rule detects casts that mypy proves unnecessary, helping to clean up redundant type casts that clutter the codebase.
This is one of the boolean-flag rules being gradually adopted from the stricter mypy profile in /tmp/pyproject.toml. It produces just 1 error during initial rollout.
util: Remove redundant cast in run_curl_into
The cast to 'T' in run_curl_into was redundant: mypy already narrows the return value of json.loads() to type T after the isinstance(ret, expected_type) check (where expected_type: type[T]).
Remove the unnecessary cast and clean up the unused 'cast' import. This satisfies the new warn_redundant_casts mypy rule.
pyproject.toml: Enable mypy.truthy-bool
Add the truthy-bool error code to the mypy configuration. This detects conditions and expressions that are always truthy because the type has no bool or len method.
lib.Distro: Fix mypy.truthy-bool fallout
The _select() method in Distro.py has an assert on a PackageFilter parameter that doesn't define bool or len. Since the type signature already guarantees it is not None, the assertion is redundant and is now removed.
pyproject.toml: Enable mypy.possibly-undefined
Add the possibly-undefined error code to the mypy configuration. This detects variables that may not be defined on all execution paths, catching a class of NameError bugs at type-check time.
lib.log: Fix mypy.possibly-undefined fallout
The log_m() function has margs conditionally assigned inside an if block but used unconditionally afterwards. Initialize margs outside the if to guarantee it is always defined.
pyproject.toml: Enable mypy.ignore-without-code
Add the ignore-without-code error code to the mypy configuration. This requires all # type: ignore comments to include a specific error code, improving the precision and maintainability of type ignore annotations.
lib.AsyncRunner: Fix mypy.ignore-without-code fallout
Annotate the one existing bare "# type: ignore" in AsyncRunner.py with arg-type and var-annotated codes to prepare for mypy.ignore-without-code.
pyproject.toml, pyrightconfig.json: Require @override
Add mypy's explicit-override error code and pyrightconfig's reportImplicitOverride "error" directive. This requires all methods that override base class methods to be decorated with @override from typing. The change complements the previous commit, which added exactly that decorator to all relevant methods.
App, lib, cmds: Fix mypy.explicit-override fallout
This commit adds @override decorators to approximately 300 methods across 76 files that inherit from base classes such as AbstractCmd, FileContext, ExecContext, Distro, SSHClient, and others.
The decorator ensures the type checker can verify that overridden methods have compatible signatures and prevents accidental shadowing of inherited methods without intent.
Files modified include command classes, library modules, distro implementations, and SSH client implementations.
pyrightconfig.json: Mirror strict mypy settingsto jw.pkg: Massively tighten linter checksc1c1d82d761f6da7ff3b1f6da7ff3bbe46a5ebcf