summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-11-29 14:52:29 +0000
committerChris McDonough <chrism@agendaless.com>2009-11-29 14:52:29 +0000
commitaf9f2e5fd5664aeaea2057ce1c518fb04617a0f0 (patch)
treed0ca3dbda2df89acc15b76ed6e5f7e34bbad90f0
parent7fb23b46b7b3fe3729d99166d13b96954b1de44a (diff)
downloadpyramid-af9f2e5fd5664aeaea2057ce1c518fb04617a0f0.tar.gz
pyramid-af9f2e5fd5664aeaea2057ce1c518fb04617a0f0.tar.bz2
pyramid-af9f2e5fd5664aeaea2057ce1c518fb04617a0f0.zip
- Trying to use an HTTP method name string such as ``GET`` as a
``request_type`` predicate caused a startup time failure when it was encountered in imperative configuration or in a decorator (symptom: ``Type Error: Required specification must be a specification``). This now works again, although ``request_method`` is a more modern predicate.
-rw-r--r--CHANGES.txt1143
-rw-r--r--HISTORY.txt1130
-rw-r--r--repoze/bfg/configuration.py5
-rw-r--r--repoze/bfg/tests/test_configuration.py13
4 files changed, 1161 insertions, 1130 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index b5a130feb..3464bf2ef 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,16 @@
+Next release
+============
+
+Bug Fixes
+---------
+
+- Trying to use an HTTP method name string such as ``GET`` as a
+ ``request_type`` predicate caused a startup time failure when it was
+ encountered in imperative configuration or in a decorator (symptom:
+ ``Type Error: Required specification must be a specification``).
+ This now works again, although ``request_method`` is a more modern
+ predicate.
+
1.2a1 (2009-11-28)
==================
@@ -347,1133 +360,3 @@ Dependencies
- A dependency on the ``repoze.zcml`` package has been removed (its
functionality is replaced internally).
-1.1.1 (2009-11-21)
-==================
-
-Bug Fixes
----------
-
-- "Hybrid mode" applications (applications which explicitly used
- traversal *after* url dispatch via ``<route>`` paths containing the
- ``*traverse`` element) were broken in 1.1-final and all 1.1 alpha
- and beta releases. Views registered without a ``route_name`` route
- shadowed views registered with a ``route_name`` inappropriately.
-
-1.1 (2009-11-15)
-================
-
-Internals
----------
-
-- Remove dead IRouteRequirement interface from ``repoze.bfg.zcml``
- module.
-
-Documentation
--------------
-
-- Improve the "Extending an Existing Application" narrative chapter.
-
-- Add more sections to the "Defending Design" chapter.
-
-1.1b4 (2009-11-12)
-==================
-
-Bug Fixes
----------
-
-- Use ``alsoProvides`` in the urldispatch module to attach an
- interface to the request rather than ``directlyProvides`` to avoid
- disturbing interfaces set in a NewRequest event handler.
-
-Documentation
--------------
-
-- Move 1.0.1 and previous changelog to HISTORY.txt.
-
-- Add examples to ``repoze.bfg.url.model_url`` docstring.
-
-- Add "Defending BFG Design" chapter to frontpage docs.
-
-Templates
----------
-
-- Remove ``ez_setup.py`` and its import from all paster templates,
- samples, and tutorials for ``distribute`` compatibility. The
- documentation already explains how to install virtualenv (which will
- include some ``setuptools`` package), so these files, imports and
- usages were superfluous.
-
-Deprecations
-------------
-
-- The ``options`` kw arg to the ``repoze.bfg.router.make_app``
- function is deprecated. In its place is the keyword argument
- ``settings``. The ``options`` keyword continues to work, and a
- deprecation warning is not emitted when it is detected. However,
- the paster templates, code samples, and documentation now make
- reference to ``settings`` rather than ``options``. This
- change/deprecation was mainly made for purposes of clarity and
- symmetry with the ``get_settings()`` API and dicussions of
- "settings" in various places in the docs: we want to use the same
- name to refer to the same thing everywhere.
-
-1.1b3 (2009-11-06)
-==================
-
-Features
---------
-
-- ``repoze.bfg.testing.registerRoutesMapper`` testing facility added.
- This testing function registers a routes "mapper" object in the
- registry, for tests which require its presence. This function is
- documented in the ``repoze.bfg.testing`` API documentation.
-
-Bug Fixes
----------
-
-- Compound statements that used an assignment entered into in an
- interactive IPython session invoked via ``paster bfgshell`` no
- longer fail to mutate the shell namespace correctly. For example,
- this set of statements used to fail::
-
- In [2]: def bar(x): return x
- ...:
- In [3]: list(bar(x) for x in 'abc')
- Out[3]: NameError: 'bar'
-
- In this release, the ``bar`` function is found and the correct
- output is now sent to the console. Thanks to Daniel Holth for the
- patch.
-
-- The ``bfgshell`` command did not function properly; it was still
- expecting to be able to call the root factory with a bare
- ``environ`` rather than a request object.
-
-Backwards Incompatibilities
----------------------------
-
-- The ``repoze.bfg.scripting.get_root`` function now expects a
- ``request`` object as its second argument rather than an
- ``environ``.
-
-1.1b2 (2009-11-02)
-==================
-
-Bug Fixes
----------
-
-- Prevent PyPI installation failure due to ``easy_install`` trying way
- too hard to guess the best version of Paste. When ``easy_install``
- pulls from PyPI it reads links off various pages to determine "more
- up to date" versions. It incorrectly picks up a link for an ancient
- version of a package named "Paste-Deploy-0.1" (note the dash) when
- trying to find the "Paste" distribution and somehow believes it's
- the latest version of "Paste". It also somehow "helpfully" decides
- to check out a version of this package from SVN. We pin the Paste
- dependency version to a version greater than 1.7 to work around
- this ``easy_install`` bug.
-
-Documentation
--------------
-
-- Fix "Hybrid" narrative chapter: stop claiming that ``<view>``
- statements that mention a route_name need to come afer (in XML
- order) the ``<route>`` statement which creates the route. This
- hasn't been true since 1.1a1.
-
-- "What's New in ``repoze.bfg`` 1.1" document added to narrative
- documentation.
-
-Features
---------
-
-- Add a new event type: ``repoze.bfg.events.AfterTraversal``. Events
- of this type will be sent after traversal is completed, but before
- any view code is invoked. Like ``repoze.bfg.events.NewRequest``,
- This event will have a single attribute: ``request`` representing
- the current request. Unlike the request attribute of
- ``repoze.bfg.events.NewRequest`` however, during an AfterTraversal
- event, the request object will possess attributes set by the
- traverser, most notably ``context``, which will be the context used
- when a view is found and invoked. The interface
- ``repoze.bfg.events.IAfterTraversal`` can be used to subscribe to
- the event. For example::
-
- <subscriber for="repoze.bfg.interfaces.IAfterTraversal"
- handler="my.app.handle_after_traverse"/>
-
- Like any framework event, a subscriber function should expect one
- parameter: ``event``.
-
-Dependencies
-------------
-
-- Rather than depending on ``chameleon.core`` and ``chameleon.zpt``
- distributions individually, depend on Malthe's repackaged
- ``Chameleon`` distribution (which includes both ``chameleon.core``
- and ``chameleon.zpt``).
-
-1.1b1 (2009-11-01)
-==================
-
-Bug Fixes
----------
-
-- The routes root factory called route factories and the default route
- factory with an environ rather than a request. One of the symptoms
- of this bug: applications generated using the ``bfg_zodb`` paster
- template in 1.1a9 did not work properly.
-
-- Reinstate ``renderer`` alias for ``view_renderer`` in the
- ``<route>`` ZCML directive (in-the-wild 1.1a bw compat).
-
-- ``bfg_routesalchemy`` paster template: change ``<route>``
- declarations: rename ``renderer`` attribute to ``view_renderer``.
-
-- Header values returned by the ``authtktauthenticationpolicy``
- ``remember`` and ``forget`` methods would be of type ``unicode``.
- This violated the WSGI spec, causing a ``TypeError`` to be raised
- when these headers were used under ``mod_wsgi``.
-
-- If a BFG app that had a route matching the root URL was mounted
- under a path in modwsgi, ala ``WSGIScriptAlias /myapp
- /Users/chrism/projects/modwsgi/env/bfg.wsgi``, the home route (a
- route with the path of ``'/'`` or ``''``) would not match when the
- path ``/myapp`` was visited (only when the path ``/myapp/`` was
- visited). This is now fixed: if the urldispatch root factory notes
- that the PATH_INFO is empty, it converts it to a single slash before
- trying to do matching.
-
-Documentation
--------------
-
-- In ``<route>`` declarations in tutorial ZCML, rename ``renderer``
- attribute to ``view_renderer`` (fwd compat).
-
-- Fix various tutorials broken by 1.1a9 ``<route>`` directive changes.
-
-Internal
---------
-
-- Deal with a potential circref in the traversal module.
-
-1.1a9 (2009-10-31)
-==================
-
-Bug Fixes
----------
-
-- An incorrect ZCML conflict would be encountered when the
- ``request_param`` predicate attribute was used on the ZCML ``view``
- directive if any two otherwise same-predicated views had the
- combination of a predicate value with an ``=`` sign and one without
- (e.g. ``a`` vs. ``a=123``).
-
-Features
---------
-
-- In previous versions of BFG, the "root factory" (the ``get_root``
- callable passed to ``make_app`` or a function pointed to by the
- ``factory`` attribute of a route) was called with a "bare" WSGI
- environment. In this version, and going forward, it will be called
- with a ``request`` object. The request object passed to the factory
- implements dictionary-like methods in such a way that existing root
- factory code which expects to be passed an environ will continue to
- work.
-
-- The ``__call__`` of a plugin "traverser" implementation (registered
- as an adapter for ``ITraverser`` or ``ITraverserFactory``) will now
- receive a *request* as the single argument to its ``__call__``
- method. In previous versions it was passed a WSGI ``environ``
- object. The request object passed to the factory implements
- dictionary-like methods in such a way that existing traverser code
- which expects to be passed an environ will continue to work.
-
-- The ZCML ``route`` directive's attributes ``xhr``,
- ``request_method``, ``path_info``, ``request_param``, ``header`` and
- ``accept`` are now *route* predicates rather than *view* predicates.
- If one or more of these predicates is specified in the route
- configuration, all of the predicates must return true for the route
- to match a request. If one or more of the route predicates
- associated with a route returns ``False`` when checked during a
- request, the route match fails, and the next match in the routelist
- is tried. This differs from the previous behavior, where no route
- predicates existed and all predicates were considered view
- predicates, because in that scenario, the next route was not tried.
-
-Documentation
--------------
-
-- Various changes were made to narrative and API documentation
- supporting the change from passing a request rather than an environ
- to root factories and traversers.
-
-Internal
---------
-
-- The request implements dictionary-like methods that mutate and query
- the WSGI environ. This is only for the purpose of backwards
- compatibility with root factories which expect an ``environ`` rather
- than a request.
-
-- The ``repoze.bfg.request.create_route_request_factory`` function,
- which returned a request factory was removed in favor of a
- ``repoze.bfg.request.route_request_interface`` function, which
- returns an interface.
-
-- The ``repoze.bfg.request.Request`` class, which is a subclass of
- ``webob.Request`` now defines its own ``__setattr__``,
- ``__getattr__`` and ``__delattr__`` methods, which override the
- default WebOb behavior. The default WebOb behavior stores
- attributes of the request in ``self.environ['webob.adhoc_attrs']``,
- and retrieves them from that dictionary during a ``__getattr__``.
- This behavior was undesirable for speed and "expectation" reasons.
- Now attributes of the ``request`` are stored in ``request.__dict__``
- (as you otherwise might expect from an object that did not override
- these methods).
-
-- The router no longer calls ``repoze.bfg.traversal._traverse`` and
- does its work "inline" (speed).
-
-- Reverse the order in which the router calls the request factory and
- the root factory. The request factory is now called first; the
- resulting request is passed to the root factory.
-
-- The ``repoze.bfg.request.request_factory`` function has been
- removed. Its functionality is no longer required.
-
-- The "routes root factory" that wraps the default root factory when
- there are routes mentioned in the configuration now attaches an
- interface to the request via ``zope.interface.directlyProvides``.
- This replaces logic in the (now-gone)
- ``repoze.bfg.request.request_factory`` function.
-
-- The ``route`` and ``view`` ZCML directives now register an interface
- as a named utility (retrieved from
- ``repoze.bfg.request.route_request_interface``) rather than a
- request factory (the previous return value of the now-missing
- ``repoze.bfg.request.create_route_request_factory``.
-
-- The ``repoze.bfg.functional`` module was renamed to
- ``repoze.bfg.compat``.
-
-Backwards Incompatibilities
----------------------------
-
-- Explicitly revert the feature introduced in 1.1a8: where the name
- ``root`` is available as an attribute of the request before a
- NewRequest event is emitted. This makes some potential future
- features impossible, or at least awkward (such as grouping traversal
- and view lookup into a single adapter lookup).
-
-- The ``containment``, ``attr`` and ``renderer`` attributes of the
- ``route`` ZCML directive were removed.
-
-1.1a8 (2009-10-27)
-==================
-
-Features
---------
-
-- Add ``path_info`` view configuration predicate.
-
-- ``paster bfgshell`` now supports IPython if it's available for
- import. Thanks to Daniel Holth for the initial patch.
-
-- Add ``repoze.bfg.testing.registerSettings`` API, which is documented
- in the "repoze.bfg.testing" API chapter. This allows for
- registration of "settings" values obtained via
- ``repoze.bfg.settings.get_settings()`` for use in unit tests.
-
-- The name ``root`` is available as an attribute of the request
- slightly earlier now (before a NewRequest event is emitted).
- ``root`` is the result of the application "root factory".
-
-- Added ``max_age`` parameter to ``authtktauthenticationpolicy`` ZCML
- directive. If this value is set, it must be an integer representing
- the number of seconds which the auth tkt cookie will survive.
- Mainly, its existence allows the auth_tkt cookie to survive across
- browser sessions.
-
-Bug Fixes
----------
-
-- Fix bug encountered during "scan" (when ``<scan ..>`` directive is
- used in ZCML) introduced in 1.1a7. Symptom: ``AttributeError:
- object has no attribute __provides__`` raised at startup time.
-
-- The ``reissue_time`` argument to the ``authtktauthenticationpolicy``
- ZCML directive now actually works. When it is set to an integer
- value, an authticket set-cookie header is appended to the response
- whenever a request requires authentication and 'now' minus the
- authticket's timestamp is greater than ``reissue_time`` seconds.
-
-Documentation
--------------
-
-- Add a chapter titled "Request and Response" to the narrative
- documentation, content cribbed from the WebOb documentation.
-
-- Call out predicate attributes of ZCML directive within "Views"
- chapter.
-
-- Fix route_url documentation (``_query`` argument documented as
- ``query`` and ``_anchor`` argument documented as ``anchor``).
-
-Backwards Incompatibilities
----------------------------
-
-- The ``authtkt`` authentication policy ``remember`` method now no
- longer honors ``token`` or ``userdata`` keyword arguments.
-
-Internal
---------
-
-- Change how ``bfg_view`` decorator works when used as a class method
- decorator. In 1.1a7, the``scan``directive actually tried to grope
- every class in scanned package at startup time, calling ``dir``
- against each found class, and subsequently invoking ``getattr``
- against each thing found by ``dir`` to see if it was a method. This
- led to some strange symptoms (e.g. ``AttributeError: object has no
- attribute __provides__``), and was generally just a bad idea. Now,
- instead of groping classes for methods at startup time, we just
- cause the ``bfg_view`` decorator itself to populate the method's
- class' ``__dict__`` when it is used as a method decorator. This
- also requires a nasty _getframe thing but it's slightly less nasty
- than the startup time groping behavior. This is essentially a
- reversion back to 1.1a6 "grokking" behavior plus some special magic
- for using the ``bfg_view`` decorator as method decorator inside the
- ``bfg_view`` class itself.
-
-- The router now checks for a ``global_response_headers`` attribute of
- the request object before returning a response. If this value
- exists, it is presumed to be a sequence of two-tuples, representing
- a set of headers to append to the 'normal' response headers. This
- feature is internal, rather than exposed externally, because it's
- unclear whether it will stay around in the long term. It was added
- to support the ``reissue_time`` feature of the authtkt
- authentication policy.
-
-- The interface ITraverserFactory is now just an alias for ITraverser.
-
-1.1a7 (2009-10-18)
-==================
-
-Features
---------
-
-- More than one ``@bfg_view`` decorator may now be stacked on top of
- any number of others. Each invocation of the decorator registers a
- single view configuration. For instance, the following combination
- of decorators and a function will register two view configurations
- for the same view callable::
-
- from repoze.bfg.view import bfg_view
-
- @bfg_view(name='edit')
- @bfg_view(name='change')
- def edit(context, request):
- pass
-
- This makes it possible to associate more than one view configuration
- with a single callable without requiring any ZCML.
-
-- The ``@bfg_view`` decorator can now be used against a class method::
-
- from webob import Response
- from repoze.bfg.view import bfg_view
-
- class MyView(object):
- def __init__(self, context, request):
- self.context = context
- self.request = request
-
- @bfg_view(name='hello')
- def amethod(self):
- return Response('hello from %s!' % self.context)
-
- When the bfg_view decorator is used against a class method, a view
- is registered for the *class* (it's a "class view" where the "attr"
- happens to be the name of the method it is attached to), so the
- class it's defined within must have a suitable constructor: one that
- accepts ``context, request`` or just ``request``.
-
-Documentation
--------------
-
-- Added ``Changing the Traverser`` and ``Changing How
- :mod:`repoze.bfg.url.model_url` Generates a URL`` to the "Hooks"
- narrative chapter of the docs.
-
-Internal
---------
-
-- Remove ``ez_setup.py`` and imports of it within ``setup.py``. In
- the new world, and as per virtualenv setup instructions, people will
- already have either setuptools or distribute.
-
-1.1a6 (2009-10-15)
-==================
-
-Features
---------
-
-- Add ``xhr``, ``accept``, and ``header`` view configuration
- predicates to ZCML view declaration, ZCML route declaration, and
- ``bfg_view`` decorator. See the ``Views`` narrative documentation
- chapter for more information about these predicates.
-
-- Add ``setUp`` and ``tearDown`` functions to the
- ``repoze.bfg.testing`` module. Using ``setUp`` in a test setup and
- ``tearDown`` in a test teardown is now the recommended way to do
- component registry setup and teardown. Previously, it was
- recommended that a single function named
- ``repoze.bfg.testing.cleanUp`` be called in both the test setup and
- tear down. ``repoze.bfg.testing.cleanUp`` still exists (and will
- exist "forever" due to its widespread use); it is now just an alias
- for ``repoze.bfg.testing.setUp`` and is nominally deprecated.
-
-- The BFG component registry is now available in view and event
- subscriber code as an attribute of the request
- ie. ``request.registry``. This fact is currently undocumented
- except for this note, because BFG developers never need to interact
- with the registry directly anywhere else.
-
-- The BFG component registry now inherits from ``dict``, meaning that
- it can optionally be used as a simple dictionary. *Component*
- registrations performed against it via e.g. ``registerUtility``,
- ``registerAdapter``, and similar API methods are kept in a
- completely separate namespace than its dict members, so using the
- its component API methods won't effect the keys and values in the
- dictionary namespace. Likewise, though the component registry
- "happens to be" a dictionary, use of mutating dictionary methods
- such as ``__setitem__`` will have no influence on any component
- registrations made against it. In other words, the registry object
- you obtain via e.g. ``repoze.bfg.threadlocal.get_current_registry``
- or ``request.registry`` happens to be both a component registry and
- a dictionary, but using its component-registry API won't impact data
- added to it via its dictionary API and vice versa. This is a
- forward compatibility move based on the goals of "marco".
-
-- Expose and document ``repoze.bfg.testing.zcml_configure`` API. This
- function populates a component registry from a ZCML file for testing
- purposes. It is documented in the "Unit and Integration Testing"
- chapter.
-
-Documentation
--------------
-
-- Virtual hosting narrative docs chapter updated with info about
- ``mod_wsgi``.
-
-- Point all index URLs at the literal 1.1 index (this alpha cycle may
- go on a while).
-
-- Various tutorial test modules updated to use
- ``repoze.bfg.testing.setUp`` and ``repoze.bfg.testing.tearDown``
- methods in order to encourage this as best practice going forward.
-
-- Added "Creating Integration Tests" section to unit testing narrative
- documentation chapter. As a result, the name of the unittesting
- chapter is now "Unit and Integration Testing".
-
-Backwards Incompatibilities
----------------------------
-
-- Importing ``getSiteManager`` and ``get_registry`` from
- ``repoze.bfg.registry`` is no longer supported. These imports were
- deprecated in repoze.bfg 1.0. Import of ``getSiteManager`` should
- be done as ``from zope.component import getSiteManager``. Import of
- ``get_registry`` should be done as ``from repoze.bfg.threadlocal
- import get_current_registry``. This was done to prevent a circular
- import dependency.
-
-- Code bases which alternately invoke both
- ``zope.testing.cleanup.cleanUp`` and ``repoze.bfg.testing.cleanUp``
- (treating them equivalently, using them interchangeably) in the
- setUp/tearDown of unit tests will begin to experience test failures
- due to lack of test isolation. The "right" mechanism is
- ``repoze.bfg.testing.cleanUp`` (or the combination of
- ``repoze.bfg.testing.setUp`` and
- ``repoze.bfg.testing.tearDown``). but a good number of legacy
- codebases will use ``zope.testing.cleanup.cleanUp`` instead. We
- support ``zope.testing.cleanup.cleanUp`` but not in combination with
- ``repoze.bfg.testing.cleanUp`` in the same codebase. You should use
- one or the other test cleanup function in a single codebase, but not
- both.
-
-Internal
---------
-
-- Created new ``repoze.bfg.configuration`` module which assumes
- responsibilities previously held by the ``repoze.bfg.registry`` and
- ``repoze.bfg.router`` modules (avoid a circular import dependency).
-
-- The result of the ``zope.component.getSiteManager`` function in unit
- tests set up with ``repoze.bfg.testing.cleanUp`` or
- ``repoze.bfg.testing.setUp`` will be an instance of
- ``repoze.bfg.registry.Registry`` instead of the global
- ``zope.component.globalregistry.base`` registry. This also means
- that the threadlocal ZCA API functions such as ``getAdapter`` and
- ``getUtility`` as well as internal BFG machinery (such as
- ``model_url`` and ``route_url``) will consult this registry within
- unit tests. This is a forward compatibility move based on the goals
- of "marco".
-
-- Removed ``repoze.bfg.testing.addCleanUp`` function and associated
- module-scope globals. This was never an API.
-
-1.1a5 (2009-10-10)
-==================
-
-Documentation
--------------
-
-- Change "Traversal + ZODB" and "URL Dispatch + SQLAlchemy" Wiki
- tutorials to make use of the new-to-1.1 "renderer" feature (return
- dictionaries from all views).
-
-- Add tests to the "URL Dispatch + SQLAlchemy" tutorial after the
- "view" step.
-
-- Added a diagram of model graph traversal to the "Traversal"
- narrative chapter of the documentation.
-
-- An ``exceptions`` API chapter was added, documenting the new
- ``repoze.bfg.exceptions`` module.
-
-- Describe "request-only" view calling conventions inside the
- urldispatch narrative chapter, where it's most helpful.
-
-- Add a diagram which explains the operation of the BFG router to the
- "Router" narrative chapter.
-
-Features
---------
-
-- Add a new ``repoze.bfg.testing`` API: ``registerRoute``, for
- registering routes to satisfy calls to
- e.g. ``repoze.bfg.url.route_url`` in unit tests.
-
-- The ``notfound`` and ``forbidden`` ZCML directives now accept the
- following addtional attributes: ``attr``, ``renderer``, and
- ``wrapper``. These have the same meaning as they do in the context
- of a ZCML ``view`` directive.
-
-- For behavior like Django's ``APPEND_SLASH=True``, use the
- ``repoze.bfg.view.append_slash_notfound_view`` view as the Not Found
- view in your application. When this view is the Not Found view
- (indicating that no view was found), and any routes have been
- defined in the configuration of your application, if the value of
- ``PATH_INFO`` does not already end in a slash, and if the value of
- ``PATH_INFO`` *plus* a slash matches any route's path, do an HTTP
- redirect to the slash-appended PATH_INFO. Note that this will
- *lose* ``POST`` data information (turning it into a GET), so you
- shouldn't rely on this to redirect POST requests.
-
-- Speed up ``repoze.bfg.location.lineage`` slightly.
-
-- Speed up ``repoze.bfg.encode.urlencode`` (nee'
- ``repoze.bfg.url.urlencode``) slightly.
-
-- Speed up ``repoze.bfg.traversal.model_path``.
-
-- Speed up ``repoze.bfg.traversal.model_path_tuple`` slightly.
-
-- Speed up ``repoze.bfg.traversal.traverse`` slightly.
-
-- Speed up ``repoze.bfg.url.model_url`` slightly.
-
-- Speed up ``repoze.bfg.url.route_url`` slightly.
-
-- Sped up ``repoze.bfg.traversal.ModelGraphTraverser:__call__``
- slightly.
-
-- Minor speedup of ``repoze.bfg.router.Router.__call__``.
-
-- New ``repoze.bfg.exceptions`` module was created to house exceptions
- that were previously sprinkled through various modules.
-
-Internal
---------
-
-- Move ``repoze.bfg.traversal._url_quote`` into ``repoze.bfg.encode``
- as ``url_quote``.
-
-Deprecations
-------------
-
-- The import of ``repoze.bfg.view.NotFound`` is deprecated in favor of
- ``repoze.bfg.exceptions.NotFound``. The old location still
- functions, but emits a deprecation warning.
-
-- The import of ``repoze.bfg.security.Unauthorized`` is deprecated in
- favor of ``repoze.bfg.exceptions.Forbidden``. The old location
- still functions but emits a deprecation warning. The rename from
- ``Unauthorized`` to ``Forbidden`` brings parity to the the name of
- the exception and the system view it invokes when raised.
-
-Backwards Incompatibilities
----------------------------
-
-- We previously had a Unicode-aware wrapper for the
- ``urllib.urlencode`` function named ``repoze.bfg.url.urlencode``
- which delegated to the stdlib function, but which marshalled all
- unicode values to utf-8 strings before calling the stdlib version.
- A newer replacement now lives in ``repoze.bfg.encode`` The
- replacement does not delegate to the stdlib.
-
- The replacement diverges from the stdlib implementation and the
- previous ``repoze.bfg.url`` url implementation inasmuch as its
- ``doseq`` argument is now a decoy: it always behaves in the
- ``doseq=True`` way (which is the only sane behavior) for speed
- purposes.
-
- The old import location (``repoze.bfg.url.urlencode``) still
- functions and has not been deprecated.
-
-- In 0.8a7, the return value expected from an object implementing
- ``ITraverserFactory`` was changed from a sequence of values to a
- dictionary containing the keys ``context``, ``view_name``,
- ``subpath``, ``traversed``, ``virtual_root``, ``virtual_root_path``,
- and ``root``. Until now, old-style traversers which returned a
- sequence have continued to work but have generated a deprecation
- warning. In this release, traversers which return a sequence
- instead of a dictionary will no longer work.
-
-1.1a4 (2009-09-23)
-==================
-
-Bug Fixes
----------
-
-- On 64-bit Linux systems, views that were members of a multiview
- (orderings of views with predicates) were not evaluated in the
- proper order. Symptom: in a configuration that had two views with
- the same name but one with a ``request_method=POST`` predicate and
- one without, the one without the predicate would be called
- unconditionally (even if the request was a POST request). Thanks
- much to Sebastien Douche for providing the buildbots that pointed
- this out.
-
-Documentation
--------------
-
-- Added a tutorial which explains how to use ``repoze.session``
- (ZODB-based sessions) in a ZODB-based repoze.bfg app.
-
-- Added a tutorial which explains how to add ZEO to a ZODB-based
- ``repoze.bfg`` application.
-
-- Added a tutorial which explains how to run a ``repoze.bfg``
- application under `mod_wsgi <http://code.google.com/p/modwsgi/>`_.
- See "Running a repoze.bfg Application under mod_wsgi" in the
- tutorials section of the documentation.
-
-Features
---------
-
-- Add a ``repoze.bfg.url.static_url`` API which is capable of
- generating URLs to static resources defined by the ``<static>`` ZCML
- directive. See the "Views" narrative chapter's section titled
- "Generating Static Resource URLs" for more information.
-
-- Add a ``string`` renderer. This renderer converts a non-Response
- return value of any view callble into a string. It is documented in
- the "Views" narrative chapter.
-
-- Give the ``route`` ZCML directive the ``view_attr`` and
- ``view_renderer`` parameters (bring up to speed with 1.1a3
- features). These can also be spelled as ``attr`` and ``renderer``.
-
-Backwards Incompatibilities
----------------------------
-
-- An object implementing the ``IRenderer`` interface (and
- ``ITemplateRenderer`, which is a subclass of ``IRenderer``) must now
- accept an extra ``system`` argument in its ``__call__`` method
- implementation. Values computed by the system (as opposed to by the
- view) are passed by the system in the ``system`` parameter, which
- will always be a dictionary. Keys in the dictionary include:
- ``view`` (the view object that returned the value),
- ``renderer_name`` (the template name or simple name of the
- renderer), ``context`` (the context object passed to the view), and
- ``request`` (the request object passed to the view). Previously
- only ITemplateRenderers received system arguments as elements inside
- the main ``value`` dictionary.
-
-Internal
---------
-
-- The way ``bfg_view`` declarations are scanned for has been modified.
- This should have no external effects.
-
-- Speed: do not register an ITraverserFactory in configure.zcml;
- instead rely on queryAdapter and a manual default to
- ModelGraphTraverser.
-
-- Speed: do not register an IContextURL in configure.zcml; instead
- rely on queryAdapter and a manual default to TraversalContextURL.
-
-- General speed microimprovements for helloworld benchmark: replace
- try/excepts with statements which use 'in' keyword.
-
-1.1a3 (2009-09-16)
-==================
-
-Documentation
--------------
-
-- The "Views" narrative chapter in the documentation has been updated
- extensively to discuss "renderers".
-
-Features
---------
-
-- A ``renderer`` attribute has been added to view configurations,
- replacing the previous (1.1a2) version's ``template`` attribute. A
- "renderer" is an object which accepts the return value of a view and
- converts it to a string. This includes, but is not limited to,
- templating systems.
-
-- A new interface named ``IRenderer`` was added. The existing
- interface, ``ITemplateRenderer`` now derives from this new
- interface. This interface is internal.
-
-- A new interface named ``IRendererFactory`` was added. An existing
- interface named ``ITemplateRendererFactory`` now derives from this
- interface. This interface is internal.
-
-- The ``view`` attribute of the ``view`` ZCML directive is no longer
- required if the ZCML directive also has a ``renderer`` attribute.
- This is useful when the renderer is a template renderer and no names
- need be passed to the template at render time.
-
-- A new zcml directive ``renderer`` has been added. It is documented
- in the "Views" narrative chapter of the documentation.
-
-- A ZCML ``view`` directive (and the associated ``bfg_view``
- decorator) can now accept a "wrapper" value. If a "wrapper" value
- is supplied, it is the value of a separate view's *name* attribute.
- When a view with a ``wrapper`` attribute is rendered, the "inner"
- view is first rendered normally. Its body is then attached to the
- request as "wrapped_body", and then a wrapper view name is looked up
- and rendered (using ``repoze.bfg.render_view_to_response``), passed
- the request and the context. The wrapper view is assumed to do
- something sensible with ``request.wrapped_body``, usually inserting
- its structure into some other rendered template. This feature makes
- it possible to specify (potentially nested) "owrap" relationships
- between views using only ZCML or decorators (as opposed always using
- ZPT METAL and analogues to wrap view renderings in outer wrappers).
-
-Dependencies
-------------
-
-- When used under Python < 2.6, BFG now has an installation time
- dependency on the ``simplejson`` package.
-
-Deprecations
-------------
-
-- The ``repoze.bfg.testing.registerDummyRenderer`` API has been
- deprecated in favor of
- ``repoze.bfg.testing.registerTemplateRenderer``. A deprecation
- warning is *not* issued at import time for the former name; it will
- exist "forever"; its existence has been removed from the
- documentation, however.
-
-- The ``repoze.bfg.templating.renderer_from_cache`` function has been
- moved to ``repoze.bfg.renderer.template_renderer_factory``. This
- was never an API, but code in the wild was spotted that used it. A
- deprecation warning is issued at import time for the former.
-
-Backwards Incompatibilities
----------------------------
-
-- The ``ITemplateRenderer`` interface has been changed. Previously
- its ``__call__`` method accepted ``**kw``. It now accepts a single
- positional parameter named ``kw`` (REVISED: it accepts two
- positional parameters as of 1.1a4: ``value`` and ``system``). This
- is mostly an internal change, but it was exposed in APIs in one
- place: if you've used the
- ``repoze.bfg.testing.registerDummyRenderer`` API in your tests with
- a custom "renderer" argument with your own renderer implementation,
- you will need to change that renderer implementation to accept
- ``kw`` instead of ``**kw`` in its ``__call__`` method (REVISED: make
- it accept ``value`` and ``system`` positional arguments as of 1.1a4).
-
-- The ``ITemplateRendererFactory`` interface has been changed.
- Previously its ``__call__`` method accepted an ``auto_reload``
- keyword parameter. Now its ``__call__`` method accepts no keyword
- parameters. Renderers are now themselves responsible for
- determining details of auto-reload. This is purely an internal
- change. This interface was never external.
-
-- The ``template_renderer`` ZCML directive introduced in 1.1a2 has
- been removed. It has been replaced by the ``renderer`` directive.
-
-- The previous release (1.1a2) added a view configuration attribute
- named ``template``. In this release, the attribute has been renamed
- to ``renderer``. This signifies that the attribute is more generic:
- it can now be not just a template name but any renderer name (ala
- ``json``).
-
-- In the previous release (1.1a2), the Chameleon text template
- renderer was used if the system didn't associate the ``template``
- view configuration value with a filename with a "known" extension.
- In this release, you must use a ``renderer`` attribute which is a
- path that ends with a ``.txt`` extension
- (e.g. ``templates/foo.txt``) to use the Chameleon text renderer.
-
-1.1a2 (2009-09-14)
-==================
-
-Features
---------
-
-- A ZCML ``view`` directive (and the associated ``bfg_view``
- decorator) can now accept an "attr" value. If an "attr" value is
- supplied, it is considered a method named of the view object to be
- called when the response is required. This is typically only good
- for views that are classes or instances (not so useful for
- functions, as functions typically have no methods other than
- ``__call__``).
-
-- A ZCML ``view`` directive (and the associated ``bfg_view``
- decorator) can now accept a "template" value. If a "template" value
- is supplied, and the view callable returns a dictionary, the
- associated template is rendered with the dictionary as keyword
- arguments. See the section named "Views That Have a ``template``"
- in the "Views" narrative documentation chapter for more information.
-
-1.1a1 (2009-09-06)
-==================
-
-Bug Fixes
----------
-
-- "tests" module removed from the bfg_alchemy paster template; these
- tests didn't work.
-
-- Bugfix: the ``discriminator`` for the ZCML "route" directive was
- incorrect. It was possible to register two routes that collided
- without the system spitting out a ConfigurationConflictError at
- startup time.
-
-Features
---------
-
-- Feature addition: view predicates. These are exposed as the
- ``request_method``, ``request_param``, and ``containment``
- attributes of a ZCML ``view`` declaration, or the respective
- arguments to a ``@bfg_view`` decorator. View predicates can be used
- to register a view for a more precise set of environment parameters
- than was previously possible. For example, you can register two
- views with the same ``name`` with different ``request_param``
- attributes. If the ``request.params`` dict contains 'foo'
- (request_param="foo"), one view might be called; if it contains
- 'bar' (request_param="bar"), another view might be called.
- ``request_param`` can also name a key/value pair ala ``foo=123``.
- This will match only when the ``foo`` key is in the request.params
- dict and it has the value '123'. This particular example makes it
- possible to write separate view functions for different form
- submissions. The other predicates, ``containment`` and
- ``request_method`` work similarly. ``containment`` is a view
- predicate that will match only when the context's graph lineage has
- an object possessing a particular class or interface, for example.
- ``request_method`` is a view predicate that will match when the HTTP
- ``REQUEST_METHOD`` equals some string (eg. 'POST').
-
-- The ``@bfg_view`` decorator now accepts three additional arguments:
- ``request_method``, ``request_param``, and ``containment``.
- ``request_method`` is used when you'd like the view to match only a
- request with a particular HTTP ``REQUEST_METHOD``; a string naming
- the ``REQUEST_METHOD`` can also be supplied as ``request_type`` for
- backwards compatibility. ``request_param`` is used when you'd like
- a view to match only a request that contains a particular
- ``request.params`` key (with or without a value). ``containment``
- is used when you'd like to match a request that has a context that
- has some class or interface in its graph lineage. These are
- collectively known as "view predicates".
-
-- The ``route`` ZCML directive now honors ``view_request_method``,
- ``view_request_param`` and ``view_containment`` attributes, which
- pass along these values to the associated view if any is provided.
- Additionally, the ``request_type`` attribute can now be spelled as
- ``view_request_type``, and ``permission`` can be spelled as
- ``view_permission``. Any attribute which starts with ``view_`` can
- now be spelled without the ``view_`` prefix, so ``view_for`` can be
- spelled as ``for`` now, etc. Both forms are documented in the
- urldispatch narraitve documentation chapter.
-
-- The ``request_param`` ZCML view directive attribute (and its
- ``bfg_view`` decorator cousin) can now specify both a key and a
- value. For example, ``request_param="foo=123"`` means that the foo
- key must have a value of ``123`` for the view to "match".
-
-- Allow ``repoze.bfg.traversal.find_interface`` API to use a class
- object as the argument to compare against the ``model`` passed in.
- This means you can now do ``find_interface(model, SomeClass)`` and
- the first object which is found in the lineage which has
- ``SomeClass`` as its class (or the first object found which has
- ``SomeClass`` as any of its superclasses) will be returned.
-
-- Added ``static`` ZCML directive which registers a route for a view
- that serves up files in a directory. See the "Views" narrative
- documentation chapter's "Serving Static Resources Using a ZCML
- Directive" section for more information.
-
-- The ``repoze.bfg.view.static`` class now accepts a string as its
- first argument ("root_dir") that represents a package-relative name
- e.g. ``somepackage:foo/bar/static``. This is now the preferred
- mechanism for spelling package-relative static paths using this
- class. A ``package_name`` keyword argument has been left around for
- backwards compatibility. If it is supplied, it will be honored.
-
-- The API ``repoze.bfg.testing.registerView`` now takes a
- ``permission`` argument. Use this instead of using
- ``repoze.bfg.testing.registerViewPermission``.
-
-- The ordering of route declarations vs. the ordering of view
- declarations that use a "route_name" in ZCML no longer matters.
- Previously it had been impossible to use a route_name from a route
- that had not yet been defined in ZCML (order-wise) within a "view"
- declaration.
-
-- The repoze.bfg router now catches both
- ``repoze.bfg.security.Unauthorized`` and
- ``repoze.bfg.view.NotFound`` exceptions while rendering a view.
- When the router catches an ``Unauthorized``, it returns the
- registered forbidden view. When the router catches a ``NotFound``,
- it returns the registered notfound view.
-
-Internal
---------
-
-- Change urldispatch internals: Route object is now constructed using
- a path, a name, and a factory instead of a name, a matcher, a
- generator, and a factory.
-
-- Move (non-API) default_view, default_forbidden_view, and
- default_notfound_view functions into the ``repoze.bfg.view`` module
- (moved from ``repoze.bfg.router``).
-
-- Removed ViewPermissionFactory from ``repoze.bfg.security``. View
- permission checking is now done by registering and looking up an
- ISecuredView.
-
-- The ``static`` ZCML directive now uses a custom root factory when
- constructing a route.
-
-- The interface ``IRequestFactories`` was removed from the
- repoze.bfg.interfaces module. This interface was never an API.
-
-- The function named ``named_request_factories`` and the data
- structure named ``DEFAULT_REQUEST_FACTORIES`` have been removed from
- the ``repoze.bfg.request`` module. These were never APIs.
-
-- The ``IViewPermissionFactory`` interface has been removed. This was
- never an API.
-
-Documentation
--------------
-
-- Request-only-convention examples in the "Views" narrative
- documentation were broken.
-
-- Fixed documentation bugs related to forget and remember in security API
- docs.
-
-- Fixed documentation for ``repoze.bfg.view.static`` (in narrative
- ``Views`` chapter).
-
-Deprecations
-------------
-
-- The API ``repoze.bfg.testing.registerViewPermission`` has been
- deprecated.
-
-Backwards Incompatibilities
----------------------------
-
-- The interfaces ``IPOSTRequest``, ``IGETRequest``, ``IPUTRequest``,
- ``IDELETERequest``, and ``IHEADRequest`` have been removed from the
- ``repoze.bfg.interfaces`` module. These were not documented as APIs
- post-1.0. Instead of using one of these, use a ``request_method``
- ZCML attribute or ``request_method`` bfg_view decorator parameter
- containing an HTTP method name (one of ``GET``, ``POST``, ``HEAD``,
- ``PUT``, ``DELETE``) instead of one of these interfaces if you were
- using one explicitly. Passing a string in the set (``GET``,
- ``HEAD``, ``PUT``, ``POST``, ``DELETE``) as a ``request_type``
- argument will work too. Rationale: instead of relying on interfaces
- attached to the request object, BFG now uses a "view predicate" to
- determine the request type.
-
-- Views registered without the help of the ZCML ``view`` directive are
- now responsible for performing their own authorization checking.
-
-- The ``registry_manager`` backwards compatibility alias importable
- from "repoze.bfg.registry", deprecated since repoze.bfg 0.9 has been
- removed. If you are tring to use the registry manager within a
- debug script of your own, use a combination of the
- "repoze.bfg.paster.get_app" and "repoze.bfg.scripting.get_root" APIs
- instead.
-
-- The ``INotFoundAppFactory`` interface has been removed; it has
- been deprecated since repoze.bfg 0.9. If you have something like
- the following in your ``configure.zcml``::
-
- <utility provides="repoze.bfg.interfaces.INotFoundAppFactory"
- component="helloworld.factories.notfound_app_factory"/>
-
- Replace it with something like::
-
- <notfound
- view="helloworld.views.notfound_view"/>
-
- See "Changing the Not Found View" in the "Hooks" chapter of the
- documentation for more information.
-
-- The ``IUnauthorizedAppFactory`` interface has been removed; it has
- been deprecated since repoze.bfg 0.9. If you have something like
- the following in your ``configure.zcml``::
-
- <utility provides="repoze.bfg.interfaces.IUnauthorizedAppFactory"
- component="helloworld.factories.unauthorized_app_factory"/>
-
- Replace it with something like::
-
- <forbidden
- view="helloworld.views.forbidden_view"/>
-
- See "Changing the Forbidden View" in the "Hooks" chapter of the
- documentation for more information.
-
-- ``ISecurityPolicy``-based security policies, deprecated since
- repoze.bfg 0.9, have been removed. If you have something like this
- in your ``configure.zcml``, it will no longer work::
-
- <utility
- provides="repoze.bfg.interfaces.ISecurityPolicy"
- factory="repoze.bfg.security.RemoteUserInheritingACLSecurityPolicy"
- />
-
- If ZCML like the above exists in your application, you will receive
- an error at startup time. Instead of the above, you'll need
- something like::
-
- <remoteuserauthenticationpolicy/>
- <aclauthorizationpolicy/>
-
- This is just an example. See the "Security" chapter of the
- repoze.bfg documentation for more information about configuring
- security policies.
-
-- Custom ZCML directives which register an authentication or
- authorization policy (ala "authtktauthenticationpolicy" or
- "aclauthorizationpolicy") should register the policy "eagerly" in
- the ZCML directive instead of from within a ZCML action. If an
- authentication or authorization policy is not found in the component
- registry by the view machinery during deferred ZCML processing, view
- security will not work as expected.
-
diff --git a/HISTORY.txt b/HISTORY.txt
index b23d8fcb7..93de7e90c 100644
--- a/HISTORY.txt
+++ b/HISTORY.txt
@@ -1,3 +1,1133 @@
+1.1.1 (2009-11-21)
+==================
+
+Bug Fixes
+---------
+
+- "Hybrid mode" applications (applications which explicitly used
+ traversal *after* url dispatch via ``<route>`` paths containing the
+ ``*traverse`` element) were broken in 1.1-final and all 1.1 alpha
+ and beta releases. Views registered without a ``route_name`` route
+ shadowed views registered with a ``route_name`` inappropriately.
+
+1.1 (2009-11-15)
+================
+
+Internals
+---------
+
+- Remove dead IRouteRequirement interface from ``repoze.bfg.zcml``
+ module.
+
+Documentation
+-------------
+
+- Improve the "Extending an Existing Application" narrative chapter.
+
+- Add more sections to the "Defending Design" chapter.
+
+1.1b4 (2009-11-12)
+==================
+
+Bug Fixes
+---------
+
+- Use ``alsoProvides`` in the urldispatch module to attach an
+ interface to the request rather than ``directlyProvides`` to avoid
+ disturbing interfaces set in a NewRequest event handler.
+
+Documentation
+-------------
+
+- Move 1.0.1 and previous changelog to HISTORY.txt.
+
+- Add examples to ``repoze.bfg.url.model_url`` docstring.
+
+- Add "Defending BFG Design" chapter to frontpage docs.
+
+Templates
+---------
+
+- Remove ``ez_setup.py`` and its import from all paster templates,
+ samples, and tutorials for ``distribute`` compatibility. The
+ documentation already explains how to install virtualenv (which will
+ include some ``setuptools`` package), so these files, imports and
+ usages were superfluous.
+
+Deprecations
+------------
+
+- The ``options`` kw arg to the ``repoze.bfg.router.make_app``
+ function is deprecated. In its place is the keyword argument
+ ``settings``. The ``options`` keyword continues to work, and a
+ deprecation warning is not emitted when it is detected. However,
+ the paster templates, code samples, and documentation now make
+ reference to ``settings`` rather than ``options``. This
+ change/deprecation was mainly made for purposes of clarity and
+ symmetry with the ``get_settings()`` API and dicussions of
+ "settings" in various places in the docs: we want to use the same
+ name to refer to the same thing everywhere.
+
+1.1b3 (2009-11-06)
+==================
+
+Features
+--------
+
+- ``repoze.bfg.testing.registerRoutesMapper`` testing facility added.
+ This testing function registers a routes "mapper" object in the
+ registry, for tests which require its presence. This function is
+ documented in the ``repoze.bfg.testing`` API documentation.
+
+Bug Fixes
+---------
+
+- Compound statements that used an assignment entered into in an
+ interactive IPython session invoked via ``paster bfgshell`` no
+ longer fail to mutate the shell namespace correctly. For example,
+ this set of statements used to fail::
+
+ In [2]: def bar(x): return x
+ ...:
+ In [3]: list(bar(x) for x in 'abc')
+ Out[3]: NameError: 'bar'
+
+ In this release, the ``bar`` function is found and the correct
+ output is now sent to the console. Thanks to Daniel Holth for the
+ patch.
+
+- The ``bfgshell`` command did not function properly; it was still
+ expecting to be able to call the root factory with a bare
+ ``environ`` rather than a request object.
+
+Backwards Incompatibilities
+---------------------------
+
+- The ``repoze.bfg.scripting.get_root`` function now expects a
+ ``request`` object as its second argument rather than an
+ ``environ``.
+
+1.1b2 (2009-11-02)
+==================
+
+Bug Fixes
+---------
+
+- Prevent PyPI installation failure due to ``easy_install`` trying way
+ too hard to guess the best version of Paste. When ``easy_install``
+ pulls from PyPI it reads links off various pages to determine "more
+ up to date" versions. It incorrectly picks up a link for an ancient
+ version of a package named "Paste-Deploy-0.1" (note the dash) when
+ trying to find the "Paste" distribution and somehow believes it's
+ the latest version of "Paste". It also somehow "helpfully" decides
+ to check out a version of this package from SVN. We pin the Paste
+ dependency version to a version greater than 1.7 to work around
+ this ``easy_install`` bug.
+
+Documentation
+-------------
+
+- Fix "Hybrid" narrative chapter: stop claiming that ``<view>``
+ statements that mention a route_name need to come afer (in XML
+ order) the ``<route>`` statement which creates the route. This
+ hasn't been true since 1.1a1.
+
+- "What's New in ``repoze.bfg`` 1.1" document added to narrative
+ documentation.
+
+Features
+--------
+
+- Add a new event type: ``repoze.bfg.events.AfterTraversal``. Events
+ of this type will be sent after traversal is completed, but before
+ any view code is invoked. Like ``repoze.bfg.events.NewRequest``,
+ This event will have a single attribute: ``request`` representing
+ the current request. Unlike the request attribute of
+ ``repoze.bfg.events.NewRequest`` however, during an AfterTraversal
+ event, the request object will possess attributes set by the
+ traverser, most notably ``context``, which will be the context used
+ when a view is found and invoked. The interface
+ ``repoze.bfg.events.IAfterTraversal`` can be used to subscribe to
+ the event. For example::
+
+ <subscriber for="repoze.bfg.interfaces.IAfterTraversal"
+ handler="my.app.handle_after_traverse"/>
+
+ Like any framework event, a subscriber function should expect one
+ parameter: ``event``.
+
+Dependencies
+------------
+
+- Rather than depending on ``chameleon.core`` and ``chameleon.zpt``
+ distributions individually, depend on Malthe's repackaged
+ ``Chameleon`` distribution (which includes both ``chameleon.core``
+ and ``chameleon.zpt``).
+
+1.1b1 (2009-11-01)
+==================
+
+Bug Fixes
+---------
+
+- The routes root factory called route factories and the default route
+ factory with an environ rather than a request. One of the symptoms
+ of this bug: applications generated using the ``bfg_zodb`` paster
+ template in 1.1a9 did not work properly.
+
+- Reinstate ``renderer`` alias for ``view_renderer`` in the
+ ``<route>`` ZCML directive (in-the-wild 1.1a bw compat).
+
+- ``bfg_routesalchemy`` paster template: change ``<route>``
+ declarations: rename ``renderer`` attribute to ``view_renderer``.
+
+- Header values returned by the ``authtktauthenticationpolicy``
+ ``remember`` and ``forget`` methods would be of type ``unicode``.
+ This violated the WSGI spec, causing a ``TypeError`` to be raised
+ when these headers were used under ``mod_wsgi``.
+
+- If a BFG app that had a route matching the root URL was mounted
+ under a path in modwsgi, ala ``WSGIScriptAlias /myapp
+ /Users/chrism/projects/modwsgi/env/bfg.wsgi``, the home route (a
+ route with the path of ``'/'`` or ``''``) would not match when the
+ path ``/myapp`` was visited (only when the path ``/myapp/`` was
+ visited). This is now fixed: if the urldispatch root factory notes
+ that the PATH_INFO is empty, it converts it to a single slash before
+ trying to do matching.
+
+Documentation
+-------------
+
+- In ``<route>`` declarations in tutorial ZCML, rename ``renderer``
+ attribute to ``view_renderer`` (fwd compat).
+
+- Fix various tutorials broken by 1.1a9 ``<route>`` directive changes.
+
+Internal
+--------
+
+- Deal with a potential circref in the traversal module.
+
+1.1a9 (2009-10-31)
+==================
+
+Bug Fixes
+---------
+
+- An incorrect ZCML conflict would be encountered when the
+ ``request_param`` predicate attribute was used on the ZCML ``view``
+ directive if any two otherwise same-predicated views had the
+ combination of a predicate value with an ``=`` sign and one without
+ (e.g. ``a`` vs. ``a=123``).
+
+Features
+--------
+
+- In previous versions of BFG, the "root factory" (the ``get_root``
+ callable passed to ``make_app`` or a function pointed to by the
+ ``factory`` attribute of a route) was called with a "bare" WSGI
+ environment. In this version, and going forward, it will be called
+ with a ``request`` object. The request object passed to the factory
+ implements dictionary-like methods in such a way that existing root
+ factory code which expects to be passed an environ will continue to
+ work.
+
+- The ``__call__`` of a plugin "traverser" implementation (registered
+ as an adapter for ``ITraverser`` or ``ITraverserFactory``) will now
+ receive a *request* as the single argument to its ``__call__``
+ method. In previous versions it was passed a WSGI ``environ``
+ object. The request object passed to the factory implements
+ dictionary-like methods in such a way that existing traverser code
+ which expects to be passed an environ will continue to work.
+
+- The ZCML ``route`` directive's attributes ``xhr``,
+ ``request_method``, ``path_info``, ``request_param``, ``header`` and
+ ``accept`` are now *route* predicates rather than *view* predicates.
+ If one or more of these predicates is specified in the route
+ configuration, all of the predicates must return true for the route
+ to match a request. If one or more of the route predicates
+ associated with a route returns ``False`` when checked during a
+ request, the route match fails, and the next match in the routelist
+ is tried. This differs from the previous behavior, where no route
+ predicates existed and all predicates were considered view
+ predicates, because in that scenario, the next route was not tried.
+
+Documentation
+-------------
+
+- Various changes were made to narrative and API documentation
+ supporting the change from passing a request rather than an environ
+ to root factories and traversers.
+
+Internal
+--------
+
+- The request implements dictionary-like methods that mutate and query
+ the WSGI environ. This is only for the purpose of backwards
+ compatibility with root factories which expect an ``environ`` rather
+ than a request.
+
+- The ``repoze.bfg.request.create_route_request_factory`` function,
+ which returned a request factory was removed in favor of a
+ ``repoze.bfg.request.route_request_interface`` function, which
+ returns an interface.
+
+- The ``repoze.bfg.request.Request`` class, which is a subclass of
+ ``webob.Request`` now defines its own ``__setattr__``,
+ ``__getattr__`` and ``__delattr__`` methods, which override the
+ default WebOb behavior. The default WebOb behavior stores
+ attributes of the request in ``self.environ['webob.adhoc_attrs']``,
+ and retrieves them from that dictionary during a ``__getattr__``.
+ This behavior was undesirable for speed and "expectation" reasons.
+ Now attributes of the ``request`` are stored in ``request.__dict__``
+ (as you otherwise might expect from an object that did not override
+ these methods).
+
+- The router no longer calls ``repoze.bfg.traversal._traverse`` and
+ does its work "inline" (speed).
+
+- Reverse the order in which the router calls the request factory and
+ the root factory. The request factory is now called first; the
+ resulting request is passed to the root factory.
+
+- The ``repoze.bfg.request.request_factory`` function has been
+ removed. Its functionality is no longer required.
+
+- The "routes root factory" that wraps the default root factory when
+ there are routes mentioned in the configuration now attaches an
+ interface to the request via ``zope.interface.directlyProvides``.
+ This replaces logic in the (now-gone)
+ ``repoze.bfg.request.request_factory`` function.
+
+- The ``route`` and ``view`` ZCML directives now register an interface
+ as a named utility (retrieved from
+ ``repoze.bfg.request.route_request_interface``) rather than a
+ request factory (the previous return value of the now-missing
+ ``repoze.bfg.request.create_route_request_factory``.
+
+- The ``repoze.bfg.functional`` module was renamed to
+ ``repoze.bfg.compat``.
+
+Backwards Incompatibilities
+---------------------------
+
+- Explicitly revert the feature introduced in 1.1a8: where the name
+ ``root`` is available as an attribute of the request before a
+ NewRequest event is emitted. This makes some potential future
+ features impossible, or at least awkward (such as grouping traversal
+ and view lookup into a single adapter lookup).
+
+- The ``containment``, ``attr`` and ``renderer`` attributes of the
+ ``route`` ZCML directive were removed.
+
+1.1a8 (2009-10-27)
+==================
+
+Features
+--------
+
+- Add ``path_info`` view configuration predicate.
+
+- ``paster bfgshell`` now supports IPython if it's available for
+ import. Thanks to Daniel Holth for the initial patch.
+
+- Add ``repoze.bfg.testing.registerSettings`` API, which is documented
+ in the "repoze.bfg.testing" API chapter. This allows for
+ registration of "settings" values obtained via
+ ``repoze.bfg.settings.get_settings()`` for use in unit tests.
+
+- The name ``root`` is available as an attribute of the request
+ slightly earlier now (before a NewRequest event is emitted).
+ ``root`` is the result of the application "root factory".
+
+- Added ``max_age`` parameter to ``authtktauthenticationpolicy`` ZCML
+ directive. If this value is set, it must be an integer representing
+ the number of seconds which the auth tkt cookie will survive.
+ Mainly, its existence allows the auth_tkt cookie to survive across
+ browser sessions.
+
+Bug Fixes
+---------
+
+- Fix bug encountered during "scan" (when ``<scan ..>`` directive is
+ used in ZCML) introduced in 1.1a7. Symptom: ``AttributeError:
+ object has no attribute __provides__`` raised at startup time.
+
+- The ``reissue_time`` argument to the ``authtktauthenticationpolicy``
+ ZCML directive now actually works. When it is set to an integer
+ value, an authticket set-cookie header is appended to the response
+ whenever a request requires authentication and 'now' minus the
+ authticket's timestamp is greater than ``reissue_time`` seconds.
+
+Documentation
+-------------
+
+- Add a chapter titled "Request and Response" to the narrative
+ documentation, content cribbed from the WebOb documentation.
+
+- Call out predicate attributes of ZCML directive within "Views"
+ chapter.
+
+- Fix route_url documentation (``_query`` argument documented as
+ ``query`` and ``_anchor`` argument documented as ``anchor``).
+
+Backwards Incompatibilities
+---------------------------
+
+- The ``authtkt`` authentication policy ``remember`` method now no
+ longer honors ``token`` or ``userdata`` keyword arguments.
+
+Internal
+--------
+
+- Change how ``bfg_view`` decorator works when used as a class method
+ decorator. In 1.1a7, the``scan``directive actually tried to grope
+ every class in scanned package at startup time, calling ``dir``
+ against each found class, and subsequently invoking ``getattr``
+ against each thing found by ``dir`` to see if it was a method. This
+ led to some strange symptoms (e.g. ``AttributeError: object has no
+ attribute __provides__``), and was generally just a bad idea. Now,
+ instead of groping classes for methods at startup time, we just
+ cause the ``bfg_view`` decorator itself to populate the method's
+ class' ``__dict__`` when it is used as a method decorator. This
+ also requires a nasty _getframe thing but it's slightly less nasty
+ than the startup time groping behavior. This is essentially a
+ reversion back to 1.1a6 "grokking" behavior plus some special magic
+ for using the ``bfg_view`` decorator as method decorator inside the
+ ``bfg_view`` class itself.
+
+- The router now checks for a ``global_response_headers`` attribute of
+ the request object before returning a response. If this value
+ exists, it is presumed to be a sequence of two-tuples, representing
+ a set of headers to append to the 'normal' response headers. This
+ feature is internal, rather than exposed externally, because it's
+ unclear whether it will stay around in the long term. It was added
+ to support the ``reissue_time`` feature of the authtkt
+ authentication policy.
+
+- The interface ITraverserFactory is now just an alias for ITraverser.
+
+1.1a7 (2009-10-18)
+==================
+
+Features
+--------
+
+- More than one ``@bfg_view`` decorator may now be stacked on top of
+ any number of others. Each invocation of the decorator registers a
+ single view configuration. For instance, the following combination
+ of decorators and a function will register two view configurations
+ for the same view callable::
+
+ from repoze.bfg.view import bfg_view
+
+ @bfg_view(name='edit')
+ @bfg_view(name='change')
+ def edit(context, request):
+ pass
+
+ This makes it possible to associate more than one view configuration
+ with a single callable without requiring any ZCML.
+
+- The ``@bfg_view`` decorator can now be used against a class method::
+
+ from webob import Response
+ from repoze.bfg.view import bfg_view
+
+ class MyView(object):
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ @bfg_view(name='hello')
+ def amethod(self):
+ return Response('hello from %s!' % self.context)
+
+ When the bfg_view decorator is used against a class method, a view
+ is registered for the *class* (it's a "class view" where the "attr"
+ happens to be the name of the method it is attached to), so the
+ class it's defined within must have a suitable constructor: one that
+ accepts ``context, request`` or just ``request``.
+
+Documentation
+-------------
+
+- Added ``Changing the Traverser`` and ``Changing How
+ :mod:`repoze.bfg.url.model_url` Generates a URL`` to the "Hooks"
+ narrative chapter of the docs.
+
+Internal
+--------
+
+- Remove ``ez_setup.py`` and imports of it within ``setup.py``. In
+ the new world, and as per virtualenv setup instructions, people will
+ already have either setuptools or distribute.
+
+1.1a6 (2009-10-15)
+==================
+
+Features
+--------
+
+- Add ``xhr``, ``accept``, and ``header`` view configuration
+ predicates to ZCML view declaration, ZCML route declaration, and
+ ``bfg_view`` decorator. See the ``Views`` narrative documentation
+ chapter for more information about these predicates.
+
+- Add ``setUp`` and ``tearDown`` functions to the
+ ``repoze.bfg.testing`` module. Using ``setUp`` in a test setup and
+ ``tearDown`` in a test teardown is now the recommended way to do
+ component registry setup and teardown. Previously, it was
+ recommended that a single function named
+ ``repoze.bfg.testing.cleanUp`` be called in both the test setup and
+ tear down. ``repoze.bfg.testing.cleanUp`` still exists (and will
+ exist "forever" due to its widespread use); it is now just an alias
+ for ``repoze.bfg.testing.setUp`` and is nominally deprecated.
+
+- The BFG component registry is now available in view and event
+ subscriber code as an attribute of the request
+ ie. ``request.registry``. This fact is currently undocumented
+ except for this note, because BFG developers never need to interact
+ with the registry directly anywhere else.
+
+- The BFG component registry now inherits from ``dict``, meaning that
+ it can optionally be used as a simple dictionary. *Component*
+ registrations performed against it via e.g. ``registerUtility``,
+ ``registerAdapter``, and similar API methods are kept in a
+ completely separate namespace than its dict members, so using the
+ its component API methods won't effect the keys and values in the
+ dictionary namespace. Likewise, though the component registry
+ "happens to be" a dictionary, use of mutating dictionary methods
+ such as ``__setitem__`` will have no influence on any component
+ registrations made against it. In other words, the registry object
+ you obtain via e.g. ``repoze.bfg.threadlocal.get_current_registry``
+ or ``request.registry`` happens to be both a component registry and
+ a dictionary, but using its component-registry API won't impact data
+ added to it via its dictionary API and vice versa. This is a
+ forward compatibility move based on the goals of "marco".
+
+- Expose and document ``repoze.bfg.testing.zcml_configure`` API. This
+ function populates a component registry from a ZCML file for testing
+ purposes. It is documented in the "Unit and Integration Testing"
+ chapter.
+
+Documentation
+-------------
+
+- Virtual hosting narrative docs chapter updated with info about
+ ``mod_wsgi``.
+
+- Point all index URLs at the literal 1.1 index (this alpha cycle may
+ go on a while).
+
+- Various tutorial test modules updated to use
+ ``repoze.bfg.testing.setUp`` and ``repoze.bfg.testing.tearDown``
+ methods in order to encourage this as best practice going forward.
+
+- Added "Creating Integration Tests" section to unit testing narrative
+ documentation chapter. As a result, the name of the unittesting
+ chapter is now "Unit and Integration Testing".
+
+Backwards Incompatibilities
+---------------------------
+
+- Importing ``getSiteManager`` and ``get_registry`` from
+ ``repoze.bfg.registry`` is no longer supported. These imports were
+ deprecated in repoze.bfg 1.0. Import of ``getSiteManager`` should
+ be done as ``from zope.component import getSiteManager``. Import of
+ ``get_registry`` should be done as ``from repoze.bfg.threadlocal
+ import get_current_registry``. This was done to prevent a circular
+ import dependency.
+
+- Code bases which alternately invoke both
+ ``zope.testing.cleanup.cleanUp`` and ``repoze.bfg.testing.cleanUp``
+ (treating them equivalently, using them interchangeably) in the
+ setUp/tearDown of unit tests will begin to experience test failures
+ due to lack of test isolation. The "right" mechanism is
+ ``repoze.bfg.testing.cleanUp`` (or the combination of
+ ``repoze.bfg.testing.setUp`` and
+ ``repoze.bfg.testing.tearDown``). but a good number of legacy
+ codebases will use ``zope.testing.cleanup.cleanUp`` instead. We
+ support ``zope.testing.cleanup.cleanUp`` but not in combination with
+ ``repoze.bfg.testing.cleanUp`` in the same codebase. You should use
+ one or the other test cleanup function in a single codebase, but not
+ both.
+
+Internal
+--------
+
+- Created new ``repoze.bfg.configuration`` module which assumes
+ responsibilities previously held by the ``repoze.bfg.registry`` and
+ ``repoze.bfg.router`` modules (avoid a circular import dependency).
+
+- The result of the ``zope.component.getSiteManager`` function in unit
+ tests set up with ``repoze.bfg.testing.cleanUp`` or
+ ``repoze.bfg.testing.setUp`` will be an instance of
+ ``repoze.bfg.registry.Registry`` instead of the global
+ ``zope.component.globalregistry.base`` registry. This also means
+ that the threadlocal ZCA API functions such as ``getAdapter`` and
+ ``getUtility`` as well as internal BFG machinery (such as
+ ``model_url`` and ``route_url``) will consult this registry within
+ unit tests. This is a forward compatibility move based on the goals
+ of "marco".
+
+- Removed ``repoze.bfg.testing.addCleanUp`` function and associated
+ module-scope globals. This was never an API.
+
+1.1a5 (2009-10-10)
+==================
+
+Documentation
+-------------
+
+- Change "Traversal + ZODB" and "URL Dispatch + SQLAlchemy" Wiki
+ tutorials to make use of the new-to-1.1 "renderer" feature (return
+ dictionaries from all views).
+
+- Add tests to the "URL Dispatch + SQLAlchemy" tutorial after the
+ "view" step.
+
+- Added a diagram of model graph traversal to the "Traversal"
+ narrative chapter of the documentation.
+
+- An ``exceptions`` API chapter was added, documenting the new
+ ``repoze.bfg.exceptions`` module.
+
+- Describe "request-only" view calling conventions inside the
+ urldispatch narrative chapter, where it's most helpful.
+
+- Add a diagram which explains the operation of the BFG router to the
+ "Router" narrative chapter.
+
+Features
+--------
+
+- Add a new ``repoze.bfg.testing`` API: ``registerRoute``, for
+ registering routes to satisfy calls to
+ e.g. ``repoze.bfg.url.route_url`` in unit tests.
+
+- The ``notfound`` and ``forbidden`` ZCML directives now accept the
+ following addtional attributes: ``attr``, ``renderer``, and
+ ``wrapper``. These have the same meaning as they do in the context
+ of a ZCML ``view`` directive.
+
+- For behavior like Django's ``APPEND_SLASH=True``, use the
+ ``repoze.bfg.view.append_slash_notfound_view`` view as the Not Found
+ view in your application. When this view is the Not Found view
+ (indicating that no view was found), and any routes have been
+ defined in the configuration of your application, if the value of
+ ``PATH_INFO`` does not already end in a slash, and if the value of
+ ``PATH_INFO`` *plus* a slash matches any route's path, do an HTTP
+ redirect to the slash-appended PATH_INFO. Note that this will
+ *lose* ``POST`` data information (turning it into a GET), so you
+ shouldn't rely on this to redirect POST requests.
+
+- Speed up ``repoze.bfg.location.lineage`` slightly.
+
+- Speed up ``repoze.bfg.encode.urlencode`` (nee'
+ ``repoze.bfg.url.urlencode``) slightly.
+
+- Speed up ``repoze.bfg.traversal.model_path``.
+
+- Speed up ``repoze.bfg.traversal.model_path_tuple`` slightly.
+
+- Speed up ``repoze.bfg.traversal.traverse`` slightly.
+
+- Speed up ``repoze.bfg.url.model_url`` slightly.
+
+- Speed up ``repoze.bfg.url.route_url`` slightly.
+
+- Sped up ``repoze.bfg.traversal.ModelGraphTraverser:__call__``
+ slightly.
+
+- Minor speedup of ``repoze.bfg.router.Router.__call__``.
+
+- New ``repoze.bfg.exceptions`` module was created to house exceptions
+ that were previously sprinkled through various modules.
+
+Internal
+--------
+
+- Move ``repoze.bfg.traversal._url_quote`` into ``repoze.bfg.encode``
+ as ``url_quote``.
+
+Deprecations
+------------
+
+- The import of ``repoze.bfg.view.NotFound`` is deprecated in favor of
+ ``repoze.bfg.exceptions.NotFound``. The old location still
+ functions, but emits a deprecation warning.
+
+- The import of ``repoze.bfg.security.Unauthorized`` is deprecated in
+ favor of ``repoze.bfg.exceptions.Forbidden``. The old location
+ still functions but emits a deprecation warning. The rename from
+ ``Unauthorized`` to ``Forbidden`` brings parity to the the name of
+ the exception and the system view it invokes when raised.
+
+Backwards Incompatibilities
+---------------------------
+
+- We previously had a Unicode-aware wrapper for the
+ ``urllib.urlencode`` function named ``repoze.bfg.url.urlencode``
+ which delegated to the stdlib function, but which marshalled all
+ unicode values to utf-8 strings before calling the stdlib version.
+ A newer replacement now lives in ``repoze.bfg.encode`` The
+ replacement does not delegate to the stdlib.
+
+ The replacement diverges from the stdlib implementation and the
+ previous ``repoze.bfg.url`` url implementation inasmuch as its
+ ``doseq`` argument is now a decoy: it always behaves in the
+ ``doseq=True`` way (which is the only sane behavior) for speed
+ purposes.
+
+ The old import location (``repoze.bfg.url.urlencode``) still
+ functions and has not been deprecated.
+
+- In 0.8a7, the return value expected from an object implementing
+ ``ITraverserFactory`` was changed from a sequence of values to a
+ dictionary containing the keys ``context``, ``view_name``,
+ ``subpath``, ``traversed``, ``virtual_root``, ``virtual_root_path``,
+ and ``root``. Until now, old-style traversers which returned a
+ sequence have continued to work but have generated a deprecation
+ warning. In this release, traversers which return a sequence
+ instead of a dictionary will no longer work.
+
+1.1a4 (2009-09-23)
+==================
+
+Bug Fixes
+---------
+
+- On 64-bit Linux systems, views that were members of a multiview
+ (orderings of views with predicates) were not evaluated in the
+ proper order. Symptom: in a configuration that had two views with
+ the same name but one with a ``request_method=POST`` predicate and
+ one without, the one without the predicate would be called
+ unconditionally (even if the request was a POST request). Thanks
+ much to Sebastien Douche for providing the buildbots that pointed
+ this out.
+
+Documentation
+-------------
+
+- Added a tutorial which explains how to use ``repoze.session``
+ (ZODB-based sessions) in a ZODB-based repoze.bfg app.
+
+- Added a tutorial which explains how to add ZEO to a ZODB-based
+ ``repoze.bfg`` application.
+
+- Added a tutorial which explains how to run a ``repoze.bfg``
+ application under `mod_wsgi <http://code.google.com/p/modwsgi/>`_.
+ See "Running a repoze.bfg Application under mod_wsgi" in the
+ tutorials section of the documentation.
+
+Features
+--------
+
+- Add a ``repoze.bfg.url.static_url`` API which is capable of
+ generating URLs to static resources defined by the ``<static>`` ZCML
+ directive. See the "Views" narrative chapter's section titled
+ "Generating Static Resource URLs" for more information.
+
+- Add a ``string`` renderer. This renderer converts a non-Response
+ return value of any view callble into a string. It is documented in
+ the "Views" narrative chapter.
+
+- Give the ``route`` ZCML directive the ``view_attr`` and
+ ``view_renderer`` parameters (bring up to speed with 1.1a3
+ features). These can also be spelled as ``attr`` and ``renderer``.
+
+Backwards Incompatibilities
+---------------------------
+
+- An object implementing the ``IRenderer`` interface (and
+ ``ITemplateRenderer`, which is a subclass of ``IRenderer``) must now
+ accept an extra ``system`` argument in its ``__call__`` method
+ implementation. Values computed by the system (as opposed to by the
+ view) are passed by the system in the ``system`` parameter, which
+ will always be a dictionary. Keys in the dictionary include:
+ ``view`` (the view object that returned the value),
+ ``renderer_name`` (the template name or simple name of the
+ renderer), ``context`` (the context object passed to the view), and
+ ``request`` (the request object passed to the view). Previously
+ only ITemplateRenderers received system arguments as elements inside
+ the main ``value`` dictionary.
+
+Internal
+--------
+
+- The way ``bfg_view`` declarations are scanned for has been modified.
+ This should have no external effects.
+
+- Speed: do not register an ITraverserFactory in configure.zcml;
+ instead rely on queryAdapter and a manual default to
+ ModelGraphTraverser.
+
+- Speed: do not register an IContextURL in configure.zcml; instead
+ rely on queryAdapter and a manual default to TraversalContextURL.
+
+- General speed microimprovements for helloworld benchmark: replace
+ try/excepts with statements which use 'in' keyword.
+
+1.1a3 (2009-09-16)
+==================
+
+Documentation
+-------------
+
+- The "Views" narrative chapter in the documentation has been updated
+ extensively to discuss "renderers".
+
+Features
+--------
+
+- A ``renderer`` attribute has been added to view configurations,
+ replacing the previous (1.1a2) version's ``template`` attribute. A
+ "renderer" is an object which accepts the return value of a view and
+ converts it to a string. This includes, but is not limited to,
+ templating systems.
+
+- A new interface named ``IRenderer`` was added. The existing
+ interface, ``ITemplateRenderer`` now derives from this new
+ interface. This interface is internal.
+
+- A new interface named ``IRendererFactory`` was added. An existing
+ interface named ``ITemplateRendererFactory`` now derives from this
+ interface. This interface is internal.
+
+- The ``view`` attribute of the ``view`` ZCML directive is no longer
+ required if the ZCML directive also has a ``renderer`` attribute.
+ This is useful when the renderer is a template renderer and no names
+ need be passed to the template at render time.
+
+- A new zcml directive ``renderer`` has been added. It is documented
+ in the "Views" narrative chapter of the documentation.
+
+- A ZCML ``view`` directive (and the associated ``bfg_view``
+ decorator) can now accept a "wrapper" value. If a "wrapper" value
+ is supplied, it is the value of a separate view's *name* attribute.
+ When a view with a ``wrapper`` attribute is rendered, the "inner"
+ view is first rendered normally. Its body is then attached to the
+ request as "wrapped_body", and then a wrapper view name is looked up
+ and rendered (using ``repoze.bfg.render_view_to_response``), passed
+ the request and the context. The wrapper view is assumed to do
+ something sensible with ``request.wrapped_body``, usually inserting
+ its structure into some other rendered template. This feature makes
+ it possible to specify (potentially nested) "owrap" relationships
+ between views using only ZCML or decorators (as opposed always using
+ ZPT METAL and analogues to wrap view renderings in outer wrappers).
+
+Dependencies
+------------
+
+- When used under Python < 2.6, BFG now has an installation time
+ dependency on the ``simplejson`` package.
+
+Deprecations
+------------
+
+- The ``repoze.bfg.testing.registerDummyRenderer`` API has been
+ deprecated in favor of
+ ``repoze.bfg.testing.registerTemplateRenderer``. A deprecation
+ warning is *not* issued at import time for the former name; it will
+ exist "forever"; its existence has been removed from the
+ documentation, however.
+
+- The ``repoze.bfg.templating.renderer_from_cache`` function has been
+ moved to ``repoze.bfg.renderer.template_renderer_factory``. This
+ was never an API, but code in the wild was spotted that used it. A
+ deprecation warning is issued at import time for the former.
+
+Backwards Incompatibilities
+---------------------------
+
+- The ``ITemplateRenderer`` interface has been changed. Previously
+ its ``__call__`` method accepted ``**kw``. It now accepts a single
+ positional parameter named ``kw`` (REVISED: it accepts two
+ positional parameters as of 1.1a4: ``value`` and ``system``). This
+ is mostly an internal change, but it was exposed in APIs in one
+ place: if you've used the
+ ``repoze.bfg.testing.registerDummyRenderer`` API in your tests with
+ a custom "renderer" argument with your own renderer implementation,
+ you will need to change that renderer implementation to accept
+ ``kw`` instead of ``**kw`` in its ``__call__`` method (REVISED: make
+ it accept ``value`` and ``system`` positional arguments as of 1.1a4).
+
+- The ``ITemplateRendererFactory`` interface has been changed.
+ Previously its ``__call__`` method accepted an ``auto_reload``
+ keyword parameter. Now its ``__call__`` method accepts no keyword
+ parameters. Renderers are now themselves responsible for
+ determining details of auto-reload. This is purely an internal
+ change. This interface was never external.
+
+- The ``template_renderer`` ZCML directive introduced in 1.1a2 has
+ been removed. It has been replaced by the ``renderer`` directive.
+
+- The previous release (1.1a2) added a view configuration attribute
+ named ``template``. In this release, the attribute has been renamed
+ to ``renderer``. This signifies that the attribute is more generic:
+ it can now be not just a template name but any renderer name (ala
+ ``json``).
+
+- In the previous release (1.1a2), the Chameleon text template
+ renderer was used if the system didn't associate the ``template``
+ view configuration value with a filename with a "known" extension.
+ In this release, you must use a ``renderer`` attribute which is a
+ path that ends with a ``.txt`` extension
+ (e.g. ``templates/foo.txt``) to use the Chameleon text renderer.
+
+1.1a2 (2009-09-14)
+==================
+
+Features
+--------
+
+- A ZCML ``view`` directive (and the associated ``bfg_view``
+ decorator) can now accept an "attr" value. If an "attr" value is
+ supplied, it is considered a method named of the view object to be
+ called when the response is required. This is typically only good
+ for views that are classes or instances (not so useful for
+ functions, as functions typically have no methods other than
+ ``__call__``).
+
+- A ZCML ``view`` directive (and the associated ``bfg_view``
+ decorator) can now accept a "template" value. If a "template" value
+ is supplied, and the view callable returns a dictionary, the
+ associated template is rendered with the dictionary as keyword
+ arguments. See the section named "Views That Have a ``template``"
+ in the "Views" narrative documentation chapter for more information.
+
+1.1a1 (2009-09-06)
+==================
+
+Bug Fixes
+---------
+
+- "tests" module removed from the bfg_alchemy paster template; these
+ tests didn't work.
+
+- Bugfix: the ``discriminator`` for the ZCML "route" directive was
+ incorrect. It was possible to register two routes that collided
+ without the system spitting out a ConfigurationConflictError at
+ startup time.
+
+Features
+--------
+
+- Feature addition: view predicates. These are exposed as the
+ ``request_method``, ``request_param``, and ``containment``
+ attributes of a ZCML ``view`` declaration, or the respective
+ arguments to a ``@bfg_view`` decorator. View predicates can be used
+ to register a view for a more precise set of environment parameters
+ than was previously possible. For example, you can register two
+ views with the same ``name`` with different ``request_param``
+ attributes. If the ``request.params`` dict contains 'foo'
+ (request_param="foo"), one view might be called; if it contains
+ 'bar' (request_param="bar"), another view might be called.
+ ``request_param`` can also name a key/value pair ala ``foo=123``.
+ This will match only when the ``foo`` key is in the request.params
+ dict and it has the value '123'. This particular example makes it
+ possible to write separate view functions for different form
+ submissions. The other predicates, ``containment`` and
+ ``request_method`` work similarly. ``containment`` is a view
+ predicate that will match only when the context's graph lineage has
+ an object possessing a particular class or interface, for example.
+ ``request_method`` is a view predicate that will match when the HTTP
+ ``REQUEST_METHOD`` equals some string (eg. 'POST').
+
+- The ``@bfg_view`` decorator now accepts three additional arguments:
+ ``request_method``, ``request_param``, and ``containment``.
+ ``request_method`` is used when you'd like the view to match only a
+ request with a particular HTTP ``REQUEST_METHOD``; a string naming
+ the ``REQUEST_METHOD`` can also be supplied as ``request_type`` for
+ backwards compatibility. ``request_param`` is used when you'd like
+ a view to match only a request that contains a particular
+ ``request.params`` key (with or without a value). ``containment``
+ is used when you'd like to match a request that has a context that
+ has some class or interface in its graph lineage. These are
+ collectively known as "view predicates".
+
+- The ``route`` ZCML directive now honors ``view_request_method``,
+ ``view_request_param`` and ``view_containment`` attributes, which
+ pass along these values to the associated view if any is provided.
+ Additionally, the ``request_type`` attribute can now be spelled as
+ ``view_request_type``, and ``permission`` can be spelled as
+ ``view_permission``. Any attribute which starts with ``view_`` can
+ now be spelled without the ``view_`` prefix, so ``view_for`` can be
+ spelled as ``for`` now, etc. Both forms are documented in the
+ urldispatch narraitve documentation chapter.
+
+- The ``request_param`` ZCML view directive attribute (and its
+ ``bfg_view`` decorator cousin) can now specify both a key and a
+ value. For example, ``request_param="foo=123"`` means that the foo
+ key must have a value of ``123`` for the view to "match".
+
+- Allow ``repoze.bfg.traversal.find_interface`` API to use a class
+ object as the argument to compare against the ``model`` passed in.
+ This means you can now do ``find_interface(model, SomeClass)`` and
+ the first object which is found in the lineage which has
+ ``SomeClass`` as its class (or the first object found which has
+ ``SomeClass`` as any of its superclasses) will be returned.
+
+- Added ``static`` ZCML directive which registers a route for a view
+ that serves up files in a directory. See the "Views" narrative
+ documentation chapter's "Serving Static Resources Using a ZCML
+ Directive" section for more information.
+
+- The ``repoze.bfg.view.static`` class now accepts a string as its
+ first argument ("root_dir") that represents a package-relative name
+ e.g. ``somepackage:foo/bar/static``. This is now the preferred
+ mechanism for spelling package-relative static paths using this
+ class. A ``package_name`` keyword argument has been left around for
+ backwards compatibility. If it is supplied, it will be honored.
+
+- The API ``repoze.bfg.testing.registerView`` now takes a
+ ``permission`` argument. Use this instead of using
+ ``repoze.bfg.testing.registerViewPermission``.
+
+- The ordering of route declarations vs. the ordering of view
+ declarations that use a "route_name" in ZCML no longer matters.
+ Previously it had been impossible to use a route_name from a route
+ that had not yet been defined in ZCML (order-wise) within a "view"
+ declaration.
+
+- The repoze.bfg router now catches both
+ ``repoze.bfg.security.Unauthorized`` and
+ ``repoze.bfg.view.NotFound`` exceptions while rendering a view.
+ When the router catches an ``Unauthorized``, it returns the
+ registered forbidden view. When the router catches a ``NotFound``,
+ it returns the registered notfound view.
+
+Internal
+--------
+
+- Change urldispatch internals: Route object is now constructed using
+ a path, a name, and a factory instead of a name, a matcher, a
+ generator, and a factory.
+
+- Move (non-API) default_view, default_forbidden_view, and
+ default_notfound_view functions into the ``repoze.bfg.view`` module
+ (moved from ``repoze.bfg.router``).
+
+- Removed ViewPermissionFactory from ``repoze.bfg.security``. View
+ permission checking is now done by registering and looking up an
+ ISecuredView.
+
+- The ``static`` ZCML directive now uses a custom root factory when
+ constructing a route.
+
+- The interface ``IRequestFactories`` was removed from the
+ repoze.bfg.interfaces module. This interface was never an API.
+
+- The function named ``named_request_factories`` and the data
+ structure named ``DEFAULT_REQUEST_FACTORIES`` have been removed from
+ the ``repoze.bfg.request`` module. These were never APIs.
+
+- The ``IViewPermissionFactory`` interface has been removed. This was
+ never an API.
+
+Documentation
+-------------
+
+- Request-only-convention examples in the "Views" narrative
+ documentation were broken.
+
+- Fixed documentation bugs related to forget and remember in security API
+ docs.
+
+- Fixed documentation for ``repoze.bfg.view.static`` (in narrative
+ ``Views`` chapter).
+
+Deprecations
+------------
+
+- The API ``repoze.bfg.testing.registerViewPermission`` has been
+ deprecated.
+
+Backwards Incompatibilities
+---------------------------
+
+- The interfaces ``IPOSTRequest``, ``IGETRequest``, ``IPUTRequest``,
+ ``IDELETERequest``, and ``IHEADRequest`` have been removed from the
+ ``repoze.bfg.interfaces`` module. These were not documented as APIs
+ post-1.0. Instead of using one of these, use a ``request_method``
+ ZCML attribute or ``request_method`` bfg_view decorator parameter
+ containing an HTTP method name (one of ``GET``, ``POST``, ``HEAD``,
+ ``PUT``, ``DELETE``) instead of one of these interfaces if you were
+ using one explicitly. Passing a string in the set (``GET``,
+ ``HEAD``, ``PUT``, ``POST``, ``DELETE``) as a ``request_type``
+ argument will work too. Rationale: instead of relying on interfaces
+ attached to the request object, BFG now uses a "view predicate" to
+ determine the request type.
+
+- Views registered without the help of the ZCML ``view`` directive are
+ now responsible for performing their own authorization checking.
+
+- The ``registry_manager`` backwards compatibility alias importable
+ from "repoze.bfg.registry", deprecated since repoze.bfg 0.9 has been
+ removed. If you are tring to use the registry manager within a
+ debug script of your own, use a combination of the
+ "repoze.bfg.paster.get_app" and "repoze.bfg.scripting.get_root" APIs
+ instead.
+
+- The ``INotFoundAppFactory`` interface has been removed; it has
+ been deprecated since repoze.bfg 0.9. If you have something like
+ the following in your ``configure.zcml``::
+
+ <utility provides="repoze.bfg.interfaces.INotFoundAppFactory"
+ component="helloworld.factories.notfound_app_factory"/>
+
+ Replace it with something like::
+
+ <notfound
+ view="helloworld.views.notfound_view"/>
+
+ See "Changing the Not Found View" in the "Hooks" chapter of the
+ documentation for more information.
+
+- The ``IUnauthorizedAppFactory`` interface has been removed; it has
+ been deprecated since repoze.bfg 0.9. If you have something like
+ the following in your ``configure.zcml``::
+
+ <utility provides="repoze.bfg.interfaces.IUnauthorizedAppFactory"
+ component="helloworld.factories.unauthorized_app_factory"/>
+
+ Replace it with something like::
+
+ <forbidden
+ view="helloworld.views.forbidden_view"/>
+
+ See "Changing the Forbidden View" in the "Hooks" chapter of the
+ documentation for more information.
+
+- ``ISecurityPolicy``-based security policies, deprecated since
+ repoze.bfg 0.9, have been removed. If you have something like this
+ in your ``configure.zcml``, it will no longer work::
+
+ <utility
+ provides="repoze.bfg.interfaces.ISecurityPolicy"
+ factory="repoze.bfg.security.RemoteUserInheritingACLSecurityPolicy"
+ />
+
+ If ZCML like the above exists in your application, you will receive
+ an error at startup time. Instead of the above, you'll need
+ something like::
+
+ <remoteuserauthenticationpolicy/>
+ <aclauthorizationpolicy/>
+
+ This is just an example. See the "Security" chapter of the
+ repoze.bfg documentation for more information about configuring
+ security policies.
+
+- Custom ZCML directives which register an authentication or
+ authorization policy (ala "authtktauthenticationpolicy" or
+ "aclauthorizationpolicy") should register the policy "eagerly" in
+ the ZCML directive instead of from within a ZCML action. If an
+ authentication or authorization policy is not found in the component
+ registry by the view machinery during deferred ZCML processing, view
+ security will not work as expected.
+
1.0.1 (2009-07-22)
==================
diff --git a/repoze/bfg/configuration.py b/repoze/bfg/configuration.py
index c37ed2c72..4d7e8dd57 100644
--- a/repoze/bfg/configuration.py
+++ b/repoze/bfg/configuration.py
@@ -547,6 +547,11 @@ class Configurator(object):
raise ConfigurationError('"view" was not specified and '
'no "renderer" specified')
+ if request_type in ('GET', 'HEAD', 'PUT', 'POST', 'DELETE'):
+ # b/w compat for 1.0
+ request_method = request_type
+ request_type = None
+
if request_type and route_name:
raise ConfigurationError(
'A view cannot be configured with both the request_type and '
diff --git a/repoze/bfg/tests/test_configuration.py b/repoze/bfg/tests/test_configuration.py
index 060f30e3a..416df3086 100644
--- a/repoze/bfg/tests/test_configuration.py
+++ b/repoze/bfg/tests/test_configuration.py
@@ -345,6 +345,19 @@ class ConfiguratorTests(unittest.TestCase):
self.assertRaises(ConfigurationError, config.add_view, view, '', None,
None, True, True)
+ def test_add_view_with_request_type_string(self):
+ view = lambda *arg: 'OK'
+ config = self._makeOne()
+ config.add_view(view=view, request_type='GET')
+ wrapper = self._getViewCallable(config)
+ request = DummyRequest()
+ request.method = 'POST'
+ self._assertNotFound(wrapper, None, request)
+ request = DummyRequest()
+ request.method = 'GET'
+ result = wrapper(None, request)
+ self.assertEqual(result, 'OK')
+
def test_add_view_view_callable_None_with_renderer(self):
config = self._makeOne()
self._registerRenderer(config, name='dummy')