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
--------
@@ -13,7 +171,157 @@
- Make it possible to use variable arguments on ``p*`` commands (``pserve``,
  ``pshell``, ``pviews``, etc) in the form ``a=1 b=2`` so you can fill in
  values in parameterized ``.ini`` file, e.g. ``pshell etc/development.ini
  http_port=8080``.
  http_port=8080``.  See https://github.com/Pylons/pyramid/pull/714
- A somewhat advanced and obscure feature of Pyramid event handlers is their
  ability to handle "multi-interface" notifications.  These notifications have
  traditionally presented multiple objects to the subscriber callable.  For
  instance, if an event was sent by code like this::
     registry.notify(event, context)
  In the past, in order to catch such an event, you were obligated to write and
  register an event subscriber that mentioned both the event and the context in
  its argument list::
     @subscriber([SomeEvent, SomeContextType])
     def asubscriber(event, context):
         pass
  In many subscriber callables registered this way, it was common for the logic
  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.
  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", 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):
         pass
     @subscriber(SomeOtherEvent)
     def asubscriber(event):
         pass
  And you wanted to use a subscriber predicate::
     @subscriber([SomeEvent, SomeContextType], mypredicate=True)
     def asubscriber1(event, context):
         pass
     @subscriber(SomeOtherEvent, mypredicate=True)
     def asubscriber2(event):
         pass
  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, 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 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...
        def __call__(self, event, context=None):
            return self.val == event.context.foo
  This was confusing and bad.
  In order to allow people to ignore unused arguments to subscriber callables
  and to normalize the relationship between event subscribers and subscriber
  predicates, we now allow both subscribers and subscriber predicates to accept
  only a single ``event`` argument even if they've been subscribed for
  notifications that involve multiple interfaces.  Subscribers and subscriber
  predicates that accept only one argument will receive the first object passed
  to ``notify``; this is typically (but not always) the event object.  The
  other objects involved in the subscription lookup will be discarded.  You can
  now write an event subscriber that accepts only ``event`` even if it
  subscribes to multiple interfaces::
     @subscriber([SomeEvent, SomeContextType])
     def asubscriber(event):
         # this will work!
  This prevents you from needing to match the subscriber callable parameters to
  the subscription type unnecessarily, especially when you don't make use of
  any argument in your subscribers except for the event object itself.
  Note, however, that if the event object is not the first
  object in the call to ``notify``, you'll run into trouble.  For example, if
  notify is called with the context argument first::
     registry.notify(context, event)
  You won't be able to take advantage of the event-only feature.  It will
  "work", but the object received by your event handler won't be the event
  object, it will be the context object, which won't be very useful::
     @subscriber([SomeContextType, SomeEvent])
     def asubscriber(event):
         # bzzt! you'll be getting the context here as ``event``, and it'll
         # be useless
  Existing multiple-argument subscribers continue to work without issue, so you
  should continue use those if your system notifies using multiple interfaces
  and the first interface is not the event interface.  For example::
     @subscriber([SomeContextType, SomeEvent])
     def asubscriber(context, event):
         # this will still work!
  The event-only feature makes it possible to use a subscriber predicate that
  accepts only a request argument within both multiple-interface subscriber
  registrations and single-interface subscriber registrations.  You needn't
  make slightly different variations of predicates depending on the
  subscription type arguments.  Instead, just write all your subscriber
  predicates so they only accept ``event`` in their ``__call__`` and they'll be
  useful across all registrations for subscriptions that use an event as their
  first argument, even ones which accept more than just ``event``.
  However, the same caveat applies to predicates as to subscriber callables: if
  you're subscribing to a multi-interface event, and the first interface is not
  the event interface, the predicate won't work properly.  In such a case,
  you'll need to match the predicate ``__call__`` argument ordering and
  composition to the ordering of the interfaces.  For example, if the
  registration for the subscription uses ``[SomeContext, SomeEvent]``, you'll
  need to reflect that in the ordering of the parameters of the predicate's
  ``__call__`` method::
        def __call__(self, context, event):
            return event.request.path.startswith(self.val)
  tl;dr: 1) When using multi-interface subscriptions, always use the event type
  as the first subscription registration argument and 2) When 1 is true, use
  only ``event`` in your subscriber and subscriber predicate parameter lists,
  no matter how many interfaces the subscriber is notified with.  This
  combination will result in the maximum amount of reusability of subscriber
  predicates and the least amount of thought on your part.  Drink responsibly.
Bug Fixes
---------
@@ -87,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
------------
@@ -145,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.
@@ -324,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
@@ -349,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``