From 5e30ccab092f38304942df0aab0f66308ded6ca3 Mon Sep 17 00:00:00 2001 From: Sorin Sbarnea Date: Thu, 29 Feb 2024 14:38:15 +0000 Subject: [PATCH] More types --- pyproject.toml | 2 +- src/ansible_navigator/initialization.py | 5 +++-- .../ui_framework/form_handler_options.py | 17 ++++++++++------- .../ui_framework/form_handler_working.py | 7 +++++-- .../ui_framework/form_utils.py | 2 +- src/ansible_navigator/ui_framework/utils.py | 5 ++--- .../utils/version_migration/definitions.py | 12 ++++++------ tests/conftest.py | 2 +- 8 files changed, 29 insertions(+), 23 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a0d440f33..f71b2af6a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,7 @@ color_output = true error_summary = true check_untyped_defs = true # disallow_untyped_calls = true -# disallow_untyped_defs = true +disallow_untyped_defs = true disallow_any_generics = true incremental = false diff --git a/src/ansible_navigator/initialization.py b/src/ansible_navigator/initialization.py index f4c13afc5..d2ec20e95 100644 --- a/src/ansible_navigator/initialization.py +++ b/src/ansible_navigator/initialization.py @@ -146,7 +146,7 @@ def _diagnose( exit_messages: list[ExitMessage], messages: list[LogMessage], should_diagnose: bool, -): +) -> tuple[list[LogMessage], list[ExitMessage]]: """Direct to the diagnostic information writer or return. :param args: Application configuration @@ -159,13 +159,14 @@ def _diagnose( DiagnosticsCollector(args=args, messages=messages, exit_messages=exit_messages).run() else: return messages, exit_messages + return ([], []) def parse_and_update( params: list[str], args: ApplicationConfiguration, apply_previous_cli_entries: C | list[str] = C.NONE, - attach_cdc=False, + attach_cdc: bool = False, ) -> tuple[list[LogMessage], list[ExitMessage]]: """Build a configuration. diff --git a/src/ansible_navigator/ui_framework/form_handler_options.py b/src/ansible_navigator/ui_framework/form_handler_options.py index a7b252d7a..9216b5408 100644 --- a/src/ansible_navigator/ui_framework/form_handler_options.py +++ b/src/ansible_navigator/ui_framework/form_handler_options.py @@ -6,7 +6,6 @@ from curses import ascii as curses_ascii from typing import TYPE_CHECKING -from typing import Any from .curses_defs import CursesLine from .curses_defs import CursesLinePart @@ -14,14 +13,15 @@ if TYPE_CHECKING: - from .field_checks import FieldChecks - from .field_radio import FieldRadio + from ansible_navigator.action_runner import Window + from ansible_navigator.ui_framework.field_text import FieldText + from ansible_navigator.ui_framework.ui_config import UIConfig class FormHandlerOptions(CursesWindow): """Handle form checkbox field.""" - def __init__(self, screen, ui_config): + def __init__(self, screen: Window, ui_config: UIConfig) -> None: """Initialize the handler for either form checkboxes or radio buttons. :param screen: A curses window @@ -30,13 +30,14 @@ def __init__(self, screen, ui_config): super().__init__(ui_config=ui_config) self._screen = screen - def populate(self, form_field, active): + def populate(self, form_field: FieldText, active: int) -> None: """Populate the window with the checkboxes. :param form_field: Field from a form :param active: Track active checkbox/option """ - for idx, option in enumerate(form_field.options): + options = getattr(form_field, "options", []) + for idx, option in enumerate(options): option_code = option.ansi_code(form_field) color = 8 if option.disabled else 0 decoration = curses.A_STANDOUT if idx == active else 0 @@ -52,7 +53,7 @@ def populate(self, form_field, active): window=self.win, lineno=idx, line=CursesLine((clp_option_code, clp_text)) ) - def handle(self, idx, form_fields: list[Any]) -> tuple[FieldChecks | FieldRadio, int]: + def handle(self, idx: int, form_fields: list[FieldText]) -> tuple[FieldText, int]: # pylint: disable=too-many-nested-blocks """Handle the check box field. @@ -63,6 +64,8 @@ def handle(self, idx, form_fields: list[Any]) -> tuple[FieldChecks | FieldRadio, form_field = form_fields[idx] active = 0 + if not hasattr(form_field, "options"): + raise RuntimeError while True: active = active % len(form_field.options) self.populate(form_field, active) diff --git a/src/ansible_navigator/ui_framework/form_handler_working.py b/src/ansible_navigator/ui_framework/form_handler_working.py index cc46115f0..67f623f3d 100644 --- a/src/ansible_navigator/ui_framework/form_handler_working.py +++ b/src/ansible_navigator/ui_framework/form_handler_working.py @@ -4,7 +4,10 @@ from typing import TYPE_CHECKING +from ansible_navigator.ui_framework.ui_config import UIConfig + from .curses_window import CursesWindow +from .curses_window import Window if TYPE_CHECKING: @@ -14,7 +17,7 @@ class FormHandlerWorking(CursesWindow): """Handle form button.""" - def __init__(self, screen, ui_config): + def __init__(self, screen: Window, ui_config: UIConfig) -> None: """Initialize the handler for a form working notification. :param screen: A curses window @@ -24,7 +27,7 @@ def __init__(self, screen, ui_config): self._screen = screen @staticmethod - def handle(idx, form_fields: list[str]) -> tuple[FieldWorking, int]: + def handle(idx: int, form_fields: list[FieldWorking]) -> tuple[FieldWorking, int]: """Handle the information field, immediate return. :param idx: Index to retrieve specific field diff --git a/src/ansible_navigator/ui_framework/form_utils.py b/src/ansible_navigator/ui_framework/form_utils.py index 2df7a894d..13a923006 100644 --- a/src/ansible_navigator/ui_framework/form_utils.py +++ b/src/ansible_navigator/ui_framework/form_utils.py @@ -132,7 +132,7 @@ def form_to_dict(form: Form, key_on_name: bool = False) -> dict[str, Any]: return res -def break_long_lines(messages): +def break_long_lines(messages: list[str]) -> list[str]: """Break lines such that the form width !> 80%. :param messages: Lines of the form diff --git a/src/ansible_navigator/ui_framework/utils.py b/src/ansible_navigator/ui_framework/utils.py index ea336e56c..353840108 100644 --- a/src/ansible_navigator/ui_framework/utils.py +++ b/src/ansible_navigator/ui_framework/utils.py @@ -60,7 +60,7 @@ def is_percent(string: str) -> bool: return False -def distribute(available, weights): +def distribute(available: int, weights: list[int]) -> list[int]: """Distribute some available fairly across a list of numbers. :param available: the total @@ -82,8 +82,7 @@ def distribute(available, weights): distributed_amounts = [] total_weights = sum(weights) for weight in weights: - weight = float(weight) - percent_of_total = weight / total_weights + percent_of_total = float(weight) / total_weights distributed_amount = round(percent_of_total * available) distributed_amounts.append(distributed_amount) total_weights -= weight diff --git a/src/ansible_navigator/utils/version_migration/definitions.py b/src/ansible_navigator/utils/version_migration/definitions.py index 730185739..5a151f033 100644 --- a/src/ansible_navigator/utils/version_migration/definitions.py +++ b/src/ansible_navigator/utils/version_migration/definitions.py @@ -77,14 +77,14 @@ def register(cls: T, migration_step: MigrationStep[Any]) -> Callable[..., Any]: :return: The registered migration step """ - def wrapper(func): + def wrapper(func: Callable[..., Any]) -> Callable[..., Any]: """Add the dunder collector to the func. :param func: The function to decorate :returns: The decorated function """ migration_step.function_name = func.__name__ - func.__migration_step__ = migration_step + func.__migration_step__ = migration_step # type: ignore[attr-defined] return func return wrapper @@ -105,7 +105,7 @@ def __init__(self) -> None: self.was_needed: bool = False """Whether the migration was needed.""" - def __init_subclass__(cls, *args, **kwargs) -> None: + def __init_subclass__(cls, *args: Any, **kwargs: Any) -> None: """Register the migration steps. :param args: Positional arguments @@ -137,14 +137,14 @@ def needed_now(self) -> bool: """ return any(step.needed for step in self.migration_steps) - def run(self, *args, **kwargs) -> None: + def run(self, *args: Any, **kwargs: Any) -> None: """Run the migration. :param args: The positional arguments :param kwargs: The keyword arguments """ - def run_step(self, step: MigrationStep[Any], *args, **kwargs) -> None: + def run_step(self, step: MigrationStep[Any], *args: Any, **kwargs: Any) -> None: """Run the migration step. :param step: The migration step to run @@ -175,7 +175,7 @@ def run_step(self, step: MigrationStep[Any], *args, **kwargs) -> None: step.print_updated() return - def run_steps(self, *args, **kwargs) -> None: + def run_steps(self, *args: Any, **kwargs: Any) -> None: """Run all registered migration steps. :param args: The positional arguments diff --git a/tests/conftest.py b/tests/conftest.py index 74e31e9f0..2c3b2b073 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -394,7 +394,7 @@ def pytest_unconfigure(config: pytest.Config) -> None: @pytest.fixture(scope="function") def skip_if_already_failed( - request: pytest.FixtureRequest, failed=set() + request: pytest.FixtureRequest, failed: set[str] = set() ) -> Generator[None, None, None]: """Fixture that stops parametrized tests running on first failure.""" key = request.node.name.split("[")[0]