diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index 582aa35e3b..b1af1164b4 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -69,9 +69,44 @@ import errno from itertools import repeat try: - from itertools import imap # Python 2 + # Python 2 + from itertools import imap except ImportError: - imap = map # Python 3 + # Python 3 + imap = map + +try: + # Python 2 + basestring +except NameError: + # Python 3 + basestring = str + +try: + # Python 2 + unicode +except NameError: + # Python 3 + unicode = str + +try: + # Python 2.6+ + bytes +except NameError: + # Python 2.4 + bytes = str + +try: + dict.iteritems +except AttributeError: + # Python 3 + def iteritems(d): + return d.items() +else: + # Python 2 + def iteritems(d): # Python 2 + return d.iteritems() + try: import json @@ -283,7 +318,7 @@ def json_dict_unicode_to_bytes(d, encoding='utf-8'): if isinstance(d, unicode): return d.encode(encoding) elif isinstance(d, dict): - return dict(imap(json_dict_unicode_to_bytes, d.iteritems(), repeat(encoding))) + return dict(imap(json_dict_unicode_to_bytes, iteritems(d), repeat(encoding))) elif isinstance(d, list): return list(imap(json_dict_unicode_to_bytes, d, repeat(encoding))) elif isinstance(d, tuple): @@ -298,10 +333,10 @@ def json_dict_bytes_to_unicode(d, encoding='utf-8'): and dict container types (the containers that the json module returns) ''' - if isinstance(d, str): + if isinstance(d, bytes): return unicode(d, encoding) elif isinstance(d, dict): - return dict(imap(json_dict_bytes_to_unicode, d.iteritems(), repeat(encoding))) + return dict(imap(json_dict_bytes_to_unicode, iteritems(d), repeat(encoding))) elif isinstance(d, list): return list(imap(json_dict_bytes_to_unicode, d, repeat(encoding))) elif isinstance(d, tuple): @@ -398,7 +433,7 @@ class AnsibleModule(object): self.aliases = {} if add_file_common_args: - for k, v in FILE_COMMON_ARGUMENTS.iteritems(): + for k, v in FILE_COMMON_ARGUMENTS.items(): if k not in self.argument_spec: self.argument_spec[k] = v @@ -934,7 +969,7 @@ class AnsibleModule(object): def _handle_aliases(self): aliases_results = {} #alias:canon - for (k,v) in self.argument_spec.iteritems(): + for (k,v) in self.argument_spec.items(): self._legal_inputs.append(k) aliases = v.get('aliases', None) default = v.get('default', None) @@ -955,7 +990,7 @@ class AnsibleModule(object): return aliases_results def _check_arguments(self, check_invalid_arguments): - for (k,v) in self.params.iteritems(): + for (k,v) in self.params.items(): if k == '_ansible_check_mode' and v: if not self.supports_check_mode: @@ -1007,7 +1042,7 @@ class AnsibleModule(object): def _check_required_arguments(self): ''' ensure all required arguments are present ''' missing = [] - for (k,v) in self.argument_spec.iteritems(): + for (k,v) in self.argument_spec.items(): required = v.get('required', False) if required and k not in self.params: missing.append(k) @@ -1030,7 +1065,7 @@ class AnsibleModule(object): def _check_argument_values(self): ''' ensure all arguments have the requested values, and there are no stray arguments ''' - for (k,v) in self.argument_spec.iteritems(): + for (k,v) in self.argument_spec.items(): choices = v.get('choices',None) if choices is None: continue @@ -1173,7 +1208,7 @@ class AnsibleModule(object): def _check_argument_types(self): ''' ensure all arguments have the requested type ''' - for (k, v) in self.argument_spec.iteritems(): + for (k, v) in self.argument_spec.items(): wanted = v.get('type', None) if wanted is None: continue @@ -1192,7 +1227,7 @@ class AnsibleModule(object): self.fail_json(msg="argument %s is of type %s and we were unable to convert to %s" % (k, type(value), wanted)) def _set_defaults(self, pre=True): - for (k,v) in self.argument_spec.iteritems(): + for (k,v) in self.argument_spec.items(): default = v.get('default', None) if pre == True: # this prevents setting defaults on required items diff --git a/test/units/module_utils/test_basic.py b/test/units/module_utils/test_basic.py index 1a2fbefd43..78116847de 100644 --- a/test/units/module_utils/test_basic.py +++ b/test/units/module_utils/test_basic.py @@ -20,10 +20,9 @@ from __future__ import (absolute_import, division) __metaclass__ = type -import __builtin__ import errno -from nose.tools import timed +from six.moves import builtins from ansible.compat.tests import unittest from ansible.compat.tests.mock import patch, MagicMock, mock_open, Mock @@ -37,16 +36,16 @@ class TestModuleUtilsBasic(unittest.TestCase): pass def test_module_utils_basic_imports(self): - realimport = __builtin__.__import__ + realimport = builtins.__import__ def _mock_import(name, *args, **kwargs): if name == 'json': raise ImportError() realimport(name, *args, **kwargs) - with patch.object(__builtin__, '__import__', _mock_import, create=True) as m: + with patch.object(builtins, '__import__', _mock_import, create=True) as m: m('ansible.module_utils.basic') - __builtin__.__import__('ansible.module_utils.basic') + builtins.__import__('ansible.module_utils.basic') def test_module_utils_basic_get_platform(self): with patch('platform.system', return_value='foo'): @@ -510,7 +509,7 @@ class TestModuleUtilsBasic(unittest.TestCase): m = mock_open() m.side_effect = OSError - with patch('__builtin__.open', m, create=True): + with patch.object(builtins, 'open', m, create=True): self.assertEqual(am.is_special_selinux_path('/some/path/that/should/be/nfs'), (False, None)) mount_data = [ @@ -524,7 +523,7 @@ class TestModuleUtilsBasic(unittest.TestCase): m = mock_open(read_data=''.join(mount_data)) m.return_value.readlines.return_value = mount_data - with patch('__builtin__.open', m, create=True): + with patch.object(builtins, 'open', m, create=True): self.assertEqual(am.is_special_selinux_path('/some/random/path'), (False, None)) self.assertEqual(am.is_special_selinux_path('/some/path/that/should/be/nfs'), (True, ['foo_u', 'foo_r', 'foo_t', 's0'])) self.assertEqual(am.is_special_selinux_path('/weird/random/fstype/path'), (True, ['foo_u', 'foo_r', 'foo_t', 's0'])) @@ -537,8 +536,8 @@ class TestModuleUtilsBasic(unittest.TestCase): argument_spec = dict(), ) - self.assertEqual(am._to_filesystem_str(u'foo'), 'foo') - self.assertEqual(am._to_filesystem_str(u'föö'), 'f\xc3\xb6\xc3\xb6') + self.assertEqual(am._to_filesystem_str(u'foo'), b'foo') + self.assertEqual(am._to_filesystem_str(u'föö'), b'f\xc3\xb6\xc3\xb6') def test_module_utils_basic_ansible_module_user_and_group(self): from ansible.module_utils import basic @@ -603,7 +602,7 @@ class TestModuleUtilsBasic(unittest.TestCase): with patch.dict('sys.modules', {'selinux': basic.selinux}): with patch('selinux.lsetfilecon', return_value=0) as m: self.assertEqual(am.set_context_if_different('/path/to/file', ['foo_u', 'foo_r', 'foo_t', 's0'], False), True) - m.assert_called_with('/path/to/file', 'foo_u:foo_r:foo_t:s0') + m.assert_called_with(b'/path/to/file', 'foo_u:foo_r:foo_t:s0') m.reset_mock() am.check_mode = True self.assertEqual(am.set_context_if_different('/path/to/file', ['foo_u', 'foo_r', 'foo_t', 's0'], False), True) @@ -620,7 +619,7 @@ class TestModuleUtilsBasic(unittest.TestCase): with patch('selinux.lsetfilecon', return_value=0) as m: self.assertEqual(am.set_context_if_different('/path/to/file', ['foo_u', 'foo_r', 'foo_t', 's0'], False), True) - m.assert_called_with('/path/to/file', 'sp_u:sp_r:sp_t:s0') + m.assert_called_with(b'/path/to/file', 'sp_u:sp_r:sp_t:s0') delattr(basic, 'selinux')