From 6ec5a699bbd24e2d493418c3ada39390f943d517 Mon Sep 17 00:00:00 2001 From: Alex Volkov Date: Tue, 13 Nov 2012 18:20:20 -0500 Subject: My fix for Issue #721. Made view.py - render_view to convert iterable input into bytestring and joing it with bytestring. --- pyramid/tests/test_view.py | 22 +++++++++++++++++++--- pyramid/view.py | 4 +++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/pyramid/tests/test_view.py b/pyramid/tests/test_view.py index 0af941e0d..42cfea37b 100644 --- a/pyramid/tests/test_view.py +++ b/pyramid/tests/test_view.py @@ -230,6 +230,22 @@ class RenderViewToIterableTests(BaseTest, unittest.TestCase): iterable = self._callFUT(context, request, name='registered', secure=False) self.assertEqual(iterable, ['anotherview']) + def test_verify_output_bytestring(self): + from pyramid.request import Request + from pyramid.config import Configurator + from pyramid.view import render_view + from webob.compat import text_type + config = Configurator(settings={}) + def view(request): + request.response.text = text_type('') + return request.response + + config.add_view(name='test', view=view) + config.commit() + + r = Request({}) + r.registry = config.registry + self.assertEqual(render_view(object(), r, 'test'), b'') def test_call_request_has_no_registry(self): request = self._makeRequest() @@ -261,7 +277,7 @@ class RenderViewTests(BaseTest, unittest.TestCase): view = make_view(response) self._registerView(request.registry, view, 'registered') s = self._callFUT(context, request, name='registered', secure=True) - self.assertEqual(s, '') + self.assertEqual(s, b'') def test_call_view_registered_insecure_no_call_permissive(self): context = self._makeContext() @@ -270,7 +286,7 @@ class RenderViewTests(BaseTest, unittest.TestCase): view = make_view(response) self._registerView(request.registry, view, 'registered') s = self._callFUT(context, request, name='registered', secure=False) - self.assertEqual(s, '') + self.assertEqual(s, b'') def test_call_view_registered_insecure_with_call_permissive(self): context = self._makeContext() @@ -282,7 +298,7 @@ class RenderViewTests(BaseTest, unittest.TestCase): view.__call_permissive__ = anotherview self._registerView(request.registry, view, 'registered') s = self._callFUT(context, request, name='registered', secure=False) - self.assertEqual(s, 'anotherview') + self.assertEqual(s, b'anotherview') class TestIsResponse(unittest.TestCase): def setUp(self): diff --git a/pyramid/view.py b/pyramid/view.py index 835982e79..972877fea 100644 --- a/pyramid/view.py +++ b/pyramid/view.py @@ -2,6 +2,8 @@ import venusian from zope.interface import providedBy from zope.deprecation import deprecated +from webob.compat import text_type + from pyramid.interfaces import ( IRoutesMapper, @@ -136,7 +138,7 @@ def render_view(context, request, name='', secure=True): iterable = render_view_to_iterable(context, request, name, secure) if iterable is None: return None - return ''.join(iterable) + return b''.join((x.encode('utf-8') if isinstance(x, text_type) else x for x in iterable)) class view_config(object): """ A function, class or method :term:`decorator` which allows a -- cgit v1.2.3 From 0a8ea94e81e3edc68d8175eb3666a7bfc9904913 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 13 Nov 2012 21:44:26 -0600 Subject: simplfied change as response.app_iter must contain bytes per pep 3333 --- pyramid/tests/test_view.py | 7 ++++--- pyramid/view.py | 3 +-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyramid/tests/test_view.py b/pyramid/tests/test_view.py index 42cfea37b..a78b0cbab 100644 --- a/pyramid/tests/test_view.py +++ b/pyramid/tests/test_view.py @@ -224,12 +224,13 @@ class RenderViewToIterableTests(BaseTest, unittest.TestCase): response = DummyResponse() view = make_view(response) def anotherview(context, request): - return DummyResponse('anotherview') + return DummyResponse(b'anotherview') view.__call_permissive__ = anotherview self._registerView(request.registry, view, 'registered') iterable = self._callFUT(context, request, name='registered', secure=False) - self.assertEqual(iterable, ['anotherview']) + self.assertEqual(iterable, [b'anotherview']) + def test_verify_output_bytestring(self): from pyramid.request import Request from pyramid.config import Configurator @@ -294,7 +295,7 @@ class RenderViewTests(BaseTest, unittest.TestCase): response = DummyResponse() view = make_view(response) def anotherview(context, request): - return DummyResponse('anotherview') + return DummyResponse(b'anotherview') view.__call_permissive__ = anotherview self._registerView(request.registry, view, 'registered') s = self._callFUT(context, request, name='registered', secure=False) diff --git a/pyramid/view.py b/pyramid/view.py index 972877fea..dd01d9d20 100644 --- a/pyramid/view.py +++ b/pyramid/view.py @@ -2,7 +2,6 @@ import venusian from zope.interface import providedBy from zope.deprecation import deprecated -from webob.compat import text_type from pyramid.interfaces import ( @@ -138,7 +137,7 @@ def render_view(context, request, name='', secure=True): iterable = render_view_to_iterable(context, request, name, secure) if iterable is None: return None - return b''.join((x.encode('utf-8') if isinstance(x, text_type) else x for x in iterable)) + return b''.join(iterable) class view_config(object): """ A function, class or method :term:`decorator` which allows a -- cgit v1.2.3 From f89cfcdd50a8beba17a6d02854f4153961ff478c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 13 Nov 2012 21:50:05 -0600 Subject: updated changelog --- CHANGES.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index e40312c34..16e3d8586 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -61,6 +61,10 @@ Bug Fixes ``physical_path`` predicate implementations; instead of raising an exception, return False. +- :func:`pyramid.view.render_view` was not functioning properly under + Python 3.x due to a byte/unicode discrepancy. See + http://github.com/Pylons/pyramid/issues/721 + Deprecations ------------ -- cgit v1.2.3 From 23de5bafdc074a01541a2a3dd3fa9e20e5801d57 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 13 Nov 2012 23:38:50 -0600 Subject: indicate render_view returns a bytestring (see #725) --- pyramid/view.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/view.py b/pyramid/view.py index dd01d9d20..021d6ff79 100644 --- a/pyramid/view.py +++ b/pyramid/view.py @@ -117,7 +117,7 @@ def render_view(context, request, name='', secure=True): configuration` that matches the :term:`view name` ``name`` registered against the specified ``context`` and ``request`` and unwind the view response's ``app_iter`` (see - :ref:`the_response`) into a single string. This function will + :ref:`the_response`) into a single bytestring. This function will return ``None`` if a corresponding :term:`view callable` cannot be found (when no :term:`view configuration` matches the combination of ``name`` / ``context`` / and ``request``). Additionally, this -- cgit v1.2.3