CI: add type checking (#10997)

* Set up type checking with mypy.

* Make mypy pass.

* Use list() instead of sorted().
This commit is contained in:
Felix Fontein
2025-10-29 18:13:38 +01:00
committed by GitHub
parent 831787619a
commit 6088b0cff5
73 changed files with 442 additions and 175 deletions

View File

@@ -485,4 +485,4 @@ class CallbackModule(CallbackModule_default):
# When using -vv or higher, simply do the default action
if display.verbosity >= 2 or not HAS_OD:
CallbackModule = CallbackModule_default
CallbackModule = CallbackModule_default # type: ignore

View File

@@ -90,6 +90,7 @@ from ansible.errors import AnsibleError, AnsibleRuntimeError
from ansible.module_utils.ansible_release import __version__ as ansible_version
from ansible.plugins.callback import CallbackBase
ELASTIC_LIBRARY_IMPORT_ERROR: ImportError | None
try:
from elasticapm import Client, capture_span, trace_parent_from_string, instrument, label
except ImportError as imp_exc:

View File

@@ -206,7 +206,7 @@ else:
sock.connect((self.LE_API, self.LE_TLS_PORT))
self._conn = sock
SocketAppender = TLSSocketAppender
SocketAppender = TLSSocketAppender # type: ignore
class CallbackModule(CallbackBase):

View File

@@ -145,6 +145,7 @@ from ansible.errors import AnsibleError
from ansible.module_utils.ansible_release import __version__ as ansible_version
from ansible.plugins.callback import CallbackBase
OTEL_LIBRARY_IMPORT_ERROR: ImportError | None
try:
from opentelemetry import trace
from opentelemetry.trace import SpanKind

View File

@@ -28,7 +28,7 @@ try:
from yaml import CSafeDumper as SafeDumper
from yaml import CSafeLoader as SafeLoader
except ImportError:
from yaml import SafeDumper, SafeLoader
from yaml import SafeDumper, SafeLoader # type: ignore
from ansible.plugins.callback import CallbackBase

View File

@@ -46,13 +46,13 @@ from ansible.module_utils.common.text.converters import to_text
DONT_COLORIZE = False
COLORS = {
'normal': '\033[0m',
'ok': f'\x1b[{C.COLOR_CODES[C.COLOR_OK]}m',
'ok': f'\x1b[{C.COLOR_CODES[C.COLOR_OK]}m', # type: ignore
'bold': '\033[1m',
'not_so_bold': '\033[1m\033[34m',
'changed': f'\x1b[{C.COLOR_CODES[C.COLOR_CHANGED]}m',
'failed': f'\x1b[{C.COLOR_CODES[C.COLOR_ERROR]}m',
'changed': f'\x1b[{C.COLOR_CODES[C.COLOR_CHANGED]}m', # type: ignore
'failed': f'\x1b[{C.COLOR_CODES[C.COLOR_ERROR]}m', # type: ignore
'endc': '\033[0m',
'skipped': f'\x1b[{C.COLOR_CODES[C.COLOR_SKIP]}m',
'skipped': f'\x1b[{C.COLOR_CODES[C.COLOR_SKIP]}m', # type: ignore
}

View File

@@ -106,10 +106,10 @@ class Connection(ConnectionBase):
host=self._instance())
self._connected = True
def _build_command(self, cmd) -> str:
def _build_command(self, cmd) -> list[str]:
"""build the command to execute on the incus host"""
exec_cmd = [
exec_cmd: list[str] = [
self._incus_cmd,
"--project", self.get_option("project"),
"exec",

View File

@@ -108,10 +108,10 @@ class Connection(ConnectionBase):
self._display.vvv(f"ESTABLISH LXD CONNECTION FOR USER: {self.get_option('remote_user')}", host=self._host())
self._connected = True
def _build_command(self, cmd) -> str:
def _build_command(self, cmd) -> list[str]:
"""build the command to execute on the lxd host"""
exec_cmd = [self._lxc_cmd]
exec_cmd: list[str] = [self._lxc_cmd]
if self.get_option("project"):
exec_cmd.extend(["--project", self.get_option("project")])

View File

@@ -106,7 +106,7 @@ class Connection(ConnectionBase):
super(Connection, self)._connect()
self._connected = True
@ensure_connect
@ensure_connect # type: ignore # TODO: for some reason, the type infos for ensure_connect suck...
def exec_command(self, cmd, in_data=None, sudoable=False):
"""Run specified command in a running QubesVM """
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)

View File

@@ -332,31 +332,23 @@ from ansible.utils.path import makedirs_safe
from binascii import hexlify
from subprocess import list2cmdline
PARAMIKO_IMPORT_ERR: str | None
try:
import paramiko
from paramiko import MissingHostKeyPolicy
PARAMIKO_IMPORT_ERR = None
except ImportError:
paramiko = None
PARAMIKO_IMPORT_ERR = traceback.format_exc()
if t.TYPE_CHECKING and PARAMIKO_IMPORT_ERR is None:
from paramiko import MissingHostKeyPolicy
from paramiko.client import SSHClient
from paramiko.pkey import PKey
else:
MissingHostKeyPolicy: type = object
SSHClient: type = object
PKey: type = object
MissingHostKeyPolicy = object # type: ignore
display = Display()
def authenticity_msg(hostname: str, ktype: str, fingerprint: str) -> str:
def authenticity_msg(hostname: str, ktype: str, fingerprint: bytes) -> str:
msg = f"""
paramiko: The authenticity of host '{hostname}' can't be established.
The {ktype} key fingerprint is {fingerprint}.
The {ktype} key fingerprint is {to_text(fingerprint)}.
Are you sure you want to continue connecting (yes/no)?
"""
return msg
@@ -376,7 +368,7 @@ class MyAddPolicy(MissingHostKeyPolicy):
self.connection = connection
self._options = connection._options
def missing_host_key(self, client: SSHClient, hostname: str, key: PKey) -> None:
def missing_host_key(self, client: paramiko.SSHClient, hostname: str, key: paramiko.PKey) -> None:
if all((self.connection.get_option('host_key_checking'), not self.connection.get_option('host_key_auto_add'))):
@@ -396,10 +388,10 @@ class MyAddPolicy(MissingHostKeyPolicy):
if inp.lower() not in ['yes', 'y', '']:
raise AnsibleError('host connection rejected by user')
key._added_by_ansible_this_time = True
key._added_by_ansible_this_time = True # type: ignore
# existing implementation below:
client._host_keys.add(hostname, key.get_name(), key)
client._host_keys.add(hostname, key.get_name(), key) # type: ignore[attr-defined] # TODO: figure out what _host_keys is!
# host keys are actually saved in close() function below
# in order to control ordering.
@@ -540,7 +532,7 @@ class Connection(ConnectionBase):
return self
def _any_keys_added(self) -> bool:
for hostname, keys in self.ssh._host_keys.items():
for hostname, keys in self.ssh._host_keys.items(): # type: ignore[attr-defined] # TODO: figure out what _host_keys is!
for keytype, key in keys.items():
added_this_time = getattr(key, '_added_by_ansible_this_time', False)
if added_this_time:
@@ -560,14 +552,14 @@ class Connection(ConnectionBase):
makedirs_safe(path)
with open(filename, 'w') as f:
for hostname, keys in self.ssh._host_keys.items():
for hostname, keys in self.ssh._host_keys.items(): # type: ignore[attr-defined] # TODO: figure out what _host_keys is!
for keytype, key in keys.items():
# was f.write
added_this_time = getattr(key, '_added_by_ansible_this_time', False)
if not added_this_time:
f.write(f'{hostname} {keytype} {key.get_base64()}\n')
for hostname, keys in self.ssh._host_keys.items():
for hostname, keys in self.ssh._host_keys.items(): # type: ignore[attr-defined] # TODO: figure out what _host_keys is!
for keytype, key in keys.items():
added_this_time = getattr(key, '_added_by_ansible_this_time', False)
if added_this_time:
@@ -595,13 +587,16 @@ class Connection(ConnectionBase):
cmd = self._build_wsl_command(cmd)
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable) # type: ignore[safe-super]
bufsize = 4096
try:
self.ssh.get_transport().set_keepalive(5)
chan = self.ssh.get_transport().open_session()
transport = self.ssh.get_transport()
if transport is None:
raise ValueError("Transport not available")
transport.set_keepalive(5)
chan = transport.open_session()
except Exception as e:
text_e = to_text(e)
msg = 'Failed to open session'
@@ -745,7 +740,7 @@ class Connection(ConnectionBase):
# just in case any were added recently
self.ssh.load_system_host_keys()
self.ssh._host_keys.update(self.ssh._system_host_keys)
self.ssh._host_keys.update(self.ssh._system_host_keys) # type: ignore[attr-defined] # TODO this is a HACK!
# gather information about the current key file, so
# we can ensure the new file has the correct mode/owner

