summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-08-14 00:53:53 -0400
committerChris McDonough <chrism@plope.com>2011-08-14 00:53:53 -0400
commit5c52daef7004a1e43a7c2fc25613e3d92c4b6b8e (patch)
tree63e3b5b77f7904799bff1029de7804a62f7e973e
parent5396466b819692ae0d1ea2b78e6df6093545963a (diff)
downloadpyramid-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.txt9
-rw-r--r--TODO.txt3
-rw-r--r--docs/api/events.rst9
-rw-r--r--docs/api/interfaces.rst3
-rw-r--r--pyramid/events.py43
-rw-r--r--pyramid/interfaces.py104
-rw-r--r--pyramid/renderers.py17
-rw-r--r--pyramid/tests/test_events.py20
-rw-r--r--pyramid/tests/test_renderers.py6
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
------------------
diff --git a/TODO.txt b/TODO.txt
index 60c758ef2..87dd3fae8 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -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):