diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/api.rst | 1 | ||||
| -rw-r--r-- | docs/api/decorator.rst | 9 | ||||
| -rw-r--r-- | docs/changes.rst | 2 | ||||
| -rw-r--r-- | docs/index.rst | 1 | ||||
| -rw-r--r-- | docs/latexindex.rst | 2 | ||||
| -rw-r--r-- | docs/narr/advconfig.rst | 7 | ||||
| -rw-r--r-- | docs/narr/templates.rst | 36 | ||||
| -rw-r--r-- | docs/narr/upgrading.rst | 232 | ||||
| -rw-r--r-- | docs/tutorials/modwsgi/index.rst | 22 | ||||
| -rw-r--r-- | docs/tutorials/wiki/src/authorization/tutorial/views.py | 10 | ||||
| -rw-r--r-- | docs/tutorials/wiki/src/tests/tutorial/views.py | 10 | ||||
| -rw-r--r-- | docs/tutorials/wiki/src/views/tutorial/views.py | 10 | ||||
| -rw-r--r-- | docs/tutorials/wiki2/src/authorization/tutorial/views.py | 16 | ||||
| -rw-r--r-- | docs/tutorials/wiki2/src/tests/tutorial/views.py | 16 | ||||
| -rw-r--r-- | docs/tutorials/wiki2/src/views/tutorial/views.py | 16 |
15 files changed, 310 insertions, 80 deletions
diff --git a/docs/api.rst b/docs/api.rst index e33fd6a74..9e540b49b 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -12,6 +12,7 @@ documentation is organized alphabetically by module name. api/authentication api/compat api/config + api/decorator api/events api/exceptions api/httpexceptions diff --git a/docs/api/decorator.rst b/docs/api/decorator.rst new file mode 100644 index 000000000..35d9131df --- /dev/null +++ b/docs/api/decorator.rst @@ -0,0 +1,9 @@ +.. _decorator_module: + +:mod:`pyramid.decorator` +-------------------------- + +.. automodule:: pyramid.decorator + +.. autofunction:: reify + diff --git a/docs/changes.rst b/docs/changes.rst index 6294123ed..fdeaf1e99 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -1,3 +1,5 @@ +.. _changelog: + :app:`Pyramid` Change History ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/index.rst b/docs/index.rst index c84314274..321fe1fed 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -88,6 +88,7 @@ Narrative documentation in chapter form explaining how to use narr/advconfig narr/extconfig narr/scaffolding + narr/upgrading narr/threadlocals narr/zca diff --git a/docs/latexindex.rst b/docs/latexindex.rst index 99ec2f54d..604e6e7c6 100644 --- a/docs/latexindex.rst +++ b/docs/latexindex.rst @@ -85,8 +85,6 @@ API Reference api/authorization api/authentication - api/chameleon_text - api/chameleon_zpt api/config api/events api/exceptions diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 165cf7474..ad22a82c9 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -414,3 +414,10 @@ constraints: the routes they imply require relative ordering. Such ordering constraints are not absolved by two-phase configuration. Routes are still added in configuration execution order. +More Information +---------------- + +For more information, see the article entitled `"A Whirlwind Rour of Advanced +Configuration Tactics" +<http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/configuration/whirlwind_tour.html>`_ +in the Pyramid Cookbook. diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 656cf4773..ba72ebfbf 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -46,20 +46,6 @@ within the body of a view callable like so: {'foo':1, 'bar':2}, request=request) -.. warning:: - - Earlier iterations of this documentation - (pre-version-1.3) encouraged the application developer to use - ZPT-specific APIs such as - :func:`pyramid.chameleon_zpt.render_template_to_response` and - :func:`pyramid.chameleon_zpt.render_template` to render templates - directly. This style of rendering still works, but at least for - purposes of this documentation, those functions are deprecated. - Application developers are encouraged instead to use the functions - available in the :mod:`pyramid.renderers` module to perform - rendering tasks. This set of functions works to render templates - for all renderer extensions registered with :app:`Pyramid`. - The ``sample_view`` :term:`view callable` function above returns a :term:`response` object which contains the body of the ``templates/foo.pt`` template. In this case, the ``templates`` @@ -79,12 +65,12 @@ prefix on Windows. .. warning:: Only :term:`Chameleon` templates support defining a renderer for a - template relative to the location of the module where the view - callable is defined. Mako templates, and other templating system - bindings work differently. In particular, Mako templates use a - "lookup path" as defined by the ``mako.directories`` configuration - file instead of treating relative paths as relative to the current - view module. See :ref:`mako_templates`. + template relative to the location of the module where the view callable is + defined. Mako templates, and other templating system bindings work + differently. In particular, Mako templates use a "lookup path" as defined + by the ``mako.directories`` configuration file instead of treating + relative paths as relative to the current view module. See + :ref:`mako_templates`. The path can alternately be a :term:`asset specification` in the form ``some.dotted.package_name:relative/path``. This makes it possible to @@ -542,7 +528,7 @@ Sommetime you'd like to render a macro inside of a Chameleon ZPT template instead of the full Chameleon ZPT template. To render the content of a ``define-macro`` field inside a Chameleon ZPT template, given a Chameleon template file named ``foo.pt`` and a macro named ``bar`` defined within it -(e.g. ``<div metal:define-macro="bar">...</div>``, you can configure the +(e.g. ``<div metal:define-macro="bar">...</div>``), you can configure the template as a :term:`renderer` like so: .. code-block:: python @@ -554,8 +540,8 @@ template as a :term:`renderer` like so: def my_view(request): return {'project':'my project'} -The above will render the ``bar`` macro from within the ``foo.pt`` template -instead of the entire template. +The above will render only the ``bar`` macro defined within the ``foo.pt`` +template instead of the entire template. .. note:: @@ -600,10 +586,6 @@ When the template is rendered, it will show: Hello, world! -If you'd rather use templates directly within a view callable (without -the indirection of using a renderer), see :ref:`chameleon_text_module` -for the API description. - See also :ref:`built_in_renderers` for more general information about renderers, including Chameleon text renderers. diff --git a/docs/narr/upgrading.rst b/docs/narr/upgrading.rst new file mode 100644 index 000000000..92f125c0a --- /dev/null +++ b/docs/narr/upgrading.rst @@ -0,0 +1,232 @@ +Upgrading Pyramid +================= + +When a new version of Pyramid is released, it will sometimes deprecate a +feature or remove a feature that was deprecated in an older release. When +features are removed from Pyramid, applications that depend on those features +will begin to break. This chapter explains how to ensure your Pyramid +applications keep working when you upgrade the Pyramid version you're using. + +.. sidebar:: About Release Numbering + + Conventionally, application version numbering in Python is described as + ``major.minor.micro``. If your Pyramid version is "1.2.3", it means + you're running a version of Pyramid with the major version "1", the minor + version "2" and the micro version "3". A "major" release is one that + increments the first-dot number; 2.X.X might follow 1.X.X. A "minor" + release is one that increments the second-dot number; 1.3.X might follow + 1.2.X. A "micro" release is one that increments the third-dot number; + 1.2.3 might follow 1.2.2. In general, micro releases are "bugfix-only", + and contain no new features, minor releases contain new features but are + largely backwards compatible with older versions, and a major release + indicates a large set of backwards incompatibilities. + +The Pyramid core team is conservative when it comes to removing features. We +don't remove features unnecessarily, but we're human, and we make mistakes +which cause some features to be evolutionary dead ends. Though we are +willing to support dead-end features for some amount of time, some eventually +have to be removed when the cost of supporting them outweighs the benefit of +keeping them around, because each feature in Pyramid represents a certain +documentation and maintenance burden. + +Deprecation and Removal Policy +------------------------------ + +When a feature is scheduled for removal from Pyramid or any of its official +add-ons, the core development team takes these steps: + +- Using the feature will begin to generate a `DeprecationWarning`, indicating + the version in which the feature became deprecated. + +- A note is added to the documentation indicating that the feature is + deprecated. + +- A note is added to the :ref:`changelog` about the deprecation. + +When a deprecated feature is eventually removed: + +- The feature is removed. + +- A note is added to the :ref:`changelog` about the removal. + +Features are never removed in *micro* releases. They are only removed in +minor and major releases. Deprecated features are kept around for at least +*three* minor releases from the time the feature became deprecated. +Therefore, if a feature is added in Pyramid 1.0, but it's deprecated in +Pyramid 1.1, it will be kept around through all 1.1.X releases, all 1.2.X +releases and all 1.3.X releases. It will finally be removed in the first +1.4.X release. + +Sometimes features are "docs-deprecated" instead of formally deprecated. +This means that the feature will be kept around indefinitely, but it will be +removed from the documentation or a note will be added to the documentation +telling folks to use some other newer feature. This happens when the cost of +keeping an old feature around is very minimal and the support and +documentation burden is very low. For example, we might rename a function +that is an API without changing the arguments it accepts. In this case, +we'll often rename the function, and change the docs to point at the new +function name, but leave around a backwards compatibility alias to the old +function name so older code doesn't break. + +"Docs deprecated" features tend to work "forever", meaning that they won't be +removed, and they'll never generate a deprecation warning. However, such +changes are noted in the :ref:`changelog`, so it's possible to know that you +should change older spellings to newer ones to ensure that people reading +your code can find the APIs you're using in the Pyramid docs. + +Consulting the Change History +----------------------------- + +Your first line of defense against application failures caused by upgrading +to a newer Pyramid release is always to read the :ref:`changelog`. to find +the deprecations and removals for each release between the release you're +currently running and the one you wish to upgrade to. The change history +notes every deprecation within a ``Deprecation`` section and every removal +within a ``Backwards Incompatibilies`` section for each release. + +The change history often contains instructions for changing your code to +avoid deprecation warnings and how to change docs-deprecated spellings to +newer ones. You can follow along with each deprecation explanation in the +change history, simply doing a grep or other code search to your application, +using the change log examples to remediate each potential problem. + +.. _testing_under_new_release: + +Testing Your Application Under a New Pyramid Release +---------------------------------------------------- + +Once you've upgraded your application to a new Pyramid release and you've +remediated as much as possible by using the change history notes, you'll want +to run your application's tests (see :ref:`running_tests`) in such a way that +you can see DeprecationWarnings printed to the console when the tests run. + +.. code-block:: bash + + $ python -Wd setup.py test -q + +The ``-Wd`` argument is an argument that tells Python to print deprecation +warnings to the console. Note that the ``-Wd`` flag is only required for +Python 2.7 and better: Python versions 2.6 and older print deprecation +warnings to the console by default. See `the Python -W flag documentation +<http://docs.python.org/using/cmdline.html#cmdoption-W>`_ for more +information. + +As your tests run, deprecation warnings will be printed to the console +explaining the deprecation and providing instructions about how to prevent +the deprecation warning from being issued. For example: + +.. code-block:: text + + $ python -Wd setup.py test -q + # .. elided ... + running build_ext + /home/chrism/projects/pyramid/env27/myproj/myproj/views.py:3: + DeprecationWarning: static: The "pyramid.view.static" class is deprecated + as of Pyramid 1.1; use the "pyramid.static.static_view" class instead with + the "use_subpath" argument set to True. + from pyramid.view import static + . + ---------------------------------------------------------------------- + Ran 1 test in 0.014s + + OK + +In the above case, it's line #3 in the ``myproj.views`` module (``from +pyramid.view import static``) that is causing the problem: + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + + from pyramid.view import static + myview = static('static', 'static') + +The deprecation warning tells me how to fix it, so I can change the code to +do things the newer way: + +.. code-block:: python + :linenos: + + from pyramid.view. import view_config + + from pyramid.static import static_view + myview = static_view('static', 'static', use_subpath=True) + +When I run the tests again, the deprecation warning is no longer printed to +my console: + +.. code-block:: text + + $ python -Wd setup.py test -q + # .. elided ... + running build_ext + . + ---------------------------------------------------------------------- + Ran 1 test in 0.014s + + OK + + +My Application Doesn't Have Any Tests or Has Few Tests +------------------------------------------------------ + +If your application has no tests, or has only moderate test coverage, running +tests won't tell you very much, because the Pyramid codepaths that generate +deprecation warnings won't be executed. + +In this circumstance, you can start your application interactively under a +server run with the ``PYTHONWARNINGS`` environment variable set to +``default``. On UNIX, you can do that via: + +.. code-block:: bash + + $ PYTHONWARNINGS=default bin/pserve development.ini + +On Windows, you need to issue two commands: + +.. code-block:: bash + + C:\> set PYTHONWARNINGS=default + C:\> Scripts/pserve.exe development.ini + +At this point, it's ensured that deprecation warnings will be printed to the +console whenever a codepath is hit that generates one. You can then click +around in your application interactively to try to generate them, and +remediate as explained in :ref:`testing_under_new_release`. + +See `the PYTHONWARNINGS environment variable documentation +<http://docs.python.org/using/cmdline.html#envvar-PYTHONWARNINGS>`_ or `the +Python -W flag documentation +<http://docs.python.org/using/cmdline.html#cmdoption-W>`_ for more +information. + +Upgrading to the Very Latest Pyramid Release +-------------------------------------------- + +When you upgrade your application to the very most recent Pyramid release, +it's advisable to upgrade step-wise through each most recent minor release, +beginning with the one that you know your application currently runs under, +and ending on the most recent release. For example, if your application is +running in production on Pyramid 1.2.1, and the most recent Pyramid 1.3 +release is Pyramid 1.3.3, and the most recent Pyramid release is 1.4.4, it's +advisable to do this: + +- Upgrade your environment to the most recent 1.2 release. For example, the + most recent 1.2 release might be 1.2.3, so upgrade to it. Then run your + application's tests under 1.2.3 as described in + :ref:`testing_under_new_release`. Note any deprecation warnings and + remediate. + +- Upgrade to the most recent 1.3 release, 1.3.3. Run your application's + tests, note any deprecation warnings and remediate. + +- Upgrade to 1.4.4. Run your application's tests, note any deprecation + warnings and remediate. + +If you skip testing your application under each minor release (for example if +you upgrade directly from 1.2.1 to 1.4.4), you might miss a deprecation +warning and waste more time trying to figure out an error caused by a feature +removal than it would take to upgrade stepwise through each minor release. + + diff --git a/docs/tutorials/modwsgi/index.rst b/docs/tutorials/modwsgi/index.rst index d11167344..a22f12610 100644 --- a/docs/tutorials/modwsgi/index.rst +++ b/docs/tutorials/modwsgi/index.rst @@ -7,12 +7,11 @@ Running a :app:`Pyramid` Application under ``mod_wsgi`` It allows :term:`WSGI` programs to be served using the Apache web server. -This guide will outline broad steps that can be used to get a -:app:`Pyramid` application running under Apache via ``mod_wsgi``. -This particular tutorial was developed under Apple's Mac OS X platform -(Snow Leopard, on a 32-bit Mac), but the instructions should be -largely the same for all systems, delta specific path information for -commands and files. +This guide will outline broad steps that can be used to get a :app:`Pyramid` +application running under Apache via ``mod_wsgi``. This particular tutorial +was developed under Apple's Mac OS X platform (Snow Leopard, on a 32-bit +Mac), but the instructions should be largely the same for all systems, delta +specific path information for commands and files. .. note:: Unfortunately these instructions almost certainly won't work for deploying a :app:`Pyramid` application on a Windows system using @@ -90,12 +89,11 @@ commands and files. `logging` module to allow logging within your application. See :ref:`logging_config`. -#. Make the ``pyramid.wsgi`` script executable. - - .. code-block:: text - - $ cd ~/modwsgi/env - $ chmod 755 pyramid.wsgi + There is no need to make the ``pyramid.wsgi`` script executable. + However, you'll need to make sure that *two* users have access to change + into the ``~/modwsgi/env`` directory: your current user (mine is + ``chrism`` and the user that Apache will run as often named ``apache`` or + ``httpd``). Make sure both of these users can "cd" into that directory. #. Edit your Apache configuration and add some stuff. I happened to create a file named ``/etc/apache2/other/modwsgi.conf`` on my own diff --git a/docs/tutorials/wiki/src/authorization/tutorial/views.py b/docs/tutorials/wiki/src/authorization/tutorial/views.py index 21f12b31d..50485d279 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki/src/authorization/tutorial/views.py @@ -51,17 +51,17 @@ def view_page(context, request): renderer='templates/edit.pt', permission='edit') def add_page(context, request): - name = request.subpath[0] + pagename = request.subpath[0] if 'form.submitted' in request.params: body = request.params['body'] page = Page(body) - page.__name__ = name + page.__name__ = pagename page.__parent__ = context - context[name] = page + context[pagename] = page return HTTPFound(location = request.resource_url(page)) - save_url = request.resource_url(context, 'add_page', name) + save_url = request.resource_url(context, 'add_page', pagename) page = Page('') - page.__name__ = name + page.__name__ = pagename page.__parent__ = context return dict(page = page, save_url = save_url, diff --git a/docs/tutorials/wiki/src/tests/tutorial/views.py b/docs/tutorials/wiki/src/tests/tutorial/views.py index 21f12b31d..50485d279 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/views.py +++ b/docs/tutorials/wiki/src/tests/tutorial/views.py @@ -51,17 +51,17 @@ def view_page(context, request): renderer='templates/edit.pt', permission='edit') def add_page(context, request): - name = request.subpath[0] + pagename = request.subpath[0] if 'form.submitted' in request.params: body = request.params['body'] page = Page(body) - page.__name__ = name + page.__name__ = pagename page.__parent__ = context - context[name] = page + context[pagename] = page return HTTPFound(location = request.resource_url(page)) - save_url = request.resource_url(context, 'add_page', name) + save_url = request.resource_url(context, 'add_page', pagename) page = Page('') - page.__name__ = name + page.__name__ = pagename page.__parent__ = context return dict(page = page, save_url = save_url, diff --git a/docs/tutorials/wiki/src/views/tutorial/views.py b/docs/tutorials/wiki/src/views/tutorial/views.py index 016f5b6bb..b0c15297f 100644 --- a/docs/tutorials/wiki/src/views/tutorial/views.py +++ b/docs/tutorials/wiki/src/views/tutorial/views.py @@ -35,17 +35,17 @@ def view_page(context, request): @view_config(name='add_page', context='.models.Wiki', renderer='templates/edit.pt') def add_page(context, request): - name = request.subpath[0] + pagename = request.subpath[0] if 'form.submitted' in request.params: body = request.params['body'] page = Page(body) - page.__name__ = name + page.__name__ = pagename page.__parent__ = context - context[name] = page + context[pagename] = page return HTTPFound(location = request.resource_url(page)) - save_url = request.resource_url(context, 'add_page', name) + save_url = request.resource_url(context, 'add_page', pagename) page = Page('') - page.__name__ = name + page.__name__ = pagename page.__parent__ = context return dict(page = page, save_url = save_url) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views.py b/docs/tutorials/wiki2/src/authorization/tutorial/views.py index c7670b049..0d085b0e2 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views.py @@ -60,14 +60,14 @@ def view_page(request): @view_config(route_name='add_page', renderer='templates/edit.pt', permission='edit') def add_page(request): - name = request.matchdict['pagename'] + pagename = request.matchdict['pagename'] if 'form.submitted' in request.params: body = request.params['body'] - page = Page(name, body) + page = Page(pagename, body) DBSession.add(page) return HTTPFound(location = request.route_url('view_page', - pagename=name)) - save_url = request.route_url('add_page', pagename=name) + pagename=pagename)) + save_url = request.route_url('add_page', pagename=pagename) page = Page('', '') return dict(page=page, save_url=save_url, logged_in=authenticated_userid(request)) @@ -75,16 +75,16 @@ def add_page(request): @view_config(route_name='edit_page', renderer='templates/edit.pt', permission='edit') def edit_page(request): - name = request.matchdict['pagename'] - page = DBSession.query(Page).filter_by(name=name).one() + pagename = request.matchdict['pagename'] + page = DBSession.query(Page).filter_by(name=pagename).one() if 'form.submitted' in request.params: page.data = request.params['body'] DBSession.add(page) return HTTPFound(location = request.route_url('view_page', - pagename=name)) + pagename=pagename)) return dict( page=page, - save_url = request.route_url('edit_page', pagename=name), + save_url = request.route_url('edit_page', pagename=pagename), logged_in=authenticated_userid(request), ) diff --git a/docs/tutorials/wiki2/src/tests/tutorial/views.py b/docs/tutorials/wiki2/src/tests/tutorial/views.py index f2a33af1e..42ac0eb7f 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/views.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/views.py @@ -61,15 +61,15 @@ def view_page(request): @view_config(route_name='add_page', renderer='templates/edit.pt', permission='edit') def add_page(request): - name = request.matchdict['pagename'] + pagename = request.matchdict['pagename'] if 'form.submitted' in request.params: session = DBSession() body = request.params['body'] - page = Page(name, body) + page = Page(pagename, body) session.add(page) return HTTPFound(location = request.route_url('view_page', - pagename=name)) - save_url = request.route_url('add_page', pagename=name) + pagename=pagename)) + save_url = request.route_url('add_page', pagename=pagename) page = Page('', '') return dict(page=page, save_url=save_url, logged_in=authenticated_userid(request)) @@ -77,17 +77,17 @@ def add_page(request): @view_config(route_name='edit_page', renderer='templates/edit.pt', permission='edit') def edit_page(request): - name = request.matchdict['pagename'] + pagename = request.matchdict['pagename'] session = DBSession() - page = session.query(Page).filter_by(name=name).one() + page = session.query(Page).filter_by(name=pagename).one() if 'form.submitted' in request.params: page.data = request.params['body'] session.add(page) return HTTPFound(location = request.route_url('view_page', - pagename=name)) + pagename=pagename)) return dict( page=page, - save_url = request.route_url('edit_page', pagename=name), + save_url = request.route_url('edit_page', pagename=pagename), logged_in=authenticated_userid(request), ) diff --git a/docs/tutorials/wiki2/src/views/tutorial/views.py b/docs/tutorials/wiki2/src/views/tutorial/views.py index c2a94a96b..5a9c75a61 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/views.py +++ b/docs/tutorials/wiki2/src/views/tutorial/views.py @@ -44,27 +44,27 @@ def view_page(request): @view_config(route_name='add_page', renderer='templates/edit.pt') def add_page(request): - name = request.matchdict['pagename'] + pagename = request.matchdict['pagename'] if 'form.submitted' in request.params: body = request.params['body'] - page = Page(name, body) + page = Page(pagename, body) DBSession.add(page) return HTTPFound(location = request.route_url('view_page', - pagename=name)) - save_url = request.route_url('add_page', pagename=name) + pagename=pagename)) + save_url = request.route_url('add_page', pagename=pagename) page = Page('', '') return dict(page=page, save_url=save_url) @view_config(route_name='edit_page', renderer='templates/edit.pt') def edit_page(request): - name = request.matchdict['pagename'] - page = DBSession.query(Page).filter_by(name=name).one() + pagename = request.matchdict['pagename'] + page = DBSession.query(Page).filter_by(name=pagename).one() if 'form.submitted' in request.params: page.data = request.params['body'] DBSession.add(page) return HTTPFound(location = request.route_url('view_page', - pagename=name)) + pagename=pagename)) return dict( page=page, - save_url = request.route_url('edit_page', pagename=name), + save_url = request.route_url('edit_page', pagename=pagename), ) |
