diff --git a/changelogs/fragments/53289-module-option-int-long.yml b/changelogs/fragments/53289-module-option-int-long.yml new file mode 100644 index 00000000000..9492dc8caf8 --- /dev/null +++ b/changelogs/fragments/53289-module-option-int-long.yml @@ -0,0 +1,3 @@ +bugfixes: +- "If large integers are passed as options to modules under Python 2, module argument + parsing will reject them as they are of type ``long`` and not of type ``int``." diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index 9827fa889e0..d63b61bfe36 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -1864,7 +1864,7 @@ class AnsibleModule(object): raise TypeError('%s cannot be converted to a bool' % type(value)) def _check_type_int(self, value): - if isinstance(value, int): + if isinstance(value, integer_types): return value if isinstance(value, string_types): diff --git a/test/units/module_utils/basic/test_argument_spec.py b/test/units/module_utils/basic/test_argument_spec.py index a402eb2aadd..1170b48e887 100644 --- a/test/units/module_utils/basic/test_argument_spec.py +++ b/test/units/module_utils/basic/test_argument_spec.py @@ -14,7 +14,7 @@ import pytest from units.compat.mock import MagicMock, patch from ansible.module_utils import basic -from ansible.module_utils.six import string_types +from ansible.module_utils.six import string_types, integer_types from ansible.module_utils.six.moves import builtins from units.mock.procenv import ModuleTestCase, swap_stdin_and_argv @@ -24,6 +24,8 @@ MOCK_VALIDATOR_FAIL = MagicMock(side_effect=TypeError("bad conversion")) VALID_SPECS = ( # Simple type=int ({'arg': {'type': 'int'}}, {'arg': 42}, 42), + # Simple type=int with a large value (will be of type long under Python 2) + ({'arg': {'type': 'int'}}, {'arg': 18765432109876543210}, 18765432109876543210), # Simple type=list, elements=int ({'arg': {'type': 'list', 'elements': 'int'}}, {'arg': [42, 32]}, [42, 32]), # Type=int with conversion from string @@ -183,7 +185,10 @@ def test_validator_basic_types(argspec, expected, stdin): am = basic.AnsibleModule(argspec) if 'type' in argspec['arg']: - type_ = getattr(builtins, argspec['arg']['type']) + if argspec['arg']['type'] == 'int': + type_ = integer_types + else: + type_ = getattr(builtins, argspec['arg']['type']) else: type_ = str @@ -191,14 +196,14 @@ def test_validator_basic_types(argspec, expected, stdin): assert am.params['arg'] == expected -@pytest.mark.parametrize('stdin', [{'arg': 42}], indirect=['stdin']) +@pytest.mark.parametrize('stdin', [{'arg': 42}, {'arg': 18765432109876543210}], indirect=['stdin']) def test_validator_function(mocker, stdin): # Type is a callable MOCK_VALIDATOR_SUCCESS = mocker.MagicMock(return_value=27) argspec = {'arg': {'type': MOCK_VALIDATOR_SUCCESS}} am = basic.AnsibleModule(argspec) - assert isinstance(am.params['arg'], int) + assert isinstance(am.params['arg'], integer_types) assert am.params['arg'] == 27