Merge "Remove six dependency"

This commit is contained in:
Zuul 2024-01-26 16:27:58 +00:00 committed by Gerrit Code Review
commit 834d3a6fd3
35 changed files with 72 additions and 134 deletions

View File

@ -14,7 +14,6 @@ import os
from debtcollector import removals
from keystoneauth1 import plugin
import six
import stevedore
from keystoneclient import exceptions
@ -292,7 +291,7 @@ class BaseAuthPlugin(object):
# select the first ENV that is not false-y or return None
env_vars = (os.environ.get(e) for e in envs)
default = six.next(six.moves.filter(None, env_vars), None)
default = next(filter(None, env_vars), None)
parser.add_argument(*args,
default=default or opt.default,

View File

@ -16,7 +16,6 @@ import threading
import warnings
from oslo_config import cfg
import six
from keystoneclient import _discover
from keystoneclient.auth import base
@ -31,8 +30,7 @@ def get_options():
]
@six.add_metaclass(abc.ABCMeta)
class BaseIdentityPlugin(base.BaseAuthPlugin):
class BaseIdentityPlugin(base.BaseAuthPlugin, metaclass=abc.ABCMeta):
# we count a token as valid (not needing refreshing) if it is valid for at
# least this many seconds before the token expiry time

View File

@ -12,10 +12,9 @@
import abc
import logging
import urllib.parse as urlparse
from oslo_config import cfg
import six
import six.moves.urllib.parse as urlparse
from keystoneclient import _discover
from keystoneclient.auth.identity import base
@ -42,8 +41,7 @@ def get_options():
]
@six.add_metaclass(abc.ABCMeta)
class BaseGenericPlugin(base.BaseIdentityPlugin):
class BaseGenericPlugin(base.BaseIdentityPlugin, metaclass=abc.ABCMeta):
"""An identity plugin that is not version dependent.
Internally we will construct a version dependent plugin with the resolved

View File

@ -14,7 +14,6 @@ import abc
import logging
from oslo_config import cfg
import six
from keystoneclient import access
from keystoneclient.auth.identity import base
@ -24,8 +23,7 @@ from keystoneclient import utils
_logger = logging.getLogger(__name__)
@six.add_metaclass(abc.ABCMeta)
class Auth(base.BaseIdentityPlugin):
class Auth(base.BaseIdentityPlugin, metaclass=abc.ABCMeta):
"""Identity V2 Authentication Plugin.
:param string auth_url: Identity service endpoint for authorization.

View File

