diff --git a/glance/common/wsgi.py b/glance/common/wsgi.py index bc0bb084ff..95d772ad3d 100644 --- a/glance/common/wsgi.py +++ b/glance/common/wsgi.py @@ -53,12 +53,6 @@ from glance import i18n from glance.i18n import _, _LE, _LI, _LW -try: - from webob.acceptparse import AcceptLanguageValidHeader # noqa - USING_WEBOB_1_8 = True -except ImportError: - USING_WEBOB_1_8 = False - bind_opts = [ cfg.HostAddressOpt('bind_host', default='0.0.0.0', @@ -1048,18 +1042,7 @@ class Request(webob.Request): else: return content_type - def _best_match_language_1_7(self): - """Determines best available locale from the Accept-Language header. - - :returns: the best language match or None if the 'Accept-Language' - header was not available in the request. - """ - if not self.accept_language: - return None - langs = i18n.get_available_languages('glance') - return self.accept_language.best_match(langs) - - def _best_match_language_1_8(self): + def best_match_language(self): """Determines best available locale from the Accept-Language header. :returns: the best language match or None if the 'Accept-Language' @@ -1076,12 +1059,6 @@ class Request(webob.Request): best_match = None return best_match - def best_match_language(self): - if USING_WEBOB_1_8: - return self._best_match_language_1_8() - else: - return self._best_match_language_1_7() - def get_range_from_request(self, image_size): """Return the `Range` in a request.""" diff --git a/glance/tests/unit/common/test_wsgi.py b/glance/tests/unit/common/test_wsgi.py index adda23e11d..794873d427 100644 --- a/glance/tests/unit/common/test_wsgi.py +++ b/glance/tests/unit/common/test_wsgi.py @@ -184,31 +184,20 @@ class RequestTest(test_utils.BaseTestCase): req = wsgi.Request.blank('/', headers={'Accept-Language': 'unknown'}) self.assertIsNone(req.best_match_language()) - def test_best_match_language_unknown(self): - # Test that we are actually invoking language negotiation by webop + @mock.patch.object(webob.acceptparse.AcceptLanguageValidHeader, 'lookup') + def test_best_match_language_unknown(self, mock_lookup): + # Test that we are actually invoking language negotiation by WebOb request = wsgi.Request.blank('/') accepted = 'unknown-lang' request.headers = {'Accept-Language': accepted} - # TODO(rosmaita): simplify when lower_constraints has webob >= 1.8.1 - try: - from webob.acceptparse import AcceptLanguageValidHeader # noqa - cls = webob.acceptparse.AcceptLanguageValidHeader - funcname = 'lookup' - # Bug #1765748: see comment in code in the function under test - # to understand why this is the correct return value for the - # webob 1.8.x mock - retval = 'fake_LANG' - except ImportError: - cls = webob.acceptparse.AcceptLanguage - funcname = 'best_match' - retval = None + # Bug #1765748: see comment in code in the function under test + # to understand why this is the correct return value for the + # webob 1.8.x mock + mock_lookup.return_value = 'fake_LANG' - with mock.patch.object(cls, funcname) as mocked_function: - mocked_function.return_value = retval - - self.assertIsNone(request.best_match_language()) - mocked_function.assert_called_once() + self.assertIsNone(request.best_match_language()) + mock_lookup.assert_called_once() # If Accept-Language is missing or empty, match should be None request.headers = {'Accept-Language': ''} @@ -389,27 +378,18 @@ class ResourceTest(test_utils.BaseTestCase): resource, request) self.assertEqual(message_es, str(e)) + @mock.patch.object(webob.acceptparse.AcceptLanguageValidHeader, 'lookup') @mock.patch.object(i18n, 'translate') - def test_translate_exception(self, mock_translate): - # TODO(rosmaita): simplify when lower_constraints has webob >= 1.8.1 - try: - from webob.acceptparse import AcceptLanguageValidHeader # noqa - cls = webob.acceptparse.AcceptLanguageValidHeader - funcname = 'lookup' - except ImportError: - cls = webob.acceptparse.AcceptLanguage - funcname = 'best_match' + def test_translate_exception(self, mock_translate, mock_lookup): + mock_translate.return_value = 'No Encontrado' + mock_lookup.return_value = 'de' - with mock.patch.object(cls, funcname) as mocked_function: - mock_translate.return_value = 'No Encontrado' - mocked_function.return_value = 'de' + req = wsgi.Request.blank('/tests/123') + req.headers["Accept-Language"] = "de" - req = wsgi.Request.blank('/tests/123') - req.headers["Accept-Language"] = "de" - - e = webob.exc.HTTPNotFound(explanation='Not Found') - e = wsgi.translate_exception(req, e) - self.assertEqual('No Encontrado', e.explanation) + e = webob.exc.HTTPNotFound(explanation='Not Found') + e = wsgi.translate_exception(req, e) + self.assertEqual('No Encontrado', e.explanation) def test_response_headers_encoded(self): # prepare environment diff --git a/lower-constraints.txt b/lower-constraints.txt index beac1f1604..4e158cd56c 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -138,7 +138,7 @@ unittest2==1.1.0 urllib3==1.22 vine==1.1.4 voluptuous==0.11.1 -WebOb==1.7.1 +WebOb==1.8.1 whereto===0.3.0 wrapt==1.10.11 WSME==0.8.0 diff --git a/releasenotes/notes/use-webob-1.8.1-5c3cd1b1382f063e.yaml b/releasenotes/notes/use-webob-1.8.1-5c3cd1b1382f063e.yaml new file mode 100644 index 0000000000..21d8d3e5bc --- /dev/null +++ b/releasenotes/notes/use-webob-1.8.1-5c3cd1b1382f063e.yaml @@ -0,0 +1,12 @@ +--- +other: + - | + Negotiation of the 'Accept-Language' header now follows the "Lookup" + matching scheme described in `RFC 4647, section 3.4 + `_. The + "Lookup" scheme is one of the algorithms suggested in `RFC 7231, + section 5.3.5 + `_. (This is + due to a change in an underlying library, which previously used a + matching scheme that did not conform to `RFC 7231 + `_.) diff --git a/requirements.txt b/requirements.txt index 1b50271243..349d731109 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ SQLAlchemy!=1.1.5,!=1.1.6,!=1.1.7,!=1.1.8,>=1.0.10 # MIT eventlet!=0.18.3,!=0.20.1,>=0.18.2 # MIT PasteDeploy>=1.5.0 # MIT Routes>=2.3.1 # MIT -WebOb>=1.7.1 # MIT +WebOb>=1.8.1 # MIT sqlalchemy-migrate>=0.11.0 # Apache-2.0 sqlparse>=0.2.2 # BSD alembic>=0.8.10 # MIT