diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-11-29 14:52:29 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-11-29 14:52:29 +0000 |
| commit | af9f2e5fd5664aeaea2057ce1c518fb04617a0f0 (patch) | |
| tree | d0ca3dbda2df89acc15b76ed6e5f7e34bbad90f0 | |
| parent | 7fb23b46b7b3fe3729d99166d13b96954b1de44a (diff) | |
| download | pyramid-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.txt | 1143 | ||||
| -rw-r--r-- | HISTORY.txt | 1130 | ||||
| -rw-r--r-- | repoze/bfg/configuration.py | 5 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_configuration.py | 13 |
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') |
