8000 - Added new add_response_adapter method to Configurator. · alex-python/pyramid@1a6fc70 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1a6fc70

Browse files
committed
- Added new add_response_adapter method to Configurator.
- Fix Configurator docstring wrt exception responses. - Speed up registry.queryAdapterOrSelf
1 parent 3f4f67e commit 1a6fc70

File tree

7 files changed

+70
-26
lines changed

7 files changed

+70
-26
lines changed

CHANGES.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,10 @@ Features
130130
- It is now possible to return an arbitrary object from a Pyramid view
131131
callable even if a renderer is not used, as long as a suitable adapter to
132132
``pyramid.interfaces.IResponse`` is registered for the type of the returned
133-
object. See the section in the Hooks chapter of the documentation entitled
134-
"Changing How Pyramid Treats View Responses".
133+
object by using the new
134+
``pyramid.config.Configurator.add_response_adapter`` API. See the section
135+
in the Hooks chapter of the documentation entitled "Changing How Pyramid
136+
Treats View Responses".
135137

136138
- The Pyramid router will now, by default, call the ``__call__`` method of
137139
WebOb response objects when returning a WSGI response. This means that,

docs/api/config.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040

4141
.. automethod:: add_renderer(name, factory)
4242

43+
.. automethod:: add_response_adapter
44+
4345
.. automethod:: add_route
4446

4547
.. automethod:: add_static_view(name, path, cache_max_age=3600, permission='__no_permission_required__')

docs/narr/hooks.rst

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ Changing How Pyramid Treats View Responses
532532

533533
It is possible to control how Pyramid treats the result of calling a view
534534
callable on a per-type basis by using a hook involving
535-
:class:`pyramid.interfaces.IResponse`.
535+
:method:`pyramid.config.Configurator.add_response_adapter`.
536536

537537
.. note:: This feature is new as of Pyramid 1.1.
538538

@@ -559,7 +559,6 @@ Response:
559559
.. code-block:: python
560560
:linenos:
561561
562-
from pyramid.interfaces import IResponse
563562
from pyramid.response import Response
564563
565564
def string_response_adapter(s):
@@ -568,8 +567,7 @@ Response:
568567
569568
# config is an instance of pyramid.config.Configurator
570569
571-
config.registry.registerAdapter(string_response_adapter, (str,),
572-
IResponse)
570+
config.add_response_adapter(string_response_adapter, str)
573571
574572
Likewise, if you want to be able to return a simplified kind of response
575573
object from view callables, you can use the IResponse hook to register an
@@ -578,7 +576,6 @@ adapter to the more complex IResponse interface:
578576
.. code-block:: python
579577
:linenos:
580578
581-
from pyramid.interfaces import IResponse
582579
from pyramid.response import Response
583580
584581
class SimpleResponse(object):
@@ -591,14 +588,12 @@ adapter to the more complex IResponse interface:
591588
592589
# config is an instance of pyramid.config.Configurator
593590
594-
config.registry.registerAdapter(simple_response_adapter,
595-
(SimpleResponse,),
596-
IResponse)
591+
config.add_response_adapter(simple_response_adapter, SimpleResponse)
597592
598593
If you want to implement your own Response object instead of using the
599594
:class:`pyramid.response.Response` object in any capacity at all, you'll have
600595
to make sure the object implements every attribute and method outlined in
601-
:class:`pyramid.interfaces.IResponse` *and* you'll have to ensure that it's
596+
:class:`pyramid.interfaces.IResponse` and you'll have to ensure that it's
602597
marked up with ``zope.interface.implements(IResponse)``:
603598

604599
from pyramid.interfaces import IResponse

pyramid/config.py

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from zope.interface.interfaces import IInterface
2020
from zope.interface import implements
2121
from zope.interface import classProvides
22-
from zope.interface import providedBy
2322

