From 5abd97149cf428dd6f7be7874a8b1e8cfad73616 Mon Sep 17 00:00:00 2001 From: Iury Gregory Melo Ferreira Date: Fri, 13 Dec 2019 15:44:46 +0100 Subject: [PATCH] Py2 - Remove six, mock and future Since we've dropped support for Python 2.7, it's time to look at the bright future that Python 3.x will bring and stop forcing compatibility with older versions. This patch removes the six library , switches the mock library to unittest.mock and removes future. Change-Id: I71b11f13691d13df162b203f7ea5979b30c272df --- ansible/action_plugins/tenks_update_state.py | 18 ++-- ansible/filter_plugins/tenks.py | 3 +- .../library/wait_for_resources.py | 5 +- tests/test_tenks_update_state.py | 17 +--- tests/test_tenks_wait_for_resources.py | 90 +++++++++---------- tests/utils.py | 12 +-- 6 files changed, 56 insertions(+), 89 deletions(-) diff --git a/ansible/action_plugins/tenks_update_state.py b/ansible/action_plugins/tenks_update_state.py index 6b0635d..947d0c7 100644 --- a/ansible/action_plugins/tenks_update_state.py +++ b/ansible/action_plugins/tenks_update_state.py @@ -13,8 +13,6 @@ # under the License. # Avoid shadowing of system copy module by copy action plugin. -from __future__ import absolute_import - import abc from copy import deepcopy import itertools @@ -22,7 +20,6 @@ import itertools from ansible.errors import AnsibleActionFail from ansible.module_utils._text import to_text from ansible.plugins.action import ActionBase -import six class ActionModule(ActionBase): @@ -80,7 +77,7 @@ class ActionModule(ActionBase): """ Remove any nodes with state='absent' from the state dict. """ - for hyp in six.itervalues(self.args['state']): + for hyp in self.args['state'].values(): hyp['nodes'] = [n for n in hyp['nodes'] if n.get('state') != 'absent'] @@ -92,7 +89,7 @@ class ActionModule(ActionBase): ensure the generated indices are consistent. """ state = self.args['state'] - for hostname, hostvars in six.iteritems(self.hypervisor_vars): + for hostname, hostvars in self.hypervisor_vars.items(): # The desired mappings given in the Tenks configuration. These do # not include IDXs which are an implementation detail of Tenks. specified_mappings = hostvars['physnet_mappings'] @@ -105,8 +102,8 @@ class ActionModule(ActionBase): old_idxs = {} new_idxs = {} next_idx = 0 - used_idxs = list(six.itervalues(old_idxs)) - for name, dev in six.iteritems(specified_mappings): + used_idxs = list(old_idxs.values()) + for name, dev in specified_mappings.items(): try: # We need to re-use the IDXs of any existing physnets. idx = old_idxs[name] @@ -128,7 +125,7 @@ class ActionModule(ActionBase): `specs`. """ # Iterate through existing nodes, marking for deletion where necessary. - for hyp in six.itervalues(self.args['state']): + for hyp in self.args['state'].values(): # Absent nodes cannot fulfil a spec. for node in [n for n in hyp.get('nodes', []) if n.get('state') != 'absent']: @@ -173,7 +170,7 @@ class ActionModule(ActionBase): """ # Anything left in specs needs to be created. for spec in self.args['specs']: - for _ in six.moves.range(spec['count']): + for _ in range(spec['count']): node = self._gen_node(spec['type'], spec.get('ironic_config')) hostname, ipmi_port = scheduler.choose_host(node) node_name_prefix = spec.get('node_name_prefix', @@ -310,8 +307,7 @@ class Host(object): for pn in node['physical_networks']) -@six.add_metaclass(abc.ABCMeta) -class Scheduler(object): +class Scheduler(object, metaclass=abc.ABCMeta): """ Abstract class representing a 'method' of scheduling nodes to hosts. """ diff --git a/ansible/filter_plugins/tenks.py b/ansible/filter_plugins/tenks.py index 0e3bfb6..e05285a 100644 --- a/ansible/filter_plugins/tenks.py +++ b/ansible/filter_plugins/tenks.py @@ -17,7 +17,6 @@ import re from ansible.errors import AnsibleFilterError from ansible.module_utils._text import to_text from jinja2 import contextfilter -import six class FilterModule(object): @@ -239,6 +238,6 @@ def physnet_index_to_name(context, idx, inventory_hostname=None): state = _get_hostvar(context, 'tenks_state', inventory_hostname='localhost') # We should have exactly one physnet with this index. - for k, v in six.iteritems(state[inventory_hostname]['physnet_indices']): + for k, v in state[inventory_hostname]['physnet_indices'].items(): if v == idx: return k diff --git a/ansible/roles/wait-for-resources/library/wait_for_resources.py b/ansible/roles/wait-for-resources/library/wait_for_resources.py index d922292..9de1974 100644 --- a/ansible/roles/wait-for-resources/library/wait_for_resources.py +++ b/ansible/roles/wait-for-resources/library/wait_for_resources.py @@ -66,7 +66,6 @@ iterations: # Need to disable PEP8, as it wants all imports at top of file from ansible.module_utils.basic import AnsibleModule # noqa from collections import namedtuple # noqa -import six # noqa import os # noqa import time # noqa @@ -185,10 +184,10 @@ def merge(x, y, f): """ Merges two dictionaries. If a key appears in both dictionaries, the common values are merged using the function ``f``""" # Start with symmetric difference; keys either in A or B, but not both - merged = {k: x.get(k, y.get(k)) for k in six.viewkeys(x) ^ six.viewkeys(y)} + merged = {k: x.get(k, y.get(k)) for k in x.keys() ^ y.keys()} # Update with `f()` applied to the intersection merged.update( - {k: f(x[k], y[k]) for k in six.viewkeys(x) & six.viewkeys(y)}) + {k: f(x[k], y[k]) for k in x.keys() & y.keys()}) return merged diff --git a/tests/test_tenks_update_state.py b/tests/test_tenks_update_state.py index c99a6c3..2a973be 100644 --- a/tests/test_tenks_update_state.py +++ b/tests/test_tenks_update_state.py @@ -12,22 +12,12 @@ # License for the specific language governing permissions and limitations # under the License. -from __future__ import absolute_import - import copy import imp import os import unittest from ansible.errors import AnsibleActionFail -import six - - -# Python 2/3 compatibility. -try: - from unittest.mock import MagicMock -except ImportError: - from mock import MagicMock # noqa # Import method lifted from kolla_ansible's test_merge_config.py @@ -122,10 +112,9 @@ class TestTenksUpdateState(unittest.TestCase): }) self.mod._set_physnet_idxs() for host in {'foo', 'bar'}: - idxs = list(six.itervalues( - self.args['state'][host]['physnet_indices'])) + idxs = list(self.args['state'][host]['physnet_indices'].values()) # Check all physnets have different IDs on the same host. - six.assertCountEqual(self, idxs, set(idxs)) + self.assertCountEqual(idxs, set(idxs)) def test_set_physnet_idxs__idx_maintained_after_removal(self): self.mod.hypervisor_vars['foo']['physnet_mappings'].update({ @@ -222,7 +211,7 @@ class TestTenksUpdateState(unittest.TestCase): # After one or more runs, the 'absent' state nodes should still exist, # since they're only removed after completion of deployment in a # playbook. - for _ in six.moves.range(3): + for _ in range(3): self.mod._process_specs() self.assertEqual(expected_state, self.args['state']) diff --git a/tests/test_tenks_wait_for_resources.py b/tests/test_tenks_wait_for_resources.py index b8a104c..27a7dbd 100644 --- a/tests/test_tenks_wait_for_resources.py +++ b/tests/test_tenks_wait_for_resources.py @@ -12,24 +12,18 @@ # License for the specific language governing permissions and limitations # under the License. -from __future__ import absolute_import - import copy import imp import json import os import random from itertools import repeat, chain, cycle +from unittest.mock import patch from ansible.module_utils import basic from tests.utils import ModuleTestCase, set_module_args, AnsibleExitJson, \ AnsibleFailJson -# Python 2/3 compatibility. -try: - from unittest.mock import MagicMock, patch -except ImportError: - from mock import MagicMock, patch # noqa # Import method lifted from kolla_ansible's test_merge_config.py PROJECT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '../')) @@ -49,36 +43,36 @@ Specifier = wait_for.Specifier inventory_list_out = """[ { - "allocation_ratio": 1.0, - "total": 1, - "reserved": 0, - "resource_class": "CUSTOM_TEST_RC", - "step_size": 1, - "min_unit": 1, + "allocation_ratio": 1.0, + "total": 1, + "reserved": 0, + "resource_class": "CUSTOM_TEST_RC", + "step_size": 1, + "min_unit": 1, "max_unit": 1 } ]""" # noqa inventory_custom_b_out = """[ { - "allocation_ratio": 1.0, - "total": 1, - "reserved": 0, - "resource_class": "CUSTOM_B", - "step_size": 1, - "min_unit": 1, + "allocation_ratio": 1.0, + "total": 1, + "reserved": 0, + "resource_class": "CUSTOM_B", + "step_size": 1, + "min_unit": 1, "max_unit": 1 } ]""" # noqa inventory_reserved_out = """[ { - "allocation_ratio": 1.0, - "total": 1, - "reserved": 1, - "resource_class": "CUSTOM_TEST_RC", - "step_size": 1, - "min_unit": 1, + "allocation_ratio": 1.0, + "total": 1, + "reserved": 1, + "resource_class": "CUSTOM_TEST_RC", + "step_size": 1, + "min_unit": 1, "max_unit": 1 } ]""" # noqa @@ -93,18 +87,18 @@ inventory_list = [{'allocation_ratio': 1.0, resource_provider_list_out = """[ { - "generation": 2, - "uuid": "657c4ab0-de82-4def-b7b0-d13ce672bfd0", + "generation": 2, + "uuid": "657c4ab0-de82-4def-b7b0-d13ce672bfd0", "name": "kayobe-will-master" - }, + }, { - "generation": 1, - "uuid": "e2e78f98-d3ec-466a-862b-42d7ef5dca7d", + "generation": 1, + "uuid": "e2e78f98-d3ec-466a-862b-42d7ef5dca7d", "name": "e2e78f98-d3ec-466a-862b-42d7ef5dca7d" - }, + }, { - "generation": 1, - "uuid": "07072aea-cc2b-4135-a7e2-3a4dd3a9f629", + "generation": 1, + "uuid": "07072aea-cc2b-4135-a7e2-3a4dd3a9f629", "name": "07072aea-cc2b-4135-a7e2-3a4dd3a9f629" } ]""" # noqa @@ -121,49 +115,49 @@ resource_provider_list = [{'generation': 2, 'name': 'kayobe-will-master', resource_provider_traits_out = """[ { "name": "HW_CPU_X86_SSE2" - }, + }, { "name": "HW_CPU_X86_CLMUL" - }, + }, { "name": "HW_CPU_X86_SSE" - }, + }, { "name": "HW_CPU_X86_ABM" - }, + }, { "name": "HW_CPU_X86_MMX" - }, + }, { "name": "HW_CPU_X86_AVX2" - }, + }, { "name": "HW_CPU_X86_SSE41" - }, + }, { "name": "HW_CPU_X86_SSE42" - }, + }, { "name": "HW_CPU_X86_AESNI" - }, + }, { "name": "HW_CPU_X86_AVX" - }, + }, { "name": "HW_CPU_X86_VMX" - }, + }, { "name": "HW_CPU_X86_BMI2" - }, + }, { "name": "HW_CPU_X86_FMA3" - }, + }, { "name": "HW_CPU_X86_SSSE3" - }, + }, { "name": "HW_CPU_X86_F16C" - }, + }, { "name": "HW_CPU_X86_BMI" } diff --git a/tests/utils.py b/tests/utils.py index 1e5bc8c..5b1b662 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,15 +1,10 @@ import json import unittest +from unittest.mock import patch from ansible.module_utils import basic from ansible.module_utils._text import to_bytes -# Python 2/3 compatibility. -try: - from unittest.mock import MagicMock, patch -except ImportError: - from mock import MagicMock, patch # noqa - def set_module_args(args): if '_ansible_remote_tmp' not in args: @@ -44,11 +39,6 @@ class ModuleTestCase(unittest.TestCase): def __init__(self, *args, **kwargs): super(ModuleTestCase, self).__init__(*args, **kwargs) - # Python 2 / 3 compatibility. assertRaisesRegexp was renamed to - # assertRaisesRegex in python 3.1. - if hasattr(self, 'assertRaisesRegexp') and \ - not hasattr(self, 'assertRaisesRegex'): - self.assertRaisesRegex = self.assertRaisesRegexp def setUp(self): self.mock_module = patch.multiple(basic.AnsibleModule,