diff --git a/lower-constraints.txt b/lower-constraints.txt index 910fa578..c42d8c1d 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -32,7 +32,6 @@ PyYAML==3.12 reno==2.5.0 requests==2.14.2 requestsexceptions==1.2.0 -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 14f51f55..1829f68a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,5 @@ pbr!=2.1.0,>=2.0.0 # Apache-2.0 requests>=2.14.2 # Apache-2.0 -six>=1.10.0 # MIT python-dateutil>=2.7.0 # BSD stevedore>=1.29.0 # Apache-2.0 diff --git a/sushy/auth.py b/sushy/auth.py index c537c848..beebdad6 100644 --- a/sushy/auth.py +++ b/sushy/auth.py @@ -15,15 +15,12 @@ import abc import logging -import six - from sushy import exceptions LOG = logging.getLogger(__name__) -@six.add_metaclass(abc.ABCMeta) -class AuthBase(object): +class AuthBase(object, metaclass=abc.ABCMeta): def __init__(self, username=None, password=None): """A class representing a base Sushy authentication mechanism diff --git a/sushy/connector.py b/sushy/connector.py index 7c316362..80e038f9 100644 --- a/sushy/connector.py +++ b/sushy/connector.py @@ -14,9 +14,9 @@ # under the License. import logging +from urllib import parse as urlparse import requests -from six.moves.urllib import parse from sushy import exceptions @@ -77,7 +77,7 @@ class Connector(object): :raises: ConnectionError :raises: HTTPError """ - url = parse.urljoin(self._url, path) + url = urlparse.urljoin(self._url, path) headers = headers or {} if not any(k.lower() == 'odata-version' for k in headers): headers['OData-Version'] = '4.0' diff --git a/sushy/exceptions.py b/sushy/exceptions.py index 9f552b81..9f1e01ae 100644 --- a/sushy/exceptions.py +++ b/sushy/exceptions.py @@ -13,10 +13,9 @@ # License for the specific language governing permissions and limitations # under the License. +from http import client as http_client import logging -from six.moves import http_client - LOG = logging.getLogger(__name__) diff --git a/sushy/resources/base.py b/sushy/resources/base.py index e53e4ebb..d33355ba 100644 --- a/sushy/resources/base.py +++ b/sushy/resources/base.py @@ -16,13 +16,6 @@ import abc import collections -# (rpittau) this allows usage of collection ABC abstract classes in both -# Python 2.7 and Python 3.8+ -try: - collectionsAbc = collections.abc -except AttributeError: - collectionsAbc = collections - import copy import io import json @@ -30,8 +23,6 @@ import logging import pkg_resources import zipfile -import six - from sushy import exceptions from sushy.resources import oem from sushy import utils @@ -143,8 +134,7 @@ def _collect_fields(resource): yield (attr, field) -@six.add_metaclass(abc.ABCMeta) -class CompositeField(collectionsAbc.Mapping, Field): +class CompositeField(collections.abc.Mapping, Field, metaclass=abc.ABCMeta): """Base class for fields consisting of several sub-fields.""" def __init__(self, *args, **kwargs): @@ -175,7 +165,6 @@ class CompositeField(collectionsAbc.Mapping, Field): return instance # Satisfy the mapping interface, see - # https://docs.python.org/2/library/collections.html#collections.Mapping. # https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping def __getitem__(self, key): @@ -274,7 +263,7 @@ class MappedField(Field): Only has effect when the field is not required. This value is not matched against the mapping. """ - if not isinstance(mapping, collectionsAbc.Mapping): + if not isinstance(mapping, collections.abc.Mapping): raise TypeError("The mapping argument must be a mapping") super(MappedField, self).__init__( @@ -300,7 +289,7 @@ class MappedListField(Field): :param default: the default value to use when the field is missing. Only has effect when the field is not required. """ - if not isinstance(mapping, collectionsAbc.Mapping): + if not isinstance(mapping, collections.abc.Mapping): raise TypeError("The mapping argument must be a mapping") self._mapping_adapter = mapping.get @@ -328,8 +317,7 @@ class MappedListField(Field): return instances -@six.add_metaclass(abc.ABCMeta) -class AbstractJsonReader(object): +class AbstractJsonReader(object, metaclass=abc.ABCMeta): def set_connection(self, connector, path): """Sets mandatory connection parameters @@ -406,8 +394,7 @@ class JsonPackagedFileReader(AbstractJsonReader): return json.loads(resource.read().decode(encoding='utf-8')) -@six.add_metaclass(abc.ABCMeta) -class ResourceBase(object): +class ResourceBase(object, metaclass=abc.ABCMeta): redfish_version = None """The Redfish version""" @@ -568,8 +555,7 @@ class ResourceBase(object): return self._registries -@six.add_metaclass(abc.ABCMeta) -class ResourceCollectionBase(ResourceBase): +class ResourceCollectionBase(ResourceBase, metaclass=abc.ABCMeta): name = Field('Name') """The name of the collection""" diff --git a/sushy/resources/manager/virtual_media.py b/sushy/resources/manager/virtual_media.py index 7f2cdacc..150e7d06 100644 --- a/sushy/resources/manager/virtual_media.py +++ b/sushy/resources/manager/virtual_media.py @@ -13,7 +13,7 @@ # This is referred from Redfish standard schema. # https://redfish.dmtf.org/schemas/VirtualMedia.v1_2_0.json -from six.moves import http_client +from http import client as http_client from sushy import exceptions from sushy.resources import base diff --git a/sushy/resources/system/bios.py b/sushy/resources/system/bios.py index 4ec0f2fa..b1ae6fa8 100644 --- a/sushy/resources/system/bios.py +++ b/sushy/resources/system/bios.py @@ -13,8 +13,8 @@ # This is referred from Redfish standard schema. # https://redfish.dmtf.org/schemas/Bios.v1_0_3.json +from http import client as http_client import logging -from six.moves import http_client from sushy import exceptions from sushy.resources import base diff --git a/sushy/tests/unit/resources/manager/test_virtual_media.py b/sushy/tests/unit/resources/manager/test_virtual_media.py index b85925be..92fd5641 100644 --- a/sushy/tests/unit/resources/manager/test_virtual_media.py +++ b/sushy/tests/unit/resources/manager/test_virtual_media.py @@ -12,10 +12,10 @@ # License for the specific language governing permissions and limitations # under the License. +from http import client as http_client import json import mock -from six.moves import http_client import sushy from sushy import exceptions diff --git a/sushy/tests/unit/resources/system/test_bios.py b/sushy/tests/unit/resources/system/test_bios.py index 97c8bc6f..ea52695e 100644 --- a/sushy/tests/unit/resources/system/test_bios.py +++ b/sushy/tests/unit/resources/system/test_bios.py @@ -12,11 +12,11 @@ # License for the specific language governing permissions and limitations # under the License. +from http import client as http_client import json import mock from dateutil import parser -from six.moves import http_client from sushy import exceptions from sushy.resources.registry import message_registry diff --git a/sushy/tests/unit/resources/test_base.py b/sushy/tests/unit/resources/test_base.py index 94320941..8e169a77 100644 --- a/sushy/tests/unit/resources/test_base.py +++ b/sushy/tests/unit/resources/test_base.py @@ -14,12 +14,11 @@ # under the License. import copy +from http import client as http_client import io import json import mock -from six.moves import http_client - from sushy import exceptions from sushy.resources import base as resource_base from sushy.tests.unit import base diff --git a/sushy/tests/unit/test_connector.py b/sushy/tests/unit/test_connector.py index cd5e99f9..4d84c405 100644 --- a/sushy/tests/unit/test_connector.py +++ b/sushy/tests/unit/test_connector.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 json import mock import requests -from six.moves import http_client from sushy import auth as sushy_auth from sushy import connector diff --git a/sushy/utils.py b/sushy/utils.py index b4d2a92e..d0300d1e 100644 --- a/sushy/utils.py +++ b/sushy/utils.py @@ -14,19 +14,11 @@ # under the License. import collections - -# (rpittau) this allows usage of collection ABC abstract classes in both -# Python 2.7 and Python 3.8+ -try: - collectionsAbc = collections.abc -except AttributeError: - collectionsAbc = collections +import functools import logging import threading -import six - from sushy import exceptions LOG = logging.getLogger(__name__) @@ -220,7 +212,7 @@ def cache_it(res_accessor_method): """ cache_attr_name = '_cache_' + res_accessor_method.__name__ - @six.wraps(res_accessor_method) + @functools.wraps(res_accessor_method) def func_wrapper(res_selfie): cache_attr_val = getattr(res_selfie, cache_attr_name, None) @@ -239,7 +231,7 @@ def cache_it(res_accessor_method): if isinstance(cache_attr_val, base.ResourceBase): cache_attr_val.refresh(force=False) - elif isinstance(cache_attr_val, collectionsAbc.Sequence): + elif isinstance(cache_attr_val, collections.abc.Sequence): for elem in cache_attr_val: if isinstance(elem, base.ResourceBase): elem.refresh(force=False) @@ -268,7 +260,7 @@ def cache_clear(res_selfie, force_refresh, only_these=None): cache_attr_names = setdefaultattr( res_selfie, CACHE_ATTR_NAMES_VAR_NAME, set()) if only_these is not None: - if not isinstance(only_these, collectionsAbc.Sequence): + if not isinstance(only_these, collections.abc.Sequence): raise TypeError("'only_these' must be a sequence.") cache_attr_names = cache_attr_names.intersection( @@ -281,7 +273,7 @@ def cache_clear(res_selfie, force_refresh, only_these=None): if isinstance(cache_attr_val, base.ResourceBase): cache_attr_val.invalidate(force_refresh) - elif isinstance(cache_attr_val, collectionsAbc.Sequence): + elif isinstance(cache_attr_val, collections.abc.Sequence): for elem in cache_attr_val: if isinstance(elem, base.ResourceBase): elem.invalidate(force_refresh) @@ -331,7 +323,7 @@ def synchronized(wrapped): """ lock = threading.RLock() - @six.wraps(wrapped) + @functools.wraps(wrapped) def wrapper(*args, **kwargs): with lock: return wrapped(*args, **kwargs)