2423
from pyramid.interfaces import IAuthenticationPolicy
2524
from pyramid.interfaces import IAuthorizationPolicy
@@ -260,15 +259,11 @@ class or a :term:`dotted Python name` to same. The debug logger
260259
261260
If ``exceptionresponse_view`` is passed, it must be a :term:`view
262261
callable` or ``None``. If it is a view callable, it will be used as an
263-
exception view callable when an :term:`exception response` is raised (any
264-
object that implements the :class:`pyramid.interaces.IExceptionResponse`
265-
interface, such as a :class:`pyramid.response.Response` object or any
266-
``HTTP`` exception documented in :mod:`pyramid.httpexceptions` as well as
267-
exception responses raised via :func:`pyramid.exceptions.abort`,
268-
:func:`pyramid.exceptions.redirect`). If ``exceptionresponse_view`` is
269-
``None``, no exception response view will be registered, and all raised
270-
exception responses will be bubbled up to Pyramid's caller. By
271-
default, the ``pyramid.exceptions.default_exceptionresponse_view``
262+
exception view callable when an :term:`exception response` is raised. If
263+
``exceptionresponse_view`` is ``None``, no exception response view will
264+
be registered, and all raised exception responses will be bubbled up to
265+
Pyramid's caller. By
266+
default, the ``pyramid.httpexceptions.default_exceptionresponse_view``
272267
function is used as the ``exceptionresponse_view``. This argument is new
273268
in Pyramid 1.1. """
274269

@@ -433,8 +428,7 @@ def notify(*events):
433428

434429
if not hasattr(_registry, 'queryAdapterOrSelf'):
435430
def queryAdapterOrSelf(object, interface, default=None):
436-
provides = providedBy(object)
437-
if not interface in provides:
431+
if not interface.providedBy(object):
438432
return _registry.queryAdapter(object, interface,
439433
default=default)
440434
return object
@@ -893,6 +887,30 @@ def register():
893887
self.action(None, register)
894888
return subscriber
895889

890+
@action_method
891+
def add_response_adapter(self, adapter, type_or_iface):
892+
""" When an object of type (or interface) ``type_or_iface`` is
893+
returned from a view callable, Pyramid will use the adapter
894+
``adapter`` to convert it into an object which implements the
895+
:class:`pyramid.interfaces.IResponse` interface. If ``adapter`` is
896+
None, an object returned of type (or interface) ``type_or_iface``
897+
will itself be used as a response object.
898+
899+
``adapter`` and ``type_or_interface`` may be Python objects or
900+
strings representing dotted names to importable Python global
901+
objects.
902+
903+
See :ref:`using_iresponse` for more information."""
904+
adapter = self.maybe_dotted(adapter)
905+
type_or_iface = self.maybe_dotted(type_or_iface)
906+
def register():
907+
reg = self.registry
908+
if adapter is None:
909+
reg.registerSelfAdapter((type_or_iface,), IResponse)
910+
else:
911+
reg.registerAdapter(adapter, (type_or_iface,), IResponse)
912+
self.action((IResponse, type_or_iface), register)
913+
896914
def add_settings(self, settings=None, **kw):
897915
"""Augment the ``settings`` argument passed in to the Configurator
898916
constructor with one or more 'setting' key/value pairs. A setting is

pyramid/registry.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ def queryAdapterOrSelf(self, object, interface, default=None):
4141
# queryAdapter analogue which returns the object if it implements
4242
# the interface, otherwise it will return an adaptation to the
4343
# interface
44-
provides = providedBy(object)
45-
if not interface in provides:
44+
if not interface.providedBy(object):
4645
return self.queryAdapter(object, interface, default=default)
4746
return object
4847

pyramid/router.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ def __call__(self, environ, start_response):
185185
if response is None:
186186
raise ValueError(
187187
'Could not convert view return value "%s" into a '
188-
'response' % (result,))
188+
'response object' % (result,))
189189

190190
has_listeners and registry.notify(NewResponse(request,response))
191191

pyramid/tests/test_config.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2628,6 +2628,34 @@ def test_add_renderer_dottedname_factory(self):
26282628
self.assertEqual(config.registry.getUtility(IRendererFactory, 'name'),
26292629
pyramid.tests)
26302630

2631+
def test_add_response_adapter(self):
2632+
from pyramid.interfaces import IResponse
2633+
config = self._makeOne(autocommit=True)
2634+
class Adapter(object):
2635+
def __init__(self, other):
2636+
self.other = other
2637+
config.add_response_adapter(Adapter, str)
2638+
result = config.registry.queryAdapter('foo', IResponse)
2639+
self.assertTrue(result.other, 'foo')
2640+
2641+
def test_add_response_adapter_self(self):
2642+
from pyramid.interfaces import IResponse
2643+
config = self._makeOne(autocommit=True)
2644+
class Adapter(object):
2645+
pass
2646+
config.add_response_adapter(None, Adapter)
2647+
adapter = Adapter()
2648+
result = config.registry.queryAdapter(adapter, IResponse)
2649+
self.assertTrue(result is adapter)
2650+
2651+
def test_add_response_adapter_dottednames(self):
2652+
from pyramid.interfaces import IResponse
2653+
config = self._makeOne(autocommit=True)
2654+
config.add_response_adapter('pyramid.response.Response',
2655+
'types.StringType')
2656+
result = config.registry.queryAdapter('foo', IResponse)
2657+
self.assertTrue(result.body, 'foo')
2658+
26312659
def test_scan_integration(self):
26322660
import os
26332661
from zope.interface import alsoProvides

0 commit comments

Comments
 (0)
0