diff options
| author | Chris McDonough <chrism@plope.com> | 2011-08-14 00:53:53 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2011-08-14 00:53:53 -0400 |
| commit | 5c52daef7004a1e43a7c2fc25613e3d92c4b6b8e (patch) | |
| tree | 63e3b5b77f7904799bff1029de7804a62f7e973e | |
| parent | 5396466b819692ae0d1ea2b78e6df6093545963a (diff) | |
| download | pyramid-5c52daef7004a1e43a7c2fc25613e3d92c4b6b8e.tar.gz pyramid-5c52daef7004a1e43a7c2fc25613e3d92c4b6b8e.tar.bz2 pyramid-5c52daef7004a1e43a7c2fc25613e3d92c4b6b8e.zip | |
- Added the ``pyramid.interfaces.IDict`` interface representing the methods
of a dictionary, for documentation purposes only (IMultiDict and
IBeforeRender inherit from it).
- Previously the ``pyramid.events.BeforeRender`` event *wrapped* a dictionary
(it addressed it as its ``_system`` attribute). Now it *is* a dictionary
(it inherits from ``dict``), and it's the value that is passed to templates
as a top-level dictionary.
| -rw-r--r-- | CHANGES.txt | 9 | ||||
| -rw-r--r-- | TODO.txt | 3 | ||||
| -rw-r--r-- | docs/api/events.rst | 9 | ||||
| -rw-r--r-- | docs/api/interfaces.rst | 3 | ||||
| -rw-r--r-- | pyramid/events.py | 43 | ||||
| -rw-r--r-- | pyramid/interfaces.py | 104 | ||||
| -rw-r--r-- | pyramid/renderers.py | 17 | ||||
| -rw-r--r-- | pyramid/tests/test_events.py | 20 | ||||
| -rw-r--r-- | pyramid/tests/test_renderers.py | 6 |
9 files changed, 119 insertions, 95 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 8a14a82de..19d586ac9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -66,6 +66,11 @@ Internal will be set, and subsequent calls to ``__call__`` will always return the same body. Delete the body attribute to rerender the exception body. +- Previously the ``pyramid.events.BeforeRender`` event *wrapped* a dictionary + (it addressed it as its ``_system`` attribute). Now it *is* a dictionary + (it inherits from ``dict``), and it's the value that is passed to templates + as a top-level dictionary. + Deprecations ------------ @@ -109,6 +114,10 @@ Documentation - Added a Logging chapter to the narrative docs (based on the Pylons logging docs, thanks Phil). +- Added the ``pyramid.interfaces.IDict`` interface representing the methods + of a dictionary, for documentation purposes only (IMultiDict and + IBeforeRender inherit from it). + Dependency Changes ------------------ @@ -10,9 +10,6 @@ Should-Have - Make it possible to use tween aliases in explicit tween config? If not, the tween factories of all add-ons must be APIs. -- BeforeRender event subclasses dict but implements a bunch of shit. Its - repr is currently broken (it always shows empty). Decide what to do. - - Come up with an analogue of repoze.zodbconn that doesn't require a closer in the pipeline and use it in the ZODB scaffold and tutorial. diff --git a/docs/api/events.rst b/docs/api/events.rst index 59657a820..31a0e22c1 100644 --- a/docs/api/events.rst +++ b/docs/api/events.rst @@ -25,6 +25,15 @@ Event Types .. autoclass:: BeforeRender :members: + :inherited-members: + :exclude-members: update + + .. method:: update(E, **F) + + Update D from dict/iterable E and F. If E has a .keys() method, does: + for k in E: D[k] = E[k] If E lacks .keys() method, does: for (k, v) in + E: D[k] = v. In either case, this is followed by: for k in F: D[k] = + F[k]. See :ref:`events_chapter` for more information about how to register code which subscribes to these events. diff --git a/docs/api/interfaces.rst b/docs/api/interfaces.rst index 9ab9eefc3..b336e549d 100644 --- a/docs/api/interfaces.rst +++ b/docs/api/interfaces.rst @@ -59,6 +59,9 @@ Other Interfaces .. autointerface:: IViewMapper :members: + .. autointerface:: IDict + :members: + .. autointerface:: IMultiDict :members: diff --git a/pyramid/events.py b/pyramid/events.py index 327a339a7..28280cc9b 100644 --- a/pyramid/events.py +++ b/pyramid/events.py @@ -164,7 +164,6 @@ class ApplicationCreated(object): WSGIApplicationCreatedEvent = ApplicationCreated # b/c (as of 1.0) class BeforeRender(dict): - implements(IBeforeRender) """ Subscribers to this event may introspect the and modify the set of :term:`renderer globals` before they are passed to a :term:`renderer`. @@ -172,9 +171,9 @@ class BeforeRender(dict): for this purpose. For example:: from repoze.events import subscriber - from pyramid.interfaces import IBeforeRender + from pyramid.events import BeforeRender - @subscriber(IBeforeRender) + @subscriber(BeforeRender) def add_global(event): event['mykey'] = 'foo' @@ -198,42 +197,12 @@ class BeforeRender(dict): The event has an additional attribute named ``rendering_val``. This is the (non-system) value returned by a view or passed to ``render*`` as ``value``. This feature is new in Pyramid 1.2. - """ + See also :class:`pyramid.interfaces.IBeforeRender`. + """ + implements(IBeforeRender) def __init__(self, system, rendering_val=None): - self._system = system + dict.__init__(self, system) self.rendering_val = rendering_val - def __setitem__(self, name, value): - """ Set a name/value pair into the dictionary which is passed to a - renderer as the renderer globals dictionary.""" - self._system[name] = value - - def setdefault(self, name, default=None): - """ Return the existing value for ``name`` in the renderers globals - dictionary. If no value with ``name`` exists in the dictionary, set - the ``default`` value into the renderer globals dictionary under the - name passed. If a value already existed in the dictionary, return - it. If a value did not exist in the dictionary, return the default""" - return self._system.setdefault(name, default) - - def update(self, d): - """ Update the renderer globals dictionary with another dictionary - ``d``.""" - return self._system.update(d) - - def __contains__(self, k): - """ Return ``True`` if ``k`` exists in the renderer globals - dictionary.""" - return k in self._system - - def __getitem__(self, k): - """ Return the value for key ``k`` from the renderer globals - dictionary.""" - return self._system[k] - - def get(self, k, default=None): - """ Return the value for key ``k`` from the renderer globals - dictionary, or the default if no such value exists.""" - return self._system.get(k) diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py index 22d879506..61462bb5e 100644 --- a/pyramid/interfaces.py +++ b/pyramid/interfaces.py @@ -268,13 +268,80 @@ class IExceptionResponse(IException, IResponse): def prepare(environ): """ Prepares the response for being called as a WSGI application """ -class IBeforeRender(Interface): +class IDict(Interface): + # Documentation-only interface + + def __contains__(k): + """ Return ``True`` if key ``k`` exists in the dictionary.""" + + def __setitem__(k, value): + """ Set a key/value pair into the dictionary""" + + def __delitem__(k): + """ Delete an item from the dictionary which is passed to the + renderer as the renderer globals dictionary.""" + + def __getitem__(k): + """ Return the value for key ``k`` from the dictionary or raise a + KeyError if the key doesn't exist""" + + def __iter__(): + """ Return an iterator over the keys of this dictionary """ + + def get(k, default=None): + """ Return the value for key ``k`` from the renderer dictionary, or + the default if no such value exists.""" + + has_key = __contains__ + + def items(): + """ Return a list of [(k,v)] pairs from the dictionary """ + + def iteritems(): + """ Return an iterator of (k,v) pairs from the dictionary """ + + def keys(): + """ Return a list of keys from the dictionary """ + + def iterkeys(): + """ Return an iterator of keys from the dictionary """ + + def values(): + """ Return a list of values from the dictionary """ + + def itervalues(): + """ Return an iterator of values from the dictionary """ + + def pop(k, default=None): + """ Pop the key k from the dictionary and return its value. If k + doesn't exist, and default is provided, return the default. If k + doesn't exist and default is not provided, raise a KeyError.""" + + def popitem(): + """ Pop the item with key k from the dictionary and return it as a + two-tuple (k, v). If k doesn't exist, raise a KeyError.""" + + def setdefault(k, default=None): + """ Return the existing value for key ``k`` in the dictionary. If no + value with ``k`` exists in the dictionary, set the ``default`` + value into the dictionary under the k name passed. If a value already + existed in the dictionary, return it. If a value did not exist in + the dictionary, return the default""" + + def update(d): + """ Update the renderer dictionary with another dictionary ``d``.""" + + def clear(): + """ Clear all values from the dictionary """ + +class IBeforeRender(IDict): """ Subscribers to this event may introspect the and modify the set of :term:`renderer globals` before they are passed to a :term:`renderer`. - This event object iself has a dictionary-like interface that can be used - for this purpose. For example:: - + The event object itself provides a dictionary-like interface for adding + and removing :term:`renderer globals`. The keys and values of the + dictionary are those globals. For example:: + from repoze.events import subscriber from pyramid.interfaces import IBeforeRender @@ -284,33 +351,6 @@ class IBeforeRender(Interface): See also :ref:`beforerender_event`. """ - def __setitem__(name, value): - """ Set a name/value pair into the dictionary which is passed to a - renderer as the renderer globals dictionary. """ - - def setdefault(name, default=None): - """ Return the existing value for ``name`` in the renderers globals - dictionary. If no value with ``name`` exists in the dictionary, set - the ``default`` value into the renderer globals dictionary under the - name passed. If a value already existed in the dictionary, return - it. If a value did not exist in the dictionary, return the default""" - - def update(d): - """ Update the renderer globals dictionary with another dictionary - ``d``. """ - - def __contains__(k): - """ Return ``True`` if ``k`` exists in the renderer globals - dictionary.""" - - def __getitem__(k): - """ Return the value for key ``k`` from the renderer globals - dictionary.""" - - def get(k, default=None): - """ Return the value for key ``k`` from the renderer globals - dictionary, or the default if no such value exists.""" - rendering_val = Attribute('The value returned by a view or passed to a ' '``render`` method for this rendering. ' 'This feature is new in Pyramid 1.2.') @@ -405,7 +445,7 @@ class IAuthorizationPolicy(Interface): ``pyramid.security.principals_allowed_by_permission`` API is used.""" -class IMultiDict(Interface): # docs-only interface +class IMultiDict(IDict): # docs-only interface """ An ordered dictionary that can have multiple values for each key. A multidict adds the methods ``getall``, ``getone``, ``mixed``, ``extend`` diff --git a/pyramid/renderers.py b/pyramid/renderers.py index 6f9b87698..2efe0f123 100644 --- a/pyramid/renderers.py +++ b/pyramid/renderers.py @@ -384,13 +384,12 @@ class RendererHelper(object): return self.renderer def render_view(self, request, response, view, context): - system = { - 'view':view, - 'renderer_name':self.name, # b/c - 'renderer_info':self, - 'context':context, - 'request':request - } + system = {'view':view, + 'renderer_name':self.name, # b/c + 'renderer_info':self, + 'context':context, + 'request':request + } return self.render_to_response(response, system, request=request) def render(self, value, system_values, request=None): @@ -404,6 +403,8 @@ class RendererHelper(object): 'request':request, } + system_values = BeforeRender(system_values, value) + registry = self.registry globals_factory = registry.queryUtility(IRendererGlobalsFactory) @@ -412,7 +413,7 @@ class RendererHelper(object): if renderer_globals: system_values.update(renderer_globals) - registry.notify(BeforeRender(system_values, value)) + registry.notify(system_values) result = renderer(value, system_values) return result diff --git a/pyramid/tests/test_events.py b/pyramid/tests/test_events.py index 116a48bb7..e7468f1f3 100644 --- a/pyramid/tests/test_events.py +++ b/pyramid/tests/test_events.py @@ -190,31 +190,27 @@ class TestBeforeRender(unittest.TestCase): verifyObject(IBeforeRender, event) def test_setitem_success(self): - system = {} - event = self._makeOne(system) + event = self._makeOne({}) event['a'] = 1 - self.assertEqual(system, {'a':1}) + self.assertEqual(event, {'a':1}) def test_setdefault_fail(self): - system = {} - event = self._makeOne(system) + event = self._makeOne({}) result = event.setdefault('a', 1) self.assertEqual(result, 1) - self.assertEqual(system, {'a':1}) + self.assertEqual(event, {'a':1}) def test_setdefault_success(self): - system = {} - event = self._makeOne(system) + event = self._makeOne({}) event['a'] = 1 result = event.setdefault('a', 2) self.assertEqual(result, 1) - self.assertEqual(system, {'a':1}) + self.assertEqual(event, {'a':1}) def test_update_success(self): - system = {'a':1} - event = self._makeOne(system) + event = self._makeOne({'a':1}) event.update({'b':2}) - self.assertEqual(system, {'a':1, 'b':2}) + self.assertEqual(event, {'a':1, 'b':2}) def test__contains__True(self): system = {'a':1} diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py index b5c5d1242..f4a3b7dfa 100644 --- a/pyramid/tests/test_renderers.py +++ b/pyramid/tests/test_renderers.py @@ -520,9 +520,9 @@ class TestRendererHelper(unittest.TestCase): self._registerResponseFactory() request = Dummy() helper = self._makeOne('loo.foo') - response = helper.render_to_response('values', 'system_values', + response = helper.render_to_response('values', {}, request=request) - self.assertEqual(response.body, ('values', 'system_values')) + self.assertEqual(response.body, ('values', {})) def test_render_view(self): self._registerRendererFactory() @@ -558,7 +558,7 @@ class TestRendererHelper(unittest.TestCase): result = helper.render('value', {}) self.assertEqual(result, ('value', {})) self.assertTrue(reg.queried) - self.assertEqual(reg.event._system, {}) + self.assertEqual(reg.event, {}) self.assertEqual(reg.event.__class__.__name__, 'BeforeRender') def test_render_system_values_is_None(self): |
