diff options
| author | Michael Merickel <github@m.merickel.org> | 2018-11-03 13:12:37 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-11-03 13:12:37 -0500 |
| commit | fc67869fb2732e715905614af3f9a69d48aed644 (patch) | |
| tree | 05c3c6163ba096f8aeda882c25e4b405fce4423e | |
| parent | aa1660f3d9a5dc654a91544d72de596af2fdf9ba (diff) | |
| parent | 0cef6bc5d627524354c47295df7a0aa84a64539e (diff) | |
| download | pyramid-fc67869fb2732e715905614af3f9a69d48aed644.tar.gz pyramid-fc67869fb2732e715905614af3f9a69d48aed644.tar.bz2 pyramid-fc67869fb2732e715905614af3f9a69d48aed644.zip | |
Merge pull request #3411 from mmerickel/drop-media-ranges
remove deprecated media range support from add_view and add_route
| -rw-r--r-- | CHANGES.rst | 7 | ||||
| -rw-r--r-- | docs/narr/viewconfig.rst | 4 | ||||
| -rw-r--r-- | src/pyramid/config/predicates.py | 4 | ||||
| -rw-r--r-- | src/pyramid/config/routes.py | 27 | ||||
| -rw-r--r-- | src/pyramid/config/views.py | 21 | ||||
| -rw-r--r-- | src/pyramid/predicates.py | 8 | ||||
| -rw-r--r-- | tests/test_config/test_routes.py | 18 | ||||
| -rw-r--r-- | tests/test_config/test_views.py | 29 | ||||
| -rw-r--r-- | tests/test_integration.py | 39 |
9 files changed, 36 insertions, 121 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index cd2d05054..f847cec7a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -32,6 +32,13 @@ Backward Incompatibilities request. For example, ``request.authenticated_userid``. See https://github.com/Pylons/pyramid/pull/3410 +- Removed support for supplying a media range to the ``accept`` predicate of + both ``pyramid.config.Configurator.add_view`` and + ``pyramid.config.Configurator.add_route``. These options were deprecated + in Pyramid 1.10 and WebOb 1.8 because they resulted in uncontrollable + matching that was not compliant with the RFC. + See https://github.com/Pylons/pyramid/pull/3411 + Documentation Changes --------------------- diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index dd767e3f1..da2c41409 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -302,6 +302,10 @@ Non-Predicate Arguments Specifying a media range is deprecated and will be removed in :app:`Pyramid` 2.0. Use explicit media types to avoid any ambiguities in content negotiation. + .. versionchanged:: 2.0 + + Removed support for media ranges. + ``exception_only`` When this value is ``True``, the ``context`` argument must be a subclass of diff --git a/src/pyramid/config/predicates.py b/src/pyramid/config/predicates.py index 8f16f74af..31e770562 100644 --- a/src/pyramid/config/predicates.py +++ b/src/pyramid/config/predicates.py @@ -197,9 +197,7 @@ class PredicateList(object): return order, preds, phash.hexdigest() -def normalize_accept_offer(offer, allow_range=False): - if allow_range and '*' in offer: - return offer.lower() +def normalize_accept_offer(offer): return str(Accept.parse_offer(offer)) diff --git a/src/pyramid/config/routes.py b/src/pyramid/config/routes.py index a14662370..f9180bd76 100644 --- a/src/pyramid/config/routes.py +++ b/src/pyramid/config/routes.py @@ -247,6 +247,10 @@ class RoutesConfiguratorMixin(object): :app:`Pyramid` 2.0. Use a list of specific media types to match more than one type. + .. versionchanged:: 2.0 + + Removed support for media ranges. + effective_principals If specified, this value should be a :term:`principal` identifier or @@ -308,24 +312,11 @@ class RoutesConfiguratorMixin(object): if accept is not None: if not is_nonstr_iter(accept): - if '*' in accept: - warnings.warn( - ( - 'Passing a media range to the "accept" argument ' - 'of Configurator.add_route is deprecated as of ' - 'Pyramid 1.10. Use a list of explicit media types.' - ), - DeprecationWarning, - stacklevel=3, - ) - # XXX switch this to False when range support is dropped - accept = [normalize_accept_offer(accept, allow_range=True)] - - else: - accept = [ - normalize_accept_offer(accept_option) - for accept_option in accept - ] + accept = [accept] + accept = [ + normalize_accept_offer(accept_option) + for accept_option in accept + ] # these are route predicates; if they do not match, the next route # in the routelist will be tried diff --git a/src/pyramid/config/views.py b/src/pyramid/config/views.py index bd1b693ba..0c4a17376 100644 --- a/src/pyramid/config/views.py +++ b/src/pyramid/config/views.py @@ -116,7 +116,7 @@ class MultiView(object): self.views[i] = (order, view, phash) return - if accept is None or '*' in accept: + if accept is None: self.views.append((order, view, phash)) self.views.sort(key=operator.itemgetter(0)) else: @@ -570,6 +570,10 @@ class ViewsConfiguratorMixin(object): :app:`Pyramid` 2.0. Use explicit media types to avoid any ambiguities in content negotiation. + .. versionchanged:: 2.0 + + Removed support for media ranges. + exception_only .. versionadded:: 1.8 @@ -838,20 +842,7 @@ class ViewsConfiguratorMixin(object): raise ConfigurationError( 'A list is not supported in the "accept" view predicate.' ) - if '*' in accept: - warnings.warn( - ( - 'Passing a media range to the "accept" argument of ' - 'Configurator.add_view is deprecated as of ' - 'Pyramid 1.10. Use explicit media types to avoid ' - 'ambiguities in content negotiation that may impact ' - 'your users.' - ), - DeprecationWarning, - stacklevel=4, - ) - # XXX when media ranges are gone, switch allow_range=False - accept = normalize_accept_offer(accept, allow_range=True) + accept = normalize_accept_offer(accept) view = self.maybe_dotted(view) context = self.maybe_dotted(context) diff --git a/src/pyramid/predicates.py b/src/pyramid/predicates.py index b95dfd9be..280f6c03c 100644 --- a/src/pyramid/predicates.py +++ b/src/pyramid/predicates.py @@ -133,15 +133,9 @@ class HeaderPredicate(object): class AcceptPredicate(object): - _is_using_deprecated_ranges = False - def __init__(self, values, config): if not is_nonstr_iter(values): values = (values,) - # deprecated media ranges were only supported in versions of the - # predicate that didn't support lists, so check it here - if len(values) == 1 and '*' in values[0]: - self._is_using_deprecated_ranges = True self.values = values def text(self): @@ -150,8 +144,6 @@ class AcceptPredicate(object): phash = text def __call__(self, context, request): - if self._is_using_deprecated_ranges: - return self.values[0] in request.accept return bool(request.accept.acceptable_offers(self.values)) diff --git a/tests/test_config/test_routes.py b/tests/test_config/test_routes.py index d6f45608d..32a64b4bd 100644 --- a/tests/test_config/test_routes.py +++ b/tests/test_config/test_routes.py @@ -216,17 +216,12 @@ class RoutesConfiguratorMixinTests(unittest.TestCase): request.accept = DummyAccept('text/html') self.assertEqual(predicate(None, request), False) - def test_add_route_with_wildcard_accept(self): + def test_add_route_with_wildcard_accept_raises(self): config = self._makeOne(autocommit=True) - config.add_route('name', 'path', accept='text/*') - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.accept = DummyAccept('text/xml', contains=True) - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.accept = DummyAccept('application/json', contains=False) - self.assertEqual(predicate(None, request), False) + self.assertRaises( + ValueError, + lambda: config.add_route('name', 'path', accept='text/*'), + ) def test_add_route_no_pattern_with_path(self): config = self._makeOne(autocommit=True) @@ -313,6 +308,3 @@ class DummyAccept(object): if match in offers: results.append((match, 1.0)) return results - - def __contains__(self, value): - return self.contains diff --git a/tests/test_config/test_views.py b/tests/test_config/test_views.py index 5e722c9a0..b72b9b36a 100644 --- a/tests/test_config/test_views.py +++ b/tests/test_config/test_views.py @@ -1815,25 +1815,12 @@ class TestViewsConfigurationMixin(unittest.TestCase): request.accept = DummyAccept('text/html') self._assertNotFound(wrapper, None, request) - def test_add_view_with_range_accept_match(self): - from pyramid.renderers import null_renderer - - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, accept='text/*', renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.accept = DummyAccept('text/html', contains=True) - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_range_accept_nomatch(self): + def test_add_view_with_wildcard_accept_raises(self): view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) - config.add_view(view=view, accept='text/*') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.accept = DummyAccept('application/json', contains=False) - self._assertNotFound(wrapper, None, request) + self.assertRaises( + ValueError, lambda: config.add_view(view=view, accept='text/*') + ) def test_add_view_with_containment_true(self): from pyramid.renderers import null_renderer @@ -3142,11 +3129,6 @@ class TestMultiView(unittest.TestCase): self.assertEqual(mv.media_views['text/xml'], [(100, 'view5', None)]) self.assertEqual(set(mv.accepts), set(['text/xml', 'text/html'])) self.assertEqual(mv.views, [(99, 'view2', None), (100, 'view', None)]) - mv.add('view6', 98, accept='text/*') - self.assertEqual( - mv.views, - [(98, 'view6', None), (99, 'view2', None), (100, 'view', None)], - ) def test_add_with_phash(self): mv = self._makeOne() @@ -4266,9 +4248,6 @@ class DummyAccept(object): results.append((match, 1.0)) return results - def __contains__(self, value): - return self.contains - class DummyConfig: def __init__(self): diff --git a/tests/test_integration.py b/tests/test_integration.py index 28160eb7a..d57a7cf6e 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -869,45 +869,6 @@ class AcceptContentTypeTest(unittest.TestCase): ) self.assertEqual(res.content_type, 'text/x-fallback') - def test_deprecated_ranges_in_route_predicate(self): - config = self._makeConfig() - config.add_route('foo', '/foo', accept='text/*') - config.add_view(lambda r: 'OK', route_name='foo', renderer='string') - app = self._makeTestApp(config) - res = app.get( - '/foo', - headers={'Accept': 'application/json; q=1.0, text/plain; q=0.9'}, - status=200, - ) - self.assertEqual(res.content_type, 'text/plain') - self.assertEqual(res.body, b'OK') - res = app.get( - '/foo', headers={'Accept': 'application/json'}, status=404 - ) - self.assertEqual(res.content_type, 'application/json') - - def test_deprecated_ranges_in_view_predicate(self): - config = self._makeConfig() - config.add_route('foo', '/foo') - config.add_view( - lambda r: 'OK', - route_name='foo', - accept='text/*', - renderer='string', - ) - app = self._makeTestApp(config) - res = app.get( - '/foo', - headers={'Accept': 'application/json; q=1.0, text/plain; q=0.9'}, - status=200, - ) - self.assertEqual(res.content_type, 'text/plain') - self.assertEqual(res.body, b'OK') - res = app.get( - '/foo', headers={'Accept': 'application/json'}, status=404 - ) - self.assertEqual(res.content_type, 'application/json') - class DummyContext(object): pass |