View File

@@ -16,7 +16,7 @@ from ansible.module_utils.common.collections import is_sequence
try:
from ansible.errors import AnsibleTypeError
except ImportError:
from ansible.errors import AnsibleFilterTypeError as AnsibleTypeError
from ansible.errors import AnsibleFilterTypeError as AnsibleTypeError # type: ignore
try:
from hashids import Hashids

View File

@@ -3,17 +3,18 @@
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
import typing as t
from json import loads
from typing import TYPE_CHECKING
from ansible.errors import AnsibleFilterError
if TYPE_CHECKING:
if t.TYPE_CHECKING:
from typing import Any, Callable, Union
JSONPATCH_IMPORT_ERROR: ImportError | None
try:
import jsonpatch
except ImportError as exc:
HAS_LIB = False
JSONPATCH_IMPORT_ERROR = exc
@@ -82,7 +83,7 @@ class FilterModule:
"You need to install 'jsonpatch' package prior to running 'json_patch' filter"
) from JSONPATCH_IMPORT_ERROR
args = {"op": op, "path": path}
args: dict[str, t.Any] = {"op": op, "path": path}
from_arg = kwargs.pop("from", None)
fail_test = kwargs.pop("fail_test", False)

View File

@@ -11,15 +11,16 @@ from yaml import dump
try:
from yaml.cyaml import CSafeDumper as SafeDumper
except ImportError:
from yaml import SafeDumper
from yaml import SafeDumper # type: ignore
from ansible.module_utils.common.collections import is_sequence
try:
# This is ansible-core 2.19+
from ansible.utils.vars import transform_to_native_types
from ansible.parsing.vault import VaultHelper, VaultLib
HAS_TRANSFORM_TO_NATIVE_TYPES = True
except ImportError:
transform_to_native_types = None
HAS_TRANSFORM_TO_NATIVE_TYPES = False
from ansible.parsing.yaml.objects import AnsibleVaultEncryptedUnicode
from ansible.utils.unsafe_proxy import AnsibleUnsafe
@@ -31,7 +32,7 @@ def _to_native_types_compat(value: t.Any, *, redact_value: str | None) -> t.Any:
return value
if isinstance(value, AnsibleUnsafe):
# This only works up to ansible-core 2.18:
return _to_native_types_compat(value._strip_unsafe(), redact_value=redact_value)
return _to_native_types_compat(value._strip_unsafe(), redact_value=redact_value) # type: ignore
# But that's fine, since this code path isn't taken on ansible-core 2.19+ anyway.
if isinstance(value, Mapping):
return {
@@ -74,10 +75,10 @@ def remove_all_tags(value: t.Any, *, redact_sensitive_values: bool = False) -> t
If ``redact_sensitive_values`` is ``True``, all sensitive values will be redacted.
"""
if transform_to_native_types is not None:
if HAS_TRANSFORM_TO_NATIVE_TYPES:
return _to_native_types(value, redact=redact_sensitive_values)
return _to_native_types_compat(
return _to_native_types_compat( # type: ignore[unreachable]
value,
redact_value="<redacted>" if redact_sensitive_values else None, # same string as in ansible-core 2.19 by transform_to_native_types()
)

View File

@@ -52,7 +52,7 @@ from ansible.errors import AnsibleFilterError
try:
from ansible.errors import AnsibleTypeError
except ImportError:
from ansible.errors import AnsibleFilterTypeError as AnsibleTypeError
from ansible.errors import AnsibleFilterTypeError as AnsibleTypeError # type: ignore
def unicode_normalize(data, form='NFC'):

View File

@@ -179,6 +179,7 @@ from ansible.errors import AnsibleError, AnsibleParserError
from ansible_collections.community.general.plugins.module_utils.lxd import LXDClient, LXDClientException
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
IPADDRESS_IMPORT_ERROR: ImportError | None
try:
import ipaddress
except ImportError as exc:

View File

@@ -118,6 +118,7 @@ variables:
import os
import json
YAML_IMPORT_ERROR: ImportError | None
try:
import yaml
except ImportError as exc:

View File

@@ -244,7 +244,7 @@ class Bitwarden(object):
out, err = self._run(params)
# This includes things that matched in different fields.
initial_matches = AnsibleJSONDecoder().raw_decode(out)[0]
initial_matches = AnsibleJSONDecoder().raw_decode(out)[0] # type: ignore[operator]
# Filter to only return the ID of a collections with exactly matching name
return [item['id'] for item in initial_matches

View File

@@ -82,7 +82,7 @@ except ImportError:
HAS_PYTHON_JWT = False # vs pyjwt
if HAS_JWT and hasattr(jwt, 'JWT'):
HAS_PYTHON_JWT = True
from jwt import jwk_from_pem, JWT
from jwt import jwk_from_pem, JWT # type: ignore[attr-defined]
jwt_instance = JWT()
try:

View File

@@ -65,6 +65,7 @@ from ansible.plugins.lookup import LookupBase
from ansible.utils.display import Display
from ansible.errors import AnsibleError
ANOTHER_LIBRARY_IMPORT_ERROR: ImportError | None
try:
from pam.revbits_ansible.server import SecretServer
except ImportError as imp_exc:

View File

@@ -11,10 +11,11 @@ import traceback
from operator import itemgetter
PARAMIKO_IMPORT_ERROR: str | None
try:
from paramiko.config import SSHConfig
except ImportError:
SSHConfig = object
SSHConfig = object # type: ignore
HAS_PARAMIKO = False
PARAMIKO_IMPORT_ERROR = traceback.format_exc()
else:

View File

@@ -4,10 +4,17 @@
from __future__ import annotations
import typing as t
from functools import wraps
from ansible.module_utils.common.collections import is_sequence
if t.TYPE_CHECKING:
from collections.abc import Callable
ArgFormatType = Callable[[t.Any], list[str]]
def _ensure_list(value):
return list(value) if is_sequence(value) else [value]

View File

@@ -9,6 +9,7 @@ from __future__ import annotations
import copy
import json
import re
import typing as t
from urllib import error as urllib_error
from urllib.parse import urlencode
@@ -118,12 +119,12 @@ class _ConsulModule:
As such backwards incompatible changes can occur even in bugfix releases.
"""
api_endpoint = None # type: str
unique_identifiers = None # type: list
result_key = None # type: str
create_only_fields = set()
operational_attributes = set()
params = {}
api_endpoint: str | None = None
unique_identifiers: list | None = None
result_key: str | None = None
create_only_fields: set[str] = set()
operational_attributes: set[str] = set()
params: dict[str, t.Any] = {}
def __init__(self, module):
self._module = module

View File

@@ -4,12 +4,16 @@
from __future__ import annotations
import typing as t
from ansible.module_utils.common.dict_transformations import dict_merge
from ansible_collections.community.general.plugins.module_utils import cmd_runner_fmt
from ansible_collections.community.general.plugins.module_utils.python_runner import PythonRunner
from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelper
if t.TYPE_CHECKING:
from .cmd_runner_fmt import ArgFormatType
django_std_args = dict(
# environmental options
@@ -32,7 +36,7 @@ _pks = dict(
primary_keys=dict(type="list", elements="str"),
)
_django_std_arg_fmts = dict(
_django_std_arg_fmts: dict[str, ArgFormatType] = dict(
all=cmd_runner_fmt.as_bool("--all"),
app=cmd_runner_fmt.as_opt_val("--app"),
apps=cmd_runner_fmt.as_list(),
@@ -95,11 +99,11 @@ class _DjangoRunner(PythonRunner):
class DjangoModuleHelper(ModuleHelper):
module = {}
django_admin_cmd = None
arg_formats = {}
django_admin_arg_order = ()
_django_args = []
_check_mode_arg = ""
django_admin_cmd: str | None = None
arg_formats: dict[str, ArgFormatType] = {}
django_admin_arg_order: tuple[str, ...] | str = ()
_django_args: list[str] = []
_check_mode_arg: str = ""
def __init__(self):
self.module["argument_spec"], self.arg_formats = self._build_args(self.module.get("argument_spec", {}),

View File

@@ -6,6 +6,8 @@
from __future__ import annotations
import typing as t
from ansible.module_utils.basic import missing_required_lib
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
@@ -15,7 +17,7 @@ from urllib.parse import urljoin
import traceback
def _determine_list_all_kwargs(version):
def _determine_list_all_kwargs(version) -> dict[str, t.Any]:
gitlab_version = LooseVersion(version)
if gitlab_version >= LooseVersion('4.0.0'):
# 4.0.0 removed 'as_list'
@@ -27,14 +29,14 @@ def _determine_list_all_kwargs(version):
return {'as_list': False, 'all': True, 'per_page': 100}
GITLAB_IMP_ERR = None
GITLAB_IMP_ERR: str | None = None
try:
import gitlab
import requests
HAS_GITLAB_PACKAGE = True
list_all_kwargs = _determine_list_all_kwargs(gitlab.__version__)
except Exception:
gitlab = None
gitlab = None # type: ignore
GITLAB_IMP_ERR = traceback.format_exc()
HAS_GITLAB_PACKAGE = False
list_all_kwargs = {}

View File

@@ -20,7 +20,7 @@ from urllib.parse import urlparse
try:
from hashlib import sha1
except ImportError:
import sha as sha1
import sha as sha1 # type: ignore[no-redef]
HASHED_KEY_MAGIC = "|1|"

View File

@@ -5,15 +5,17 @@
from __future__ import annotations
import typing as t
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.mh.exceptions import ModuleHelperException as _MHE
from ansible_collections.community.general.plugins.module_utils.mh.deco import module_fails_on_exception
class ModuleHelperBase(object):
module = None
module: dict[str, t.Any] | None = None # TODO: better spec using t.TypedDict
ModuleHelperException = _MHE
_delegated_to_module = (
_delegated_to_module: tuple[str, ...] = (
'check_mode', 'get_bin_path', 'warn', 'deprecate', 'debug',
)

View File

@@ -5,13 +5,15 @@
from __future__ import annotations
import typing as t
from ansible.module_utils.common.text.converters import to_native
class ModuleHelperException(Exception):
def __init__(self, msg, update_output=None, *args, **kwargs):
self.msg = to_native(msg or f"Module failed with exception: {self}")
def __init__(self, msg: str, update_output: dict[str, t.Any] | None = None, *args, **kwargs):
self.msg: str = to_native(msg or f"Module failed with exception: {self}")
if update_output is None:
update_output = {}
self.update_output = update_output
self.update_output: dict[str, t.Any] = update_output
super(ModuleHelperException, self).__init__(*args)

View File

@@ -7,8 +7,8 @@ from __future__ import annotations
class StateMixin(object):
state_param = 'state'
default_state = None
state_param: str = 'state'
default_state: str | None = None
def _state(self):
state = self.module.params.get(self.state_param)

View File

@@ -5,6 +5,7 @@
from __future__ import annotations
import typing as t
from ansible.module_utils.common.dict_transformations import dict_merge
@@ -13,13 +14,16 @@ from ansible_collections.community.general.plugins.module_utils.mh.base import M
from ansible_collections.community.general.plugins.module_utils.mh.mixins.state import StateMixin
from ansible_collections.community.general.plugins.module_utils.mh.mixins.deprecate_attrs import DeprecateAttrsMixin
if t.TYPE_CHECKING:
from collections.abc import Sequence
class ModuleHelper(DeprecateAttrsMixin, ModuleHelperBase):
facts_name = None
output_params = ()
diff_params = ()
change_params = ()
facts_params = ()
facts_name: str | None = None
output_params: Sequence[str] = ()
diff_params: Sequence[str] = ()
change_params: Sequence[str] = ()
facts_params: Sequence[str] = ()
def __init__(self, module=None):
super(ModuleHelper, self).__init__(module)

View File

@@ -19,12 +19,11 @@ from ansible_collections.community.general.plugins.module_utils.datetime import
now,
)
SCALEWAY_SECRET_IMP_ERR = None
SCALEWAY_SECRET_IMP_ERR: str | None = None
try:
from passlib.hash import argon2
HAS_SCALEWAY_SECRET_PACKAGE = True
except Exception:
argon2 = None
SCALEWAY_SECRET_IMP_ERR = traceback.format_exc()
HAS_SCALEWAY_SECRET_PACKAGE = False

View File

@@ -53,7 +53,7 @@ __all__ = [
]
_singletons = {}
_singletons: dict[str, object] = {}
def ldap_module():
@@ -61,7 +61,7 @@ def ldap_module():
return orig_ldap
def _singleton(name, constructor):
def _singleton(name: str, constructor):
if name in _singletons:
return _singletons[name]
_singletons[name] = constructor()

View File

@@ -129,6 +129,7 @@ from ansible.module_utils.basic import (
)
from ansible.module_utils.common.text.converters import to_native
RPM_PYTHON_IMPORT_ERROR: str | None
try:
import rpm
except ImportError:

View File

@@ -114,14 +114,7 @@ EXAMPLES = r"""
msg: Task completed ... with feeling.
"""
try:
from html import escape as html_escape
except ImportError:
# Python-3.2 or later
import cgi
def html_escape(text, quote=True):
return cgi.escape(text, quote)
from html import escape as html_escape
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.urls import fetch_url

View File

@@ -166,10 +166,11 @@ def main():
class Crypttab(object):
_lines = []
_lines: list[str]
def __init__(self, path):
self.path = path
self._lines = []
if not os.path.exists(path):
if not os.path.exists(os.path.dirname(path)):
os.makedirs(os.path.dirname(path))

View File

@@ -201,16 +201,16 @@ class Device(object):
class Filesystem(object):
MKFS = None
MKFS_FORCE_FLAGS = []
MKFS_SET_UUID_OPTIONS = None
MKFS_SET_UUID_EXTRA_OPTIONS = []
INFO = None
GROW = None
GROW_MAX_SPACE_FLAGS = []
MKFS: str | None = None
MKFS_FORCE_FLAGS: list[str] | None = []
MKFS_SET_UUID_OPTIONS: list[str] | None = None
MKFS_SET_UUID_EXTRA_OPTIONS: list[str] | None = []
INFO: str | None = None
GROW: str | None = None
GROW_MAX_SPACE_FLAGS: list[str] | None = []
GROW_MOUNTPOINT_ONLY = False
CHANGE_UUID = None
CHANGE_UUID_OPTION = None
CHANGE_UUID: str | None = None
CHANGE_UUID_OPTION: str | None = None
CHANGE_UUID_OPTION_HAS_ARG = True
LANG_ENV = {'LANG': 'C', 'LC_ALL': 'C', 'LC_MESSAGES': 'C'}

View File

@@ -273,6 +273,7 @@ from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.basic import jsonify
from ansible.module_utils.common.text.formatters import human_to_bytes
CRYPT_IMPORT_ERROR: str | None
try:
import crypt
except ImportError:
@@ -282,6 +283,7 @@ else:
HAS_CRYPT = True
CRYPT_IMPORT_ERROR = None
LEGACYCRYPT_IMPORT_ERROR: str | None
try:
import legacycrypt
if not HAS_CRYPT:

View File

@@ -112,7 +112,9 @@ from ansible.module_utils.common.text.converters import to_native
with deps.declare("passlib"):
from passlib.apache import HtpasswdFile, htpasswd_context
# Apparently the type infos don't know htpasswd_context, which *does* exist
# (but isn't mentioned in the documentation for some reason)
from passlib.apache import HtpasswdFile, htpasswd_context # type: ignore[attr-defined]
from passlib.context import CryptContext

View File

@@ -164,7 +164,7 @@ IS_PYTHON_2 = sys.version_info[0] <= 2
class JenkinsNode:
def __init__(self, module):
def __init__(self, module: AnsibleModule) -> None:
self.module = module
self.name = module.params['name']
@@ -174,7 +174,7 @@ class JenkinsNode:
self.url = module.params['url']
self.num_executors = module.params['num_executors']
self.labels = module.params['labels']
self.offline_message = module.params['offline_message'] # type: str | None
self.offline_message: str | None = module.params['offline_message']
if self.offline_message is not None:
self.offline_message = self.offline_message.strip()

View File

@@ -74,7 +74,7 @@ class PacemakerInfo(ModuleHelper):
"constraint_info": "constraint",
"property_info": "property"
}
output_params = info_vars.keys()
output_params = list(info_vars.keys())
def __init_module__(self):
self.runner = pacemaker_runner(self.module)

View File

@@ -209,6 +209,7 @@ import re
import traceback
from ansible.module_utils.basic import AnsibleModule, missing_required_lib, human_to_bytes
XMLTODICT_LIBRARY_IMPORT_ERROR: str | None
try:
import xmltodict
except ImportError:

View File

@@ -347,7 +347,7 @@ RHEV_UNAVAILABLE = 2
RHEV_TYPE_OPTS = ['desktop', 'host', 'server']
STATE_OPTS = ['absent', 'cd', 'down', 'info', 'ping', 'present', 'restart', 'up']
msg = []
msg: list[str] = []
changed = False
failed = False
@@ -1258,7 +1258,7 @@ def setChanged():
changed = True
def setMsg(message):
def setMsg(message: str) -> None:
msg.append(message)

View File

@@ -328,6 +328,7 @@ from ansible_collections.community.general.plugins.module_utils.univention_umc i
base_dn,
)
CRYPT_IMPORT_ERROR: str | None
try:
import crypt
except ImportError:
@@ -337,6 +338,7 @@ else:
HAS_CRYPT = True
CRYPT_IMPORT_ERROR = None
LEGACYCRYPT_IMPORT_ERROR: str | None
try:
import legacycrypt
if not HAS_CRYPT:

View File

@@ -10,8 +10,9 @@ from collections.abc import Mapping
try:
# Introduced with Data Tagging (https://github.com/ansible/ansible/pull/84621):
from ansible.module_utils.datatag import native_type_name as _native_type_name
HAS_NATIVE_TYPE_NAME = True
except ImportError:
_native_type_name = None
HAS_NATIVE_TYPE_NAME = False
def _atype(data, alias, *, use_native_type: bool = False):
@@ -19,7 +20,7 @@ def _atype(data, alias, *, use_native_type: bool = False):
Returns the name of the type class.
"""
if use_native_type and _native_type_name:
if use_native_type and HAS_NATIVE_TYPE_NAME:
data_type = _native_type_name(data)
else:
data_type = type(data).__name__

View File

@@ -43,7 +43,7 @@ from ansible.plugins.loader import action_loader, module_loader
try:
from ansible.errors import AnsiblePluginRemovedError
except ImportError:
AnsiblePluginRemovedError = Exception
AnsiblePluginRemovedError = Exception # type: ignore
def a_module(term):

View File

@@ -65,6 +65,7 @@ _value:
from ansible.errors import AnsibleError
ANOTHER_LIBRARY_IMPORT_ERROR: ImportError | None
try:
from fqdn import FQDN
except ImportError as imp_exc: