Michael Merickel
2018-10-26 197eb3a2ad19c944b88b1ee3bc84c6501ea9ba35
commit | author | age
41aeac 1 What's New in Pyramid 1.5
e7638b 2 =========================
CM 3
4 This article explains the new features in :app:`Pyramid` version 1.5 as
5 compared to its predecessor, :app:`Pyramid` 1.4.  It also documents backwards
6 incompatibilities between the two versions and deprecations added to
7 :app:`Pyramid` 1.5, as well as software dependency changes and notable
8 documentation additions.
9
0778ee 10 Major Backwards Incompatibilities
CM 11 ---------------------------------
12
13 - Pyramid no longer depends on or configures the Mako and Chameleon templating
14   system renderers by default.  Disincluding these templating systems by
15   default means that the Pyramid core has fewer dependencies and can run on
16   future platforms without immediate concern for the compatibility of its
17   templating add-ons.  It also makes maintenance slightly more effective, as
18   different people can maintain the templating system add-ons that they
19   understand and care about without needing commit access to the Pyramid core,
20   and it allows users who just don't want to see any packages they don't use
21   come along for the ride when they install Pyramid.
22
23   This means that upon upgrading to Pyramid 1.5a2+, projects that use either
24   of these templating systems will see a traceback that ends something like
25   this when their application attempts to render a Chameleon or Mako template::
26
27      ValueError: No such renderer factory .pt
28
29   Or::
30
31      ValueError: No such renderer factory .mako
32
33   Or::
34
35      ValueError: No such renderer factory .mak
36
37   Support for Mako templating has been moved into an add-on package named 
38   ``pyramid_mako``, and support for Chameleon templating has been moved into 
39   an add-on package named ``pyramid_chameleon``.  These packages are drop-in 
40   replacements for the old built-in support for these templating langauges. 
41   All you have to do is install them and make them active in your configuration
42   to register renderer factories for ``.pt`` and/or ``.mako`` (or ``.mak``) to
43   make your application work again.
44
45   To re-add support for Chameleon and/or Mako template renderers into your
46   existing projects, follow the below steps.
47
48   If you depend on Mako templates:
49
50   * Make sure the ``pyramid_mako`` package is installed.  One way to do this
51     is by adding ``pyramid_mako`` to the ``install_requires`` section of your
52     package's ``setup.py`` file and afterwards rerunning ``setup.py develop``::
53
54         setup(
55             #...
56             install_requires=[
57                 'pyramid_mako',         # new dependency
58                 'pyramid',
59                 #...
60             ],
61         )
62
63   * Within the portion of your application which instantiates a Pyramid 
64     :class:`~pyramid.config.Configurator` (often the ``main()`` function in 
65     your project's ``__init__.py`` file), tell Pyramid to include the 
66     ``pyramid_mako`` includeme::
67
68         config = Configurator(.....)
69         config.include('pyramid_mako')
70
71   If you depend on Chameleon templates:
72
73   * Make sure the ``pyramid_chameleon`` package is installed.  One way to do
74     this is by adding ``pyramid_chameleon`` to the ``install_requires`` section
75     of your package's ``setup.py`` file and afterwards rerunning 
76     ``setup.py develop``::
77
78         setup(
79             #...
80             install_requires=[
81                 'pyramid_chameleon',         # new dependency
82                 'pyramid',
83                 #...
84             ],
85         )
86
87   * Within the portion of your application which instantiates a Pyramid 
88     :class:`~pyramid.config.Configurator` (often the ``main()`` function in 
89     your project's ``__init__.py`` file), tell Pyramid to include the 
90     ``pyramid_chameleon`` includeme::
91
92         config = Configurator(.....)
93         config.include('pyramid_chameleon')
94
95   Note that it's also fine to install these packages into *older* Pyramids for
96   forward compatibility purposes.  Even if you don't upgrade to Pyramid 1.5
97   immediately, performing the above steps in a Pyramid 1.4 installation is
98   perfectly fine, won't cause any difference, and will give you forward
99   compatibility when you eventually do upgrade to Pyramid 1.5.
100
101   With the removal of Mako and Chameleon support from the core, some
102   unit tests that use the ``pyramid.renderers.render*`` methods may begin to 
103   fail.  If any of your unit tests are invoking either 
104   ``pyramid.renderers.render()``  or ``pyramid.renderers.render_to_response()``
105   with either Mako or Chameleon templates then the 
106   ``pyramid.config.Configurator`` instance in effect during
107   the unit test should be also be updated to include the addons, as shown
108   above. For example::
109
110         class ATest(unittest.TestCase):
111             def setUp(self):
112                 self.config = pyramid.testing.setUp()
113                 self.config.include('pyramid_mako')
114
115             def test_it(self):
116                 result = pyramid.renderers.render('mypkg:templates/home.mako', {})
117
118   Or::
119
120         class ATest(unittest.TestCase):
121             def setUp(self):
122                 self.config = pyramid.testing.setUp()
123                 self.config.include('pyramid_chameleon')
124
125             def test_it(self):
126                 result = pyramid.renderers.render('mypkg:templates/home.pt', {})
127
128 - If you're using the Pyramid debug toolbar, when you upgrade Pyramid to
129   1.5a2+, you'll also need to upgrade the ``pyramid_debugtoolbar`` package to 
130   at least version 1.0.8, as older toolbar versions are not compatible with 
131   Pyramid 1.5a2+ due to the removal of Mako support from the core.  It's 
132   fine to use this newer version of the toolbar code with older Pyramids too.
133
e7638b 134 Feature Additions
CM 135 -----------------
136
137 The feature additions in Pyramid 1.5 follow.
138
752d65 139 - Python 3.4 compatibility.
SP 140
b210ce 141 - Add ``pdistreport`` script, which prints the Python version in use, the
CM 142   Pyramid version in use, and the version number and location of all Python
143   distributions currently installed.
144
32333e 145 - Add the ability to invert the result of any view, route, or subscriber
CM 146   predicate value using the ``not_`` class.  For example:
147
148   .. code-block:: python
149
150      from pyramid.config import not_
151
152      @view_config(route_name='myroute', request_method=not_('POST'))
153      def myview(request): ...
154
155   The above example will ensure that the view is called if the request method
156   is not POST, at least if no other view is more specific.
157
158   The :class:`pyramid.config.not_` class can be used against any value that is
159   a predicate value passed in any of these contexts:
160
161   - :meth:`pyramid.config.Configurator.add_view`
162
163   - :meth:`pyramid.config.Configurator.add_route`
164
165   - :meth:`pyramid.config.Configurator.add_subscriber`
166
167   - :meth:`pyramid.view.view_config`
168
169   - :meth:`pyramid.events.subscriber`
170
e7638b 171 - View lookup will now search for valid views based on the inheritance
CM 172   hierarchy of the context. It tries to find views based on the most specific
173   context first, and upon predicate failure, will move up the inheritance chain
174   to test views found by the super-type of the context.  In the past, only the
175   most specific type containing views would be checked and if no matching view
176   could be found then a PredicateMismatch would be raised. Now predicate
177   mismatches don't hide valid views registered on super-types. Here's an
178   example that now works:
179
180   .. code-block:: python
181
182      class IResource(Interface):
183
184          ...
185
186      @view_config(context=IResource)
187      def get(context, request):
188
189          ...
190
191      @view_config(context=IResource, request_method='POST')
192      def post(context, request):
193
194          ...
195
196      @view_config(context=IResource, request_method='DELETE')
197      def delete(context, request):
198
199          ...
200
e01b1c 201      @implementer(IResource)
e7638b 202      class MyResource:
CM 203
204          ...
205
206      @view_config(context=MyResource, request_method='POST')
207      def override_post(context, request):
208
209          ...
210
211   Previously the override_post view registration would hide the get
212   and delete views in the context of MyResource -- leading to a
213   predicate mismatch error when trying to use GET or DELETE
214   methods. Now the views are found and no predicate mismatch is
215   raised.
216   See https://github.com/Pylons/pyramid/pull/786 and
217   https://github.com/Pylons/pyramid/pull/1004 and
218   https://github.com/Pylons/pyramid/pull/1046
219
220 - ``scripts/prequest.py`` (aka the ``prequest`` console script): added support
221   for submitting ``PUT`` and ``PATCH`` requests.  See
222   https://github.com/Pylons/pyramid/pull/1033.  add support for submitting
223   ``OPTIONS`` and ``PROPFIND`` requests, and allow users to specify basic
224   authentication credentials in the request via a ``--login`` argument to the
225   script.  See https://github.com/Pylons/pyramid/pull/1039.
226
e01b1c 227 - The :meth:`pyramid.config.Configurator.add_route` method now supports being
CM 228   called with an external URL as pattern. See
229   https://github.com/Pylons/pyramid/issues/611 and the documentation section
230   :ref:`external_route_narr`.
231
e7638b 232 - :class:`pyramid.authorization.ACLAuthorizationPolicy` supports ``__acl__`` as
CM 233   a callable. This removes the ambiguity between the potential
234   ``AttributeError`` that would be raised on the ``context`` when the property
235   was not defined and the ``AttributeError`` that could be raised from any
236   user-defined code within a dynamic property. It is recommended to define a
237   dynamic ACL as a callable to avoid this ambiguity. See
238   https://github.com/Pylons/pyramid/issues/735.
239
240 - Allow a protocol-relative URL (e.g. ``//example.com/images``) to be passed to
241   :meth:`pyramid.config.Configurator.add_static_view`. This allows
242   externally-hosted static URLs to be generated based on the current protocol.
243
e01b1c 244 - The :class:`pyramid.authentication.AuthTktAuthenticationPolicy` class has two
CM 245   new options to configure its domain usage:
246
247   * ``parent_domain``: if set the authentication cookie is set on
248     the parent domain. This is useful if you have multiple sites sharing the
249     same domain.
250
251   * ``domain``: if provided the cookie is always set for this domain, bypassing
252     all usual logic.
253
254   See https://github.com/Pylons/pyramid/pull/1028,
255   https://github.com/Pylons/pyramid/pull/1072 and
256   https://github.com/Pylons/pyramid/pull/1078.
257
258 - The :class:`pyramid.authentication.AuthTktPolicy` now supports IPv6
259   addresses when using the ``include_ip=True`` option. This is possibly
260   incompatible with alternative ``auth_tkt`` implementations, as the
261   specification does not define how to properly handle IPv6. See
e7638b 262   https://github.com/Pylons/pyramid/issues/831.
CM 263
264 - Make it possible to use variable arguments via
265   :func:`pyramid.paster.get_appsettings`. This also allowed the generated
266   ``initialize_db`` script from the ``alchemy`` scaffold to grow support for
267   options in the form ``a=1 b=2`` so you can fill in values in a parameterized
b4ae42 268   ``.ini`` file, e.g.  ``initialize_myapp_db etc/development.ini a=1 b=2``.
MM 269   See https://github.com/Pylons/pyramid/pull/911
e7638b 270
CM 271 - The ``request.session.check_csrf_token()`` method and the ``check_csrf`` view
272   predicate now take into account the value of the HTTP header named
273   ``X-CSRF-Token`` (as well as the ``csrf_token`` form parameter, which they
274   always did).  The header is tried when the form parameter does not exist.
275
e01b1c 276 - You can now generate "hybrid" urldispatch/traversal URLs more easily by using
CM 277   the new ``route_name``, ``route_kw`` and ``route_remainder_name`` arguments
278   to :meth:`~pyramid.request.Request.resource_url` and
279   :meth:`~pyuramid.request.Request.resource_path`.  See
280   :ref:`generating_hybrid_urls`.
281
282 - A new http exception superclass named
283   :class:`~pyramid.httpexceptions.HTTPSuccessful` was added.  You can use this
284   class as the ``context`` of an exception view to catch all 200-series
285   "exceptions" (e.g. "raise HTTPOk").  This also allows you to catch *only* the
286   :class:`~pyramid.httpexceptions.HTTPOk` exception itself; previously this was
287   impossible because a number of other exceptions (such as ``HTTPNoContent``)
288   inherited from ``HTTPOk``, but now they do not.
289
290 - It is now possible to escape double braces in Pyramid scaffolds (unescaped, 
291   these represent replacement values).  You can use ``\{\{a\}\}`` to
292   represent a "bare" ``{{a}}``.  See 
293   https://github.com/Pylons/pyramid/pull/862
294
295 - Add ``localizer`` and ``locale_name`` properties (reified) to
296   :class:`pyramid.request.Request`.  See
297   https://github.com/Pylons/pyramid/issues/508.  Note that the
298   :func:`pyramid.i18n.get_localizer` and :func:`pyramid.i18n.get_locale_name`
299   functions now simply look up these properties on the request.
300
301 - The ``pserve`` command now takes a ``-v`` (or ``--verbose``) flag and a
302   ``-q`` (or ``--quiet``) flag.  Output from running ``pserve`` can be
303   controlled using these flags.  ``-v`` can be specified multiple times to
304   increase verbosity.  ``-q`` sets verbosity to ``0`` unconditionally.  The
305   default verbosity level is ``1``.
306
307 - The ``alchemy`` scaffold tests now provide better coverage.  See
308   https://github.com/Pylons/pyramid/pull/1029
309
0778ee 310 - Users can now provide dotted Python names to as the ``factory`` argument
CM 311   the Configurator methods named 
312   :meth:`~pyramid.config.Configurator.add_view_predicate`, 
313   :meth:`~pyramid.config.Configurator.add_route_predicate` and 
314   :meth:`~pyramid.config.Configurator.add_subscriber_predicate`.  Instead of 
315   passing the predicate factory directly, you can pass a dotted name which 
316   refers to the factory.
317
318 - :func:`pyramid.path.package_name` no longer thows an exception when resolving 
319   the package name for namespace packages that have no ``__file__`` attribute.
320
4caf2b 321 - An authorization API has been added as a method of the request:
CM 322   :meth:`pyramid.request.Request.has_permission`.  It is a method-based
323   alternative to the :func:`pyramid.security.has_permission` API and works
324   exactly the same.  The older API is now deprecated.
325
326 - Property API attributes have been added to the request for easier access to
327   authentication data: :attr:`pyramid.request.Request.authenticated_userid`,
328   :attr:`pyramid.request.Request.unauthenticated_userid`, and
329   :attr:`pyramid.request.Request.effective_principals`.  These are analogues,
330   respectively, of :func:`pyramid.security.authenticated_userid`,
331   :func:`pyramid.security.unauthenticated_userid`, and
332   :func:`pyramid.security.effective_principals`.  They operate exactly the
333   same, except they are attributes of the request instead of functions
334   accepting a request.  They are properties, so they cannot be assigned to.
335   The older function-based APIs are now deprecated.
336
337 - Pyramid's console scripts (``pserve``, ``pviews``, etc) can now be run
338   directly, allowing custom arguments to be sent to the python interpreter
339   at runtime. For example::
340
341       python -3 -m pyramid.scripts.pserve development.ini
342
343 - Added a specific subclass of :class:`pyramid.httpexceptions.HTTPBadRequest`
344   named :class:`pyramid.exceptions.BadCSRFToken` which will now be raised in
345   response to failures in the ``check_csrf_token`` view predicate.  See
346   https://github.com/Pylons/pyramid/pull/1149
347
348 - Added a new ``SignedCookieSessionFactory`` which is very similar to the
349   ``UnencryptedCookieSessionFactoryConfig`` but with a clearer focus on
350   signing content. The custom serializer arguments to this function should
351   only focus on serializing, unlike its predecessor which required the
352   serializer to also perform signing.
5c4318 353   See https://github.com/Pylons/pyramid/pull/1142 . Note
CM 354   that cookies generated using ``SignedCookieSessionFactory`` are not
355   compatible with cookies generated using ``UnencryptedCookieSessionFactory``,
356   so existing user session data will be destroyed if you switch to it.
4caf2b 357
CM 358 - Added a new ``BaseCookieSessionFactory`` which acts as a generic cookie
359   factory that can be used by framework implementors to create their own
360   session implementations. It provides a reusable API which focuses strictly
361   on providing a dictionary-like object that properly handles renewals,
362   timeouts, and conformance with the ``ISession`` API.
363   See https://github.com/Pylons/pyramid/pull/1142
364
d7b647 365 - We no longer eagerly clear ``request.exception`` and ``request.exc_info`` in
CM 366   the exception view tween.  This makes it possible to inspect exception
367   information within a finished callback.  See
368   https://github.com/Pylons/pyramid/issues/1223.
369
4caf2b 370
0778ee 371 Other Backwards Incompatibilities
CM 372 ---------------------------------
e7638b 373
e01b1c 374 - Modified the :meth:`~pyramid.request.Reuqest.current_route_url` method. The
CM 375   method previously returned the URL without the query string by default, it
376   now does attach the query string unless it is overriden.
377
378 - The :meth:`~pyramid.request.Request.route_url` and
379   :meth:`~pyramid.request.Request.route_path` APIs no longer quote ``/`` to
380   ``%2F`` when a replacement value contains a ``/``.  This was pointless, as
381   WSGI servers always unquote the slash anyway, and Pyramid never sees the
382   quoted value.
383
384 - It is no longer possible to set a ``locale_name`` attribute of the request, 
385   nor is it possible to set a ``localizer`` attribute of the request.  These
386   are now "reified" properties that look up a locale name and localizer
387   respectively using the machinery described in :ref:`i18n_chapter`.
388
cb06eb 389 - If you send an ``X-Vhm-Root`` header with a value that ends with any number
OR 390   of slashes, the trailing slashes will be removed before the URL
de2721 391   is generated when you use :meth:`~pyramid.request.Request.resource_url`
e01b1c 392   or :meth:`~pyramid.request.Request.resource_path`.  Previously the virtual
CM 393   root path would not have trailing slashes stripped, which would influence URL
394   generation.
395
396 - The :class:`pyramid.interfaces.IResourceURL` interface has now grown two new
397   attributes: ``virtual_path_tuple`` and ``physical_path_tuple``.  These should
398   be the tuple form of the resource's path (physical and virtual).
33e0fe 399
0778ee 400 - Removed the ``request.response_*`` varying attributes (such
CM 401   as``request.response_headers``) . These attributes had been deprecated
402   since Pyramid 1.1, and as per the deprecation policy, have now been removed.
403
404 - ``request.response`` will no longer be mutated when using the 
405   :func:`pyramid.renderers.render` API.  Almost all renderers mutate the 
406   ``request.response`` response object (for example, the JSON renderer sets
407   ``request.response.content_type`` to ``application/json``), but this is
408   only necessary when the renderer is generating a response; it was a bug
409   when it was done as a side effect of calling 
410   :func:`pyramid.renderers.render`.
411
412 - Removed the ``bfg2pyramid`` fixer script.
413
414 - The :class:`pyramid.events.NewResponse` event is now sent **after** response 
415   callbacks are executed.  It previously executed before response callbacks
416   were executed.  Rationale: it's more useful to be able to inspect the response
417   after response callbacks have done their jobs instead of before.
418
419 - Removed the class named ``pyramid.view.static`` that had been deprecated
420   since Pyramid 1.1.  Instead use :class:`pyramid.static.static_view` with the
421   ``use_subpath=True`` argument.
422
423 - Removed the ``pyramid.view.is_response`` function that had been deprecated
424   since Pyramid 1.1.  Use the :meth:`pyramid.request.Request.is_response`
425   method instead.
426
427 - Removed the ability to pass the following arguments to
428   :meth:`pyramid.config.Configurator.add_route`: ``view``, ``view_context``.
429   ``view_for``, ``view_permission``, ``view_renderer``, and ``view_attr``.
430   Using these arguments had been deprecated since Pyramid 1.1.  Instead of
431   passing view-related arguments to ``add_route``, use a separate call to
432   :meth:`pyramid.config.Configurator.add_view` to associate a view with a route
433   using its ``route_name`` argument.  Note that this impacts the
434   :meth:`pyramid.config.Configurator.add_static_view` function too, because
435   it delegates to``add_route``.
436
437 - Removed the ability to influence and query a :class:`pyramid.request.Request`
438   object as if it were a dictionary.  Previously it was possible to use methods
439   like ``__getitem__``, ``get``, ``items``, and other dictlike methods to
440   access values in the WSGI environment.  This behavior had been deprecated
441   since Pyramid 1.1.  Use methods of ``request.environ`` (a real dictionary)
442   instead.
443
444 - Removed ancient backwards compatibily hack in
445   ``pyramid.traversal.DefaultRootFactory`` which populated the ``__dict__`` of
446   the factory with the matchdict values for compatibility with BFG 0.9.
447
448 - The ``renderer_globals_factory`` argument to the 
449   :class:`pyramid.config.Configurator` constructor and the 
450   coresponding argument to :meth:`~pyramid.config.Configurator.setup_registry` 
451   has been removed.  The ``set_renderer_globals_factory`` method of
452   :class:`~pyramid.config.Configurator` has also been removed.  The (internal)
453   ``pyramid.interfaces.IRendererGlobals`` interface was also removed.  These
454   arguments, methods and interfaces had been deprecated since 1.1.  Use a
455   ``BeforeRender`` event subscriber as documented in the "Hooks" chapter of the
456   Pyramid narrative documentation instead of providing renderer globals values
457   to the configurator.
458
4caf2b 459 - The key/values in the ``_query`` parameter of
CM 460   :meth:`pyramid.request.Request.route_url` and the ``query`` parameter of
461   :meth:`pyramid.request.Request.resource_url` (and their variants), used to
462   encode a value of ``None`` as the string ``'None'``, leaving the resulting
463   query string to be ``a=b&key=None``. The value is now dropped in this
464   situation, leaving a query string of ``a=b&key=``.  See
465   https://github.com/Pylons/pyramid/issues/1119
e7638b 466
CM 467 Deprecations
468 ------------
469
e01b1c 470 - Returning a ``("defname", dict)`` tuple from a view which has a Mako renderer
CM 471   is now deprecated.  Instead you should use the renderer spelling
472   ``foo#defname.mak`` in the view configuration definition and return a dict
473   only.
0778ee 474
CM 475 - The :meth:`pyramid.config.Configurator.set_request_property` method now issues
476   a deprecation warning when used.  It had been docs-deprecated in 1.4
477   but did not issue a deprecation warning when used.
e7638b 478
4caf2b 479 - :func:`pyramid.security.has_permission` is now deprecated in favor of using
CM 480   :meth:`pyramid.request.Request.has_permission`.
481
482 - The :func:`pyramid.security.authenticated_userid`,
483   :func:`pyramid.security.unauthenticated_userid`, and
484   :func:`pyramid.security.effective_principals` functions have been
485   deprecated. Use :attr:`pyramid.request.Request.authenticated_userid`,
486   :attr:`pyramid.request.Request.unauthenticated_userid` and
487   :attr:`pyramid.request.Request.effective_principals` instead.
488
489 - Deprecate the ``pyramid.interfaces.ITemplateRenderer`` interface. It was
490   ill-defined and became unused when Mako and Chameleon template bindings were
491   split into their own packages.
492
493 - The ``pyramid.session.UnencryptedCookieSessionFactoryConfig`` API has been 
494   deprecated and is superseded by the 
495   ``pyramid.session.SignedCookieSessionFactory``.  Note that while the cookies
496   generated by the ``UnencryptedCookieSessionFactoryConfig``
497   are compatible with cookies generated by old releases, cookies generated by
498   the SignedCookieSessionFactory are not. See 
499   https://github.com/Pylons/pyramid/pull/1142
500
e7638b 501 Documentation Enhancements
CM 502 --------------------------
503
664172 504 - A new documentation chapter named :ref:`quick_tour` was added.  It describes
CM 505   starting out with Pyramid from a high level.
506
4caf2b 507 - Added a :ref:`quick_tutorial` to go with the Quick Tour
CM 508
664172 509 - Many other enhancements.
CM 510
e49670 511 Scaffolding Enhancements
CM 512 ------------------------
513
514 - All scaffolds have a new HTML + CSS theme.
515
610b85 516 - Updated docs and scaffolds to keep in step with new 2.0 release of
CM 517   ``Lingua``.  This included removing all ``setup.cfg`` files from scaffolds
518   and documentation environments.
e7638b 519
CM 520 Dependency Changes
521 ------------------
522
0778ee 523 - Pyramid no longer depends upon ``Mako`` or ``Chameleon``.
e7638b 524
767e44 525 - Pyramid now depends on WebOb>=1.3 (it uses ``webob.cookies.CookieProfile``
CM 526   from 1.3+).