repoze.bfg 1.3a6 has been released.  This is a feature release.

Install it via:

  easy_install -i http://dist.repoze.org/bfg/1.3/simple repoze.bfg

Or via PyPI.

The documentation at http://docs.repoze.org/bfg/1.3 has been updated.

This release has a lot changes and two backwards incompatibilities.
Trivia: this release also runs exactly 1000 unit tests.

The changelog follows.

1.3a6 (2010-07-25)
==================

Features
--------

- New argument to ``repoze.bfg.configuration.Configurator.add_route``
  and the ``route`` ZCML directive: ``traverse``.  If you would like
  to cause the ``context`` to be something other than the ``root``
  object when this route matches, you can spell a traversal pattern as
  the ``traverse`` argument.  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 the
  ``factory`` associated with this route).

  The syntax of the ``traverse`` argument is the same as it is for
  ``path``. For example, if the ``path`` provided is
  ``articles/:article/edit``, and the ``traverse`` argument provided
  is ``/:article``, when a request comes in that causes the route to
  match in such a way that the ``article`` match 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 name ``1`` during the
  traversal phase.  If the ``1`` object exists, it will become the
  ``context`` of 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.  The
  ``traverse`` pattern should not contain segment markers that do not
  exist in the ``path``.

  A similar combining of routing and traversal is available when a
  route is matched which contains a ``*traverse`` remainder marker in
  its path.  The ``traverse`` argument allows you to associate route
  patterns with an arbitrary traversal path without using a a
  ``*traverse`` remainder marker; instead you can use other match
  information.

  Note that the ``traverse`` argument is ignored when attached to a
  route that has a ``*traverse`` remainder marker in its path.

- A new method of the ``Configurator`` exists:
  ``set_request_factory``.  If used, this method will set the factory
  used by the ``repoze.bfg`` router to create all request objects.

- The ``Configurator`` constructor takes an additional argument:
  ``request_factory``.  If used, this argument will set the factory
  used by the ``repoze.bfg`` router to create all request objects.

- The ``Configurator`` constructor takes an additional argument:
  ``request_factory`.  If used, this argument will set the factory
  used by the ``repoze.bfg`` router to create all request objects.

- A new method of the ``Configurator`` exists:
  ``set_renderer_globals_factory``.  If used, this method will set the
  factory used by the ``repoze.bfg`` router to create renderer
  globals.

- A new method of the ``Configurator`` exists: ``get_settings``.  If
  used, this method will return the current settings object (performs
  the same job as the ``repoze.bfg.settings.get_settings`` API).

- The ``Configurator`` constructor takes an additional argument:
  ``renderer_globals_factory``.  If used, this argument will set the
  factory used by the ``repoze.bfg`` router to create renderer
  globals.

- Add ``repoze.bfg.renderers.render``,
  ``repoze.bfg.renderers.render_to_response`` and
  ``repoze.bfg.renderers.get_renderer`` functions.  These are
  imperative APIs which will use the same rendering machinery used by
  view configurations with a ``renderer=`` 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 named
  ``render_*` from modules such as ``repoze.bfg.chameleon_zpt`` and
  ``repoze.bfg.chameleon_text`` is now discouraged (although not
  deprecated).  The code the backing older templating-system-specific
  APIs now calls into the newer ``repoze.bfg.renderer`` code.

- The ``repoze.bfg.configuration.Configurator.testing_add_template``
  has been renamed to ``testing_add_renderer``.  A backwards
  compatibility alias is present using the old name.

Documentation
-------------

- The ``Hybrid`` narrative chapter now contains a description of the
  ``traverse`` route argument.

- The ``Hooks`` narrative 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``.

- The ``Templates`` chapter was updated; all narrative that used
  templating-specific APIs within examples to perform rendering (such
  as the ``repoze.bfg.chameleon_zpt.render_template_to_response``
  method) was changed to use ``repoze.bfg.renderers.render_*``
  functions.

Bug Fixes
---------

- The ``header`` predicate (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 fed ``None``, causing it to throw a
  ``TypeError: expected string or buffer`` exception.  Now, the
  predicate returns False as intended.

Deprecations
------------

- The ``repoze.bfg.renderers.rendered_response`` function was never an
  official API, but may have been imported by extensions in the wild.
  It is officially deprecated in this release.  Use
  ``repoze.bfg.renderers.render_to_response`` instead.

- The following APIs are *documentation* deprecated (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 the ``repoze.bfg.chameleon_zpt`` module: ``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 the ``repoze.bfg.chameleon_text`` module: ``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 the ``repoze.bfg.renderers`` module.

Backwards Incompatibilities
---------------------------

- A new internal exception class (*not* an API) named
  ``repoze.bfg.exceptions.PredicateMismatch`` now 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, a ``repoze.bfg.exceptions.NotFound`` was raised.  We
  provide backwards compatibility for code that expected a
  ``NotFound`` to be raised when no predicates match by causing
  ``repoze.bfg.exceptions.PredicateMismatch`` to inherit from
  ``NotFound``.  This will cause any exception view registered for
  ``NotFound`` to 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 a ``NotFound``
  exception *in order to* proceed 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 raising ``NotFound`` to
  proceed to the next predicate match, would be tragic, but not
  impossible, given that ``NotFound`` is a public interface.
  ``repoze.bfg.exceptions.PredicateMismatch`` is not a public API and
  cannot be depended upon by application code, so you should not
  change your view code to raise ``PredicateMismatch``.  Instead, move
  the logic which raised the ``NotFound`` exception in the view out
  into a custom view predicate.

- If, when you run your application's unit test suite under BFG 1.3, a
  ``KeyError`` naming a template or a ``ValueError`` indicating 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 the
  ``repoze.bfg.configuration.Configurator.testing_add_renderer`` (or,
  alternately the deprecated
  ``repoze.bfg.testing.registerTemplateRenderer`` or
  ``registerDummyRenderer``) 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.  The ``testing_add_renderer`` API actually
  *returns* the 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 actually *be* unit tests, but it is easier.  Always ensure you
  call the ``setup_registry()`` method of the Configurator .  Eg::

    reg = MyRegistry()
    config = Configurator(registry=reg)
    config.setup_registry()

  Calling ``setup_registry`` only has an effect if you're *passing in*
  a ``registry`` argument to the Configurator constructor.
  ``setup_registry`` is called by the course of normal operations
  anyway if you do not pass in a ``registry``.

  If your test suite isn't using a Configurator yet, and is still
  using the older ``repoze.bfg.testing`` APIs name ``setUp`` or
  ``cleanUp``, 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 using ``testing_register_renderer``
  or ``registerTemplateRenderer``, but (perhaps unbeknownst to you)
  the code under test expects to be able to use a "real" template
  renderer implementation to retrieve or render *another* template
  that you forgot was being rendered as a side effect of calling the
  code you're testing.  This happened to work because it found the
  *real* template while the system was under test previously, and now
  it cannot.  The solution is the same.

  It may also help reduce confusion to use a *resource specification*
  to 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).


_______________________________________________
Repoze-dev mailing list
Repoze-dev@lists.repoze.org
http://lists.repoze.org/listinfo/repoze-dev

Reply via email to