summaryrefslogtreecommitdiff
path: root/HISTORY.txt
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 /HISTORY.txt
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.
Diffstat (limited to 'HISTORY.txt')
-rw-r--r--HISTORY.txt1130
1 files changed, 1130 insertions, 0 deletions
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)
==================