Chris McDonough
2013-06-20 56511b0defbc4437a1e1d3b013c504886270d01b
CHANGES.txt
@@ -1,5 +1,163 @@
Next release
next release
============
Features
--------
- ``scripts/prequest.py``:  add support for submitting ``PUT`` and ``PATCH``
  requests.  See https://github.com/Pylons/pyramid/pull/1033.
- ``ACLAuthorizationPolicy`` supports ``__acl__`` as a callable. This
  removes the ambiguity between the potential ``AttributeError`` that would
  be raised on the ``context`` when the property was not defined and the
  ``AttributeError`` that could be raised from any user-defined code within
  a dynamic property. It is recommended to define a dynamic ACL as a callable
  to avoid this ambiguity. See https://github.com/Pylons/pyramid/issues/735.
- Allow a protocol-relative URL (e.g. ``//example.com/images``) to be passed to
  ``pyramid.config.Configurator.add_static_view``. This allows
  externally-hosted static URLs to be generated based on the current protocol.
- The ``AuthTktAuthenticationPolicy`` now supports IPv6 addresses when using
  the ``include_ip=True`` option. This is possibly incompatible with
  alternative ``auth_tkt`` implementations, as the specification does not
  define how to properly handle IPv6. See
  https://github.com/Pylons/pyramid/issues/831.
- Make it possible to use variable arguments via
  ``pyramid.paster.get_appsettings``. This also allowed the generated
  ``initialize_db`` script from the ``alchemy`` scaffold to grow support
  for options in the form ``a=1 b=2`` so you can fill in
  values in a parameterized ``.ini`` file, e.g.
  ``initialize_myapp_db etc/development.ini a=1 b=2``.
  See https://github.com/Pylons/pyramid/pull/911
- The ``request.session.check_csrf_token()`` method and the ``check_csrf`` view
  predicate now take into account the value of the HTTP header named
  ``X-CSRF-Token`` (as well as the ``csrf_token`` form parameter, which they
  always did).  The header is tried when the form parameter does not exist.
Bug Fixes
---------
- Make the ``pyramid.config.assets.PackageOverrides`` object implement the API
  for ``__loader__`` objects specified in PEP 302.  Proxies to the
  ``__loader__`` set by the importer, if present; otherwise, raises
  ``NotImplementedError``.  This makes Pyramid static view overrides work
  properly under Python 3.3 (previously they would not).  See
  https://github.com/Pylons/pyramid/pull/1015 for more information.
- ``mako_templating``: added defensive workaround for non-importability of
  ``mako`` due to upstream ``markupsafe`` dropping Python 3.2 support.  Mako
  templating will no longer work under the combination of MarkupSafe 0.17 and
  Python 3.2 (although the combination of MarkupSafe 0.17 and Python 3.3 or any
  supported Python 2 version will work OK).
- View lookup will now search for valid views based on the inheritance
  hierarchy of the context. It tries to find views based on the most
  specific context first, and upon predicate failure, will move up the
  inheritance chain to test views found by the super-type of the context.
  In the past, only the most specific type containing views would be checked
  and if no matching view could be found then a PredicateMismatch would be
  raised. Now predicate mismatches don't hide valid views registered on
  super-types. Here's an example that now works::
  .. code-block:: python
     class IResource(Interface):
         ...
     @view_config(context=IResource)
     def get(context, request):
         ...
     @view_config(context=IResource, request_method='POST')
     def post(context, request):
         ...
     @view_config(context=IResource, request_method='DELETE')
     def delete(context, request):
         ...
     @implementor(IResource)
     class MyResource:
         ...
     @view_config(context=MyResource, request_method='POST')
     def override_post(context, request):
         ...
  Previously the override_post view registration would hide the get
  and delete views in the context of MyResource -- leading to a
  predicate mismatch error when trying to use GET or DELETE
  methods. Now the views are found and no predicate mismatch is
  raised.
  See https://github.com/Pylons/pyramid/pull/786
- Spaces and dots may now be in mako renderer template paths. This was
  broken when support for the new makodef syntax was added in 1.4a1.
  See https://github.com/Pylons/pyramid/issues/950
- ``pyramid.debug_authorization=true`` will now correctly print out
  ``Allowed`` for views registered with ``NO_PERMISSION_REQUIRED`` instead
  of invoking the ``permits`` method of the authorization policy.
  See https://github.com/Pylons/pyramid/issues/954
- Pyramid failed to install on some systems due to being packaged with
  some test files containing higher order characters in their names. These
  files have now been removed. See
  https://github.com/Pylons/pyramid/issues/981
- ``pyramid.testing.DummyResource`` didn't define ``__bool__``, so code under
   Python 3 would use ``__len__`` to find truthiness; this usually caused an
   instance of DummyResource to be "falsy" instead of "truthy".  See
   https://github.com/Pylons/pyramid/pull/1032
1.4 (2012-12-18)
================
Docs
----
- Fix functional tests in the ZODB tutorial
1.4b3 (2012-12-10)
==================
- Packaging release only, no code changes.  1.4b2 was a brownbag release due to
  missing directories in the tarball.
1.4b2 (2012-12-10)
==================
Docs
----
- Scaffolding is now PEP-8 compliant (at least for a brief shining moment).
- Tutorial improvements.
Backwards Incompatibilities
---------------------------
- Modified the ``_depth`` argument to ``pyramid.view.view_config`` to accept
  a value relative to the invocation of ``view_config`` itself. Thus, when it
  was previously expecting a value of ``1`` or greater, to reflect that
  the caller of ``view_config`` is 1 stack frame away from ``venusian.attach``,
  this implementation detail is now hidden.
- Modified the ``_backframes`` argument to ``pyramid.util.action_method`` in a
  similar way to the changes described to ``_depth`` above.  This argument
  remains undocumented, but might be used in the wild by some insane person.
1.4b1 (2012-11-21)
==================
Features
--------
@@ -34,16 +192,16 @@
  in the subscriber callable to completely ignore the second and following
  arguments (e.g. ``context`` in the above example might be ignored), because
  they usually existed as attributes of the event anyway.  You could usually
  get the same value by doing ``event.context`` or similar in most cases.
  get the same value by doing ``event.context`` or similar.
  The fact that you needed to put an extra argument which you usually ignored
  in the subscriber callable body was only a minor annoyance until we added
  "subscriber predicates" in a prior 1.4 alpha release.  Subscriber predicates
  are used to narrow the set of circumstances under which a subscriber will be
  executed.  Once those were added, the annoyance was escalated, because
  subscriber predicates needed to accept the same argument list and arity as
  the subscriber callables that they were configured against.  So, for example,
  if you had these two subscriber registrations in your code::
  "subscriber predicates", used to narrow the set of circumstances under which
  a subscriber will be executed, in a prior 1.4 alpha release.  Once those were
  added, the annoyance was escalated, because subscriber predicates needed to
  accept the same argument list and arity as the subscriber callables that they
  were configured against.  So, for example, if you had these two subscriber
  registrations in your code::
     @subscriber([SomeEvent, SomeContextType])
     def asubscriber(event, context):
@@ -56,33 +214,37 @@
  And you wanted to use a subscriber predicate::
     @subscriber([SomeEvent, SomeContextType], mypredicate=True)
     def asubscriber(event, context):
     def asubscriber1(event, context):
         pass
     @subscriber(SomeOtherEvent, mypredicate=True)
     def asubscriber(event):
     def asubscriber2(event):
         pass
  If you had previously written your ``mypredicate`` subscriber predicate that
  accepted in such a way that it accepted only one argument in its
  ``__call__``, you could not use it against a subscription which named more
  than one interface in its subscriber interface list.  Similarly, if you had
  written a subscriber predicate that accepted two arguments, you couldn't use
  it against a registration that named only a single interface type.  For
  example, if you created this predicate::
  If an existing ``mypredicate`` subscriber predicate had been written in such
  a way that it accepted only one argument in its ``__call__``, you could not
  use it against a subscription which named more than one interface in its
  subscriber interface list.  Similarly, if you had written a subscriber
  predicate that accepted two arguments, you couldn't use it against a
  registration that named only a single interface type.
  For example, if you created this predicate::
    class MyPredicate(object):
        # portions elided...
        def __call__(self, event):
            return self.val == event.context.foo
  It would not work against a multi-interface-registered subscription.
  It would not work against a multi-interface-registered subscription, so in
  the above example, when you attempted to use it against ``asubscriber1``, it
  would fail at runtime with a TypeError, claiming something was attempting to
  call it with too many arguments.
  To hack around this limitation, you needed to design a ``mypredicate``
  predicate to expect to receive in its ``__call__`` either a single ``event``
  argument (a SomeOtherEvent object) *or* a pair of arguments (a SomeEvent
  object and a SomeContextType object), presumably by doing something like
  this::
  To hack around this limitation, you were obligated to design the
  ``mypredicate`` predicate to expect to receive in its ``__call__`` either a
  single ``event`` argument (a SomeOtherEvent object) *or* a pair of arguments
  (a SomeEvent object and a SomeContextType object), presumably by doing
  something like this::
    class MyPredicate(object):
        # portions elided...
@@ -233,7 +395,7 @@
- ``pyramid.view.render_view`` was not functioning properly under Python 3.x
  due to a byte/unicode discrepancy. See
  http://github.com/Pylons/pyramid/issues/721
  https://github.com/Pylons/pyramid/issues/721
Deprecations
------------
@@ -291,7 +453,7 @@
- When registering a view configuration that named a Chameleon ZPT renderer
  with a macro name in it (e.g. ``renderer='some/template#somemacro.pt``) as
  well as a view configuration without a macro name it it that pointed to the
  well as a view configuration without a macro name in it that pointed to the
  same template (e.g. ``renderer='some/template.pt'``), internal caching could
  confuse the two, and your code might have rendered one instead of the
  other.
@@ -470,7 +632,7 @@
- The static view machinery now raises (rather than returns) ``HTTPNotFound``
  and ``HTTPMovedPermanently`` exceptions, so these can be caught by the
  NotFound view (and other exception views).
  Not Found View (and other exception views).
- The Mako renderer now supports a def name in an asset spec.  When the def
  name is present in the asset spec, the system will render the template def
@@ -495,7 +657,7 @@
- An ``add_permission`` directive method was added to the Configurator.  This
  directive registers a free-standing permission introspectable into the
  Pyramid introspection system.  Frameworks built atop Pyramid can thus use
  the the ``permissions`` introspectable category data to build a
  the ``permissions`` introspectable category data to build a
  comprehensive list of permissions supported by a running system.  Before
  this method was added, permissions were already registered in this
  introspectable category as a side effect of naming them in an ``add_view``