@ -15,7 +15,6 @@ import logging
from oslo_config import cfg
from oslo_serialization import jsonutils
import six
from keystoneclient import access
from keystoneclient.auth.identity import base
@ -27,8 +26,7 @@ _logger = logging.getLogger(__name__)
__all__ = ('Auth', 'AuthMethod', 'AuthConstructor', 'BaseAuth')
@six.add_metaclass(abc.ABCMeta)
class BaseAuth(base.BaseIdentityPlugin):
class BaseAuth(base.BaseIdentityPlugin, metaclass=abc.ABCMeta):
"""Identity V3 Authentication Plugin.
:param string auth_url: Identity service endpoint for authentication.
@ -198,8 +196,7 @@ class Auth(BaseAuth):
**resp_data)
@six.add_metaclass(abc.ABCMeta)
class AuthMethod(object):
class AuthMethod(object, metaclass=abc.ABCMeta):
"""One part of a V3 Authentication strategy.
V3 Tokens allow multiple methods to be presented when authentication
@ -243,8 +240,7 @@ class AuthMethod(object):
pass # pragma: no cover
@six.add_metaclass(abc.ABCMeta)
class AuthConstructor(Auth):
class AuthConstructor(Auth, metaclass=abc.ABCMeta):
"""Abstract base class for creating an Auth Plugin.
The Auth Plugin created contains only one authentication method. This

View File

@ -13,7 +13,6 @@
import abc
from oslo_config import cfg
import six
from keystoneclient.auth.identity.v3 import base
from keystoneclient.auth.identity.v3 import token
@ -21,8 +20,7 @@ from keystoneclient.auth.identity.v3 import token
__all__ = ('FederatedBaseAuth',)
@six.add_metaclass(abc.ABCMeta)
class FederatedBaseAuth(base.BaseAuth):
class FederatedBaseAuth(base.BaseAuth, metaclass=abc.ABCMeta):
rescoping_plugin = token.Token

View File

@ -20,13 +20,12 @@
import abc
import copy
import functools
import urllib
import warnings
from keystoneauth1 import exceptions as ksa_exceptions
from keystoneauth1 import plugin
from oslo_utils import strutils
import six
from six.moves import urllib
from keystoneclient import exceptions as ksc_exceptions
from keystoneclient.i18n import _
@ -265,8 +264,7 @@ class Manager(object):
return self._prepare_return_value(resp, body)
@six.add_metaclass(abc.ABCMeta)
class ManagerWithFind(Manager):
class ManagerWithFind(Manager, metaclass=abc.ABCMeta):
"""Manager with additional `find()`/`findall()` methods."""
@abc.abstractmethod

View File

@ -26,7 +26,6 @@ import logging
import zlib
from debtcollector import removals
import six
from keystoneclient import exceptions
from keystoneclient.i18n import _
@ -116,7 +115,7 @@ def _process_communicate_handle_oserror(process, data, files):
retcode, err = _check_files_accessible(files)
if process.stderr:
msg = process.stderr.read()
if isinstance(msg, six.binary_type):
if isinstance(msg, bytes):
msg = msg.decode('utf-8')
if err:
err = (_('Hit OSError in '
@ -133,7 +132,7 @@ def _process_communicate_handle_oserror(process, data, files):
else:
retcode = process.poll()
if err is not None:
if isinstance(err, six.binary_type):
if isinstance(err, bytes):
err = err.decode('utf-8')
return output, err, retcode
@ -162,8 +161,8 @@ def cms_verify(formatted, signing_cert_file_name, ca_file_name,
properly.
"""
_ensure_subprocess()
if isinstance(formatted, six.string_types):
data = bytearray(formatted, _encoding_for_form(inform))
if isinstance(formatted, str):
data = bytes(formatted, _encoding_for_form(inform))
else:
data = formatted
process = subprocess.Popen(['openssl', 'cms', '-verify',
@ -356,8 +355,8 @@ def cms_sign_data(data_to_sign, signing_cert_file_name, signing_key_file_name,
"""
_ensure_subprocess()
if isinstance(data_to_sign, six.string_types):
data = bytearray(data_to_sign, encoding='utf-8')
if isinstance(data_to_sign, str):
data = bytes(data_to_sign, encoding='utf-8')
else:
data = data_to_sign
process = subprocess.Popen(['openssl', 'cms', '-sign',
@ -437,7 +436,7 @@ def cms_hash_token(token_id, mode='md5'):
return None
if is_asn1_token(token_id) or is_pkiz(token_id):
hasher = hashlib.new(mode)
if isinstance(token_id, six.text_type):
if isinstance(token_id, str):
token_id = token_id.encode('utf-8')
hasher.update(token_id)
return hasher.hexdigest()

View File

@ -11,11 +11,11 @@
# under the License.
import datetime
import urllib.parse
import uuid
from lxml import etree # nosec(cjschaef): used to create xml, not parse it
from oslo_config import cfg
from six.moves import urllib
from keystoneclient import access
from keystoneclient.auth.identity import v3

View File

@ -20,9 +20,7 @@ import base64
import hashlib
import hmac
import re
import six
from six.moves import urllib
import urllib.parse
from keystoneclient.i18n import _
@ -106,9 +104,9 @@ class Ec2Signer(object):
@staticmethod
def _get_utf8_value(value):
"""Get the UTF8-encoded version of a value."""
if not isinstance(value, (six.binary_type, six.text_type)):
if not isinstance(value, (str, bytes)):
value = str(value)
if isinstance(value, six.text_type):
if isinstance(value, str):
return value.encode('utf-8')
else:
return value
@ -121,9 +119,7 @@ class Ec2Signer(object):
def _calc_signature_1(self, params):
"""Generate AWS signature version 1 string."""
keys = list(params)
keys.sort(key=six.text_type.lower)
for key in keys:
for key in sorted(params, key=str.lower):
self.hmac.update(key.encode('utf-8'))
val = self._get_utf8_value(params[key])
self.hmac.update(val)

View File

@ -14,9 +14,9 @@
# under the License.
import logging
import urllib.parse as urlparse
from debtcollector import removals
from six.moves.urllib import parse as urlparse
from keystoneclient import exceptions
from keystoneclient import httpclient

View File

@ -19,14 +19,11 @@
import abc
import warnings
import six
from keystoneclient import exceptions
from keystoneclient.i18n import _
@six.add_metaclass(abc.ABCMeta)
class ServiceCatalog(object):
class ServiceCatalog(object, metaclass=abc.ABCMeta):
"""Helper methods for dealing with a Keystone Service Catalog.
.. warning::

View File

@ -17,6 +17,7 @@ import logging
import os
import socket
import time
import urllib.parse
import warnings
from debtcollector import removals
@ -26,8 +27,6 @@ from oslo_utils import encodeutils
from oslo_utils import importutils
from oslo_utils import strutils
import requests
import six
from six.moves import urllib
from keystoneclient import exceptions
from keystoneclient.i18n import _
@ -191,7 +190,7 @@ class Session(object):
# so we need to actually check that this is False.
if self.verify is False:
string_parts.append('--insecure')
elif isinstance(self.verify, six.string_types):
elif isinstance(self.verify, str):
string_parts.append('--cacert "%s"' % self.verify)
if method:
@ -205,7 +204,7 @@ class Session(object):
% self._process_header(header))
if data:
if isinstance(data, six.binary_type):
if isinstance(data, bytes):
try:
data = data.decode("ascii")
except UnicodeDecodeError:

View File

@ -18,7 +18,6 @@ import uuid
from keystoneauth1 import fixture
from keystoneauth1 import plugin
from oslo_utils import timeutils
import six
from keystoneclient import access
from keystoneclient.auth import base
@ -28,8 +27,7 @@ from keystoneclient import session
from keystoneclient.tests.unit import utils
@six.add_metaclass(abc.ABCMeta)
class CommonIdentityTests(object):
class CommonIdentityTests(object, metaclass=abc.ABCMeta):
TEST_ROOT_URL = 'http://127.0.0.1:5000/'
TEST_ROOT_ADMIN_URL = 'http://127.0.0.1:35357/'

View File

@ -23,7 +23,6 @@ from keystoneauth1 import identity as ksa_identity
from keystoneauth1 import session as ksa_session
from oslo_serialization import jsonutils
from oslo_utils import timeutils
import six
import testresources
from keystoneclient.auth import identity as ksc_identity
@ -204,7 +203,7 @@ class KsaSessionV3(BaseV3):
def _hash_signed_token_safe(signed_text, **kwargs):
if isinstance(signed_text, six.text_type):
if isinstance(signed_text, str):
signed_text = signed_text.encode('utf-8')
return utils.hash_signed_token(signed_text, **kwargs)
@ -299,7 +298,7 @@ class Examples(fixtures.Fixture):
self.v3_UUID_TOKEN_UNKNOWN_BIND = '7ed9781b62cd4880b8d8c6788ab1d1e2'
revoked_token = self.REVOKED_TOKEN
if isinstance(revoked_token, six.text_type):
if isinstance(revoked_token, str):
revoked_token = revoked_token.encode('utf-8')
self.REVOKED_TOKEN_HASH = utils.hash_signed_token(revoked_token)
self.REVOKED_TOKEN_HASH_SHA256 = utils.hash_signed_token(revoked_token,
@ -310,7 +309,7 @@ class Examples(fixtures.Fixture):
self.REVOKED_TOKEN_LIST_JSON = jsonutils.dumps(self.REVOKED_TOKEN_LIST)
revoked_v3_token = self.REVOKED_v3_TOKEN
if isinstance(revoked_v3_token, six.text_type):
if isinstance(revoked_v3_token, str):
revoked_v3_token = revoked_v3_token.encode('utf-8')
self.REVOKED_v3_TOKEN_HASH = utils.hash_signed_token(revoked_v3_token)
hash = utils.hash_signed_token(revoked_v3_token, mode='sha256')
@ -322,12 +321,12 @@ class Examples(fixtures.Fixture):
self.REVOKED_v3_TOKEN_LIST)
revoked_token_pkiz = self.REVOKED_TOKEN_PKIZ
if isinstance(revoked_token_pkiz, six.text_type):
if isinstance(revoked_token_pkiz, str):
revoked_token_pkiz = revoked_token_pkiz.encode('utf-8')
self.REVOKED_TOKEN_PKIZ_HASH = utils.hash_signed_token(
revoked_token_pkiz)
revoked_v3_token_pkiz = self.REVOKED_v3_TOKEN_PKIZ
if isinstance(revoked_v3_token_pkiz, six.text_type):
if isinstance(revoked_v3_token_pkiz, str):
revoked_v3_token_pkiz = revoked_v3_token_pkiz.encode('utf-8')
self.REVOKED_v3_PKIZ_TOKEN_HASH = utils.hash_signed_token(
revoked_v3_token_pkiz)

View File

@ -15,7 +15,6 @@ import uuid
from keystoneauth1 import fixture
from oslo_serialization import jsonutils
import six
from testtools import matchers
from keystoneclient import _discover
@ -105,7 +104,7 @@ V3_VERSION = fixture.V3Discovery(V3_URL)
V3_MEDIA_TYPES = V3_VERSION.media_types
V3_VERSION.updated_str = UPDATED
V3_TOKEN = six.u('3e2813b7ba0b4006840c3825860b86ed'),
V3_TOKEN = ('3e2813b7ba0b4006840c3825860b86ed',)
V3_AUTH_RESPONSE = jsonutils.dumps({
"token": {
"methods": [

View File

@ -12,9 +12,9 @@
# License for the specific language governing permissions and limitations
# under the License.
import io
import logging
import six
from testtools import matchers
from keystoneclient import exceptions
@ -153,7 +153,7 @@ class BasicRequestTests(utils.TestCase):
def setUp(self):
super(BasicRequestTests, self).setUp()
self.logger_message = six.moves.cStringIO()
self.logger_message = io.StringIO()
handler = logging.StreamHandler(self.logger_message)
handler.setLevel(logging.DEBUG)

View File

@ -13,6 +13,7 @@
# under the License.
import argparse
from io import StringIO
import itertools
import logging
from unittest import mock
@ -22,7 +23,6 @@ from oslo_config import cfg
from oslo_config import fixture as config
from oslo_serialization import jsonutils
import requests
import six
from testtools import matchers
from keystoneclient import adapter
@ -249,27 +249,6 @@ class SessionTests(utils.TestCase):
self.assertIn("'%s'" % data, self.logger.output)
def test_binary_data_not_in_debug_output(self):
"""Verify that non-ascii-encodable data causes replacement."""
if six.PY2:
data = "my data" + chr(255)
else:
# Python 3 logging handles binary data well.
return
session = client_session.Session(verify=False)
body = 'RESP'
self.stub_url('POST', text=body)
# Forced mixed unicode and byte strings in request
# elements to make sure that all joins are appropriately
# handled (any join of unicode and byte strings should
# raise a UnicodeDecodeError)
session.post(six.text_type(self.TEST_URL), data=data)
self.assertNotIn('my data', self.logger.output)
def test_logging_cacerts(self):
path_to_certs = '/path/to/certs'
session = client_session.Session(verify=path_to_certs)
@ -328,11 +307,12 @@ class SessionTests(utils.TestCase):
# The exception should contain the URL and details about the SSL error
msg = _('SSL exception connecting to %(url)s: %(error)s') % {
'url': self.TEST_URL, 'error': error}
six.assertRaisesRegex(self,
exceptions.SSLError,
msg,
session.get,
self.TEST_URL)
self.assertRaisesRegex(
exceptions.SSLError,
msg,
session.get,
self.TEST_URL,
)
def test_mask_password_in_http_log_response(self):
session = client_session.Session()
@ -807,7 +787,7 @@ class SessionAuthTests(utils.TestCase):
logger.setLevel(logging.DEBUG)
logger.propagate = False
io = six.StringIO()
io = StringIO()
handler = logging.StreamHandler(io)
logger.addHandler(handler)
@ -1003,7 +983,7 @@ class AdapterTest(utils.TestCase):
logger.setLevel(logging.DEBUG)
logger.propagate = False
io = six.StringIO()
io = StringIO()
handler = logging.StreamHandler(io)
logger.addHandler(handler)

View File

@ -11,7 +11,6 @@
# under the License.
from keystoneauth1 import exceptions as ksa_exceptions
import six
import testresources
from testtools import matchers
@ -112,8 +111,7 @@ class HashSignedTokenTestCase(test_utils.TestCase,
def test_default_md5(self):
"""The default hash method is md5."""
token = self.examples.SIGNED_TOKEN_SCOPED
if six.PY3:
token = token.encode('utf-8')
token = token.encode('utf-8')
token_id_default = utils.hash_signed_token(token)
token_id_md5 = utils.hash_signed_token(token, mode='md5')
self.assertThat(token_id_default, matchers.Equals(token_id_md5))
@ -123,8 +121,7 @@ class HashSignedTokenTestCase(test_utils.TestCase,
def test_sha256(self):
"""Can also hash with sha256."""
token = self.examples.SIGNED_TOKEN_SCOPED
if six.PY3:
token = token.encode('utf-8')
token = token.encode('utf-8')
token_id = utils.hash_signed_token(token, mode='sha256')
# sha256 hash is 64 chars.
self.assertThat(token_id, matchers.HasLength(64))

View File

@ -12,6 +12,7 @@
import logging
import sys
import urllib.parse as urlparse
import uuid
import fixtures
@ -19,7 +20,6 @@ from oslo_serialization import jsonutils
import requests
import requests_mock
from requests_mock.contrib import fixture
from six.moves.urllib import parse as urlparse
import testscenarios
import testtools

View File

@ -10,9 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import six
SP_SOAP_RESPONSE = six.b("""<S:Envelope
SP_SOAP_RESPONSE = b"""<S:Envelope
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<paos:Request xmlns:paos="urn:liberty:paos:2003-08"
@ -44,10 +42,10 @@ AssertionConsumerServiceURL="https://openstack4.local/Shibboleth.sso/SAML2/ECP"
<samlp:IDPList>
<samlp:IDPEntry ProviderID="https://idp.testshib.org/idp/shibboleth"/>
</samlp:IDPList></samlp:Scoping></samlp:AuthnRequest></S:Body></S:Envelope>
""")
"""
SAML2_ASSERTION = six.b("""<?xml version="1.0" encoding="UTF-8"?>
SAML2_ASSERTION = b"""<?xml version="1.0" encoding="UTF-8"?>
<soap11:Envelope xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<soap11:Header>
<ecp:Response xmlns:ecp="urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp"
@ -95,7 +93,7 @@ xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
<xenc:CipherValue>VALUE=</xenc:CipherValue></xenc:CipherData>
</xenc:EncryptedData></saml2:EncryptedAssertion></saml2p:Response>
</soap11:Body></soap11:Envelope>
""")
"""
UNSCOPED_TOKEN_HEADER = 'UNSCOPED_TOKEN'

View File

@ -10,10 +10,11 @@
# License for the specific language governing permissions and limitations
# under the License.
import urllib.parse
import uuid
from oslo_config import fixture as config
from six.moves import urllib
import testtools
from keystoneclient.auth import conf

View File

@ -11,12 +11,12 @@
# under the License.
import os
import urllib.parse
import uuid
from lxml import etree
from oslo_config import fixture as config
import requests
from six.moves import urllib
from keystoneclient.auth import conf
from keystoneclient.contrib.auth.v3 import saml2

View File

@ -19,7 +19,6 @@ from keystoneauth1 import fixture
from keystoneauth1.identity import v3
from keystoneauth1 import session
from keystoneauth1.tests.unit import k2k_fixtures
import six
from testtools import matchers
from keystoneclient import access
@ -423,7 +422,7 @@ class K2KFederatedProjectTests(utils.TestCase):
self.requests_mock.register_uri(
'POST',
self.REQUEST_ECP_URL,
content=six.b(k2k_fixtures.ECP_ENVELOPE),
content=k2k_fixtures.ECP_ENVELOPE.encode(),
headers={'Content-Type': 'application/vnd.paos+xml'},
status_code=200)
@ -433,7 +432,7 @@ class K2KFederatedProjectTests(utils.TestCase):
self.requests_mock.register_uri(
'POST',
self.SP_URL,
content=six.b(k2k_fixtures.TOKEN_BASED_ECP),
content=k2k_fixtures.TOKEN_BASED_ECP.encode(),
headers={'Content-Type': 'application/vnd.paos+xml'},
status_code=302)

View File

@ -14,10 +14,9 @@
from unittest import mock
import fixtures
from urllib import parse as urlparse
import uuid
import six
from six.moves.urllib import parse as urlparse
from testtools import matchers
from keystoneclient import session
@ -106,7 +105,7 @@ class TokenTests(object):
self.assertEqual('HMAC-SHA1', parameters['oauth_signature_method'])
self.assertEqual('1.0', parameters['oauth_version'])
self.assertIsInstance(parameters['oauth_nonce'], six.string_types)
self.assertIsInstance(parameters['oauth_nonce'], str)
self.assertEqual(oauth_client.client_key,
parameters['oauth_consumer_key'])
if oauth_client.resource_owner_key:

View File

@ -13,7 +13,7 @@
import requests
import uuid
from six.moves.urllib import parse as urlparse
from urllib import parse as urlparse
from keystoneauth1.identity import v3
from keystoneauth1 import session

View File

@ -16,7 +16,6 @@ import sys
from keystoneauth1 import exceptions as ksa_exceptions
from oslo_utils import timeutils
import six
from keystoneclient import exceptions as ksc_exceptions
@ -27,12 +26,12 @@ def find_resource(manager, name_or_id):
try:
return manager.get(name_or_id)
except (ksa_exceptions.NotFound): # nosec(cjschaef): try to find
# 'name_or_id' as a six.binary_type instead
# 'name_or_id' as a bytes instead
pass
# finally try to find entity by name
try:
if isinstance(name_or_id, six.binary_type):
if isinstance(name_or_id, bytes):
name_or_id = name_or_id.decode('utf-8', 'strict')
return manager.find(name=name_or_id)
except ksa_exceptions.NotFound:

View File

@ -15,7 +15,7 @@
# under the License.
from keystoneauth1 import plugin
from six.moves import urllib
import urllib.parse
from keystoneclient import base
from keystoneclient import exceptions

View File

@ -14,9 +14,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from six.moves import urllib
from keystoneclient import base
import urllib.parse
class User(base.Resource):

View File

@ -12,8 +12,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import six
from keystoneclient import base
from keystoneclient import exceptions
from keystoneclient.i18n import _
@ -78,7 +76,7 @@ class ApplicationCredentialManager(base.CrudManager):
if not isinstance(roles, list):
roles = [roles]
for role in roles:
if isinstance(role, six.string_types):
if isinstance(role, str):
role_list.extend([{'id': role}])
elif isinstance(role, dict):
role_list.extend([role])

View File

@ -14,13 +14,11 @@ import abc
from keystoneauth1 import exceptions
from keystoneauth1 import plugin
import six
from keystoneclient import base
@six.add_metaclass(abc.ABCMeta)
class EntityManager(base.Manager):
class EntityManager(base.Manager, metaclass=abc.ABCMeta):
"""Manager class for listing federated accessible objects."""
resource_class = None

View File

@ -11,8 +11,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import urllib.parse as urlparse
from keystoneauth1 import plugin
from six.moves.urllib import parse as urlparse
from keystoneclient import base
from keystoneclient.v3.contrib.oauth1 import utils

View File

@ -11,8 +11,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import six
from six.moves.urllib import parse as urlparse
import urllib.parse as urlparse
OAUTH_PATH = '/OS-OAUTH1'
@ -25,8 +24,7 @@ def get_oauth_token_from_body(body):
'oauth_token=12345&oauth_token_secret=67890' with
'oauth_expires_at=2013-03-30T05:27:19.463201' possibly there, too.
"""
if six.PY3:
body = body.decode('utf-8')
body = body.decode('utf-8')
credentials = urlparse.parse_qs(body)
key = credentials['oauth_token'][0]

View File

@ -14,7 +14,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import six.moves.urllib as urllib
import urllib.parse
from keystoneclient import base
from keystoneclient import exceptions

View File

@ -15,6 +15,5 @@ oslo.i18n>=3.15.3 # Apache-2.0
oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0
oslo.utils>=3.33.0 # Apache-2.0
requests>=2.14.2 # Apache-2.0
six>=1.10.0 # MIT
stevedore>=1.20.0 # Apache-2.0
packaging>=20.4 # BSD