Address UP014: use NamedTuple class syntax (#11168)

* Address UP014: use NamedTuple class syntax.

* Convert type comments to type hints.
This commit is contained in:
Felix Fontein
2025-11-21 18:19:36 +01:00
committed by GitHub
parent d98df2d3a5
commit e57de70c2a
3 changed files with 23 additions and 19 deletions

View File

@@ -0,0 +1,2 @@
bugfixes:
- "homebrew_service - slightly refactor code (https://github.com/ansible-collections/community.general/pull/11168)."

View File

@@ -87,7 +87,7 @@ running:
""" """
import json import json
from typing import NamedTuple, Optional import typing as t
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.homebrew import ( from ansible_collections.community.general.plugins.module_utils.homebrew import (
@@ -95,16 +95,22 @@ from ansible_collections.community.general.plugins.module_utils.homebrew import
parse_brew_path, parse_brew_path,
) )
# Stores validated arguments for an instance of an action. # Stores validated arguments for an instance of an action.
# See DOCUMENTATION string for argument-specific information. # See DOCUMENTATION string for argument-specific information.
HomebrewServiceArgs = NamedTuple("HomebrewServiceArgs", [("name", str), ("state", str), ("brew_path", str)]) class HomebrewServiceArgs(t.NamedTuple):
name: str
state: str
brew_path: str
# Stores the state of a Homebrew service. # Stores the state of a Homebrew service.
HomebrewServiceState = NamedTuple("HomebrewServiceState", [("running", bool), ("pid", Optional[int])]) class HomebrewServiceState(t.NamedTuple):
running: bool
pid: int | None
def _brew_service_state(args, module): def _brew_service_state(args: HomebrewServiceArgs, module: AnsibleModule) -> HomebrewServiceState:
# type: (HomebrewServiceArgs, AnsibleModule) -> HomebrewServiceState
cmd = [args.brew_path, "services", "info", args.name, "--json"] cmd = [args.brew_path, "services", "info", args.name, "--json"]
rc, stdout, stderr = module.run_command(cmd, check_rc=True) rc, stdout, stderr = module.run_command(cmd, check_rc=True)
@@ -116,22 +122,22 @@ def _brew_service_state(args, module):
return HomebrewServiceState(running=data["status"] == "started", pid=data["pid"]) return HomebrewServiceState(running=data["status"] == "started", pid=data["pid"])
def _exit_with_state(args, module, changed=False, message=None): def _exit_with_state(
# type: (HomebrewServiceArgs, AnsibleModule, bool, Optional[str]) -> None args: HomebrewServiceArgs, module: AnsibleModule, changed: bool = False, message: str | None = None
) -> None:
state = _brew_service_state(args, module) state = _brew_service_state(args, module)
if message is None: if message is None:
message = f"Running: {state.running}, Changed: {changed}, PID: {state.pid}" message = f"Running: {state.running}, Changed: {changed}, PID: {state.pid}"
module.exit_json(msg=message, pid=state.pid, running=state.running, changed=changed) module.exit_json(msg=message, pid=state.pid, running=state.running, changed=changed)
def validate_and_load_arguments(module): def validate_and_load_arguments(module: AnsibleModule) -> HomebrewServiceArgs:
# type: (AnsibleModule) -> HomebrewServiceArgs
"""Reuse the Homebrew module's validation logic to validate these arguments.""" """Reuse the Homebrew module's validation logic to validate these arguments."""
package = module.params["name"] # type: ignore package: str = module.params["name"]
if not HomebrewValidate.valid_package(package): if not HomebrewValidate.valid_package(package):
module.fail_json(msg=f"Invalid package name: {package}") module.fail_json(msg=f"Invalid package name: {package}")
state = module.params["state"] # type: ignore state: t.Literal["present", "absent", "restarted"] = module.params["state"]
if state not in ["present", "absent", "restarted"]: if state not in ["present", "absent", "restarted"]:
module.fail_json(msg=f"Invalid state: {state}") module.fail_json(msg=f"Invalid state: {state}")
@@ -140,8 +146,7 @@ def validate_and_load_arguments(module):
return HomebrewServiceArgs(name=package, state=state, brew_path=brew_path) return HomebrewServiceArgs(name=package, state=state, brew_path=brew_path)
def start_service(args, module): def start_service(args: HomebrewServiceArgs, module: AnsibleModule) -> None:
# type: (HomebrewServiceArgs, AnsibleModule) -> None
"""Start the requested brew service if it is not already running.""" """Start the requested brew service if it is not already running."""
state = _brew_service_state(args, module) state = _brew_service_state(args, module)
if state.running: if state.running:
@@ -157,8 +162,7 @@ def start_service(args, module):
_exit_with_state(args, module, changed=True) _exit_with_state(args, module, changed=True)
def stop_service(args, module): def stop_service(args: HomebrewServiceArgs, module: AnsibleModule) -> None:
# type: (HomebrewServiceArgs, AnsibleModule) -> None
"""Stop the requested brew service if it is running.""" """Stop the requested brew service if it is running."""
state = _brew_service_state(args, module) state = _brew_service_state(args, module)
if not state.running: if not state.running:
@@ -174,8 +178,7 @@ def stop_service(args, module):
_exit_with_state(args, module, changed=True) _exit_with_state(args, module, changed=True)
def restart_service(args, module): def restart_service(args: HomebrewServiceArgs, module: AnsibleModule) -> None:
# type: (HomebrewServiceArgs, AnsibleModule) -> None
"""Restart the requested brew service. This always results in a change.""" """Restart the requested brew service. This always results in a change."""
if module.check_mode: if module.check_mode:
_exit_with_state(args, module, changed=True, message="Service would be restarted") _exit_with_state(args, module, changed=True, message="Service would be restarted")
@@ -186,7 +189,7 @@ def restart_service(args, module):
_exit_with_state(args, module, changed=True) _exit_with_state(args, module, changed=True)
def main(): def main() -> None:
module = AnsibleModule( module = AnsibleModule(
argument_spec=dict( argument_spec=dict(
name=dict( name=dict(

View File

@@ -21,7 +21,6 @@ ignore = [
"B905", # zip-without-explicit-strict - needs Python 3.10+ "B905", # zip-without-explicit-strict - needs Python 3.10+
"UP045", # Use `X | None` for type annotations - needs Python 3.10+ "UP045", # Use `X | None` for type annotations - needs Python 3.10+
# To fix: # To fix:
"UP014", # Convert `xxx` from `NamedTuple` functional to class syntax
"UP024", # Replace aliased errors with `OSError` "UP024", # Replace aliased errors with `OSError`
"UP030", # Use implicit references for positional format fields "UP030", # Use implicit references for positional format fields
"UP031", # Use format specifiers instead of percent format "UP031", # Use format specifiers instead of percent format