Make APIVersion's null check more pythonic
Our current APIVersion object has an is_null method to check when the version instance is null (major=0 and minor=0). While this works it is not very pythonic, since you have to write expressions such as: if not min_version and not max_version: return True elif ((min_version and max_version) and max_version.is_null() and min_version.is_null()): return True This patch removes the is_null method and instead implements the truth value testing to simplify expressions and make code more pythonic. So previous code would just look like: if not min_version and not max_version: return True Because this will work with min_version being None or being an APIVersion instance with major=0 and minor=0. Change-Id: I7497c5dc940c1e726507117cadbad232d8c1d80d
This commit is contained in:
parent
8db4ca1d90
commit
8b5a772e36
cinderclient
@ -75,13 +75,14 @@ class APIVersion(object):
|
||||
% (self.ver_major, self.ver_minor))
|
||||
|
||||
def __repr__(self):
|
||||
if self.is_null():
|
||||
return "<APIVersion: null>"
|
||||
else:
|
||||
if self:
|
||||
return "<APIVersion: %s>" % self.get_string()
|
||||
return "<APIVersion: null>"
|
||||
|
||||
def is_null(self):
|
||||
return self.ver_major == 0 and self.ver_minor == 0
|
||||
def __bool__(self):
|
||||
return self.ver_major != 0 or self.ver_minor != 0
|
||||
|
||||
__nonzero__ = __bool__
|
||||
|
||||
def is_latest(self):
|
||||
return self.ver_minor == float("inf")
|
||||
@ -133,7 +134,7 @@ class APIVersion(object):
|
||||
If self is null then raise ValueError
|
||||
"""
|
||||
|
||||
if self.is_null():
|
||||
if not self:
|
||||
raise ValueError("Null APIVersion doesn't support 'matches'.")
|
||||
|
||||
if isinstance(min_version, str):
|
||||
@ -141,24 +142,21 @@ class APIVersion(object):
|
||||
if isinstance(max_version, str):
|
||||
max_version = APIVersion(version_str=max_version)
|
||||
|
||||
# This will work when they are None and when they are version 0.0
|
||||
if not min_version and not max_version:
|
||||
return True
|
||||
elif ((min_version and max_version) and
|
||||
max_version.is_null() and min_version.is_null()):
|
||||
return True
|
||||
|
||||
elif not max_version or max_version.is_null():
|
||||
if not max_version:
|
||||
return min_version <= self
|
||||
elif not min_version or min_version.is_null():
|
||||
if not min_version:
|
||||
return self <= max_version
|
||||
else:
|
||||
return min_version <= self <= max_version
|
||||
return min_version <= self <= max_version
|
||||
|
||||
def get_string(self):
|
||||
"""Converts object to string representation which if used to create
|
||||
an APIVersion object results in the same version.
|
||||
"""
|
||||
if self.is_null():
|
||||
if not self:
|
||||
raise ValueError("Null APIVersion cannot be converted to string.")
|
||||
elif self.is_latest():
|
||||
return "%s.%s" % (self.ver_major, "latest")
|
||||
@ -208,8 +206,7 @@ def check_major_version(api_version):
|
||||
supported
|
||||
"""
|
||||
available_versions = get_available_major_versions()
|
||||
if (not api_version.is_null() and
|
||||
str(api_version.ver_major) not in available_versions):
|
||||
if (api_version and str(api_version.ver_major) not in available_versions):
|
||||
if len(available_versions) == 1:
|
||||
msg = ("Invalid client version '%(version)s'. "
|
||||
"Major part should be '%(major)s'") % {
|
||||
@ -260,9 +257,10 @@ def discover_version(client, requested_version):
|
||||
server_start_version, server_end_version = _get_server_version_range(
|
||||
client)
|
||||
|
||||
both_versions_null = not (server_start_version or server_end_version)
|
||||
if (not requested_version.is_latest() and
|
||||
requested_version != APIVersion('2.0')):
|
||||
if server_start_version.is_null() and server_end_version.is_null():
|
||||
if both_versions_null:
|
||||
raise exceptions.UnsupportedVersion(
|
||||
_("Server doesn't support microversions"))
|
||||
if not requested_version.matches(server_start_version,
|
||||
@ -275,18 +273,15 @@ def discover_version(client, requested_version):
|
||||
return requested_version
|
||||
|
||||
if requested_version == APIVersion('2.0'):
|
||||
if (server_start_version == APIVersion('2.1') or
|
||||
(server_start_version.is_null() and
|
||||
server_end_version.is_null())):
|
||||
if server_start_version == APIVersion('2.1') or both_versions_null:
|
||||
return APIVersion('2.0')
|
||||
else:
|
||||
raise exceptions.UnsupportedVersion(
|
||||
_("The server isn't backward compatible with Cinder V2 REST "
|
||||
"API"))
|
||||
raise exceptions.UnsupportedVersion(
|
||||
_("The server isn't backward compatible with Cinder V2 REST "
|
||||
"API"))
|
||||
|
||||
if server_start_version.is_null() and server_end_version.is_null():
|
||||
if both_versions_null:
|
||||
return APIVersion('2.0')
|
||||
elif cinderclient.API_MIN_VERSION > server_end_version:
|
||||
if cinderclient.API_MIN_VERSION > server_end_version:
|
||||
raise exceptions.UnsupportedVersion(
|
||||
_("Server version is too old. The client valid version range is "
|
||||
"'%(client_min)s' to '%(client_max)s'. The server valid version "
|
||||
@ -315,7 +310,7 @@ def update_headers(headers, api_version):
|
||||
null
|
||||
"""
|
||||
|
||||
if not api_version.is_null() and api_version.ver_minor != 0:
|
||||
if api_version and api_version.ver_minor != 0:
|
||||
headers["OpenStack-API-Version"] = "volume " + api_version.get_string()
|
||||
|
||||
|
||||
@ -326,7 +321,7 @@ def add_substitution(versioned_method):
|
||||
|
||||
def get_substitutions(func_name, api_version=None):
|
||||
substitutions = _SUBSTITUTIONS.get(func_name, [])
|
||||
if api_version and not api_version.is_null():
|
||||
if api_version:
|
||||
return [m for m in substitutions
|
||||
if api_version.matches(m.start_version, m.end_version)]
|
||||
return substitutions
|
||||
|
@ -34,19 +34,19 @@ class UnsupportedAttribute(AttributeError):
|
||||
"""
|
||||
|
||||
def __init__(self, argument_name, start_version, end_version):
|
||||
if not start_version.is_null() and not end_version.is_null():
|
||||
if start_version and end_version:
|
||||
self.message = (
|
||||
"'%(name)s' argument is only allowed for microversions "
|
||||
"%(start)s - %(end)s." % {"name": argument_name,
|
||||
"start": start_version.get_string(),
|
||||
"end": end_version.get_string()})
|
||||
elif not start_version.is_null():
|
||||
elif start_version:
|
||||
self.message = (
|
||||
"'%(name)s' argument is only allowed since microversion "
|
||||
"%(start)s." % {"name": argument_name,
|
||||
"start": start_version.get_string()})
|
||||
|
||||
elif not end_version.is_null():
|
||||
elif end_version:
|
||||
self.message = (
|
||||
"'%(name)s' argument is not allowed after microversion "
|
||||
"%(end)s." % {"name": argument_name,
|
||||
|
@ -433,11 +433,11 @@ class OpenStackCinderShell(object):
|
||||
subparser.set_defaults(func=self.do_bash_completion)
|
||||
|
||||
def _build_versioned_help_message(self, start_version, end_version):
|
||||
if not start_version.is_null() and not end_version.is_null():
|
||||
if start_version and end_version:
|
||||
msg = (_(" (Supported by API versions %(start)s - %(end)s)")
|
||||
% {"start": start_version.get_string(),
|
||||
"end": end_version.get_string()})
|
||||
elif not start_version.is_null():
|
||||
elif start_version:
|
||||
msg = (_(" (Supported by API version %(start)s and later)")
|
||||
% {"start": start_version.get_string()})
|
||||
else:
|
||||
@ -504,8 +504,7 @@ class OpenStackCinderShell(object):
|
||||
start_version = api_versions.APIVersion(start_version)
|
||||
end_version = kwargs.get('end_version', None)
|
||||
end_version = api_versions.APIVersion(end_version)
|
||||
if do_help and not (start_version.is_null()
|
||||
and end_version.is_null()):
|
||||
if do_help and (start_version or end_version):
|
||||
kwargs["help"] = kwargs.get("help", "") + (
|
||||
self._build_versioned_help_message(start_version,
|
||||
end_version))
|
||||
|
@ -40,7 +40,11 @@ class APIVersionTestCase(utils.TestCase):
|
||||
|
||||
def test_null_version(self):
|
||||
v = api_versions.APIVersion()
|
||||
self.assertTrue(v.is_null())
|
||||
self.assertFalse(v)
|
||||
|
||||
def test_not_null_version(self):
|
||||
v = api_versions.APIVersion('1.1')
|
||||
self.assertTrue(v)
|
||||
|
||||
@ddt.data("2", "200", "2.1.4", "200.23.66.3", "5 .3", "5. 3", "5.03",
|
||||
"02.1", "2.001", "", " 2.1", "2.1 ")
|
||||
@ -159,16 +163,24 @@ class GetAPIVersionTestCase(utils.TestCase):
|
||||
self.assertRaises(exceptions.UnsupportedVersion,
|
||||
api_versions.get_api_version, "4")
|
||||
|
||||
@mock.patch("cinderclient.api_versions.get_available_major_versions")
|
||||
@mock.patch("cinderclient.api_versions.APIVersion")
|
||||
def test_only_major_part_is_presented(self, mock_apiversion):
|
||||
def test_only_major_part_is_presented(self, mock_apiversion,
|
||||
mock_get_majors):
|
||||
mock_get_majors.return_value = [
|
||||
str(mock_apiversion.return_value.ver_major)]
|
||||
version = 7
|
||||
self.assertEqual(mock_apiversion.return_value,
|
||||
api_versions.get_api_version(version))
|
||||
mock_apiversion.assert_called_once_with("%s.0" % str(version))
|
||||
|
||||
@mock.patch("cinderclient.api_versions.get_available_major_versions")
|
||||
@mock.patch("cinderclient.api_versions.APIVersion")
|
||||
def test_major_and_minor_parts_is_presented(self, mock_apiversion):
|
||||
def test_major_and_minor_parts_is_presented(self, mock_apiversion,
|
||||
mock_get_majors):
|
||||
version = "2.7"
|
||||
mock_get_majors.return_value = [
|
||||
str(mock_apiversion.return_value.ver_major)]
|
||||
self.assertEqual(mock_apiversion.return_value,
|
||||
api_versions.get_api_version(version))
|
||||
mock_apiversion.assert_called_once_with(version)
|
||||
|
Loading…
x
Reference in New Issue
Block a user