Provide own getargspec for roles and modules with Python 3.11

Python 3.11 dropped compat inspect.getargspec. As the roles and modules
need to support Python2 and Python3, the code for getargspec has been
copied from Python 3.10 and is added as a fallback as soon as getargspec
can not be imported from inspect. The copied getargspec is using
getfullargspec internally.

Fixes: #855 (Python's inspect.getargspec was removed in version 3.11)
This commit is contained in:
Thomas Woerner
2022-07-06 11:21:08 +02:00
parent 90f6e14c40
commit 07b056ad25
16 changed files with 126 additions and 51 deletions

View File

@@ -29,7 +29,7 @@ __all__ = ["gssapi", "netaddr", "api", "ipalib_errors", "Env",
"DEFAULT_CONFIG", "LDAP_GENERALIZED_TIME_FORMAT", "DEFAULT_CONFIG", "LDAP_GENERALIZED_TIME_FORMAT",
"kinit_password", "kinit_keytab", "run", "DN", "VERSION", "kinit_password", "kinit_keytab", "run", "DN", "VERSION",
"paths", "get_credentials_if_valid", "Encoding", "paths", "get_credentials_if_valid", "Encoding",
"load_pem_x509_certificate", "DNSName"] "load_pem_x509_certificate", "DNSName", "getargspec"]
import sys import sys
@@ -48,7 +48,28 @@ else:
import gssapi import gssapi
from datetime import datetime from datetime import datetime
from contextlib import contextmanager from contextlib import contextmanager
import inspect
# Import getargspec from inspect or provide own getargspec for
# Python 2 compatibility with Python 3.11+.
try:
from inspect import getargspec
except ImportError:
from collections import namedtuple
from inspect import getfullargspec
# The code is copied from Python 3.10 inspect.py
# Authors: Ka-Ping Yee <ping@lfw.org>
# Yury Selivanov <yselivanov@sprymix.com>
ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
def getargspec(func):
args, varargs, varkw, defaults, kwonlyargs, _kwonlydefaults, \
ann = getfullargspec(func)
if kwonlyargs or ann:
raise ValueError(
"Function has keyword-only parameters or annotations"
", use inspect.signature() API which can support them")
return ArgSpec(args, varargs, varkw, defaults)
# ansible-freeipa requires locale to be C, IPA requires utf-8. # ansible-freeipa requires locale to be C, IPA requires utf-8.
os.environ["LANGUAGE"] = "C" os.environ["LANGUAGE"] = "C"
@@ -1228,7 +1249,7 @@ else:
elif result_handler is not None: elif result_handler is not None:
if "errors" not in handlers_user_args: if "errors" not in handlers_user_args:
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec(result_handler) argspec = getargspec(result_handler)
if "errors" in argspec.args: if "errors" in argspec.args:
handlers_user_args["errors"] = _errors handlers_user_args["errors"] = _errors

View File

