From aa7b06b946b4e8e66818da29e64e9cbccb6ccb10 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 2 Sep 2013 01:03:02 -0400 Subject: move docs section to a more appropriate place --- docs/narr/viewconfig.rst | 59 ++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index e09fd83ab..76cf1daac 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -465,6 +465,36 @@ configured view. .. versionadded:: 1.4a1 +Inverting Predicate Values +++++++++++++++++++++++++++ + +You can invert the meaning of any predicate value by wrapping it in a call to +:class:`pyramid.config.not_`. + +.. code-block:: python + :linenos: + + from pyramid.config import not_ + + config.add_view( + 'mypackage.views.my_view', + route_name='ok', + request_method=not_('POST') + ) + +The above example will ensure that the view is called if the request method +is *not* ``POST``, at least if no other view is more specific. + +This technique of wrapping a predicate value in ``not_`` can be used anywhere +predicate values are accepted: + +- :meth:`pyramid.config.Configurator.add_view` + +- :meth:`pyramid.view.view_config` + +.. versionadded:: 1.5 + + .. index:: single: view_config decorator @@ -557,35 +587,6 @@ form of :term:`declarative configuration`, while :meth:`pyramid.config.Configurator.add_view` is a form of :term:`imperative configuration`. However, they both do the same thing. -Inverting Predicate Values -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can invert the meaning of any predicate value by wrapping it in a call to -:class:`pyramid.config.not_`. - -.. code-block:: python - :linenos: - - from pyramid.config import not_ - - config.add_view( - 'mypackage.views.my_view', - route_name='ok', - request_method=not_('POST') - ) - -The above example will ensure that the view is called if the request method -is *not* ``POST``, at least if no other view is more specific. - -This technique of wrapping a predicate value in ``not_`` can be used anywhere -predicate values are accepted: - -- :meth:`pyramid.config.Configurator.add_view` - -- :meth:`pyramid.view.view_config` - -.. versionadded:: 1.5 - .. index:: single: view_config placement -- cgit v1.2.3 From 3803d92fc0da5282656d4229e063a1908ec5522a Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 02:26:42 -0500 Subject: update render() to preserve the original response object --- CHANGES.txt | 12 ++++++++++++ pyramid/renderers.py | 18 +++++++++++++++++- pyramid/tests/test_renderers.py | 8 ++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index cdaad5a90..3c953e728 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,15 @@ +Next Release +============ + +Backwards Incompatibilities +--------------------------- + +- Almost all renderers affect properties on the ``request.response`` response + object. For example, setting the content-type in the JSON renderer to + 'application/json'. These mutations will no longer affect + ``request.response`` when using the ``pyramid.renderers.render()`` API as + its only expected output is a rendered string object. + 1.5a1 (2013-08-30) ================== diff --git a/pyramid/renderers.py b/pyramid/renderers.py index 602655be8..4b192f37d 100644 --- a/pyramid/renderers.py +++ b/pyramid/renderers.py @@ -85,7 +85,23 @@ def render(renderer_name, value, request=None, package=None): package = caller_package() helper = RendererHelper(name=renderer_name, package=package, registry=registry) - return helper.render(value, None, request=request) + + saved_response = None + # save the current response, preventing the renderer from affecting it + attrs = request.__dict__ if request is not None else {} + if 'response' in attrs: + saved_response = attrs['response'] + del attrs['response'] + + result = helper.render(value, None, request=request) + + # restore the original response, overwriting any changes + if saved_response is not None: + attrs['response'] = saved_response + elif 'response' in attrs: + del attrs['response'] + + return result def render_to_response(renderer_name, value, request=None, package=None): """ Using the renderer ``renderer_name`` (a template diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index befb714bd..e9d8dec68 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -897,6 +897,14 @@ class Test_render(unittest.TestCase): renderer.assert_(a=1) renderer.assert_(request=request) + def test_it_preserves_response(self): + request = testing.DummyRequest() + response = object() # should error if mutated + request.response = response + result = self._callFUT('json', dict(a=1), request=request) + self.assertEqual(result, '{"a": 1}') + self.assertEqual(request.response, response) + class Test_render_to_response(unittest.TestCase): def setUp(self): self.config = testing.setUp() -- cgit v1.2.3 From f6f1d1685f09f1ecd3717c90e687a6e3652b4fdc Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 02:32:41 -0500 Subject: remove the deprecated request.response_* attributes --- CHANGES.txt | 10 +++++ docs/api/request.rst | 18 --------- docs/narr/renderers.rst | 34 ----------------- pyramid/renderers.py | 20 ---------- pyramid/request.py | 82 ----------------------------------------- pyramid/tests/test_renderers.py | 57 ---------------------------- 6 files changed, 10 insertions(+), 211 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index cdaad5a90..80578d539 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,13 @@ +Next Release +============ + +Backwards Incompatibilities +--------------------------- + +- Removed the ``request.response_*`` varying attributes. These attributes + have been deprecated since Pyramid 1.1, and as per the deprecation policy, + have now been removed. + 1.5a1 (2013-08-30) ================== diff --git a/docs/api/request.rst b/docs/api/request.rst index 02290eaf3..ef41ba4c8 100644 --- a/docs/api/request.rst +++ b/docs/api/request.rst @@ -235,24 +235,6 @@ .. automethod:: resource_path - .. attribute:: response_* - - In Pyramid 1.0, you could set attributes on a - :class:`pyramid.request.Request` which influenced the behavior of - *rendered* responses (views which use a :term:`renderer` and which - don't directly return a response). These attributes began with - ``response_``, such as ``response_headerlist``. If you needed to - influence response values from a view that uses a renderer (such as the - status code, a header, the content type, etc) you would set these - attributes. See :ref:`response_prefixed_attrs` for further discussion. - As of Pyramid 1.1, assignment to ``response_*`` attrs is deprecated. - Assigning to one is still supported but will cause a deprecation - warning to be emitted, and eventually the feature will be removed. For - new code, instead of assigning ``response_*`` attributes to the - request, use API of the :attr:`pyramid.request.Request.response` - object (exposed to view code as ``request.response``) to influence - rendered response behavior. - .. attribute:: json_body This property will return the JSON-decoded variant of the request diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index a2811dbae..9132606b3 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -556,40 +556,6 @@ For more information on attributes of the request, see the API documentation in :ref:`request_module`. For more information on the API of ``request.response``, see :attr:`pyramid.request.Request.response`. -.. _response_prefixed_attrs: - -Deprecated Mechanism to Vary Attributes of Rendered Responses -------------------------------------------------------------- - -In previous releases of Pyramid (1.0 and before), the ``request.response`` -attribute did not exist. Instead, Pyramid required users to set special -``response_`` -prefixed attributes of the request to influence response -behavior. As of Pyramid 1.1, those request attributes are deprecated and -their use will cause a deprecation warning to be issued when used. Until -their existence is removed completely, we document them below, for benefit of -people with older code bases. - -``response_content_type`` - Defines the content-type of the resulting response, - e.g. ``text/xml``. - -``response_headerlist`` - A sequence of tuples describing header values that should be set in the - response, e.g. ``[('Set-Cookie', 'abc=123'), ('X-My-Header', 'foo')]``. - -``response_status`` - A WSGI-style status code (e.g. ``200 OK``) describing the status of the - response. - -``response_charset`` - The character set (e.g. ``UTF-8``) of the response. - -``response_cache_for`` - A value in seconds which will influence ``Cache-Control`` and ``Expires`` - headers in the returned response. The same can also be achieved by - returning various values in the ``response_headerlist``, this is purely a - convenience. - .. _adding_and_overriding_renderers: Adding and Changing Renderers diff --git a/pyramid/renderers.py b/pyramid/renderers.py index 602655be8..a647d273c 100644 --- a/pyramid/renderers.py +++ b/pyramid/renderers.py @@ -576,26 +576,6 @@ class RendererHelper(object): else: response.body = result - if request is not None: - # deprecated mechanism to set up request.response_* attrs, see - # pyramid.request.Request - attrs = request.__dict__ - content_type = attrs.get('_response_content_type', None) - if content_type is not None: - response.content_type = content_type - headerlist = attrs.get('_response_headerlist', None) - if headerlist is not None: - for k, v in headerlist: - response.headers.add(k, v) - status = attrs.get('_response_status', None) - if status is not None: - response.status = status - charset = attrs.get('_response_charset', None) - if charset is not None: - response.charset = charset - cache_for = attrs.get('_response_cache_for', None) - if cache_for is not None: - response.cache_expires = cache_for return response def clone(self, name=None, package=None, registry=None): diff --git a/pyramid/request.py b/pyramid/request.py index 9b62bee00..5c064d3ef 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -111,88 +111,6 @@ class DeprecatedRequestMethodsMixin(object): def values(self): return self.environ.values() - # 1.0 deprecated bw compat code for using response_* values - - rr_dep = ('Accessing and setting "request.response_%s" is ' - 'deprecated as of Pyramid 1.1; access or set ' - '"request.response.%s" instead.') - - # response_content_type - def _response_content_type_get(self): - return self._response_content_type - def _response_content_type_set(self, value): - self._response_content_type = value - def _response_content_type_del(self): - del self._response_content_type - response_content_type = property(_response_content_type_get, - _response_content_type_set, - _response_content_type_del) - response_content_type = deprecated( - response_content_type, - rr_dep % ('content_type', 'content_type')) - - # response_headerlist - def _response_headerlist_get(self): - return self._response_headerlist - def _response_headerlist_set(self, value): - self._response_headerlist = value - def _response_headerlist_del(self): - del self._response_headerlist - response_headerlist = property(_response_headerlist_get, - _response_headerlist_set, - _response_headerlist_del) - - hl_dep = ('Accessing and setting "request.response_headerlist" is ' - 'deprecated as of Pyramid 1.1; access the headerlist via ' - '"request.response.headerlist" and extend headers via ' - '"request.response.headerlist.extend(alist)" instead of ' - '"request.response_headerlist = alist"') - - response_headerlist = deprecated(response_headerlist, hl_dep) - - # response_status - def _response_status_get(self): - return self._response_status - def _response_status_set(self, value): - self._response_status = value - def _response_status_del(self): - del self._response_status - response_status = property(_response_status_get, - _response_status_set, - _response_status_del) - - response_status = deprecated( - response_status, - rr_dep % ('status', 'status')) - - # response_charset - def _response_charset_get(self): - return self._response_charset - def _response_charset_set(self, value): - self._response_charset = value - def _response_charset_del(self): - del self._response_charset - response_charset = property(_response_charset_get, - _response_charset_set, - _response_charset_del) - response_charset = deprecated( - response_charset, - rr_dep % ('charset', 'charset')) - - # response_cache_for - def _response_cache_for_get(self): - return self._response_cache_for - def _response_cache_for_set(self, value): - self._response_cache_for = value - def _response_cache_for_del(self): - del self._response_cache_for - response_cache_for = property(_response_cache_for_get, - _response_cache_for_set, - _response_cache_for_del) - response_cache_for = deprecated( - response_cache_for, - rr_dep % ('cache_for', 'cache_expires')) - class CallbackMethodsMixin(object): response_callbacks = () finished_callbacks = () diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index befb714bd..078373f2e 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -680,63 +680,6 @@ class TestRendererHelper(unittest.TestCase): helper = self._makeOne('loo.foo') response = helper._make_response(None, request) self.assertEqual(response.body, b'abc') - - def test__make_response_with_content_type(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - attrs = {'_response_content_type':'text/nonsense'} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.content_type, 'text/nonsense') - self.assertEqual(response.body, b'abc') - - def test__make_response_with_headerlist(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - attrs = {'_response_headerlist':[('a', '1'), ('b', '2')]} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.headerlist, - [('Content-Type', 'text/html; charset=UTF-8'), - ('Content-Length', '3'), - ('a', '1'), - ('b', '2')]) - self.assertEqual(response.body, b'abc') - - def test__make_response_with_status(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - attrs = {'_response_status':'406 You Lose'} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.status, '406 You Lose') - self.assertEqual(response.body, b'abc') - - def test__make_response_with_charset(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - attrs = {'_response_charset':'UTF-16'} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.charset, 'UTF-16') - - def test__make_response_with_cache_for(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - attrs = {'_response_cache_for':100} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.cache_control.max_age, 100) def test_with_alternate_response_factory(self): from pyramid.interfaces import IResponseFactory -- cgit v1.2.3 From 13b1871878932091e56b01bb27eef7033521a83f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 5 Sep 2013 23:23:27 -0400 Subject: update HACKING --- HACKING.txt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/HACKING.txt b/HACKING.txt index abfed6dab..684a42ee6 100644 --- a/HACKING.txt +++ b/HACKING.txt @@ -78,7 +78,7 @@ In order to add a feature to Pyramid: documentation (in ``docs/``). - The feature must work fully on the following CPython versions: 2.6, - 2.7, and 3.2 on both UNIX and Windows. + 2.7, 3.2, and 3.3 on both UNIX and Windows. - The feature must work on the latest version of PyPy. @@ -104,7 +104,9 @@ Coding Style - PEP8 compliance. Whitespace rules are relaxed: not necessary to put 2 newlines between classes. But 80-column lines, in particular, are - mandatory. + mandatory. See + http://docs.pylonsproject.org/en/latest/community/codestyle.html for more + information. - Please do not remove trailing whitespace. Configure your editor to reduce diff noise. See https://github.com/Pylons/pyramid/issues/788 for more. @@ -112,13 +114,15 @@ Coding Style Running Tests -------------- -- To run all tests for Pyramid on a single Python version, run ``nosetests`` from - your development virtualenv (See *Using a Development Checkout* above). +- To run all tests for Pyramid on a single Python version, run ``nosetests`` + from your development virtualenv (See *Using a Development Checkout* above). - To run individual tests (i.e. during development) you can use a regular expression with the ``-t`` parameter courtesy of the `nose-selecttests - `_ plugin that's been installed (along with nose itself) via ``python setup.py dev``. The easiest usage is to - simply provide the verbatim name of the test you're working on. + `_ plugin that's been + installed (along with nose itself) via ``python setup.py dev``. The + easiest usage is to simply provide the verbatim name of the test you're + working on. - To run the full set of Pyramid tests on all platforms, install ``tox`` (http://codespeak.net/~hpk/tox/) into a system Python. The ``tox`` console -- cgit v1.2.3