diff --git a/ironicclient/common/apiclient/base.py b/ironicclient/common/apiclient/base.py index fcf536d0c..a1a13999a 100644 --- a/ironicclient/common/apiclient/base.py +++ b/ironicclient/common/apiclient/base.py @@ -26,11 +26,10 @@ Base utilities to build API operation managers and objects on top of. import abc import copy +from http import client as http_client +from urllib import parse as urlparse from oslo_utils import strutils -import six -from six.moves import http_client -from six.moves.urllib import parse from ironicclient.common.apiclient import exceptions from ironicclient.common.i18n import _ @@ -212,8 +211,7 @@ class BaseManager(HookableMixin): return self.client.delete(url) -@six.add_metaclass(abc.ABCMeta) -class ManagerWithFind(BaseManager): +class ManagerWithFind(BaseManager, metaclass=abc.ABCMeta): """Manager with additional `find()`/`findall()` methods.""" @abc.abstractmethod @@ -341,7 +339,7 @@ class CrudManager(BaseManager): return self._list( '%(base_url)s%(query)s' % { 'base_url': self.build_url(base_url=base_url, **kwargs), - 'query': '?%s' % parse.urlencode(kwargs) if kwargs else '', + 'query': '?%s' % urlparse.urlencode(kwargs) if kwargs else '', }, self.collection_key) @@ -380,7 +378,7 @@ class CrudManager(BaseManager): rl = self._list( '%(base_url)s%(query)s' % { 'base_url': self.build_url(base_url=base_url, **kwargs), - 'query': '?%s' % parse.urlencode(kwargs) if kwargs else '', + 'query': '?%s' % urlparse.urlencode(kwargs) if kwargs else '', }, self.collection_key) num = len(rl) diff --git a/ironicclient/common/apiclient/exceptions.py b/ironicclient/common/apiclient/exceptions.py index 81a3340a2..2ae9bf67e 100644 --- a/ironicclient/common/apiclient/exceptions.py +++ b/ironicclient/common/apiclient/exceptions.py @@ -20,13 +20,10 @@ Exception definitions. """ - +from http import client as http_client import inspect import sys -import six -from six.moves import http_client - from ironicclient.common.i18n import _ @@ -450,7 +447,7 @@ def from_response(response, method, url): kwargs["message"] = (error.get("message") or error.get("faultstring")) kwargs["details"] = (error.get("details") or - six.text_type(body)) + str(body)) elif content_type.startswith("text/"): kwargs["details"] = getattr(response, 'text', '') diff --git a/ironicclient/common/base.py b/ironicclient/common/base.py index 0bd4a35d3..2244c6555 100644 --- a/ironicclient/common/base.py +++ b/ironicclient/common/base.py @@ -19,9 +19,7 @@ Base utilities to build API operation managers and objects on top of. import abc import copy -import six - -import six.moves.urllib.parse as urlparse +from urllib import parse as urlparse from ironicclient.common.apiclient import base from ironicclient import exc @@ -39,8 +37,7 @@ def getid(obj): return obj -@six.add_metaclass(abc.ABCMeta) -class Manager(object): +class Manager(object, metaclass=abc.ABCMeta): """Provides CRUD operations with a particular API.""" def __init__(self, api): @@ -55,13 +52,15 @@ class Manager(object): return ('/v1/%s/%s' % (self._resource_name, resource_id) if resource_id else '/v1/%s' % self._resource_name) - @abc.abstractproperty + @property + @abc.abstractmethod def resource_class(self): """The resource class """ - @abc.abstractproperty + @property + @abc.abstractmethod def _resource_name(self): """The resource name. @@ -259,11 +258,11 @@ class Manager(object): self.api.raw_request('DELETE', self._path(resource_id)) -@six.add_metaclass(abc.ABCMeta) -class CreateManager(Manager): +class CreateManager(Manager, metaclass=abc.ABCMeta): """Provides creation operations with a particular API.""" - @abc.abstractproperty + @property + @abc.abstractmethod def _creation_attributes(self): """A list of required creation attributes for a resource type. diff --git a/ironicclient/common/http.py b/ironicclient/common/http.py index fd916a2c3..bf41d2f4d 100644 --- a/ironicclient/common/http.py +++ b/ironicclient/common/http.py @@ -14,6 +14,8 @@ # under the License. from distutils.version import StrictVersion +import functools +from http import client as http_client import logging import os import re @@ -21,13 +23,11 @@ import socket import ssl import textwrap import time +from urllib import parse as urlparse from keystoneauth1 import adapter from keystoneauth1 import exceptions as kexc from oslo_serialization import jsonutils -import six -from six.moves import http_client -import six.moves.urllib.parse as urlparse from ironicclient.common import filecache from ironicclient.common.i18n import _ @@ -196,7 +196,7 @@ class VersionNegotiationMixin(object): % {'req': requested_version, 'min': min_ver, 'max': max_ver})) - if isinstance(requested_version, six.string_types): + if isinstance(requested_version, str): if requested_version == 'latest': negotiated_ver = max_ver else: @@ -276,7 +276,7 @@ _RETRY_EXCEPTIONS = (exc.Conflict, exc.ServiceUnavailable, def with_retries(func): """Wrapper for _http_request adding support for retries.""" - @six.wraps(func) + @functools.wraps(func) def wrapper(self, url, method, **kwargs): if self.conflict_max_retries is None: self.conflict_max_retries = DEFAULT_MAX_RETRIES @@ -303,7 +303,7 @@ def with_retries(func): return wrapper -class VerifiedHTTPSConnection(six.moves.http_client.HTTPSConnection): +class VerifiedHTTPSConnection(http_client.HTTPSConnection): """httplib-compatible connection using client-side SSL authentication :see http://code.activestate.com/recipes/ @@ -312,9 +312,9 @@ class VerifiedHTTPSConnection(six.moves.http_client.HTTPSConnection): def __init__(self, host, port, key_file=None, cert_file=None, ca_file=None, timeout=None, insecure=False): - six.moves.http_client.HTTPSConnection.__init__(self, host, port, - key_file=key_file, - cert_file=cert_file) + http_client.HTTPSConnection.__init__(self, host, port, + key_file=key_file, + cert_file=cert_file) self.key_file = key_file self.cert_file = cert_file if ca_file is not None: @@ -380,7 +380,7 @@ class SessionClient(VersionNegotiationMixin, adapter.LegacyJsonAdapter): self.api_version_select_state = api_version_select_state self.conflict_max_retries = max_retries self.conflict_retry_interval = retry_interval - if isinstance(kwargs.get('endpoint_override'), six.string_types): + if isinstance(kwargs.get('endpoint_override'), str): kwargs['endpoint_override'] = _trim_endpoint_api_version( kwargs['endpoint_override']) @@ -421,7 +421,7 @@ class SessionClient(VersionNegotiationMixin, adapter.LegacyJsonAdapter): kwargs.setdefault('user_agent', USER_AGENT) kwargs.setdefault('auth', self.auth) - if isinstance(self.endpoint_override, six.string_types): + if isinstance(self.endpoint_override, str): kwargs.setdefault('endpoint_override', self.endpoint_override) if getattr(self, 'os_ironic_api_version', None): diff --git a/ironicclient/common/utils.py b/ironicclient/common/utils.py index fac527857..cf3b1bad9 100644 --- a/ironicclient/common/utils.py +++ b/ironicclient/common/utils.py @@ -28,7 +28,6 @@ import time from oslo_serialization import base64 from oslo_utils import strutils -import six from ironicclient.common.i18n import _ from ironicclient import exc @@ -163,7 +162,7 @@ def convert_list_props_to_comma_separated(data, props=None): for prop in props: val = data.get(prop, None) if isinstance(val, list): - result[prop] = ', '.join(map(six.text_type, val)) + result[prop] = ', '.join(map(str, val)) return result diff --git a/ironicclient/tests/functional/base.py b/ironicclient/tests/functional/base.py index cb87f4831..c62fcd101 100644 --- a/ironicclient/tests/functional/base.py +++ b/ironicclient/tests/functional/base.py @@ -12,10 +12,9 @@ # License for the specific language governing permissions and limitations # under the License. +import configparser import os -import six -import six.moves.configparser as config_parser from tempest.lib.cli import base from tempest.lib.common.utils import data_utils from tempest.lib import exceptions @@ -60,16 +59,12 @@ class FunctionalTestBase(base.ClientTestBase): def _get_config(self): config_file = os.environ.get('IRONICCLIENT_TEST_CONFIG', DEFAULT_CONFIG_FILE) - # SafeConfigParser was deprecated in Python 3.2 - if six.PY3: - config = config_parser.ConfigParser() - else: - config = config_parser.SafeConfigParser() + config = configparser.ConfigParser() if not config.read(config_file): self.skipTest('Skipping, no test config found @ %s' % config_file) try: auth_strategy = config.get('functional', 'auth_strategy') - except config_parser.NoOptionError: + except configparser.NoOptionError: auth_strategy = 'keystone' if auth_strategy not in ['keystone', 'noauth']: raise self.fail( @@ -92,7 +87,7 @@ class FunctionalTestBase(base.ClientTestBase): for c in conf_settings + keystone_v3_conf_settings: try: cli_flags[c] = config.get('functional', c) - except config_parser.NoOptionError: + except configparser.NoOptionError: # NOTE(vdrok): Here we ignore the absence of KS v3 options as # v2 may be used. Keystone client will do the actual check of # the parameters' correctness. diff --git a/ironicclient/tests/functional/osc/v1/test_baremetal_deploy_template_basic.py b/ironicclient/tests/functional/osc/v1/test_baremetal_deploy_template_basic.py index 5a717509c..d3bfdbe9b 100644 --- a/ironicclient/tests/functional/osc/v1/test_baremetal_deploy_template_basic.py +++ b/ironicclient/tests/functional/osc/v1/test_baremetal_deploy_template_basic.py @@ -13,7 +13,6 @@ import json import ddt -import six from tempest.lib.common.utils import data_utils from tempest.lib import exceptions @@ -160,9 +159,7 @@ class BaremetalDeployTemplateTests(base.TestCase): @ddt.data( ('--uuid', '', 'expected one argument'), ('--uuid', '!@#$^*&%^', 'Expected a UUID'), - ('', '', - 'too few arguments' if six.PY2 - else 'the following arguments are required'), + ('', '', 'the following arguments are required'), ('', 'not/a/name', 'Deploy template name must be a valid trait'), ('', 'foo', 'Deploy template name must be a valid trait'), ('--steps', '', 'expected one argument'), diff --git a/ironicclient/tests/functional/osc/v1/test_baremetal_node_create_negative.py b/ironicclient/tests/functional/osc/v1/test_baremetal_node_create_negative.py index eec76db78..82c4201dd 100644 --- a/ironicclient/tests/functional/osc/v1/test_baremetal_node_create_negative.py +++ b/ironicclient/tests/functional/osc/v1/test_baremetal_node_create_negative.py @@ -13,7 +13,6 @@ # under the License. import ddt -import six from tempest.lib import exceptions from ironicclient.tests.functional.osc.v1 import base @@ -44,5 +43,5 @@ class BaremetalNodeCreateNegativeTests(base.TestCase): def test_baremetal_node_create(self, argument, value, ex_text): base_cmd = 'baremetal node create --driver %s' % self.driver_name command = self.construct_cmd(base_cmd, argument, value) - six.assertRaisesRegex(self, exceptions.CommandFailed, ex_text, - self.openstack, command) + self.assertRaisesRegex(exceptions.CommandFailed, ex_text, + self.openstack, command) diff --git a/ironicclient/tests/functional/osc/v1/test_baremetal_node_fields.py b/ironicclient/tests/functional/osc/v1/test_baremetal_node_fields.py index dd19958ff..681b8fc3e 100644 --- a/ironicclient/tests/functional/osc/v1/test_baremetal_node_fields.py +++ b/ironicclient/tests/functional/osc/v1/test_baremetal_node_fields.py @@ -12,7 +12,6 @@ # License for the specific language governing permissions and limitations # under the License. -import six from tempest.lib import exceptions from ironicclient.tests.functional.osc.v1 import base @@ -44,8 +43,7 @@ class TestNodeListFields(base.TestCase): fields = ['instance_uuid', 'name', 'uuid'] node_list = self.openstack( - 'baremetal node list --fields {}' - .format(' '.join(fields))) + 'baremetal node list --fields {}'.format(' '.join(fields))) nodes_list_headers = self._get_table_headers(node_list) self.assertEqual(headers, nodes_list_headers) @@ -53,14 +51,14 @@ class TestNodeListFields(base.TestCase): def test_list_no_fields(self): command = 'baremetal node list --fields' ex_text = 'expected at least one argument' - six.assertRaisesRegex(self, exceptions.CommandFailed, ex_text, - self.openstack, command) + self.assertRaisesRegex(exceptions.CommandFailed, ex_text, + self.openstack, command) def test_list_wrong_field(self): command = 'baremetal node list --fields ABC' ex_text = 'invalid choice' - six.assertRaisesRegex(self, exceptions.CommandFailed, ex_text, - self.openstack, command) + self.assertRaisesRegex(exceptions.CommandFailed, ex_text, + self.openstack, command) class TestNodeShowFields(base.TestCase): @@ -117,8 +115,8 @@ class TestNodeShowFields(base.TestCase): 'uuid'] node_show = self.openstack( - 'baremetal node show {} --fields {} {}' - .format(self.node['uuid'], ' '.join(rows), self.api_version)) + 'baremetal node show {} --fields {} {}'.format( + self.node['uuid'], ' '.join(rows), self.api_version)) nodes_show_rows = self._get_table_rows(node_show) self.assertEqual(set(rows), set(nodes_show_rows)) @@ -127,12 +125,12 @@ class TestNodeShowFields(base.TestCase): command = 'baremetal node show {} --fields {}'.format( self.node['uuid'], self.api_version) ex_text = 'expected at least one argument' - six.assertRaisesRegex(self, exceptions.CommandFailed, ex_text, - self.openstack, command) + self.assertRaisesRegex(exceptions.CommandFailed, ex_text, + self.openstack, command) def test_show_wrong_field(self): command = 'baremetal node show {} --fields ABC {}'.format( self.node['uuid'], self.api_version) ex_text = 'invalid choice' - six.assertRaisesRegex(self, exceptions.CommandFailed, ex_text, - self.openstack, command) + self.assertRaisesRegex(exceptions.CommandFailed, ex_text, + self.openstack, command) diff --git a/ironicclient/tests/functional/osc/v1/test_baremetal_node_negative.py b/ironicclient/tests/functional/osc/v1/test_baremetal_node_negative.py index 22013aa3b..7970a1223 100644 --- a/ironicclient/tests/functional/osc/v1/test_baremetal_node_negative.py +++ b/ironicclient/tests/functional/osc/v1/test_baremetal_node_negative.py @@ -13,7 +13,6 @@ # under the License. import ddt -import six from tempest.lib import exceptions from ironicclient.tests.functional.osc.v1 import base @@ -28,9 +27,7 @@ class BaremetalNodeNegativeTests(base.TestCase): self.node = self.node_create() @ddt.data( - ('', '', - 'error: argument --driver is required' if six.PY2 - else 'error: the following arguments are required: --driver'), + ('', '', 'error: the following arguments are required: --driver'), ('--driver', 'wrongdriver', 'No valid host was found. Reason: No conductor service ' 'registered which supports driver wrongdriver.') @@ -40,29 +37,26 @@ class BaremetalNodeNegativeTests(base.TestCase): """Negative test for baremetal node driver options.""" base_cmd = 'baremetal node create' command = self.construct_cmd(base_cmd, argument, value) - six.assertRaisesRegex(self, exceptions.CommandFailed, ex_text, - self.openstack, command) + self.assertRaisesRegex(exceptions.CommandFailed, ex_text, + self.openstack, command) def test_delete_no_node(self): """Test for baremetal node delete without node specified.""" command = 'baremetal node delete' - ex_text = 'error: too few arguments' - if six.PY3: - ex_text = '' - six.assertRaisesRegex(self, exceptions.CommandFailed, ex_text, - self.openstack, command) + ex_text = '' + self.assertRaisesRegex(exceptions.CommandFailed, ex_text, + self.openstack, command) def test_list_wrong_argument(self): """Test for baremetal node list with wrong argument.""" command = 'baremetal node list --wrong_arg' ex_text = 'error: unrecognized arguments: --wrong_arg' - six.assertRaisesRegex(self, exceptions.CommandFailed, ex_text, - self.openstack, command) + self.assertRaisesRegex(exceptions.CommandFailed, ex_text, + self.openstack, command) @ddt.data( ('--property', '', - 'error: too few arguments' if six.PY2 - else 'error: the following arguments are required: '), + 'error: the following arguments are required: '), ('--property', 'prop', 'Attributes must be a list of PATH=VALUE') ) @ddt.unpack @@ -71,13 +65,12 @@ class BaremetalNodeNegativeTests(base.TestCase): base_cmd = 'baremetal node set' command = self.construct_cmd(base_cmd, argument, value, self.node['uuid']) - six.assertRaisesRegex(self, exceptions.CommandFailed, ex_text, - self.openstack, command) + self.assertRaisesRegex(exceptions.CommandFailed, ex_text, + self.openstack, command) @ddt.data( ('--property', '', - 'error: too few arguments' if six.PY2 - else 'error: the following arguments are required: '), + 'error: the following arguments are required: '), ('--property', 'prop', "Reason: can't remove non-existent object") ) @ddt.unpack @@ -86,5 +79,5 @@ class BaremetalNodeNegativeTests(base.TestCase): base_cmd = 'baremetal node unset' command = self.construct_cmd(base_cmd, argument, value, self.node['uuid']) - six.assertRaisesRegex(self, exceptions.CommandFailed, ex_text, - self.openstack, command) + self.assertRaisesRegex(exceptions.CommandFailed, ex_text, + self.openstack, command) diff --git a/ironicclient/tests/functional/utils.py b/ironicclient/tests/functional/utils.py index 49d208915..ba11c40af 100644 --- a/ironicclient/tests/functional/utils.py +++ b/ironicclient/tests/functional/utils.py @@ -12,8 +12,6 @@ # License for the specific language governing permissions and limitations # under the License. -import six - def get_dict_from_output(output): """Parse list of dictionaries, return a dictionary. @@ -22,7 +20,7 @@ def get_dict_from_output(output): """ obj = {} for item in output: - obj[item['Property']] = six.text_type(item['Value']) + obj[item['Property']] = str(item['Value']) return obj diff --git a/ironicclient/tests/unit/common/apiclient/test_exceptions.py b/ironicclient/tests/unit/common/apiclient/test_exceptions.py index 2ac5b398c..d466c41d7 100644 --- a/ironicclient/tests/unit/common/apiclient/test_exceptions.py +++ b/ironicclient/tests/unit/common/apiclient/test_exceptions.py @@ -13,9 +13,9 @@ # License for the specific language governing permissions and limitations # under the License. +from http import client as http_client + from oslotest import base as test_base -import six -from six.moves import http_client from ironicclient.common.apiclient import exceptions @@ -89,17 +89,17 @@ class ExceptionsArgsTest(test_base.BaseTestCase): json_data1 = {"error_message": {"debuginfo": None, "faultcode": "Client", "faultstring": "fake message"}} - message = six.text_type( + message = str( json_data1["error_message"]["faultstring"]) - details = six.text_type(json_data1) + details = str(json_data1) self.assert_exception( exceptions.BadRequest, method, url, status_code, json_data1, message, details) json_data2 = {"badRequest": {"message": "fake message", "code": http_client.BAD_REQUEST}} - message = six.text_type(json_data2["badRequest"]["message"]) - details = six.text_type(json_data2) + message = str(json_data2["badRequest"]["message"]) + details = str(json_data2) self.assert_exception( exceptions.BadRequest, method, url, status_code, json_data2, message, details) diff --git a/ironicclient/tests/unit/common/test_http.py b/ironicclient/tests/unit/common/test_http.py index 441e4eeb5..9f603365b 100644 --- a/ironicclient/tests/unit/common/test_http.py +++ b/ironicclient/tests/unit/common/test_http.py @@ -13,11 +13,11 @@ # License for the specific language governing permissions and limitations # under the License. +from http import client as http_client import time import mock from oslo_serialization import jsonutils -from six.moves import http_client from keystoneauth1 import exceptions as kexc diff --git a/ironicclient/tests/unit/common/test_utils.py b/ironicclient/tests/unit/common/test_utils.py index ffc31bbe8..c60ec3178 100644 --- a/ironicclient/tests/unit/common/test_utils.py +++ b/ironicclient/tests/unit/common/test_utils.py @@ -13,6 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. +import builtins import json import os import subprocess @@ -20,7 +21,6 @@ import sys import tempfile import mock -import six.moves.builtins as __builtin__ from ironicclient.common import utils from ironicclient import exc @@ -355,7 +355,7 @@ class HandleJsonFileTest(test_utils.BaseTestCase): self.assertEqual(json.loads(contents), steps) - @mock.patch.object(__builtin__, 'open', autospec=True) + @mock.patch.object(builtins, 'open', autospec=True) def test_handle_json_or_file_arg_file_fail(self, mock_open): mock_file_object = mock.MagicMock() mock_file_handle = mock.MagicMock() diff --git a/ironicclient/tests/unit/test_exc.py b/ironicclient/tests/unit/test_exc.py index d7c838263..ea57098d3 100644 --- a/ironicclient/tests/unit/test_exc.py +++ b/ironicclient/tests/unit/test_exc.py @@ -13,8 +13,9 @@ # License for the specific language governing permissions and limitations # under the License. +from http import client as http_client + import mock -from six.moves import http_client from ironicclient.common.apiclient import exceptions from ironicclient import exc diff --git a/ironicclient/tests/unit/utils.py b/ironicclient/tests/unit/utils.py index ea3308e63..02a8767d8 100644 --- a/ironicclient/tests/unit/utils.py +++ b/ironicclient/tests/unit/utils.py @@ -14,13 +14,13 @@ # under the License. import copy +import io import os import fixtures import mock from oslo_utils import strutils import requests -import six import testtools @@ -58,7 +58,7 @@ class FakeAPI(object): def raw_request(self, *args, **kwargs): response = self._request(*args, **kwargs) - body_iter = iter(six.StringIO(response[1])) + body_iter = iter(io.StringIO(response[1])) return FakeResponse(response[0]), body_iter def json_request(self, *args, **kwargs): diff --git a/ironicclient/tests/unit/v1/test_create_resources.py b/ironicclient/tests/unit/v1/test_create_resources.py index 4b37934f5..455877f82 100644 --- a/ironicclient/tests/unit/v1/test_create_resources.py +++ b/ironicclient/tests/unit/v1/test_create_resources.py @@ -10,10 +10,9 @@ # License for the specific language governing permissions and limitations # under the License. +import builtins import jsonschema import mock -import six -import six.moves.builtins as __builtin__ from ironicclient import exc from ironicclient.tests.unit import utils @@ -193,14 +192,14 @@ class CreateResourcesTest(utils.BaseTestCase): class LoadFromFileTest(utils.BaseTestCase): - @mock.patch.object(__builtin__, 'open', + @mock.patch.object(builtins, 'open', mock.mock_open(read_data='{"a": "b"}')) def test_load_json(self): fname = 'abc.json' res = create_resources.load_from_file(fname) self.assertEqual({'a': 'b'}, res) - @mock.patch.object(__builtin__, 'open', + @mock.patch.object(builtins, 'open', mock.mock_open(read_data='{"a": "b"}')) def test_load_unknown_extension(self): fname = 'abc' @@ -208,7 +207,7 @@ class LoadFromFileTest(utils.BaseTestCase): 'must have .json or .yaml extension', create_resources.load_from_file, fname) - @mock.patch.object(__builtin__, 'open', autospec=True) + @mock.patch.object(builtins, 'open', autospec=True) def test_load_ioerror(self, mock_open): mock_open.side_effect = IOError('file does not exist') fname = 'abc.json' @@ -216,7 +215,7 @@ class LoadFromFileTest(utils.BaseTestCase): 'Cannot read file', create_resources.load_from_file, fname) - @mock.patch.object(__builtin__, 'open', + @mock.patch.object(builtins, 'open', mock.mock_open(read_data='{{bbb')) def test_load_incorrect_json(self): fname = 'abc.json' @@ -224,14 +223,14 @@ class LoadFromFileTest(utils.BaseTestCase): exc.ClientException, 'File "%s" is invalid' % fname, create_resources.load_from_file, fname) - @mock.patch.object(__builtin__, 'open', + @mock.patch.object(builtins, 'open', mock.mock_open(read_data='---\na: b')) def test_load_yaml(self): fname = 'abc.yaml' res = create_resources.load_from_file(fname) self.assertEqual({'a': 'b'}, res) - @mock.patch.object(__builtin__, 'open', + @mock.patch.object(builtins, 'open', mock.mock_open(read_data='---\na-: - b')) def test_load_incorrect_yaml(self): fname = 'abc.yaml' @@ -365,7 +364,7 @@ class CreateMethodsTest(utils.BaseTestCase): 'node-uuid-1', 'pg-uuid-2') self.assertEqual(1, len(errs)) self.assertIsInstance(errs[0], exc.ClientException) - self.assertIn('port group', six.text_type(errs[0])) + self.assertIn('port group', str(errs[0])) self.assertFalse(self.client.port.create.called) @mock.patch.object(create_resources, 'create_portgroups', autospec=True) diff --git a/ironicclient/tests/unit/v1/test_node.py b/ironicclient/tests/unit/v1/test_node.py index 8eae43115..de558780b 100644 --- a/ironicclient/tests/unit/v1/test_node.py +++ b/ironicclient/tests/unit/v1/test_node.py @@ -17,7 +17,6 @@ import tempfile import time import mock -import six import testtools from testtools.matchers import HasLength @@ -28,9 +27,6 @@ from ironicclient.v1 import node from ironicclient.v1 import volume_connector from ironicclient.v1 import volume_target -if six.PY3: - import io - file = io.BytesIO NODE1 = {'uuid': '66666666-7777-8888-9999-000000000000', 'chassis_uuid': 'aaaaaaaa-1111-bbbb-2222-cccccccccccc', diff --git a/ironicclient/v1/create_resources.py b/ironicclient/v1/create_resources.py index 3ca56a95d..75f6f0554 100644 --- a/ironicclient/v1/create_resources.py +++ b/ironicclient/v1/create_resources.py @@ -10,10 +10,10 @@ # License for the specific language governing permissions and limitations # under the License. +import functools import json import jsonschema -import six import yaml from ironicclient import exc @@ -61,14 +61,14 @@ def create_resources(client, filenames): if errors: raise exc.ClientException('While validating the resources file(s), the' ' following error(s) were encountered:\n%s' % - '\n'.join(six.text_type(e) for e in errors)) + '\n'.join(str(e) for e in errors)) for r in resources: errors.extend(create_chassis(client, r.get('chassis', []))) errors.extend(create_nodes(client, r.get('nodes', []))) if errors: raise exc.ClientException('During resources creation, the following ' 'error(s) were encountered:\n%s' % - '\n'.join(six.text_type(e) for e in errors)) + '\n'.join(str(e) for e in errors)) def load_from_file(filename): @@ -113,7 +113,7 @@ def create_single_handler(resource_type): """ def outer_wrapper(create_method): - @six.wraps(create_method) + @functools.wraps(create_method) def wrapper(client, **params): uuid = None error = None diff --git a/lower-constraints.txt b/lower-constraints.txt index 388f62a29..5f9da80eb 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -85,7 +85,6 @@ requestsexceptions==1.2.0 restructuredtext-lint==1.1.1 rfc3986==0.3.1 simplejson==3.5.1 -six==1.10.0 snowballstemmer==1.2.1 Sphinx==1.6.2 sphinxcontrib-websupport==1.0.1 diff --git a/requirements.txt b/requirements.txt index 4adff2f02..412c047c8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,4 +13,3 @@ oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0 oslo.utils>=3.33.0 # Apache-2.0 PyYAML>=3.12 # MIT requests>=2.14.2 # Apache-2.0 -six>=1.10.0 # MIT