Package: repoze.bfg
repoze.bfgrepoze.bfgis a small, fast, down-to-earth, open source Python web
development framework. It makes real-world web application development
and deployment more fun, more predictable, and more productive.Support and DocumentationSee therepoze.bfg websiteto view
documentation, report bugs, and obtain support.Licenserepoze.bfgis offered under the BSD-derivedRepoze Public License.Authorsrepoze.bfgis made available byAgendaless Consultingand a team of contributors.1.3 (2010-11-01)FeaturesRaise more understandable error when a Jython application attempts to use a
Chameleon template.1.3b3 (2010-10-29)Bug FixesWhen a default permission was in effect, and a “static view” had
been registered (viarepoze.bfg.configuration.Configurator.add_static_view, or via thestaticZCML directiveq), the static view, was, by default,
protected by the default permission, without a way to indicate that
it was anonymously viewable.  As of this release, a static view is
registered using the permission sentinel__no_permission_required__as the permission by default, making
its resources viewable by completely anonymous users.FeaturesApermissionargument has been added to therepoze.bfg.configuration.Configurator.add_static_viewmethod and
apermissionattribute is now available on thestaticZCML
directive.DocumentationA “default permission” glossary entry was added to the glossary.1.3b2 (2010-10-28)Bug FixesTherepoze.bfg.security.view_execution_permittedAPI could
return the wrong boolean result due to a bug in the configurator,
leading to inappropriate view execution by persons without
permission when it was imported and used directly.  Thanks to Shane
Hathaway for a bug report and a patch.Backwards IncompatibilitiesPreviously, the sentinel to register a view as explicitly “no
permission required” (most useful when a default permission is in
effect) was to register it explicitly with the valueNoneas an
argument to thepermissionparameter of therepoze.bfg.configuration.Configurator.add_view.  UsingNoneas a sentinel meaning “no permission required” in that location,
however, was incompatible with the expectations of both theviewZCML directive and thebfg_viewdecorator, which both passedNoneexplicitly toadd_view, overriding any default
permission.  The symptom was that any “default permission”
configured appeared to not work if either ZCML or thebfg_viewdirective was used to register a view (although usingadd_viewdirectly did work).  TheNonevalue as a sentinel could also not
be spelled using ZCML.Now, the sentinel meaning “no permission required” is the string__no_permission_required__, which satisfies the expectation of
theviewZCML directive and thebfg_viewdecorator, and,
since it’s a string, it can be spelled in both Python and within
ZCML.Thanks to Wichert Akkerman for the bug report.1.3b1 (2010-10-25)FeaturesThepastertemplate namedbfg_routesalchemyhas been updated
to use SQLAlchemy declarative syntax.  Thanks to Ergo^.Bug FixesWhen a renderer factory could not be found, a misleading error
message was raised if the renderer name was not a string.DocumentationThe “”bfgwiki2” (SQLAlchemy + url dispatch) tutorial has been
updated slightly.  In particular, the source packages no longer
attempt to use a private index, and the recommended Python version
is now 2.6.  It was also updated to take into account the changes to
thebfg_routesalchemytemplate used to set up an environment.The “bfgwiki” (ZODB + traversal) tutorial has been updated slightly.
In particular, the source packages no longer attempt to use a
private index, and the recommended Python version is now 2.6.1.3a15 (2010-09-30)FeaturesTherepoze.bfg.traversal.traversal_pathAPI now eagerly attempts
to encode a Unicodepathinto ASCII before attempting to split
it and decode its segments.  This is for convenience, effectively to
allow a (stored-as-Unicode-in-a-database, or
retrieved-as-Unicode-from-a-request-parameter) Unicode path to be
passed tofind_model, which eventually internally uses thetraversal_pathfunction under the hood.  In version 1.2 and
prior, if thepathwas Unicode, that Unicode was split on
slashes and each resulting segment value was Unicode.  An
inappropriate call to thedecode()method of a resulting Unicode
path segment could cause aUnicodeDecodeErrorto occur even if
the Unicode representation of the path contained no ‘high order’
characters (it effectively did a “double decode”).  By converting
the Unicode path argument to ASCII before we attempt to decode and
split, genuine errors will occur in a more obvious place while also
allowing us to handle (for convenience) the case that it’s a Unicode
representation formed entirely from ASCII-compatible characters.1.3a14 (2010-09-14)Bug FixesIf an exception view was registered through the legacyset_notfound_vieworset_forbidden_viewAPIs, the context
sent to the view was incorrect (could beNoneinappropriately).FeaturesCompatibility with WebOb 1.0.RequirementsNow requires WebOb >= 1.0.Backwards IncompatibilitiesDue to changes introduced WebOb 1.0, therepoze.bfg.request.make_request_asciievent subscriber no longer
works, so it has been removed.  This subscriber was meant to be used
in a deployment so that code written before BFG 0.7.0 could run
unchanged.  At this point, such code will need to be rewritten to
expect Unicode fromrequest.GET,request.POSTandrequest.paramsor it will need to be changed to userequest.str_POST,request.str_GETand/orrequest.str_paramsinstead of the non-strversions of same,
as the non-strversions of the same APIs always now perform
decoding to Unicode.ErrataA prior changelog entry asserted that theINewResponseevent was
not sent to listeners if the response was not “valid” (if a view or
renderer returned a response object that did not have a
status/headers/app_iter).  This is not true in this release, nor was
it true in 1.3a13.1.3a13 (2010-09-14)Bug FixesThetraverseroute predicate could not successfully generate a
traversal path.FeaturesIn support of making it easier to configure applications which are
“secure by default”, a default permission feature was added.  If
supplied, the default permission is used as the permission string to
all view registrations which don’t otherwise name a permission.
These APIs are in support of that:A new constructor argument was added to the Configurator:default_permission.A new method was added to the Configurator:set_default_permission.A new ZCML directive was added:default_permission.Add a new request API:request.add_finished_callback.  Finished
callbacks are called by the router unconditionally near the very end
of request processing.  See the “Using Finished Callbacks” section
of the “Hooks” narrative chapter of the documentation for more
information.Arequest.matched_routeattribute is now added to the request
when a route has matched.  Its value is the “route” object that
matched (see theIRouteinterface withinrepoze.bfg.interfacesAPI documentation for the API of a route
object).Theexceptionattribute of the request is now set slightly
earlier and in a slightly different set of scenarios, for benefit of
“finished callbacks” and “response callbacks”.  In previous
versions, theexceptionattribute of the request was not set at
all if an exception view was not found.  In this version, therequest.exceptionattribute is set immediately when an exception
is caught by the router, even if an exception view could not be
found.Theadd_routemethod of a Configurator now accepts apregeneratorargument.  The pregenerator for the resulting route
is called byroute_urlin order to adjust the set of arguments
passed to it by the user for special purposes, such as Pylons
‘subdomain’ support.  It will influence the URL returned byroute_url.  See therepoze.bfg.interfaces.IRoutePregeneratorinterface for more information.Backwards IncompatibilitiesThe router no longer sets the valuewsgiorg.routing_argsinto
the environ when a route matches. The value used to be something
like((),matchdict).  This functionality was only ever
obliquely referred to in change logs; it was never documented as an
API.Theexceptionattribute of the request now defaults toNone.
In prior versions, therequest.exceptionattribute did not exist
if an exception was not raised by user code during request
processing; it only began existence once an exception view was
found.DeprecationsTherepoze.bfg.interfaces.IWSGIApplicationCreatedEventevent
interface was renamed torepoze.bfg.interfaces.IApplicationCreated.  Likewise, therepoze.bfg.events.WSGIApplicationCreatedEventclass was renamed
torepoze.bfg.events.ApplicationCreated.  The older aliases will
continue to work indefinitely.Therepoze.bfg.interfaces.IAfterTraversalevent interface was
renamed torepoze.bfg.interfaces.IContextFound.  Likewise, therepoze.bfg.events.AfterTraversalclass was renamed torepoze.bfg.events.ContextFound.  The older aliases will continue
to work indefinitely.References to the WSGI environment valuesbfg.routes.matchdictandbfg.routes.routewere removed from documentation.  These
will stick around internally for several more releases, but it isrequest.matchdictandrequest.matched_routeare now the
“official” way to obtain the matchdict and the route object which
resulted in the match.DocumentationAdded documentation for thedefault_permissionZCML directive.Added documentation for thedefault_permissionconstructor value
and theset_default_permissionmethod in the Configurator API
documentation.Added a new section to the “security” chapter named “Setting a
Default Permission”.Documentrenderer_globals_factoryandrequest_factoryarguments to Configurator constructor.Added two sections to the “Hooks” chapter of the documentation:
“Using Response Callbacks” and “Using Finished Callbacks”.Added documentation of therequest.exceptionattribute to therepoze.bfg.request.RequestAPI documentation.Added glossary entries for “response callback” and “finished
callback”.The “Request Processing” narrative chapter has been updated to note
finished and response callback steps.New interface in interfaces API documentation:IRoutePregenerator.Added a “The Matched Route” section to the URL Dispatch narrative
docs chapter, detailing thematched_routeattribute.1.3a12 (2010-09-08)Bug FixesFix a bug inrepoze.bfg.url.static_urlURL generation: if two
resource specifications were used to create two separate static
views, but they shared a common prefix, it was possible thatstatic_urlwould generate an incorrect URL.Fix another bug inrepoze.bfg.static_urlURL generation: too
many slashes in generated URL.Prevent a race condition which could result in aRuntimeErrorwhen rendering a Chameleon template that has not already been
rendered once.  This would usually occur directly after a restart,
when more than one person or thread is trying to execute the same
view at the same time:https://bugs.launchpad.net/karl3/+bug/621364FeaturesThe argument torepoze.bfg.configuration.Configurator.add_routewhich was previously calledpathis now calledpatternfor
better explicability.  For backwards compatibility purposes, passing
a keyword argument namedpathtoadd_routewill still work
indefinitely.Thepathattribute to the ZCMLroutedirective is now namedpatternfor better explicability.  The olderpathattribute
will continue to work indefinitely.DocumentationAll narrative, API, and tutorial docs which referred to a route
pattern as apathhave now been updated to refer to them as apattern.Therepoze.bfg.interfacesAPI documentation page is now rendered
viarepoze.sphinx.autointerface.The URL Dispatch narrative chapter now refers to theinterfaceschapter to explain the API of anIRouteobject.Paster TemplatesThe routesalchemy template has been updated to usepatternin
its route declarations rather thanpath.Dependenciestests_requirenow includesrepoze.sphinx.autointerfaceas a
dependency.InternalAdd an API to theConfiguratornamedget_routes_mapper.
This returns an object implementing theIRoutesMapperinterface.Therepoze.bfg.urldispatch.RoutesMapperobject now has aget_routemethod which returns a single Route object orNone.A new interfacerepoze.bfg.interfaces.IRoutewas added.  Therepoze.bfg.urldispatch.Routeobject implements this interface.The canonical attribute for accessing the routing pattern from a
route object is nowpatternrather thanpath.Usehash()rather thanid()when computing the “phash” of a
custom route/view predicate in order to allow the custom predicate
some control over which predicates are “equal”.Useresponse.headerlist.appendinstead ofresponse.headers.addinrepoze.bfg.request.add_global_response_headersin case the
response is not a WebOb response.Therepoze.bfg.urldispatch.Routeconstructor (not an API) now
accepts a different ordering of arguments.  Previously it was(pattern, name, factory=None,predicates=()).  It is now(name, pattern, factory=None,predicates=()).  This is in
support of consistency withconfigurator.add_route.Therepoze.bfg.urldispatch.RoutesMapper.connectmethod (not an
API) now accepts a different ordering of arguments.  Previously it
was(pattern, name, factory=None,predicates=()).  It is now(name, pattern, factory=None,predicates=()).  This is in
support of consistency withconfigurator.add_route.1.3a11 (2010-09-05)Bug FixesProcess the response callbacks and the NewResponse event earlier, to
enable mutations to the response to take effect.1.3a10 (2010-09-05)FeaturesA newrepoze.bfg.request.Request.add_response_callbackAPI has
been added.  This method is documented in the newrepoze.bfg.requestAPI chapter.  It can be used to influence
response values before a concrete response object has been created.Therepoze.bfg.interfaces.INewResponseinterface now includes arequestattribute; as a result, a handler for INewResponse now
has access to the request which caused the response.Each of the follow methods of the Configurator now allow the
below-named arguments to be passed as “dotted name strings”
(e.g. “foo.bar.baz”) rather than as actual implementation objects
that must be imported:setup_registryroot_factory, authentication_policy, authorization_policy,
debug_logger, locale_negotiator, request_factory,
renderer_globals_factoryadd_subscribersubscriber, ifacederive_viewviewadd_viewview,for_, context, request_type, containmentadd_route()view, view_for, factory,for_, view_contextscanpackageadd_rendererfactoryset_forbidden_viewviewset_notfound_viewviewset_request_factoryfactoryset_renderer_globals_factory()factoryset_locale_negotiatornegotiatortesting_add_subscriberevent_ifaceBug FixesThe route pattern registered internally for a a local “static view”
(either via thestaticZCML directive or via theadd_static_viewmethod of the configurator) was incorrect.  It
was regsistered for e.g.static*traverse, while it should have
been registered forstatic/*traverse.  Symptom: two static views
could not reliably be added to a system when they both shared the
same path prefix (e.g./staticand/static2).Backwards IncompatibilitiesThe INewResponse event is now not sent to listeners if the response
returned by view code (or a renderer) is not a “real” response
(e.g. if it does not have.status,.headerlistand.app_iterattribtues).DocumentationAdd an API chapter for therepoze.bfg.requestmodule, which
includes documentation for therepoze.bfg.request.Requestclass
(the “request object”).Modify the “Request and Response” narrative chapter to reference the
newrepoze.bfg.requestAPI chapter.  Some content was moved from
this chapter into the API documentation itself.Various changes to denote that Python dotted names are now allowed
as input to Configurator methods.InternalThe (internal) feature which made it possible to attach aglobal_response_headersattribute to the request (which was
assumed to contain a sequence of header key/value pairs which would
later be added to the response by the router), has been removed.
The functionality ofrepoze.bfg.request.Request.add_response_callbacktakes its
place.Therepoze.bfg.events.NewResponseclass’s construct has changed:
it now must be created with(request, response)rather than
simply(response).1.3a9 (2010-08-22)FeaturesThe Configurator now accepts a dotted namestringto a package as
apackageconstructor argument. Thepackageargument was
previously required to be a packageobject(not a dotted name
string).Therepoze.bfg.configuration.Configurator.with_packagemethod
was added.  This method returns a new Configurator using the same
application registry as the configurator object it is called
upon. The new configurator is created afresh with itspackageconstructor argument set to the value passed towith_package.
This feature will make it easier for future BFG versions to allow
dotted names as arguments in places where currently only object
references are allowed (the work to allow dotted names isntead of
object references everywhere has not yet been done, however).The newrepoze.bfg.configuration.Configurator.maybe_dottedmethod resolves a Python dotted name string supplied as itsdottedargument to a global Python object.  If the value cannot
be resolved, arepoze.bfg.configuration.ConfigurationErroris
raised.  If the value supplied asdottedis not a string, the
value is returned unconditionally without any resolution attempted.The newrepoze.bfg.configuration.Configurator.absolute_resource_specmethod resolves a potentially relative “resource specification”
string into an absolute version.  If the value supplied asrelative_specis not a string, the value is returned
unconditionally without any resolution attempted.Backwards IncompatibilitiesThe functions inrepoze.bfg.renderersnamedrenderandrender_to_responseintroduced in 1.3a6 previously took a set of**valuesarguments for the values to be passed to the renderer.
This was wrong, as renderers don’t need to accept only dictionaries
(they can accept any type of object).  Now, the value sent to the
renderer must be supplied as a positional argument namedvalue.
Therequestargument is still a keyword argument, however.The functions inrepoze.bfg.renderersnamedrenderandrender_to_responsenow accept an additonal keyword argument
namedpackage.Theget_rendererAPI inrepoze.bfg.renderersnow accepts apackageargument.DocumentationThe ZCMLincludedirective docs were incorrect: they specifiedfilenamerather than (the correct)fileas an allowable
attribute.InternalTherepoze.bfg.resource.resolve_resource_specfunction can now
accept a package object as itspnameargument instead of just a
package name.The_renderer_factory_from_nameand_renderer_from_namemethods of the Configurator were removed.  These were never APIs.The_render,_render_to_responseand_make_responsefunctions withrepoze.bfg.render(added in 1.3a6) have been
removed.A new helper classrepoze.bfg.renderers.RendererHelperwas
added.The _map_view function ofrepoze.bfg.configurationnow takes
only a renderer_name argument instead of both arendererandrenderer``_nameargument.  It also takes a ``packageargument
now.Useimp.get_suffixesindirection inrepoze.bfg.path.package_nameinstead of hardcoded.py.pycand.pyoto use for comparison when attemtping to
decide if a directory is a package.Make tests runnable again under Jython (although they do not all
pass currently).The reify decorator now maintains the docstring of the function it
wraps.1.3a8 (2010-08-08)FeaturesNew public interface:repoze.bfg.exceptions.IExceptionResponse.
This interface is provided by all internal exception classes (such
asrepoze.bfg.exceptions.NotFoundandrepoze.bfg.exceptions.Forbidden), instances of which are both
exception objects and can behave as WSGI response objects.  This
interface is made public so that exception classes which are also
valid WSGI response factories can be configured to implement them or
exception instances which are also or response instances can be
configured to provide them.New API class:repoze.bfg.view.AppendSlashNotFoundViewFactory.There can only be one Not Found view in anyrepoze.bfgapplication.  Even if you userepoze.bfg.view.append_slash_notfound_viewas the Not Found
view,repoze.bfgstill must generate a404 Not Foundresponse when it cannot redirect to a slash-appended URL; this not
found response will be visible to site users.If you don’t care what this 404 response looks like, and you only
need redirections to slash-appended route URLs, you may use therepoze.bfg.view.append_slash_notfound_viewobject as the Not
Found view.  However, if you wish to use acustomnotfound view
callable when a URL cannot be redirected to a slash-appended URL,
you may wish to use an instance of therepoze.bfg.view.AppendSlashNotFoundViewFactoryclass as the Not
Found view, supplying the notfound view callable as the first
argument to its constructor.  For instance:from repoze.bfg.exceptions import NotFound
from repoze.bfg.view import AppendSlashNotFoundViewFactory

def notfound_view(context, request):
    return HTTPNotFound('It aint there, stop trying!')

custom_append_slash = AppendSlashNotFoundViewFactory(notfound_view)
config.add_view(custom_append_slash, context=NotFound)Thenotfound_viewsupplied must adhere to the two-argument view
callable calling convention of(context, request)(contextwill be the exception object).DocumentationExpanded the “Cleaning Up After a Request” section of the URL
Dispatch narrative chapter.Expanded the “Redirecting to Slash-Appended Routes” section of the
URL Dispatch narrative chapter.InternalPreviously, two default view functions were registered at
Configurator setup (one forrepoze.bfg.exceptions.NotFoundnameddefault_notfound_viewand one forrepoze.bfg.exceptions.Forbiddennameddefault_forbidden_view) to render internal exception responses.
Those default view functions have been removed, replaced with a
generic default view function which is registered at Configurator
setup for therepoze.bfg.interfaces.IExceptionResponseinterface
that simply returns the exception instance; theNotFoundandForbiddenclasses are now still exception factories but they are
also response factories which generate instances that implement the
newrepoze.bfg.interfaces.IExceptionResponseinterface.1.3a7 (2010-08-01)FeaturesTherepoze.bfg.configuration.Configurator.add_routeAPI now
returns the route object that was added.Arepoze.bfg.events.subscriberdecorator was added.  This
decorator decorates module-scope functions, which are then treated
as event listeners after a scan() is performed.  See the Events
narrative documentation chapter and therepoze.bfg.eventsmodule
documentation for more information.Bug FixesWhen adding a view for a route which did not yet exist (“did not yet
exist” meaning, temporally, a view was added with a route name for a
route which had not yet been added via add_route), the value of thecustom_predicateargument toadd_viewwas lost.  Symptom:
wrong view matches when using URL dispatch and custom view
predicates together.Pattern matches for a:segmentmarker in a URL dispatch route
pattern now always match at least one character.  See “Backwards
Incompatibilities” below in this changelog.Backwards IncompatibilitiesA bug existed in the regular expression to do URL matching.  As an
example, the URL matching machinery would cause the pattern/{foo}to match the root URL/resulting in a match
dictionary of{'foo':u''}or the pattern/{fud}/editmight match the URL``//editresulting in a match dictionary of{'fud':u''}.  It was always the intent that:segmentmarkers
in the pattern would need to matchat least onecharacter, and
never match the empty string.  This, however, means that in certain
circumstances, a routing match which your application inadvertently
depended upon may no longer happen.DocumentationAdded description of therepoze.bfg.events.subscriberdecorator
to the Events narrative chapter.Addedrepoze.bfg.events.subscriberAPI documentation torepoze.bfg.eventsAPI docs.Added a section named “Zope 3 Enforces ‘TTW’ Authorization Checks By
Default; BFG Does Not” to the “Design Defense” chapter.1.3a6 (2010-07-25)FeaturesNew argument torepoze.bfg.configuration.Configurator.add_routeand therouteZCML directive:traverse.  If you would like
to cause thecontextto be something other than therootobject when this route matches, you can spell a traversal pattern as
thetraverseargument.  This traversal pattern will be used as
the traversal path: traversal will begin at the root object implied
by this route (either the global root, or the object returned by thefactoryassociated with this route).The syntax of thetraverseargument is the same as it is forpath. For example, if thepathprovided isarticles/:article/edit, and thetraverseargument provided
is/:article, when a request comes in that causes the route to
match in such a way that thearticlematch value is ‘1’ (when
the request URI is/articles/1/edit), the traversal path will be
generated as/1.  This means that the root object’s__getitem__will be called with the name1during the
traversal phase.  If the1object exists, it will become thecontextof the request.  The Traversal narrative has more
information about traversal.If the traversal path contains segment marker names which are not
present in the path argument, a runtime error will occur.  Thetraversepattern should not contain segment markers that do not
exist in thepath.A similar combining of routing and traversal is available when a
route is matched which contains a*traverseremainder marker in
its path.  Thetraverseargument allows you to associate route
patterns with an arbitrary traversal path without using a a*traverseremainder marker; instead you can use other match
information.Note that thetraverseargument is ignored when attached to a
route that has a*traverseremainder marker in its path.A new method of theConfiguratorexists:set_request_factory.  If used, this method will set the factory
used by therepoze.bfgrouter to create all request objects.TheConfiguratorconstructor takes an additional argument:request_factory.  If used, this argument will set the factory
used by therepoze.bfgrouter to create all request objects.TheConfiguratorconstructor takes an additional argument:request_factory.  If used, this argument will set the factory
used by therepoze.bfgrouter to create all request objects.A new method of theConfiguratorexists:set_renderer_globals_factory.  If used, this method will set the
factory used by therepoze.bfgrouter to create renderer
globals.A new method of theConfiguratorexists:get_settings.  If
used, this method will return the current settings object (performs
the same job as therepoze.bfg.settings.get_settingsAPI).TheConfiguratorconstructor takes an additional argument:renderer_globals_factory.  If used, this argument will set the
factory used by therepoze.bfgrouter to create renderer
globals.Addrepoze.bfg.renderers.render,repoze.bfg.renderers.render_to_responseandrepoze.bfg.renderers.get_rendererfunctions.  These are
imperative APIs which will use the same rendering machinery used by
view configurations with arenderer=attribute/argument to
produce a rendering or renderer.  Because these APIs provide a
central API for all rendering, they now form the preferred way to
perform imperative template rendering.  Using functions namedrender_*from modules such asrepoze.bfg.chameleon_zptandrepoze.bfg.chameleon_textis now discouraged (although not
deprecated).  The code the backing older templating-system-specific
APIs now calls into the newerrepoze.bfg.renderercode.Therepoze.bfg.configuration.Configurator.testing_add_templatehas been renamed totesting_add_renderer.  A backwards
compatibility alias is present using the old name.DocumentationTheHybridnarrative chapter now contains a description of thetraverseroute argument.TheHooksnarrative chapter now contains sections about
changing the request factory and adding a renderer globals factory.The API documentation includes a new module:repoze.bfg.renderers.TheTemplateschapter was updated; all narrative that used
templating-specific APIs within examples to perform rendering (such
as therepoze.bfg.chameleon_zpt.render_template_to_responsemethod) was changed to userepoze.bfg.renderers.render_*functions.Bug FixesTheheaderpredicate (when used as either a view predicate or a
route predicate) had a problem when specified with a name/regex
pair.  When the header did not exist in the headers dictionary, the
regex match could be fedNone, causing it to throw aTypeError: expected string or bufferexception.  Now, the
predicate returns False as intended.DeprecationsTherepoze.bfg.renderers.rendered_responsefunction was never an
official API, but may have been imported by extensions in the wild.
It is officially deprecated in this release.  Userepoze.bfg.renderers.render_to_responseinstead.The following APIs aredocumentationdeprecated (meaning they are
officially deprecated in documentation but do not raise a
deprecation error upon their usage, and may continue to work for an
indefinite period of time):In therepoze.bfg.chameleon_zptmodule:get_renderer,get_template,render_template,render_template_to_response.  The suggested alternatives are
documented within the docstrings of those methods (which are still
present in the documentation).In therepoze.bfg.chameleon_textmodule:get_renderer,get_template,render_template,render_template_to_response.  The suggested alternatives are
documented within the docstrings of those methods (which are still
present in the documentation).In general, to perform template-related functions, one should now
use the various methods in therepoze.bfg.renderersmodule.Backwards IncompatibilitiesA new internal exception class (notan API) namedrepoze.bfg.exceptions.PredicateMismatchnow exists.  This
exception is currently raised when no constituent view of a
multiview can be called (due to no predicate match).  Previously, in
this situation, arepoze.bfg.exceptions.NotFoundwas raised.  We
provide backwards compatibility for code that expected aNotFoundto be raised when no predicates match by causingrepoze.bfg.exceptions.PredicateMismatchto inherit fromNotFound.  This will cause any exception view registered forNotFoundto be called when a predicate mismatch occurs, as was
the previous behavior.There is however, one perverse case that will expose a backwards
incompatibility.  If 1) you had a view that was registered as a
member of a multiview 2) this view explicitly raised aNotFoundexceptionin order toproceed to the next predicate check in the
multiview, that code will now behave differently: rather than
skipping to the next view match, a NotFound will be raised to the
top-level exception handling machinery instead.  For code to be
depending upon the behavior of a view raisingNotFoundto
proceed to the next predicate match, would be tragic, but not
impossible, given thatNotFoundis a public interface.repoze.bfg.exceptions.PredicateMismatchis not a public API and
cannot be depended upon by application code, so you should not
change your view code to raisePredicateMismatch.  Instead, move
the logic which raised theNotFoundexception in the view out
into a custom view predicate.If, when you run your application’s unit test suite under BFG 1.3, aKeyErrornaming a template or aValueErrorindicating that a
‘renderer factory’ is not registered may is raised
(e.g.ValueError: No factory for renderer named '.pt' when looking up karl.views:templates/snippets.pt), you may need to perform some
extra setup in your test code.The best solution is to use therepoze.bfg.configuration.Configurator.testing_add_renderer(or,
alternately the deprecatedrepoze.bfg.testing.registerTemplateRendererorregisterDummyRenderer) API within the code comprising each
individual unit test suite to register a “dummy” renderer for each
of the templates and renderers used by code under test.  For
example:config = Configurator()
config.testing_add_renderer('karl.views:templates/snippets.pt')This will register a basic dummy renderer for this particular
missing template.  Thetesting_add_rendererAPI actuallyreturnsthe renderer, but if you don’t care about how the render
is used, you don’t care about having a reference to it either.A more rough way to solve the issue exists.  It causes the “real”
template implementations to be used while the system is under test,
which is suboptimal, because tests will run slower, and unit tests
won’t actuallybeunit tests, but it is easier.  Always ensure you
call thesetup_registry()method of the Configurator .  Eg:reg = MyRegistry()
config = Configurator(registry=reg)
config.setup_registry()Callingsetup_registryonly has an effect if you’repassing inaregistryargument to the Configurator constructor.setup_registryis called by the course of normal operations
anyway if you do not pass in aregistry.If your test suite isn’t using a Configurator yet, and is still
using the olderrepoze.bfg.testingAPIs namesetUporcleanUp, these will register the renderers on your behalf.A variant on the symptom for this theme exists: you may already be
dutifully registering a dummy template or renderer for a template
used by the code you’re testing usingtesting_register_rendererorregisterTemplateRenderer, but (perhaps unbeknownst to you)
the code under test expects to be able to use a “real” template
renderer implementation to retrieve or renderanothertemplate
that you forgot was being rendered as a side effect of calling the
code you’re testing.  This happened to work because it found therealtemplate while the system was under test previously, and now
it cannot.  The solution is the same.It may also help reduce confusion to use aresource specificationto specify the template path in the test suite and code rather than
a relative path in either.  A resource specification is unambiguous,
while a relative path needs to be relative to “here”, where “here”
isn’t always well-defined (“here” in a test suite may or may not be
the same as “here” in the code under test).1.3a5 (2010-07-14)FeaturesNew internal exception:repoze.bfg.exceptions.URLDecodeError.
This URL is a subclass of the built-in Python exception namedUnicodeDecodeError.When decoding a URL segment to Unicode fails, the exception raised
is nowrepoze.bfg.exceptions.URLDecodeErrorinstead ofUnicodeDecodeError.  This makes it possible to register an
exception view invoked specifically whenrepoze.bfgcannot
decode a URL.Bug FixesFix regression inrepoze.bfg.configuration.Configurator.add_static_view.  Before
1.3a4, view names that contained a slash were supported as route
prefixes. 1.3a4 broke this by trying to treat them as full URLs.DocumentationTherepoze.bfg.exceptions.URLDecodeErrorexception was added to
the exceptions chapter of the API documentation.Backwards Incompatibilitiesin previous releases, when a URL could not be decoded from UTF-8
during traversal, aTypeErrorwas raised.  Now the error which
is raised is arepoze.bfg.exceptions.URLDecodeError.1.3a4 (2010-07-03)FeaturesUndocumented hook: makeget_appandget_rootof therepoze.bfg.paster.BFGShellCommandhookable in cases where
endware may interfere with the default versions.In earlier versions, a custom route predicate associated with a url
dispatch route (each of the predicate functions fed to thecustom_predicatesargument ofrepoze.bfg.configuration.Configurator.add_route) has always
required a 2-positional argument signature, e.g.(context, request).  Before this release, thecontextargument was
alwaysNone.As of this release, the first argument passed to a predicate is now
a dictionary conventionally namedinfoconsisting ofroute,
andmatch.matchis a dictionary: it represents the
arguments matched in the URL by the route.routeis an object
representing the route which was matched.This is useful when predicates need access to the route match.  For
example:def any_of(segment_name, *args):
    def predicate(info, request):
        if info['match'][segment_name] in args:
            return True
    return predicate

num_one_two_or_three = any_of('num, 'one', 'two', 'three')

add_route('num', '/:num', custom_predicates=(num_one_two_or_three,))Therouteobject is an object that has two useful attributes:nameandpath.  Thenameattribute is the route name.
Thepathattribute is the route pattern.  An example of using
the route in a set of route predicates:def twenty_ten(info, request):
    if info['route'].name in ('ymd', 'ym', 'y'):
        return info['match']['year'] == '2010'

add_route('y', '/:year', custom_predicates=(twenty_ten,))
add_route('ym', '/:year/:month', custom_predicates=(twenty_ten,))
add_route('ymd', '/:year/:month:/day', custom_predicates=(twenty_ten,))Therepoze.bfg.url.route_urlAPI has changed.  If a keyword_app_urlis present in the arguments passed toroute_url,
this value will be used as the protocol/hostname/port/leading path
prefix of the generated URL.  For example, using an_app_urlofhttp://example.com:8080/foowould cause the URLhttp://example.com:8080/foo/fleeb/flubto be returned from this
function if the expansion of the route pattern associated with theroute_nameexpanded to/fleeb/flub.It is now possible to use a URL as thenameargument fed torepoze.bfg.configuration.Configurator.add_static_view.  When the
name argument is a URL, therepoze.bfg.url.static_urlAPI will
generate join this URL (as a prefix) to a path including the static
file name.  This makes it more possible to put static media on a
separate webserver for production, while keeping static media
package-internal and served by the development webserver during
development.DocumentationThe authorization chapter of the ZODB Wiki Tutorial
(docs/tutorials/bfgwiki) was changed to demonstrate authorization
via a group rather than via a direct username (thanks to Alex
Marandon).The authorization chapter of the SQLAlchemy Wiki Tutorial
(docs/tutorials/bfgwiki2) was changed to demonstrate authorization
via a group rather than via a direct username.Redirect requests for tutorial sources tohttp://docs.repoze.org/bfgwiki-1.3andhttp://docs.repoze.org/bfgwiki2-1.3/respectively.A section namedCustom Route Predicateswas added to the URL
Dispatch narrative chapter.The Static Resources chapter has been updated to mention usingstatic_urlto generate URLs to external webservers.InternalRemovedrepoze.bfg.static.StaticURLFactoryin favor of a new
abstraction revolving around the (still-internal)repoze.bfg.static.StaticURLInfohelper class.1.3a3 (2010-05-01)Paster TemplatesThebfg_alchemyandbfg_routesalchemytemplates no longer
register ahandle_teardownevent listener which callsDBSession.remove.  This was found by Chris Withers to be
unnecessary.DocumentationThe “bfgwiki2” (URL dispatch wiki) tutorial code and documentation
was changed to remove thehandle_teardownevent listener which
callsDBSession.remove.Any mention of thehandle_teardownevent listener as used by the
paster templates was removed from the URL Dispatch narrative chapter.A section entitled Detecting Available Languages was added to the
i18n narrative docs chapter.1.3a2 (2010-04-28)FeaturesA locale negotiator no longer needs to be registered explicitly. The
default locale negotiator atrepoze.bfg.i18n.default_locale_negotiatoris now used
unconditionally as… um, the default locale negotiator.The default locale negotiator has become more complex.First, the negotiator looks for the_LOCALE_attribute of
the request object (possibly set by a view or an event listener).Then it looks for therequest.params['_LOCALE_']value.Then it looks for therequest.cookies['_LOCALE_']value.Backwards IncompatibilitiesThe default locale negotiator now looks for the parameter named_LOCALE_rather than a parameter namedlocaleinrequest.params.Behavior ChangesA locale negotiator may now returnNone, signifying that the
default locale should be used.DocumentationDocumentation concerning locale negotiation in the
Internationalizationa and Localization chapter was updated.Expanded portion of i18n narrative chapter docs which discuss
working with gettext files.1.3a1 (2010-04-26)FeaturesAdded “exception views”.  When you use an exception (anything that
inherits from the PythonExceptionbuiltin) as view context
argument, e.g.:from repoze.bfg.view import bfg_view
from repoze.bfg.exceptions import NotFound
from webob.exc import HTTPNotFound

@bfg_view(context=NotFound)
def notfound_view(request):
    return HTTPNotFound()For the above example, when therepoze.bfg.exceptions.NotFoundexception is raised by any view or any root factory, thenotfound_viewview callable will be invoked and its response
returned.Other normal view predicates can also be used in combination with an
exception view registration:from repoze.bfg.view import bfg_view
from repoze.bfg.exceptions import NotFound
from webob.exc import HTTPNotFound

@bfg_view(context=NotFound, route_name='home')
def notfound_view(request):
    return HTTPNotFound()The above exception view names theroute_nameofhome,
meaning that it will only be called when the route matched has a
name ofhome.  You can therefore have more than one exception
view for any given exception in the system: the “most specific” one
will be called when the set of request circumstances which match the
view registration.  The only predicate that cannot be not be used
successfully isname.  The name used to look up an exception
view is always the empty string.Existing (pre-1.3) normal views registered against objects
inheriting fromExceptionwill continue to work.  Exception
views used for user-defined exceptions and system exceptions used as
contexts will also work.The feature can be used with any view registration mechanism
(@bfg_viewdecorator, ZCML, or imperativeconfig.add_viewstyles).This feature was kindly contributed by Andrey Popp.Use “Venusian” (http://docs.repoze.org/venusian) to performbfg_viewdecorator scanning rather than relying on a BFG-internal decorator
scanner.  (Truth be told, Venusian is really just a generalization
of the BFG-internal decorator scanner).Internationalization and localization features as documented in the
narrative documentation chapter entitledInternationalization and Localization.A new deployment setting nameddefault_locale_namewas added.
If this string is present as a Paster.inifile option, it will
be considered the default locale name.  The default locale name is
used during locale-related operations such as language translation.It is now possible to turn on Chameleon template “debugging mode”
for all Chameleon BFG templates by setting a BFG-related Paster.inifile setting nameddebug_templates. The exceptions
raised by Chameleon templates when a rendering fails are sometimes
less than helpful.debug_templatesallows you to configure your
application development environment so that exceptions generated by
Chameleon during template compilation and execution will contain
more helpful debugging information.  This mode is on by default in
all new projects.Add a new method of the Configurator namedderive_viewwhich can
be used to generate a BFG view callable from a user-supplied
function, instance, or class. This useful for external framework and
plugin authors wishing to wrap callables supplied by their users
which follow the same calling conventions and response conventions
as objects that can be supplied directly to BFG as a view callable.
See thederive_viewmethod in therepoze.bfg.configuration.Configuratordocs.ZCMLAdd atranslationdirZCML directive to support localization.Add alocalenegotiatorZCML directive to support localization.DeprecationsThe exception views feature replaces the need for theset_notfound_viewandset_forbidden_viewmethods of theConfiguratoras well as thenotfoundandforbiddenZCML
directives.  Those methods and directives will continue to work for
the foreseeable future, but they are deprecated in the
documentation.DependenciesA new install-time dependency on thevenusiandistribution was
added.A new install-time dependency on thetranslationstringdistribution was added.Chameleon 1.2.3 or better is now required (internationalization and
per-template debug settings).InternalView registrations and lookups are now done with three “requires”
arguments instead of two to accomodate orthogonality of exception
views.Therepoze.bfg.interfaces.IForbiddenViewandrepoze.bfg.interfaces.INotFoundViewinterfaces were removed;
they weren’t APIs and they became vestigial with the addition of
exception views.Removerepoze.bfg.compat.pkgutil_26.pyand import aliasrepoze.bfg.compat.walk_packages.  These were only required by
internal scanning machinery; Venusian replaced the internal scanning
machinery, so these are no longer required.DocumentationException view documentation was added to theHooksnarrative
chapter.A new narrative chapter entitledInternationalization and Localizationwas added.The “Environment Variables andiniFile Settings” chapter was
changed: documentation about thedefault_locale_namesetting was
added.A new API chapter for therepoze.bfg.i18nmodule was added.Documentation for the newtranslationdirandlocalenegotiatorZCML directives were added.A section was added to the Templates chapter entitled “Nicer
Exceptions in Templates” describing the result of settingdebug_templates = true.Paster TemplatesAll paster templates now create asetup.cfgwhich includes
commands related to nose testing and Babel message catalog
extraction/compilation.Adefault_locale_name = ensetting was added to each existing paster
template.Adebug_templates = truesetting was added to each existing
paster template.LicensingThe Edgewall (BSD) license was added to the LICENSES.txt file, as
some code in therepoze.bfg.i18nderives from Babel source.