@@ -75,7 +75,6 @@ subject_base:
''' '''
import os import os
import inspect
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ansible_ipa_client import ( from ansible.module_utils.ansible_ipa_client import (
@@ -83,7 +82,7 @@ from ansible.module_utils.ansible_ipa_client import (
paths, x509, NUM_VERSION, serialization, certdb, api, paths, x509, NUM_VERSION, serialization, certdb, api,
delete_persistent_client_session_data, write_tmp_file, delete_persistent_client_session_data, write_tmp_file,
ipa_generate_password, CalledProcessError, errors, disable_ra, DN, ipa_generate_password, CalledProcessError, errors, disable_ra, DN,
CLIENT_INSTALL_ERROR, logger CLIENT_INSTALL_ERROR, logger, getargspec
) )
@@ -134,7 +133,7 @@ def main():
# Add CA certs to a temporary NSS database # Add CA certs to a temporary NSS database
try: try:
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec(tmp_db.create_db) argspec = getargspec(tmp_db.create_db)
# pylint: enable=deprecated-method # pylint: enable=deprecated-method
if "password_filename" not in argspec.args: if "password_filename" not in argspec.args:
tmp_db.create_db() tmp_db.create_db()

View File

@@ -57,11 +57,10 @@ EXAMPLES = '''
RETURN = ''' RETURN = '''
''' '''
import inspect
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ansible_ipa_client import ( from ansible.module_utils.ansible_ipa_client import (
setup_logging, options, sysrestore, paths, configure_nisdomain setup_logging, options, sysrestore, paths, configure_nisdomain,
getargspec
) )
@@ -83,7 +82,7 @@ def main():
statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE) statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE)
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec(configure_nisdomain) argspec = getargspec(configure_nisdomain)
# pylint: enable=deprecated-method # pylint: enable=deprecated-method
if "statestore" not in argspec.args: if "statestore" not in argspec.args:
# NUM_VERSION < 40500: # NUM_VERSION < 40500:

View File

@@ -141,7 +141,6 @@ RETURN = '''
import os import os
import time import time
import inspect
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ansible_ipa_client import ( from ansible.module_utils.ansible_ipa_client import (
@@ -151,7 +150,7 @@ from ansible.module_utils.ansible_ipa_client import (
get_certs_from_ldap, DN, certstore, x509, logger, certdb, get_certs_from_ldap, DN, certstore, x509, logger, certdb,
CalledProcessError, tasks, client_dns, configure_certmonger, services, CalledProcessError, tasks, client_dns, configure_certmonger, services,
update_ssh_keys, save_state, configure_ldap_conf, configure_nslcd_conf, update_ssh_keys, save_state, configure_ldap_conf, configure_nslcd_conf,
configure_openldap_conf, hardcode_ldap_server configure_openldap_conf, hardcode_ldap_server, getargspec
) )
@@ -323,7 +322,7 @@ def main():
pass pass
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec_save_state = inspect.getargspec(save_state) argspec_save_state = getargspec(save_state)
# Name Server Caching Daemon. Disable for SSSD, use otherwise # Name Server Caching Daemon. Disable for SSSD, use otherwise
# (if installed) # (if installed)
@@ -387,7 +386,7 @@ def main():
if not options.no_ac: if not options.no_ac:
# Modify nsswitch/pam stack # Modify nsswitch/pam stack
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec(tasks.modify_nsswitch_pam_stack) argspec = getargspec(tasks.modify_nsswitch_pam_stack)
if "sudo" in argspec.args: if "sudo" in argspec.args:
tasks.modify_nsswitch_pam_stack( tasks.modify_nsswitch_pam_stack(
sssd=options.sssd, sssd=options.sssd,

View File

@@ -66,13 +66,11 @@ EXAMPLES = '''
RETURN = ''' RETURN = '''
''' '''
import inspect
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ansible_ipa_client import ( from ansible.module_utils.ansible_ipa_client import (
setup_logging, setup_logging,
options, sysrestore, paths, sync_time, logger, ipadiscovery, options, sysrestore, paths, sync_time, logger, ipadiscovery,
timeconf timeconf, getargspec
) )
@@ -114,7 +112,7 @@ def main():
if options.conf_ntp: if options.conf_ntp:
# Attempt to configure and sync time with NTP server (chrony). # Attempt to configure and sync time with NTP server (chrony).
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec(sync_time) argspec = getargspec(sync_time)
# pylint: enable=deprecated-method # pylint: enable=deprecated-method
if "options" not in argspec.args: if "options" not in argspec.args:
synced_ntp = sync_time(options.ntp_servers, options.ntp_pool, synced_ntp = sync_time(options.ntp_servers, options.ntp_pool,

View File

@@ -197,7 +197,6 @@ nosssd_files:
import os import os
import socket import socket
import inspect
try: try:
from ansible.module_utils.six.moves.configparser import RawConfigParser from ansible.module_utils.six.moves.configparser import RawConfigParser
@@ -212,7 +211,7 @@ from ansible.module_utils.ansible_ipa_client import (
CLIENT_INSTALL_ERROR, tasks, check_ldap_conf, timeconf, constants, CLIENT_INSTALL_ERROR, tasks, check_ldap_conf, timeconf, constants,
validate_hostname, nssldap_exists, gssapi, remove_file, validate_hostname, nssldap_exists, gssapi, remove_file,
check_ip_addresses, ipadiscovery, print_port_conf_info, check_ip_addresses, ipadiscovery, print_port_conf_info,
IPA_PYTHON_VERSION IPA_PYTHON_VERSION, getargspec
) )
@@ -344,7 +343,7 @@ def main():
if options.realm_name: if options.realm_name:
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec(validate_domain_name) argspec = getargspec(validate_domain_name)
if "entity" in argspec.args: if "entity" in argspec.args:
# NUM_VERSION >= 40690: # NUM_VERSION >= 40690:
validate_domain_name(options.realm_name, entity="realm") validate_domain_name(options.realm_name, entity="realm")

View File

@@ -46,7 +46,7 @@ __all__ = ["gssapi", "version", "ipadiscovery", "api", "errors", "x509",
"configure_nslcd_conf", "configure_ssh_config", "configure_nslcd_conf", "configure_ssh_config",
"configure_sshd_config", "configure_automount", "configure_sshd_config", "configure_automount",
"configure_firefox", "sync_time", "check_ldap_conf", "configure_firefox", "sync_time", "check_ldap_conf",
"sssd_enable_ifp"] "sssd_enable_ifp", "getargspec"]
import sys import sys
@@ -110,10 +110,31 @@ else:
# IPA version >= 4.4 # IPA version >= 4.4
# import sys # import sys
import inspect
import gssapi import gssapi
import logging import logging
# Import getargspec from inspect or provide own getargspec for
# Python 2 compatibility with Python 3.11+.
try:
from inspect import getargspec
except ImportError:
from collections import namedtuple
from inspect import getfullargspec
# The code is copied from Python 3.10 inspect.py
# Authors: Ka-Ping Yee <ping@lfw.org>
# Yury Selivanov <yselivanov@sprymix.com>
ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
def getargspec(func):
args, varargs, varkw, defaults, kwonlyargs, _kwonlydefaults, \
ann = getfullargspec(func)
if kwonlyargs or ann:
raise ValueError(
"Function has keyword-only parameters or annotations"
", use inspect.signature() API which can support them")
return ArgSpec(args, varargs, varkw, defaults)
from ipapython import version from ipapython import version
try: try:
from ipaclient.install import ipadiscovery from ipaclient.install import ipadiscovery
@@ -200,7 +221,7 @@ else:
sys.path.remove(temp_dir) sys.path.remove(temp_dir)
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec( argspec = getargspec(
ipa_client_install.configure_krb5_conf) ipa_client_install.configure_krb5_conf)
if argspec.keywords is None: if argspec.keywords is None:
def configure_krb5_conf( def configure_krb5_conf(
@@ -240,7 +261,7 @@ else:
create_ipa_nssdb = certdb.create_ipa_nssdb create_ipa_nssdb = certdb.create_ipa_nssdb
argspec = \ argspec = \
inspect.getargspec(ipa_client_install.configure_nisdomain) getargspec(ipa_client_install.configure_nisdomain)
if len(argspec.args) == 3: if len(argspec.args) == 3:
configure_nisdomain = ipa_client_install.configure_nisdomain configure_nisdomain = ipa_client_install.configure_nisdomain
else: else:

View File

@@ -96,13 +96,13 @@ RETURN = '''
''' '''
import os import os
import inspect
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ansible_ipa_replica import ( from ansible.module_utils.ansible_ipa_replica import (
AnsibleModuleLog, setup_logging, installer, DN, paths, AnsibleModuleLog, setup_logging, installer, DN, paths,
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize, gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
gen_ReplicaConfig, gen_remote_api, redirect_stdout, custodiainstance gen_ReplicaConfig, gen_remote_api, redirect_stdout, custodiainstance,
getargspec
) )
@@ -200,7 +200,7 @@ def main():
ansible_log.debug("-- CUSTODIA IMPORT DM PASSWORD --") ansible_log.debug("-- CUSTODIA IMPORT DM PASSWORD --")
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec(custodia.import_dm_password) argspec = getargspec(custodia.import_dm_password)
# pylint: enable=deprecated-method # pylint: enable=deprecated-method
if "master_host_name" in argspec.args: if "master_host_name" in argspec.args:
custodia.import_dm_password(config.master_host_name) custodia.import_dm_password(config.master_host_name)

View File

@@ -149,7 +149,6 @@ RETURN = '''
''' '''
import os import os
import inspect
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ansible_ipa_replica import ( from ansible.module_utils.ansible_ipa_replica import (
@@ -157,7 +156,8 @@ from ansible.module_utils.ansible_ipa_replica import (
ansible_module_get_parsed_ip_addresses, ansible_module_get_parsed_ip_addresses,
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize, gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
gen_ReplicaConfig, gen_remote_api, redirect_stdout, ipaldap, gen_ReplicaConfig, gen_remote_api, redirect_stdout, ipaldap,
install_replica_ds, install_dns_records, ntpinstance, ScriptError install_replica_ds, install_dns_records, ntpinstance, ScriptError,
getargspec
) )
@@ -317,7 +317,7 @@ def main():
# Configure dirsrv # Configure dirsrv
with redirect_stdout(ansible_log): with redirect_stdout(ansible_log):
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec(install_replica_ds) argspec = getargspec(install_replica_ds)
# pylint: enable=deprecated-method # pylint: enable=deprecated-method
if "promote" in argspec.args: if "promote" in argspec.args:
ds = install_replica_ds(config, options, ca_enabled, ds = install_replica_ds(config, options, ca_enabled,
@@ -343,7 +343,7 @@ def main():
# pylint: enable=deprecated-method # pylint: enable=deprecated-method
# Always try to install DNS records # Always try to install DNS records
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec(install_dns_records) argspec = getargspec(install_dns_records)
# pylint: enable=deprecated-method # pylint: enable=deprecated-method
if "fstore" not in argspec.args: if "fstore" not in argspec.args:
install_dns_records(config, options, remote_api) install_dns_records(config, options, remote_api)

View File

@@ -90,14 +90,13 @@ RETURN = '''
''' '''
import os import os
import inspect
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ansible_ipa_replica import ( from ansible.module_utils.ansible_ipa_replica import (
AnsibleModuleLog, setup_logging, installer, DN, paths, sysrestore, AnsibleModuleLog, setup_logging, installer, DN, paths, sysrestore,
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize, gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout, create_ipa_conf, gen_ReplicaConfig, gen_remote_api, api, redirect_stdout, create_ipa_conf,
install_http install_http, getargspec
) )
@@ -203,7 +202,7 @@ def main():
master=config.master_host_name) master=config.master_host_name)
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec(install_http) argspec = getargspec(install_http)
# pylint: enable=deprecated-method # pylint: enable=deprecated-method
if "promote" in argspec.args: if "promote" in argspec.args:
install_http( install_http(

View File

@@ -78,13 +78,12 @@ RETURN = '''
''' '''
import os import os
import inspect
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ansible_ipa_replica import ( from ansible.module_utils.ansible_ipa_replica import (
AnsibleModuleLog, setup_logging, installer, DN, paths, sysrestore, AnsibleModuleLog, setup_logging, installer, DN, paths, sysrestore,
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize, gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
gen_ReplicaConfig, api, redirect_stdout, install_krb gen_ReplicaConfig, api, redirect_stdout, install_krb, getargspec
) )
@@ -162,7 +161,7 @@ def main():
with redirect_stdout(ansible_log): with redirect_stdout(ansible_log):
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec(install_krb) argspec = getargspec(install_krb)
# pylint: enable=deprecated-method # pylint: enable=deprecated-method
if "promote" in argspec.args: if "promote" in argspec.args:
install_krb( install_krb(

View File

@@ -136,7 +136,6 @@ RETURN = '''
''' '''
import os import os
import inspect
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ansible_ipa_replica import ( from ansible.module_utils.ansible_ipa_replica import (
@@ -144,7 +143,7 @@ from ansible.module_utils.ansible_ipa_replica import (
ansible_module_get_parsed_ip_addresses, service, ansible_module_get_parsed_ip_addresses, service,
redirect_stdout, create_ipa_conf, ipautil, redirect_stdout, create_ipa_conf, ipautil,
x509, validate_domain_name, common_check, x509, validate_domain_name, common_check,
IPA_PYTHON_VERSION IPA_PYTHON_VERSION, getargspec
) )
@@ -287,7 +286,7 @@ def main():
# create_ipa_conf has the additional master argument. # create_ipa_conf has the additional master argument.
change_master_for_certmonger = False change_master_for_certmonger = False
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec(create_ipa_conf) argspec = getargspec(create_ipa_conf)
# pylint: enable=deprecated-method # pylint: enable=deprecated-method
if "master" in argspec.args: if "master" in argspec.args:
change_master_for_certmonger = True change_master_for_certmonger = True
@@ -421,7 +420,7 @@ def main():
try: try:
with redirect_stdout(ansible_log): with redirect_stdout(ansible_log):
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec(common_check) argspec = getargspec(common_check)
# pylint: enable=deprecated-method # pylint: enable=deprecated-method
if "skip_mem_check" in argspec.args: if "skip_mem_check" in argspec.args:
common_check(options.no_ntp, options.skip_mem_check, common_check(options.no_ntp, options.skip_mem_check,

View File

@@ -46,7 +46,7 @@ __all__ = ["contextlib", "dnsexception", "dnsresolver", "dnsreversename",
"common_check", "current_domain_level", "common_check", "current_domain_level",
"check_domain_level_is_supported", "promotion_check_ipa_domain", "check_domain_level_is_supported", "promotion_check_ipa_domain",
"SSSDConfig", "CalledProcessError", "timeconf", "ntpinstance", "SSSDConfig", "CalledProcessError", "timeconf", "ntpinstance",
"dnsname", "kernel_keyring", "krbinstance"] "dnsname", "kernel_keyring", "krbinstance", "getargspec"]
import sys import sys
@@ -59,6 +59,28 @@ else:
import logging import logging
from contextlib import contextmanager as contextlib_contextmanager from contextlib import contextmanager as contextlib_contextmanager
# Import getargspec from inspect or provide own getargspec for
# Python 2 compatibility with Python 3.11+.
try:
from inspect import getargspec
except ImportError:
from collections import namedtuple
from inspect import getfullargspec
# The code is copied from Python 3.10 inspect.py
# Authors: Ka-Ping Yee <ping@lfw.org>
# Yury Selivanov <yselivanov@sprymix.com>
ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
def getargspec(func):
args, varargs, varkw, defaults, kwonlyargs, _kwonlydefaults, \
ann = getfullargspec(func)
if kwonlyargs or ann:
raise ValueError(
"Function has keyword-only parameters or annotations"
", use inspect.signature() API which can support them")
return ArgSpec(args, varargs, varkw, defaults)
from ipapython.version import NUM_VERSION, VERSION from ipapython.version import NUM_VERSION, VERSION
if NUM_VERSION < 30201: if NUM_VERSION < 30201:

View File

@@ -53,12 +53,11 @@ EXAMPLES = '''
RETURN = ''' RETURN = '''
''' '''
import inspect
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ansible_ipa_server import ( from ansible.module_utils.ansible_ipa_server import (
AnsibleModuleLog, setup_logging, options, sysrestore, paths, AnsibleModuleLog, setup_logging, options, sysrestore, paths,
redirect_stdout, time_service, sync_time, ntpinstance, timeconf redirect_stdout, time_service, sync_time, ntpinstance, timeconf,
getargspec
) )
@@ -94,7 +93,7 @@ def main():
ansible_module.log("Synchronizing time") ansible_module.log("Synchronizing time")
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec(sync_time) argspec = getargspec(sync_time)
# pylint: enable=deprecated-method # pylint: enable=deprecated-method
if "options" not in argspec.args: if "options" not in argspec.args:
synced_ntp = sync_time(options.ntp_servers, options.ntp_pool, synced_ntp = sync_time(options.ntp_servers, options.ntp_pool,

View File

@@ -212,7 +212,6 @@ RETURN = '''
import os import os
import sys import sys
import inspect
import random import random
from shutil import copyfile from shutil import copyfile
@@ -226,7 +225,7 @@ from ansible.module_utils.ansible_ipa_server import (
read_cache, ca, tasks, check_ldap_conf, timeconf, httpinstance, read_cache, ca, tasks, check_ldap_conf, timeconf, httpinstance,
check_dirsrv, ScriptError, get_fqdn, verify_fqdn, BadHostError, check_dirsrv, ScriptError, get_fqdn, verify_fqdn, BadHostError,
validate_domain_name, load_pkcs12, IPA_PYTHON_VERSION, validate_domain_name, load_pkcs12, IPA_PYTHON_VERSION,
encode_certificate, check_available_memory encode_certificate, check_available_memory, getargspec
) )
from ansible.module_utils import six from ansible.module_utils import six
@@ -944,7 +943,7 @@ def main():
realm_name = options.realm_name.upper() realm_name = options.realm_name.upper()
# pylint: disable=deprecated-method # pylint: disable=deprecated-method
argspec = inspect.getargspec(validate_domain_name) argspec = getargspec(validate_domain_name)
# pylint: enable=deprecated-method # pylint: enable=deprecated-method
if "entity" in argspec.args: if "entity" in argspec.args:
# NUM_VERSION >= 40690: # NUM_VERSION >= 40690:

View File

@@ -41,7 +41,7 @@ __all__ = ["IPAChangeConf", "certmonger", "sysrestore", "root_logger",
"adtrustinstance", "IPAAPI_USER", "sync_time", "PKIIniLoader", "adtrustinstance", "IPAAPI_USER", "sync_time", "PKIIniLoader",
"default_subject_base", "default_ca_subject_dn", "default_subject_base", "default_ca_subject_dn",
"check_ldap_conf", "encode_certificate", "decode_certificate", "check_ldap_conf", "encode_certificate", "decode_certificate",
"check_available_memory"] "check_available_memory", "getargspec"]
import sys import sys
@@ -58,6 +58,28 @@ else:
from ansible.module_utils import six from ansible.module_utils import six
import base64 import base64
# Import getargspec from inspect or provide own getargspec for
# Python 2 compatibility with Python 3.11+.
try:
from inspect import getargspec
except ImportError:
from collections import namedtuple
from inspect import getfullargspec
# The code is copied from Python 3.10 inspect.py
# Authors: Ka-Ping Yee <ping@lfw.org>
# Yury Selivanov <yselivanov@sprymix.com>
ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
def getargspec(func):
args, varargs, varkw, defaults, kwonlyargs, _kwonlydefaults, \
ann = getfullargspec(func)
if kwonlyargs or ann:
raise ValueError(
"Function has keyword-only parameters or annotations"
", use inspect.signature() API which can support them")
return ArgSpec(args, varargs, varkw, defaults)
from ipapython.version import NUM_VERSION, VERSION from ipapython.version import NUM_VERSION, VERSION
if NUM_VERSION < 30201: if NUM_VERSION < 30201: