Fix best_match() deprecation warning

wsgi call to best_match() generates the following warning:

DeprecationWarning: The behavior of .best_match for the Accept classes
is currently being maintained for backward compatibility,
but the method will be deprecated in the future,
as its behavior is not specified in
(and currently does not conform to) RFC 7231.

See the following URL for more information about deprecation.

https://docs.pylonsproject.org/projects/webob/en/stable/api/webob.html#webob.acceptparse.AcceptValidHeader.best_match

Simlar changes in the wsgi best language code as well,
except new call is to lookup().

Change-Id: Ib93ffffd3f28aa6d53a0a4eed5aeee94900cb073
Closes-Bug: #1798224
This commit is contained in:
Takashi NATSUME 2018-10-16 14:14:56 +09:00
parent 95a5ae3065
commit b9bc20ed39
2 changed files with 44 additions and 13 deletions

View File

@ -96,8 +96,10 @@ class Request(wsgi.Request):
content_type = possible_type
if not content_type:
content_type = self.accept.best_match(
best_matches = self.accept.acceptable_offers(
get_supported_content_types())
if best_matches:
content_type = best_matches[0][0]
self.environ['nova.best_content_type'] = (content_type or
'application/json')
@ -134,8 +136,19 @@ class Request(wsgi.Request):
"""
if not self.accept_language:
return None
return self.accept_language.best_match(
i18n.get_available_languages())
# NOTE(takashin): To decide the default behavior, 'default' is
# preferred over 'default_tag' because that is return as it is when
# no match. This is also little tricky that 'default' value cannot be
# None. At least one of default_tag or default must be supplied as
# an argument to the method, to define the defaulting behavior.
# So passing a sentinal value to return None from this function.
best_match = self.accept_language.lookup(
i18n.get_available_languages(), default='fake_LANG')
if best_match == 'fake_LANG':
best_match = None
return best_match
def set_api_version_request(self):
"""Set API version request based on the request header information."""

View File

@ -50,7 +50,7 @@ class RequestTest(MicroversionedTest):
super(RequestTest, self).setUp()
self.stub_out('nova.i18n.get_available_languages',
lambda *args, **kwargs:
['en_GB', 'en_AU', 'de', 'zh_CN', 'en_US'])
['en-GB', 'en-AU', 'de', 'zh-CN', 'en-US', 'ja-JP'])
def test_content_type_missing(self):
request = wsgi.Request.blank('/tests/123', method='POST')
@ -76,31 +76,49 @@ class RequestTest(MicroversionedTest):
result = request.best_match_content_type()
self.assertEqual(result, "application/json")
def test_content_type_accept_with_quality_values(self):
request = wsgi.Request.blank('/tests/123')
request.headers["Accept"] = (
"application/json;q=0.4,"
"application/vnd.openstack.compute+json;q=0.6")
result = request.best_match_content_type()
self.assertEqual("application/vnd.openstack.compute+json", result)
def test_from_request(self):
request = wsgi.Request.blank('/')
accepted = 'bogus;q=1, en-gb;q=0.7,en-us,en;q=0.5,*;q=0.7'
request.headers = {'Accept-Language': accepted}
self.assertEqual(request.best_match_language(), 'en_US')
self.assertEqual(request.best_match_language(), 'en-US')
def test_asterisk(self):
# asterisk should match first available if there
# are not any other available matches
# In the section 3.4 of RFC4647, it says as follows:
# If the language range "*"(asterisk) is the only one
# in the language priority list or if no other language range
# follows, the default value is computed and returned.
#
# In this case, the default value 'None' is returned.
request = wsgi.Request.blank('/')
accepted = '*,es;q=0.5'
accepted = '*;q=0.5'
request.headers = {'Accept-Language': accepted}
self.assertEqual(request.best_match_language(), 'en_GB')
self.assertIsNone(request.best_match_language())
def test_prefix(self):
def test_asterisk_followed_by_other_language(self):
request = wsgi.Request.blank('/')
accepted = 'zh'
accepted = '*,ja-jp;q=0.5'
request.headers = {'Accept-Language': accepted}
self.assertEqual(request.best_match_language(), 'zh_CN')
self.assertEqual('ja-JP', request.best_match_language())
def test_truncate(self):
request = wsgi.Request.blank('/')
accepted = 'de-CH'
request.headers = {'Accept-Language': accepted}
self.assertEqual('de', request.best_match_language())
def test_secondary(self):
request = wsgi.Request.blank('/')
accepted = 'nn,en-gb;q=0.5'
request.headers = {'Accept-Language': accepted}
self.assertEqual(request.best_match_language(), 'en_GB')
self.assertEqual('en-GB', request.best_match_language())
def test_none_found(self):
request = wsgi.Request.blank('/')