summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2013-04-03 17:37:21 -0400
committerChris McDonough <chrism@plope.com>2013-04-03 17:37:21 -0400
commitd64fa6136d0dec6717b273362de548d8f3bf47e8 (patch)
tree23c77ac62ab9d6c93131874f835ae3166d4af53b
parent2ca9bde9d2862655ddee276cd14a375e6a5adec6 (diff)
parent84e455cf7c8d9cbfe6658548a61af2ecbbc1749e (diff)
downloadpyramid-d64fa6136d0dec6717b273362de548d8f3bf47e8.tar.gz
pyramid-d64fa6136d0dec6717b273362de548d8f3bf47e8.tar.bz2
pyramid-d64fa6136d0dec6717b273362de548d8f3bf47e8.zip
Merge branch 'master' of github.com:Pylons/pyramid
-rw-r--r--CHANGES.txt17
-rw-r--r--CONTRIBUTORS.txt4
-rw-r--r--docs/api/paster.rst2
-rw-r--r--docs/conf.py17
-rw-r--r--docs/conventions.rst21
-rw-r--r--docs/designdefense.rst3
-rw-r--r--docs/glossary.rst20
-rw-r--r--docs/narr/assets.rst8
-rw-r--r--docs/narr/commandline.rst8
-rw-r--r--docs/narr/configuration.rst1
-rw-r--r--docs/narr/extending.rst4
-rw-r--r--docs/narr/firstapp.rst3
-rw-r--r--docs/narr/hooks.rst21
-rw-r--r--docs/narr/install.rst46
-rw-r--r--docs/narr/introduction.rst8
-rw-r--r--docs/narr/logging.rst8
-rw-r--r--docs/narr/muchadoabouttraversal.rst18
-rw-r--r--docs/narr/project.rst2
-rw-r--r--docs/narr/renderers.rst4
-rw-r--r--docs/narr/router.rst2
-rw-r--r--docs/narr/security.rst2
-rw-r--r--docs/narr/sessions.rst43
-rw-r--r--docs/narr/startup.rst4
-rw-r--r--docs/narr/subrequest.rst4
-rw-r--r--docs/narr/templates.rst1
-rw-r--r--docs/narr/testing.rst13
-rw-r--r--docs/narr/traversal.rst25
-rw-r--r--docs/narr/urldispatch.rst10
-rw-r--r--docs/narr/viewconfig.rst10
-rw-r--r--docs/narr/views.rst2
-rw-r--r--docs/narr/webob.rst4
-rw-r--r--docs/narr/zca.rst12
-rw-r--r--docs/tutorials/wiki/basiclayout.rst2
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt4
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt4
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt3
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt4
-rw-r--r--docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt3
-rw-r--r--docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt3
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt4
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/templates/login.pt4
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt3
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/templates/view.pt4
-rw-r--r--docs/tutorials/wiki2/authorization.rst8
-rw-r--r--docs/tutorials/wiki2/basiclayout.rst28
-rw-r--r--docs/tutorials/wiki2/definingmodels.rst11
-rw-r--r--docs/tutorials/wiki2/definingviews.rst42
-rw-r--r--docs/tutorials/wiki2/design.rst8
-rw-r--r--docs/tutorials/wiki2/installation.rst186
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt3
-rw-r--r--docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt3
-rw-r--r--docs/tutorials/wiki2/src/tests/tutorial/templates/edit.pt4
-rw-r--r--docs/tutorials/wiki2/src/tests/tutorial/templates/login.pt4
-rw-r--r--docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt3
-rw-r--r--docs/tutorials/wiki2/src/tests/tutorial/templates/view.pt4
-rw-r--r--docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt4
-rw-r--r--docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt3
-rw-r--r--docs/tutorials/wiki2/src/views/tutorial/templates/view.pt4
-rw-r--r--docs/whatsnew-1.1.rst8
-rw-r--r--docs/whatsnew-1.2.rst20
-rw-r--r--docs/whatsnew-1.3.rst12
-rw-r--r--docs/whatsnew-1.4.rst9
-rw-r--r--pyramid/config/__init__.py6
-rw-r--r--pyramid/config/views.py4
-rw-r--r--pyramid/decorator.py18
-rw-r--r--pyramid/mako_templating.py14
-rw-r--r--pyramid/paster.py22
-rw-r--r--pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py9
-rw-r--r--pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl3
-rw-r--r--pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl3
-rw-r--r--pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt3
-rw-r--r--pyramid/tests/fixtures/dummy.ini4
-rw-r--r--pyramid/tests/fixtures/hello .world.mako3
-rw-r--r--pyramid/tests/test_config/test_views.py3
-rw-r--r--pyramid/tests/test_mako_templating.py28
-rw-r--r--pyramid/tests/test_paster.py44
-rw-r--r--pyramid/util.py21
-rw-r--r--setup.py2
78 files changed, 514 insertions, 422 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 6ff54884a..08e498b7a 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -21,6 +21,14 @@ Features
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
+
Bug Fixes
---------
@@ -70,6 +78,15 @@ Bug Fixes
methods. Now the views are found and no predicate mismatch is
raised.
+- 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
+
1.4 (2012-12-18)
================
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 02fb81528..97eb54f7b 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -194,3 +194,7 @@ Contributors
- John Anderson, 2012/11/14
- Bert JW Regeer, 2013/02/01
+
+- Georges Dubus, 2013/03/21
+
+- Jason McKellar, 2013/03/28
diff --git a/docs/api/paster.rst b/docs/api/paster.rst
index bde128e05..edc3738fc 100644
--- a/docs/api/paster.rst
+++ b/docs/api/paster.rst
@@ -9,6 +9,6 @@
.. autofunction:: get_app(config_uri, name=None, options=None)
- .. autofunction:: get_appsettings(config_uri, name=None)
+ .. autofunction:: get_appsettings(config_uri, name=None, options=None)
.. autofunction:: setup_logging(config_uri)
diff --git a/docs/conf.py b/docs/conf.py
index 8d22d4d42..1ddcae08e 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -55,14 +55,21 @@ extensions = [
# Looks for objects in external projects
intersphinx_mapping = {
- 'who': ('http://docs.repoze.org/who/2.0', None),
- 'python': ('http://docs.python.org', None),
- 'python3': ('http://docs.python.org/3', None),
- 'tstring':
+ 'zcomponent': ('http://docs.zope.org/zope.component', None),
+ 'webtest': ('http://webtest.pythonpaste.org/en/latest', None),
+ 'webob': ('http://docs.webob.org/en/latest', None),
+ 'sqla': ('http://docs.sqlalchemy.org/en/latest', None),
+ 'who': ('http://docs.repoze.org/who/latest', None),
+ 'python': ('http://docs.python.org', None),
+ 'python3': ('http://docs.python.org/3', None),
+ 'tstring':
('http://docs.pylonsproject.org/projects/translationstring/en/latest',
None),
- 'venusian':
+ 'venusian':
('http://docs.pylonsproject.org/projects/venusian/en/latest', None),
+ 'toolbar':
+ ('http://docs.pylonsproject.org/projects/pyramid_debugtoolbar/en/latest',
+ None),
}
# Add any paths that contain templates here, relative to this directory.
diff --git a/docs/conventions.rst b/docs/conventions.rst
index 4cffd1084..21b506623 100644
--- a/docs/conventions.rst
+++ b/docs/conventions.rst
@@ -91,3 +91,24 @@ discussed on a page, is rendered like so:
Sidebar information.
+When multiple objects are imported from the same package,
+the following convention is used:
+
+ .. code-block:: python
+
+ from foo import (
+ bar,
+ baz,
+ )
+
+It may look unusual, but it has advantages:
+
+* It allows one to swap out the higher-level package ``foo`` for something
+ else that provides the similar API. An example would be swapping out
+ one Database for another (e.g. graduating from SQLite to PostgreSQL).
+
+* Looks more neat in cases where a large number of objects get imported from
+ that package.
+
+* Adding/removing imported objects from the package is quicker and results
+ in simpler diffs.
diff --git a/docs/designdefense.rst b/docs/designdefense.rst
index 749c9b099..7bc37ac06 100644
--- a/docs/designdefense.rst
+++ b/docs/designdefense.rst
@@ -120,7 +120,6 @@ that uses the ZCA global API is somewhat high. Consider a ZCA neophyte
reading the code that performs a typical "unnamed utility" lookup using the
:func:`zope.component.getUtility` global API:
-.. ignore-next-block
.. code-block:: python
:linenos:
@@ -190,7 +189,6 @@ special-purpose API functions that *do* use ZCA APIs. Take for example the
present in the current request or ``None`` if no userid is present in the
current request. The application developer calls it like so:
-.. ignore-next-block
.. code-block:: python
:linenos:
@@ -500,7 +498,6 @@ which match information in an associated "urlconf" such as
Zope, likewise allows you to add arbitrary keyword and positional
arguments to any method of a resource object found via traversal:
-.. ignore-next-block
.. code-block:: python
:linenos:
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 40c15efdc..241f951d6 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -314,7 +314,7 @@ Glossary
pipeline
The :term:`PasteDeploy` term for a single configuration of a WSGI
- server, a WSGI application, with a set of middleware in-between.
+ server, a WSGI application, with a set of :term:`middleware` in-between.
Zope
`The Z Object Publishing Framework <http://zope.org>`_, a
@@ -334,12 +334,6 @@ Glossary
`Zope Object Database <http://zodb.org>`_, a
persistent Python object store.
- ZEO
- `Zope Enterprise Objects
- <http://www.zope.org/Documentation/Books/ZopeBook/2_6Edition/ZEO.stx>`_
- allows multiple simultaneous processes to access a single
- :term:`ZODB` database.
-
WebOb
`WebOb <http://webob.org>`_ is a WSGI request/response
library created by Ian Bicking.
@@ -907,9 +901,9 @@ Glossary
The scaffold has been retired but the demo plays a similar role.
Pyramid Cookbook
- An additional documentation resource for Pyramid which presents topical,
- practical usages of Pyramid available via
- http://docs.pylonsproject.org/ .
+ Additional documentation for Pyramid which presents topical,
+ practical uses of Pyramid:
+ http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest.
distutils
The standard system for packaging and distributing Python packages. See
@@ -932,18 +926,18 @@ Glossary
provide, for example, Pyramid-specific view timing support, bookkeeping
code that examines exceptions before they are returned to the upstream
WSGI application, or a variety of other features. Tweens behave a bit
- like :term:`WSGI` 'middleware' but they have the benefit of running in a
+ like :term:`WSGI` :term:`middleware` but they have the benefit of running in a
context in which they have access to the Pyramid :term:`application
registry` as well as the Pyramid rendering machinery. See
:ref:`registering_tweens`.
pyramid_debugtoolbar
- A Pyramid add on which displays a helpful debug toolbar "on top of" HTML
+ A Pyramid add-on which displays a helpful debug toolbar "on top of" HTML
pages rendered by your application, displaying request, routing, and
database information. :mod:`pyramid_debugtoolbar` is configured into
the ``development.ini`` of all applications which use a Pyramid
:term:`scaffold`. For more information, see
- http://docs.pylonsproject.org/projects/pyramid_debugtoolbar/dev/ .
+ http://docs.pylonsproject.org/projects/pyramid_debugtoolbar/en/latest/.
scaffold
A project template that generates some of the major parts of a Pyramid
diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst
index deaf0ce08..09a2b83f2 100644
--- a/docs/narr/assets.rst
+++ b/docs/narr/assets.rst
@@ -50,7 +50,6 @@ application might address the asset using the :term:`asset specification`
``myapp:templates/some_template.pt`` using that API within a ``views.py``
file inside a ``myapp`` package:
-.. ignore-next-block
.. code-block:: python
:linenos:
@@ -120,7 +119,7 @@ from the ``/var/www/static`` directory of the computer which runs the
# config is an instance of pyramid.config.Configurator
config.add_static_view(name='static', path='/var/www/static')
-The ``name`` prepresents a URL *prefix*. In order for files that live in the
+The ``name`` represents a URL *prefix*. In order for files that live in the
``path`` directory to be served, a URL that requests one of them must begin
with that prefix. In the example above, ``name`` is ``static``, and ``path``
is ``/var/www/static``. In English, this means that you wish to serve the
@@ -331,7 +330,6 @@ root that exists at the end of your routing table, create an instance of the
:class:`~pyramid.static.static_view` class inside a ``static.py`` file in
your application root as below.
-.. ignore-next-block
.. code-block:: python
:linenos:
@@ -458,7 +456,6 @@ The ``override_asset`` API
An individual call to :meth:`~pyramid.config.Configurator.override_asset`
can override a single asset. For example:
-.. ignore-next-block
.. code-block:: python
:linenos:
@@ -473,7 +470,6 @@ colon separator in a specification separates the *package name* from the
are not specified, the override attempts to resolve every lookup into a
package from the directory of another package. For example:
-.. ignore-next-block
.. code-block:: python
:linenos:
@@ -482,7 +478,6 @@ package from the directory of another package. For example:
Individual subdirectories within a package can also be overridden:
-.. ignore-next-block
.. code-block:: python
:linenos:
@@ -511,7 +506,6 @@ construction file resides (or the ``package`` argument to the
:class:`~pyramid.config.Configurator` class construction).
For example:
-.. ignore-next-block
.. code-block:: python
:linenos:
diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst
index 07c892439..e1347f3ca 100644
--- a/docs/narr/commandline.rst
+++ b/docs/narr/commandline.rst
@@ -172,8 +172,8 @@ name ``main`` as a section name:
The WSGI application that is loaded will be available in the shell as the
``app`` global. Also, if the application that is loaded is the :app:`Pyramid`
-app with no surrounding middleware, the ``root`` object returned by the
-default :term:`root factory`, ``registry``, and ``request`` will be
+app with no surrounding :term:`middleware`, the ``root`` object returned by
+the default :term:`root factory`, ``registry``, and ``request`` will be
available.
You can also simply rely on the ``main`` default section name by omitting any
@@ -572,8 +572,8 @@ configuration implied by the ``[pipeline:main]`` section of your
configuration file by default. Specifying ``/path/to/my/development.ini`` is
logically equivalent to specifying ``/path/to/my/development.ini#main``. In
this case, we'll be using a configuration that includes an ``app`` object
-which is wrapped in the Paste "translogger" middleware (which logs requests
-to the console).
+which is wrapped in the Paste "translogger" :term:`middleware` (which logs
+requests to the console).
You can also specify a particular *section* of the PasteDeploy ``.ini`` file
to load instead of ``main``:
diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst
index 6f82baf32..f7a69d613 100644
--- a/docs/narr/configuration.rst
+++ b/docs/narr/configuration.rst
@@ -140,7 +140,6 @@ In the example above, the scanner translates the arguments to
:class:`~pyramid.view.view_config` into a call to the
:meth:`pyramid.config.Configurator.add_view` method, effectively:
-.. ignore-next-block
.. code-block:: python
config.add_view(hello)
diff --git a/docs/narr/extending.rst b/docs/narr/extending.rst
index beece7640..a60a49fea 100644
--- a/docs/narr/extending.rst
+++ b/docs/narr/extending.rst
@@ -50,7 +50,7 @@ layers are apt to provide the necessary "opinions" (such as mandating a
storage layer, a templating system, and a structured, well-documented pattern
of registering that certain URLs map to certain bits of code) which makes the
concept of a "pluggable application" possible. "Pluggable applications",
-thus, should not plug in to Pyramid itself but should instead plug into a
+thus, should not plug into Pyramid itself but should instead plug into a
system written atop Pyramid.
Although it does not provide for "pluggable applications", Pyramid *does*
@@ -209,7 +209,7 @@ like this:
- Wire the new views and assets created in the new package up using
imperative registrations within the ``main`` function of the
- ``__init__.py`` file of the new application. These wiring should happen
+ ``__init__.py`` file of the new application. This wiring should happen
*after* including the configuration functions of the old application.
These registrations will extend or override any registrations performed by
the original application. See :ref:`overriding_views`,
diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst
index 6d3786d8e..e73ef66ac 100644
--- a/docs/narr/firstapp.rst
+++ b/docs/narr/firstapp.rst
@@ -166,7 +166,6 @@ the application.
Adding Configuration
~~~~~~~~~~~~~~~~~~~~
-.. ignore-next-block
.. literalinclude:: helloworld.py
:linenos:
:lines: 11-12
@@ -186,7 +185,6 @@ The second line registers the ``hello_world`` function as a
WSGI Application Creation
~~~~~~~~~~~~~~~~~~~~~~~~~
-.. ignore-next-block
.. literalinclude:: helloworld.py
:linenos:
:lines: 13
@@ -215,7 +213,6 @@ to its ``add_view`` and ``add_route`` methods.
WSGI Application Serving
~~~~~~~~~~~~~~~~~~~~~~~~
-.. ignore-next-block
.. literalinclude:: helloworld.py
:linenos:
:lines: 14-15
diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst
index 330eb0cd3..a3de23baa 100644
--- a/docs/narr/hooks.rst
+++ b/docs/narr/hooks.rst
@@ -109,9 +109,8 @@ callable:
instance of the :exc:`~pyramid.httpexceptions.HTTPNotFound` exception that
caused the Not Found View to be called. The value of
``request.exception.message`` will be a value explaining why the Not Found
- error was raised. This message will be different when the
- ``pyramid.debug_notfound`` environment setting is true than it is when it
- is false.
+ error was raised. This message has different values depending whether the
+ ``pyramid.debug_notfound`` environment setting is true or false.
.. note::
@@ -208,9 +207,9 @@ Here's some sample code that implements a minimal forbidden view:
that caused the forbidden view to be called. The value of
``request.exception.message`` will be a value explaining why the forbidden
was raised and ``request.exception.result`` will be extended information
- about the forbidden exception. These messages will be different when the
- ``pyramid.debug_authorization`` environment setting is true than it is when
- it is false.
+ about the forbidden exception. These messages have different values
+ depending whether the ``pyramid.debug_authorization`` environment setting
+ is true or false.
.. index::
single: request factory
@@ -694,7 +693,7 @@ represents the type of interface that must be possessed by the resource for
this resource url factory to be found. If the ``resource_iface`` argument is
omitted, this resource url adapter will be used for *all* resources.
-The API that must be implemented by your a class that provides
+The API that must be implemented by a class that provides
:class:`~pyramid.interfaces.IResourceURL` is as follows:
.. code-block:: python
@@ -1036,7 +1035,7 @@ upstream WSGI component that uses :app:`Pyramid` as its "app". This is a
feature that may be used by Pyramid framework extensions, to provide, for
example, Pyramid-specific view timing support bookkeeping code that examines
exceptions before they are returned to the upstream WSGI application. Tweens
-behave a bit like :term:`WSGI` middleware but they have the benefit of
+behave a bit like :term:`WSGI` :term:`middleware` but they have the benefit of
running in a context in which they have access to the Pyramid
:term:`application registry` as well as the Pyramid rendering machinery.
@@ -1110,8 +1109,8 @@ Once you've created a tween factory, you can register it into the implicit
tween chain using the :meth:`pyramid.config.Configurator.add_tween` method
using its :term:`dotted Python name`.
-Here's an example of registering the a tween factory as an "implicit"
-tween in a Pyramid application:
+Here's an example of registering a tween factory as an "implicit" tween in a
+Pyramid application:
.. code-block:: python
:linenos:
@@ -1447,7 +1446,7 @@ view/route predicate:
subscriber predicates will assume a certain event type.
Here's an example of a subscriber predicate that can be used in conjunction
-with a subscriber that subscribes to the :class:`pyramid.events.NewReqest`
+with a subscriber that subscribes to the :class:`pyramid.events.NewRequest`
event type.
.. code-block:: python
diff --git a/docs/narr/install.rst b/docs/narr/install.rst
index 9bc62dc62..8fc63f3a4 100644
--- a/docs/narr/install.rst
+++ b/docs/narr/install.rst
@@ -19,13 +19,32 @@ run :app:`Pyramid`.
run under any version of Python before 2.6.
:app:`Pyramid` is known to run on all popular UNIX-like systems such as
-Linux, MacOS X, and FreeBSD as well as on Windows platforms. It is also
-known to run on :term:`PyPy` (1.9+).
+Linux, Mac OS X, and FreeBSD as well as on Windows platforms. It is
+also known to run on :term:`PyPy` (1.9+).
:app:`Pyramid` installation does not require the compilation of any
C code, so you need only a Python interpreter that meets the
requirements mentioned.
+For Mac OS X Users
+~~~~~~~~~~~~~~~~~~
+
+From `Python.org <http://python.org/download/mac/>`_:
+
+ Python comes pre-installed on Mac OS X, but due to Apple's release
+ cycle, it's often one or even two years old. The overwhelming
+ recommendation of the "MacPython" community is to upgrade your
+ Python by downloading and installing a newer version from
+ `the Python standard release page <http://python.org/download/releases/>`_.
+
+It is recommended to download one of the *installer* versions, unless you prefer to install your Python through a packgage manager (e.g., macports or homebrew) or to build your Python from source.
+
+Unless you have a need for a specific earlier version, it is recommended
+to install the latest 2.x or 3.x version of Python.
+
+If you use an installer for your Python, then you can skip to the
+section :ref:`installing_unix`.
+
If You Don't Yet Have A Python Interpreter (UNIX)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -322,8 +341,8 @@ for both versions are included below.
Windows Using Python 2
~~~~~~~~~~~~~~~~~~~~~~
-#. Install, or find `Python 2.7
- <http://www.python.org/download/releases/2.7.3/>`_ for your system.
+#. Install the most recent `Python 2.7.x version
+ <http://www.python.org/download/>`_ for your system.
#. Install the `Python for Windows extensions
<http://sourceforge.net/projects/pywin32/files/>`_. Make sure to
@@ -371,36 +390,47 @@ Windows Using Python 2
Windows Using Python 3
~~~~~~~~~~~~~~~~~~~~~~
-#. Install, or find `Python 3.2
- <http://www.python.org/download/releases/3.2.3/>`_ for your system.
+#. Install, or find the latest version of `Python 3.x
+ <http://www.python.org/download/>`_ for your system and which is
+ supported by Pyramid.
#. Install the `Python for Windows extensions
<http://sourceforge.net/projects/pywin32/files/>`_. Make sure to
- pick the right download for Python 3.2 and install it using the
+ pick the right download for Python 3.x and install it using the
same Python installation from the previous step.
#. Install latest :term:`distribute` distribution into the Python you
obtained/installed/found in the step above: download `distribute_setup.py
<http://python-distribute.org/distribute_setup.py>`_ and run it using the
- ``python`` interpreter of your Python 3.2 installation using a command
+ ``python`` interpreter of your Python 3.x installation using a command
prompt:
.. code-block:: text
+ # modify the command according to the python version, e.g.:
+ # for Python 3.2.x:
c:\> c:\Python32\python distribute_setup.py
+ # for Python 3.3.x:
+ c:\> c:\Python33\python distribute_setup.py
#. Install :term:`virtualenv`:
.. code-block:: text
+ # for Python 3.2.x:
c:\> c:\Python32\Scripts\easy_install virtualenv
+ # for Python 3.3.x:
+ c:\> c:\Python33\Scripts\easy_install virtualenv
#. Make a :term:`virtualenv` workspace:
.. code-block:: text
c:\> set VENV=c:\env
+ # for Python 3.2.x:
c:\> c:\Python32\Scripts\virtualenv --no-site-packages %VENV%
+ # for Python 3.3.x:
+ c:\> c:\Python33\Scripts\virtualenv --no-site-packages %VENV%
You can either follow the use of the environment variable, ``%VENV%``,
or replace it with the root directory of the :term:`virtualenv`.
diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst
index f9c25c69c..48164d323 100644
--- a/docs/narr/introduction.rst
+++ b/docs/narr/introduction.rst
@@ -600,10 +600,10 @@ Examples: :ref:`hello_traversal_chapter` and
Tweens
~~~~~~
-Pyramid has a sort of internal WSGI-middleware-ish pipeline that can be
-hooked by arbitrary add-ons named "tweens". The debug toolbar is a "tween",
-and the ``pyramid_tm`` transaction manager is also. Tweens are more useful
-than WSGI middleware in some circumstances because they run in the context of
+Pyramid has a sort of internal WSGI-middleware-ish pipeline that can be hooked
+by arbitrary add-ons named "tweens". The debug toolbar is a "tween", and the
+``pyramid_tm`` transaction manager is also. Tweens are more useful than WSGI
+:term:`middleware` in some circumstances because they run in the context of
Pyramid itself, meaning you have access to templates and other renderers, a
"real" request object, and other niceties.
diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst
index 3b903be4d..b3bfb8a1e 100644
--- a/docs/narr/logging.rst
+++ b/docs/narr/logging.rst
@@ -298,14 +298,14 @@ Request Logging with Paste's TransLogger
----------------------------------------
Paste provides the `TransLogger
-<http://pythonpaste.org/modules/translogger.html>`_ middleware for logging
-requests using the `Apache Combined Log Format
+<http://pythonpaste.org/modules/translogger.html>`_ :term:`middleware` for
+logging requests using the `Apache Combined Log Format
<http://httpd.apache.org/docs/2.2/logs.html#combined>`_. TransLogger combined
with a FileHandler can be used to create an ``access.log`` file similar to
Apache's.
-Like any standard middleware with a Paste entry point, TransLogger can be
-configured to wrap your application using ``.ini`` file syntax. First,
+Like any standard :term:`middleware` with a Paste entry point, TransLogger can
+be configured to wrap your application using ``.ini`` file syntax. First,
rename your Pyramid ``.ini`` file's ``[app:main]`` section to
``[app:mypyramidapp]``, then add a ``[filter:translogger]`` section, then use
a ``[pipeline:main]`` section file to form a WSGI pipeline with both the
diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst
index 40d498391..483b1bb16 100644
--- a/docs/narr/muchadoabouttraversal.rst
+++ b/docs/narr/muchadoabouttraversal.rst
@@ -168,18 +168,12 @@ hood, when ``adict`` is a dictionary-like object, Python translates
``adict['a']`` to ``adict.__getitem__('a')``. Try doing this in a Python
interpreter prompt if you don't believe us:
-.. code-block:: text
- :linenos:
-
- Python 2.4.6 (#2, Apr 29 2010, 00:31:48)
- [GCC 4.4.3] on linux2
- Type "help", "copyright", "credits" or "license" for more information.
- >>> adict = {}
- >>> adict['a'] = 1
- >>> adict['a']
- 1
- >>> adict.__getitem__('a')
- 1
+>>> adict = {}
+>>> adict['a'] = 1
+>>> adict['a']
+1
+>>> adict.__getitem__('a')
+1
The dictionary-like root object stores the ids of all of its subresources as
diff --git a/docs/narr/project.rst b/docs/narr/project.rst
index a168c24eb..9d69a65a5 100644
--- a/docs/narr/project.rst
+++ b/docs/narr/project.rst
@@ -416,7 +416,7 @@ If you don't see the debug toolbar image on the right hand top of the page,
it means you're browsing from a system that does not have debugging access.
By default, for security reasons, only a browser originating from
``localhost`` (``127.0.0.1``) can see the debug toolbar. To allow your
-browser on a remote system to access the server, add the a line within the
+browser on a remote system to access the server, add a line within the
``[app:main]`` section of the ``development.ini`` file in the form
``debugtoolbar.hosts = X.X.X.X``. For example, if your Pyramid application
is running on a remote system, and you're browsing from a host with the IP
diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst
index 08ebd881e..b4eb95186 100644
--- a/docs/narr/renderers.rst
+++ b/docs/narr/renderers.rst
@@ -362,7 +362,7 @@ For example (Javascript):
jqhxr = $.getJSON(api_url);
The string ``callback=?`` above in the ``url`` param to the JQuery
-``getAjax`` function indicates to jQuery that the query should be made as
+``getJSON`` function indicates to jQuery that the query should be made as
a JSONP request; the ``callback`` parameter will be automatically filled
in for you and used.
@@ -720,7 +720,7 @@ factory, which expects to be passed a filesystem path:
Adding the above code to your application startup will allow you to use the
``my.package.MyJinja2Renderer`` renderer factory implementation in view
-configurations by referring to any ``renderer`` which *ends in* ``.jinja`` in
+configurations by referring to any ``renderer`` which *ends in* ``.jinja2`` in
the ``renderer`` attribute of a :term:`view configuration`:
.. code-block:: python
diff --git a/docs/narr/router.rst b/docs/narr/router.rst
index b78362066..ac3deefdc 100644
--- a/docs/narr/router.rst
+++ b/docs/narr/router.rst
@@ -46,7 +46,7 @@ request enters a :app:`Pyramid` application through to the point that
:class:`~pyramid.interfaces.IRoute` object representing the route which
matched. The root object associated with the route found is also
generated: if the :term:`route configuration` which matched has an
- associated a ``factory`` argument, this factory is used to generate the
+ associated ``factory`` argument, this factory is used to generate the
root object, otherwise a default :term:`root factory` is used.
#. If a route match was *not* found, and a ``root_factory`` argument was
diff --git a/docs/narr/security.rst b/docs/narr/security.rst
index 203aa2404..e91e8c542 100644
--- a/docs/narr/security.rst
+++ b/docs/narr/security.rst
@@ -85,7 +85,6 @@ during application setup to specify the authentication policy.
For example:
-.. ignore-next-block
.. code-block:: python
:linenos:
@@ -151,7 +150,6 @@ API:
The equivalent view registration including the ``add`` permission name
may be performed via the ``@view_config`` decorator:
-.. ignore-next-block
.. code-block:: python
:linenos:
diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst
index fa4affd8a..c4f4b5f07 100644
--- a/docs/narr/sessions.rst
+++ b/docs/narr/sessions.rst
@@ -252,25 +252,19 @@ that were added to the flash queue, and empties the queue.
.. method:: pop_flash(queue='')
-.. code-block:: python
- :linenos:
-
- >>> request.session.flash('info message')
- >>> request.session.pop_flash()
- ['info message']
+>>> request.session.flash('info message')
+>>> request.session.pop_flash()
+['info message']
Calling ``session.pop_flash()`` again like above without a corresponding call
to ``session.flash()`` will return an empty list, because the queue has already
been popped.
-.. code-block:: python
- :linenos:
-
- >>> request.session.flash('info message')
- >>> request.session.pop_flash()
- ['info message']
- >>> request.session.pop_flash()
- []
+>>> request.session.flash('info message')
+>>> request.session.pop_flash()
+['info message']
+>>> request.session.pop_flash()
+[]
.. index::
single: session.peek_flash
@@ -285,18 +279,15 @@ popped from flash storage.
.. method:: peek_flash(queue='')
-.. code-block:: python
- :linenos:
-
- >>> request.session.flash('info message')
- >>> request.session.peek_flash()
- ['info message']
- >>> request.session.peek_flash()
- ['info message']
- >>> request.session.pop_flash()
- ['info message']
- >>> request.session.peek_flash()
- []
+>>> request.session.flash('info message')
+>>> request.session.peek_flash()
+['info message']
+>>> request.session.peek_flash()
+['info message']
+>>> request.session.pop_flash()
+['info message']
+>>> request.session.peek_flash()
+[]
.. index::
single: preventing cross-site request forgery attacks
diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst
index 3a9225032..1affa1758 100644
--- a/docs/narr/startup.rst
+++ b/docs/narr/startup.rst
@@ -8,12 +8,12 @@ you'll see something much like this show up on the console:
.. code-block:: text
- $ pserve myproject/MyProject.ini
+ $ pserve development.ini
Starting server in PID 16601.
serving on 0.0.0.0:6543 view at http://127.0.0.1:6543
This chapter explains what happens between the time you press the "Return"
-key on your keyboard after typing ``pserve myproject/MyProject.ini``
+key on your keyboard after typing ``pserve development.ini``
and the time the line ``serving on 0.0.0.0:6543 ...`` is output to your
console.
diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst
index 033f045a6..93ce747ee 100644
--- a/docs/narr/subrequest.rst
+++ b/docs/narr/subrequest.rst
@@ -155,7 +155,7 @@ In the example above, the call to
exception. This is because it's using the default value for ``use_tweens``,
which is ``False``. You can pass ``use_tweens=True`` instead to ensure that
it will convert an exception to a Response if an :term:`exception view` is
-configured instead of raising the exception. This because exception views
+configured instead of raising the exception. This is because exception views
are called by the exception view :term:`tween` as described in
:ref:`exception_views` when any view raises an exception.
@@ -250,7 +250,7 @@ It's a poor idea to use the original ``request`` object as an argument to
:meth:`~pyramid.request.Request.invoke_subrequest`. You should construct a
new request instead as demonstrated in the above example, using
:meth:`pyramid.request.Request.blank`. Once you've constructed a request
-object, you'll need to massage the it to match the view callable you'd like
+object, you'll need to massage it to match the view callable you'd like
to be executed during the subrequest. This can be done by adjusting the
subrequest's URL, its headers, its request method, and other attributes. The
documentation for :class:`pyramid.request.Request` exposes the methods you
diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst
index 1f1c07027..d4cf20b93 100644
--- a/docs/narr/templates.rst
+++ b/docs/narr/templates.rst
@@ -150,7 +150,6 @@ string, then return that string as the body of a :app:`Pyramid`
For example, here's an example of using "raw" `Mako
<http://www.makotemplates.org/>`_ from within a :app:`Pyramid` :term:`view`:
-.. ignore-next-block
.. code-block:: python
:linenos:
diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst
index 0801a8eae..bfb1287d9 100644
--- a/docs/narr/testing.rst
+++ b/docs/narr/testing.rst
@@ -128,7 +128,7 @@ functions accepts various arguments that influence the environment of the
test. See the :ref:`testing_module` chapter for information about the extra
arguments supported by these functions.
-If you also want to make :func:`~pyramid.get_current_request` return something
+If you also want to make :func:`~pyramid.threadlocal.get_current_request` return something
other than ``None`` during the course of a single test, you can pass a
:term:`request` object into the :func:`pyramid.testing.setUp` within the
``setUp`` method of your test:
@@ -231,7 +231,7 @@ application registry is not created and populated (e.g. by initializing the
configurator with an authorization policy), like when you invoke application
code via a unit test, :app:`Pyramid` API functions will tend to either fail
or return default results. So how do you test the branch of the code in this
-view function that raises :exc:`HTTPForbidden`?
+view function that raises :exc:`~pyramid.httpexceptions.HTTPForbidden`?
The testing API provided by :app:`Pyramid` allows you to simulate various
application registry registrations for use under a unit testing framework
@@ -272,7 +272,7 @@ without needing to invoke the actual application configuration implied by its
self.assertEqual(response, {'greeting':'hello'})
In the above example, we create a ``MyTest`` test case that inherits from
-:mod:`unittest.TestCase`. If it's in our :app:`Pyramid` application, it will
+:class:`unittest.TestCase`. If it's in our :app:`Pyramid` application, it will
be found when ``setup.py test`` is run. It has two test methods.
The first test method, ``test_view_fn_forbidden`` tests the ``view_fn`` when
@@ -287,8 +287,9 @@ request object that requires less setup than a "real" :app:`Pyramid` request.
We call the function being tested with the manufactured request. When the
function is called, :func:`pyramid.security.has_permission` will call the
"dummy" authentication policy we've registered through
-:meth:`~pyramid.config.Configuration.testing_securitypolicy`, which denies
-access. We check that the view function raises a :exc:`HTTPForbidden` error.
+:meth:`~pyramid.config.Configurator.testing_securitypolicy`, which denies
+access. We check that the view function raises a
+:exc:`~pyramid.httpexceptions.HTTPForbidden` error.
The second test method, named ``test_view_fn_allowed`` tests the alternate
case, where the authentication policy allows access. Notice that we pass
@@ -425,4 +426,4 @@ invoke the root URL. We then assert that the returned HTML has the string
``Pyramid`` in it.
See the :term:`WebTest` documentation for further information about the
-methods available to a :class:`webtest.TestApp` instance.
+methods available to a :class:`webtest.app.TestApp` instance.
diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst
index 1234620c2..2eb6ece13 100644
--- a/docs/narr/traversal.rst
+++ b/docs/narr/traversal.rst
@@ -22,10 +22,13 @@ resource found as the result of a traversal becomes the
subsystem is used to find some view code willing to "publish" this
resource by generating a :term:`response`.
-Using :term:`Traversal` to map a URL to code is optional. It is often
-less easy to understand than :term:`URL dispatch`, so if you're a rank
-beginner, it probably makes sense to use URL dispatch to map URLs to
-code instead of traversal. In that case, you can skip this chapter.
+.. note::
+
+ Using :term:`Traversal` to map a URL to code is optional. If you're creating
+ your first Pyramid application it probably makes more sense to use :term:`URL
+ dispatch` to map URLs to code instead of traversal, as new Pyramid developers
+ tend to find URL dispatch slightly easier to understand. If you use URL
+ dispatch, you needn't read this chapter.
.. index::
single: traversal details
@@ -356,13 +359,13 @@ when this request comes in that we're traversing the following resource tree:
Here's what happens:
-- :mod:`traversal` traverses the root, and attempts to find "foo", which it
+- :term:`traversal` traverses the root, and attempts to find "foo", which it
finds.
-- :mod:`traversal` traverses "foo", and attempts to find "bar", which it
+- :term:`traversal` traverses "foo", and attempts to find "bar", which it
finds.
-- :mod:`traversal` traverses "bar", and attempts to find "baz", which it does
+- :term:`traversal` traverses "bar", and attempts to find "baz", which it does
not find (the "bar" resource raises a :exc:`KeyError` when asked for
"baz").
@@ -407,16 +410,16 @@ However, for this tree:
The user asks for ``http://example.com/foo/bar/baz/biz/buz.txt``
-- :mod:`traversal` traverses "foo", and attempts to find "bar", which it
+- :term:`traversal` traverses "foo", and attempts to find "bar", which it
finds.
-- :mod:`traversal` traverses "bar", and attempts to find "baz", which it
+- :term:`traversal` traverses "bar", and attempts to find "baz", which it
finds.
-- :mod:`traversal` traverses "baz", and attempts to find "biz", which it
+- :term:`traversal` traverses "baz", and attempts to find "biz", which it
finds.
-- :mod:`traversal` traverses "biz", and attempts to find "buz.txt" which it
+- :term:`traversal` traverses "biz", and attempts to find "buz.txt" which it
does not find.
The fact that it does not find a resource related to "buz.txt" at this point
diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst
index 181b07259..18cb3e4db 100644
--- a/docs/narr/urldispatch.rst
+++ b/docs/narr/urldispatch.rst
@@ -16,12 +16,13 @@ receives the :term:`request` and returns a :term:`response` object.
High-Level Operational Overview
-------------------------------
-If route configuration is present in an application, the :app:`Pyramid`
+If any route configuration is present in an application, the :app:`Pyramid`
:term:`Router` checks every incoming request against an ordered set of URL
matching patterns present in a *route map*.
If any route pattern matches the information in the :term:`request`,
-:app:`Pyramid` will invoke :term:`view lookup` to find a matching view.
+:app:`Pyramid` will invoke the :term:`view lookup` process to find a
+matching view.
If no route pattern in the route map matches the information in the
:term:`request` provided in your application, :app:`Pyramid` will fail over
@@ -54,7 +55,6 @@ The :meth:`pyramid.config.Configurator.add_route` method adds a single
:term:`route configuration` to the :term:`application registry`. Here's an
example:
-.. ignore-next-block
.. code-block:: python
# "config" below is presumed to be an instance of the
@@ -81,7 +81,7 @@ this is a portion of your project's ``__init__.py``:
Note that we don't call :meth:`~pyramid.config.Configurator.add_view` in this
setup code. However, the above :term:`scan` execution
-``config.scan('mypackage')`` will pick up all :term:`configuration
+``config.scan('mypackage')`` will pick up each :term:`configuration
decoration`, including any objects decorated with the
:class:`pyramid.view.view_config` decorator in the ``mypackage`` Python
package. For example, if you have a ``views.py`` in your package, a scan will
@@ -1263,7 +1263,7 @@ invoked with the request that caused the invocation.
For most usage, you needn't understand more than this; how it works is an
implementation detail. In the interest of completeness, however, we'll
-explain how it *does* work in the this section. You can skip it if you're
+explain how it *does* work in this section. You can skip it if you're
uninterested.
When a view is associated with a route configuration, :app:`Pyramid` ensures
diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst
index d3221db3c..6f0001f61 100644
--- a/docs/narr/viewconfig.rst
+++ b/docs/narr/viewconfig.rst
@@ -62,9 +62,9 @@ particular view callable.
:term:`View predicate` attributes are an important part of view configuration
that enables the :term:`view lookup` subsystem to find and invoke the
-appropriate view. The greater number of predicate attributes possessed by a
+appropriate view. The greater the number of predicate attributes possessed by a
view's configuration, the more specific the circumstances need to be before
-the registered view callable will be invoked. The fewer number of predicates
+the registered view callable will be invoked. The fewer the number of predicates
which are supplied to a particular view configuration, the more likely it is
that the associated view callable will be invoked. A view with five
predicates will always be found and evaluated before a view with two, for
@@ -313,9 +313,9 @@ configured view.
This argument ensures that the view will only be called when the
:term:`request` has key/value pairs in its :term:`matchdict` that equal
- those supplied in the predicate. e.g. ``match_param="action=edit" would
+ those supplied in the predicate. e.g. ``match_param="action=edit"`` would
require the ``action`` parameter in the :term:`matchdict` match the right
- hande side of the expression (``edit``) for the view to "match" the current
+ hand side of the expression (``edit``) for the view to "match" the current
request.
If the ``match_param`` is a dict, every key/value pair must match for the
@@ -488,7 +488,6 @@ acts as a :app:`Pyramid` view callable.
Here's an example of the :class:`~pyramid.view.view_config` decorator that
lives within a :app:`Pyramid` application module ``views.py``:
-.. ignore-next-block
.. code-block:: python
:linenos:
@@ -503,7 +502,6 @@ lives within a :app:`Pyramid` application module ``views.py``:
Using this decorator as above replaces the need to add this imperative
configuration stanza:
-.. ignore-next-block
.. code-block:: python
:linenos:
diff --git a/docs/narr/views.rst b/docs/narr/views.rst
index 5a7be15b0..b2dd549ce 100644
--- a/docs/narr/views.rst
+++ b/docs/narr/views.rst
@@ -39,7 +39,7 @@ object. A request object represents a :term:`WSGI` environment provided to
object contains everything your application needs to know about the specific
HTTP request being made.
-A view callable's ultimate responsibility is to create a :mod:`Pyramid`
+A view callable's ultimate responsibility is to create a :app:`Pyramid`
:term:`Response` object. This can be done by creating a :term:`Response`
object in the view callable code and returning it directly or by raising
special kinds of exceptions from within the body of a view callable.
diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst
index 44940f9e6..02c03c8db 100644
--- a/docs/narr/webob.rst
+++ b/docs/narr/webob.rst
@@ -326,7 +326,6 @@ package that uses SQLAlchemy, and you'd like the current SQLAlchemy database
session to be removed after each request. Put the following in the
``mypackage.__init__`` module:
-.. ignore-next-block
.. code-block:: python
:linenos:
@@ -355,7 +354,7 @@ initialization.
cause ``DBSession.remove`` to be called in an application generated from
any :app:`Pyramid` scaffold, because these all use the ``pyramid_tm``
package. The cleanup done by ``DBSession.remove`` is unnecessary when
- ``pyramid_tm`` middleware is configured into the application.
+ ``pyramid_tm`` :term:`middleware` is configured into the application.
More Details
++++++++++++
@@ -491,7 +490,6 @@ reason for the error. For instance,
:class:`pyramid.Response`, so you can manipulate the instances in the same
way. A typical example is:
-.. ignore-next-block
.. code-block:: python
:linenos:
diff --git a/docs/narr/zca.rst b/docs/narr/zca.rst
index f7707ea29..b0e9b1709 100644
--- a/docs/narr/zca.rst
+++ b/docs/narr/zca.rst
@@ -21,7 +21,6 @@ application can be opaque. For example, here is a typical "unnamed
utility" lookup using the :func:`zope.component.getUtility` global API
as it might appear in a traditional Zope application:
-.. ignore-next-block
.. code-block:: python
:linenos:
@@ -45,7 +44,7 @@ framework implementation detail.
However, developers who are already used to writing :term:`Zope`
applications often still wish to use the ZCA while building a
-:app:`Pyramid` application; :mod:`pyramid` makes this possible.
+:app:`Pyramid` application; :app:`Pyramid` makes this possible.
.. index::
single: get_current_registry
@@ -84,7 +83,7 @@ While this services a reasonable goal, it causes some issues when
trying to use patterns which you might use to build a typical
:term:`Zope` application to build a :app:`Pyramid` application.
Without special help, ZCA "global" APIs such as
-``zope.component.getUtility`` and ``zope.component.getSiteManager``
+:func:`zope.component.getUtility` and :func:`zope.component.getSiteManager`
will use the ZCA "global" registry. Therefore, these APIs
will appear to fail when used in a :app:`Pyramid` application,
because they'll be consulting the ZCA global registry rather than the
@@ -105,8 +104,8 @@ Disusing the Global ZCA API
+++++++++++++++++++++++++++
ZCA "global" API functions such as ``zope.component.getSiteManager``,
-``zope.component.getUtility``, ``zope.component.getAdapter``, and
-``zope.component.getMultiAdapter`` aren't strictly necessary. Every
+``zope.component.getUtility``, :func:`zope.component.getAdapter`, and
+:func:`zope.component.getMultiAdapter` aren't strictly necessary. Every
component registry has a method API that offers the same
functionality; it can be used instead. For example, presuming the
``registry`` value below is a Zope Component Architecture component
@@ -114,7 +113,6 @@ registry, the following bit of code is equivalent to
``zope.component.getUtility(IFoo)``:
.. code-block:: python
- :linenos:
registry.getUtility(IFoo)
@@ -152,7 +150,6 @@ Consider the following bit of idiomatic :app:`Pyramid` startup code:
.. code-block:: python
:linenos:
- from zope.component import getGlobalSiteManager
from pyramid.config import Configurator
def app(global_settings, **settings):
@@ -189,7 +186,6 @@ For example:
.. code-block:: python
:linenos:
- from zope.component import getGlobalSiteManager
from pyramid.config import Configurator
def app(global_settings, **settings):
diff --git a/docs/tutorials/wiki/basiclayout.rst b/docs/tutorials/wiki/basiclayout.rst
index f9d4775ad..25ac9aabd 100644
--- a/docs/tutorials/wiki/basiclayout.rst
+++ b/docs/tutorials/wiki/basiclayout.rst
@@ -36,7 +36,7 @@ point happens to be the ``main`` function within the file named
#. *Line 15*. Register a "static view" which answers requests whose URL path
start with ``/static`` using the
- :meth:`pyramid.config.Configurator.add_static_view method`. This
+ :meth:`pyramid.config.Configurator.add_static_view` method. This
statement registers a view that will serve up static assets, such as CSS
and image files, for us, in this case, at
``http://localhost:6543/static/`` and below. The first argument is the
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt
index 0d0738f7f..c3a0acf6b 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt
+++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt
@@ -54,9 +54,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer"
- >&copy; Copyright 2008-2011, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt
index 2c7235761..3612dccde 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt
+++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt
@@ -50,9 +50,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer"
- >&copy; Copyright 2008-2011, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt
index 84824f605..e8672104d 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt
@@ -69,8 +69,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer">&copy; Copyright 2008-2012, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt
index 9dd6540cf..90e20764d 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt
+++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt
@@ -57,9 +57,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer"
- >&copy; Copyright 2008-2011, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt
index 84824f605..e8672104d 100644
--- a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt
@@ -69,8 +69,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer">&copy; Copyright 2008-2012, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt
index 84824f605..e8672104d 100644
--- a/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt
@@ -69,8 +69,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer">&copy; Copyright 2008-2012, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt
index 0d0738f7f..c3a0acf6b 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt
+++ b/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt
@@ -54,9 +54,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer"
- >&copy; Copyright 2008-2011, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt
index 2c7235761..3612dccde 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt
+++ b/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt
@@ -50,9 +50,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer"
- >&copy; Copyright 2008-2011, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt
index 84824f605..e8672104d 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt
@@ -69,8 +69,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer">&copy; Copyright 2008-2012, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt
index 9dd6540cf..90e20764d 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt
+++ b/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt
@@ -57,9 +57,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer"
- >&copy; Copyright 2008-2011, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst
index 5ede26920..01c301e74 100644
--- a/docs/tutorials/wiki2/authorization.rst
+++ b/docs/tutorials/wiki2/authorization.rst
@@ -381,21 +381,21 @@ We can finally examine our application in a browser (See
:ref:`wiki2-start-the-application`). Launch a browser and visit
each of the following URLs, check that the result is as expected:
-- ``http://localhost:6543/`` invokes the
+- http://localhost:6543/ invokes the
``view_wiki`` view. This always redirects to the ``view_page`` view
of the FrontPage page object. It is executable by any user.
-- ``http://localhost:6543/FrontPage`` invokes
+- http://localhost:6543/FrontPage invokes
the ``view_page`` view of the FrontPage page object.
-- ``http://localhost:6543/FrontPage/edit_page``
+- http://localhost:6543/FrontPage/edit_page
invokes the edit view for the FrontPage object. It is executable by
only the ``editor`` user. If a different user (or the anonymous
user) invokes it, a login form will be displayed. Supplying the
credentials with the username ``editor``, password ``editor`` will
display the edit page form.
-- ``http://localhost:6543/add_page/SomePageName``
+- http://localhost:6543/add_page/SomePageName
invokes the add view for a page. It is executable by only
the ``editor`` user. If a different user (or the anonymous user)
invokes it, a login form will be displayed. Supplying the
diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst
index 86fe97956..0193afab4 100644
--- a/docs/tutorials/wiki2/basiclayout.rst
+++ b/docs/tutorials/wiki2/basiclayout.rst
@@ -43,9 +43,9 @@ above is executed. It accepts some settings and returns a :term:`WSGI`
application. (See :ref:`startup_chapter` for more about ``pserve``.)
The main function first creates a :term:`SQLAlchemy` database engine using
-``engine_from_config`` from the ``sqlalchemy.`` prefixed settings in the
-``development.ini`` file's ``[app:main]`` section. This will be a URI
-(something like ``sqlite://``):
+:func:`sqlalchemy.engine_from_config` from the ``sqlalchemy.`` prefixed
+settings in the ``development.ini`` file's ``[app:main]`` section.
+This will be a URI (something like ``sqlite://``):
.. literalinclude:: src/basiclayout/tutorial/__init__.py
:lines: 13
@@ -132,11 +132,10 @@ Finally, ``main`` is finished configuring things, so it uses the
View Declarations via ``views.py``
----------------------------------
-Mapping a :term:`route` to code that will be executed when a match for
-the route's pattern occurs is done by registering a :term:`view
-configuration`. Our application uses the
-:meth:`pyramid.view.view_config` decorator to map view callables to
-each route, thereby mapping URL patterns to code.
+The main function of a web framework is mapping each URL pattern to code (a
+:term:`view callable`) that is executed when the requested URL matches the
+corresponding :term:`route`. Our application uses the
+:meth:`pyramid.view.view_config` decorator to perform this mapping.
Open ``tutorial/tutorial/views.py``. It should already contain the following:
@@ -228,11 +227,10 @@ To give a simple example of a model class, we define one named ``MyModel``:
Our example model has an ``__init__`` method that takes two arguments
(``name``, and ``value``). It stores these values as ``self.name`` and
-``self.value``
-within the ``__init__`` function itself. The ``MyModel`` class also has a
-``__tablename__`` attribute. This informs SQLAlchemy which table to use to
-store the data representing instances of this class.
-
-That's about all there is to it to models, views, and initialization code in
-our stock application.
+``self.value`` on the instance created by the ``__init__`` function itself.
+The ``MyModel`` class also has a ``__tablename__`` attribute. This informs
+SQLAlchemy which table to use to store the data representing instances of this
+class.
+That's about all there is to it regarding models, views, and initialization
+code in our stock application.
diff --git a/docs/tutorials/wiki2/definingmodels.rst b/docs/tutorials/wiki2/definingmodels.rst
index bd1cb00d7..60427a911 100644
--- a/docs/tutorials/wiki2/definingmodels.rst
+++ b/docs/tutorials/wiki2/definingmodels.rst
@@ -34,7 +34,7 @@ sample and we're not going to use it.
Then, we added a ``Page`` class. Because this is a SQLAlchemy application,
this class inherits from an instance of
-:class:`sqlalchemy.ext.declarative.declarative_base`.
+:func:`sqlalchemy.ext.declarative.declarative_base`.
.. literalinclude:: src/models/tutorial/models.py
:pyobject: Page
@@ -45,9 +45,10 @@ As you can see, our ``Page`` class has a class level attribute
``__tablename__`` which equals the string ``'pages'``. This means that
SQLAlchemy will store our wiki data in a SQL table named ``pages``. Our
``Page`` class will also have class-level attributes named ``id``, ``name`` and
-``data`` (all instances of :class:`sqlalchemy.Column`). These will map to
-columns in the ``pages`` table. The ``id`` attribute will be the primary key
-in the table. The ``name`` attribute will be a text attribute, each value of
+``data`` (all instances of :class:`sqlalchemy.schema.Column`).
+These will map to columns in the ``pages`` table.
+The ``id`` attribute will be the primary key in the table.
+The ``name`` attribute will be a text attribute, each value of
which needs to be unique within the column. The ``data`` attribute is a text
attribute that will hold the body of each page.
@@ -77,8 +78,6 @@ following:
Installing the Project and re-initializing the Database
-------------------------------------------------------
-Redo the steps in :ref:`installing_project_in_dev_mode`.
-
Because our model has changed, in order to reinitialize the database, we need
to rerun the ``initialize_tutorial_db`` command to pick up the changes you've made
to both the models.py file and to the initializedb.py file.
diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst
index f2ac2f85f..a1e2313f3 100644
--- a/docs/tutorials/wiki2/definingviews.rst
+++ b/docs/tutorials/wiki2/definingviews.rst
@@ -6,16 +6,13 @@ A :term:`view callable` in a :app:`Pyramid` application is typically a simple
Python function that accepts a single parameter named :term:`request`. A
view callable is assumed to return a :term:`response` object.
-The request object passed to every view that is called as the result of a
-route match has an attribute named ``matchdict`` that contains the elements
-placed into the URL by the ``pattern`` of a ``route`` statement. For
-instance, if a call to :meth:`pyramid.config.Configurator.add_route` in
-``__init__.py`` had the pattern ``{one}/{two}``, and the URL at
-``http://example.com/foo/bar`` was invoked, matching this pattern, the
-``matchdict`` dictionary attached to the request passed to the view would
-have a ``'one'`` key with the value ``'foo'`` and a ``'two'`` key with the
-value ``'bar'``.
-
+The request object has a dictionary as an attribute named ``matchdict``. A
+``matchdict`` maps the placeholders in the matching URL ``pattern`` to the
+substrings of the path in the :term:`request` URL. For instance, if a call to
+:meth:`pyramid.config.Configurator.add_route` has the pattern ``/{one}/{two}``,
+and a user visits ``http://example.com/foo/bar``, our pattern would be matched
+against ``/foo/bar`` and the ``matchdict`` would look like: ``{'one':'foo',
+'two':'bar'}``
Declaring Dependencies in Our ``setup.py`` File
===============================================
@@ -148,14 +145,13 @@ As a result, the ``content`` variable is now a fully formed bit of HTML
containing various view and add links for WikiWords based on the content of
our current page object.
-We then generate an edit URL (because it's easier to do here than in the
-template), and we return a dictionary with a number of arguments. The fact
-that ``view_page()`` returns a dictionary (as opposed to a :term:`response`
-object) is a cue to :app:`Pyramid` that it should try to use a :term:`renderer`
-associated with the view configuration to render a template. In our case,
-the template which will be rendered will be the ``templates/view.pt``
-template, as indicated in the ``@view_config`` decorator that is applied to
-``view_page()``.
+We then generate an edit URL because it's easier to do here than in the
+template, and we return a dictionary with a number of arguments. The fact that
+``view_page()`` returns a dictionary (as opposed to a :term:`response` object)
+is a cue to :app:`Pyramid` that it should try to use a :term:`renderer`
+associated with the view configuration to render a response. In our case, the
+renderer used will be the ``templates/view.pt`` template, as indicated in the
+``@view_config`` decorator that is applied to ``view_page()``.
The ``add_page`` view function
------------------------------
@@ -350,20 +346,20 @@ We can finally examine our application in a browser (See
:ref:`wiki2-start-the-application`). Launch a browser and visit
each of the following URLs, check that the result is as expected:
-- ``http://localhost:6543`` in a browser invokes the
+- http://localhost:6543 in a browser invokes the
``view_wiki`` view. This always redirects to the ``view_page`` view
of the FrontPage page object.
-- ``http://localhost:6543/FrontPage`` in a browser invokes
+- http://localhost:6543/FrontPage in a browser invokes
the ``view_page`` view of the front page object.
-- ``http://localhost:6543/FrontPage/edit_page`` in a browser
+- http://localhost:6543/FrontPage/edit_page in a browser
invokes the edit view for the front page object.
-- ``http://localhost:6543/add_page/SomePageName`` in a
+- http://localhost:6543/add_page/SomePageName in a
browser invokes the add view for a page.
-- To generate an error, visit ``http://localhost:6543/foobars/edit_page`` which
+- To generate an error, visit http://localhost:6543/foobars/edit_page which
will generate a ``NoResultFound: No row was found for one()`` error.
You'll see an interactive traceback facility provided
by :term:`pyramid_debugtoolbar`.
diff --git a/docs/tutorials/wiki2/design.rst b/docs/tutorials/wiki2/design.rst
index c56d7fecf..df2c83398 100644
--- a/docs/tutorials/wiki2/design.rst
+++ b/docs/tutorials/wiki2/design.rst
@@ -100,7 +100,7 @@ listed in the following table:
| | with existing | | | |
| | content. | | | |
| | | | | |
-| | If the form was | | | |
+| | If the form is | | | |
| | submitted, redirect | | | |
| | to /PageName | | | |
+----------------------+-----------------------+-------------+------------+------------+
@@ -110,15 +110,15 @@ listed in the following table:
| | the edit form | | | |
| | without content. | | | |
| | | | | |
-| | If the form was | | | |
+| | If the form is | | | |
| | submitted, | | | |
| | redirect to | | | |
| | /PageName | | | |
+----------------------+-----------------------+-------------+------------+------------+
| /login | Display login form, | login | login.pt | |
-| | Forbidden [3]_ | | | |
+| | Forbidden [3]_ | | | |
| | | | | |
-| | If the form was | | | |
+| | If the form is | | | |
| | submitted, | | | |
| | authenticate. | | | |
| | | | | |
diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst
index 8c4149bfc..17788cdde 100644
--- a/docs/tutorials/wiki2/installation.rst
+++ b/docs/tutorials/wiki2/installation.rst
@@ -5,65 +5,139 @@ Installation
Before You Begin
================
-Installation Requirements
--------------------------
-
-Follow the steps in :ref:`installing_chapter`, but name the virtualenv
-directory ``pyramidtut``. Following these steps will ensure you have met the
-following requirements:
+This tutorial assumes that you have already followed the steps in
+:ref:`installing_chapter`, thereby satisfying the following
+requirements.
* Python interpreter is installed on your operating system
* :term:`setuptools` or :term:`distribute` is installed
* :term:`virtualenv` is installed
-* a virtual Python environment named ``pyramidtut`` has been created
-* Pyramid is installed
-UNIX Requirements
------------------
+Create and Use a Virtual Python Environment
+-------------------------------------------
+
+Next let's create a `virtualenv` workspace for our project. We will
+use the `VENV` environment variable instead of absolute path of the
+virtual environment.
+
+On UNIX
+^^^^^^^
-#. Install SQLite3 and its development packages if you don't already
- have them installed. Usually this is via your system's package
- manager. On a Debian system, this would be:
+.. code-block:: text
+
+ $ export VENV=~/pyramidtut
+ $ virtualenv --no-site-packages $VENV
+ New python executable in /home/foo/env/bin/python
+ Installing setuptools.............done.
- .. code-block:: text
+On Windows
+^^^^^^^^^^
- $ sudo apt-get install libsqlite3-dev
+Set the `VENV` environment variable.
-#. Switch to the ``pyramidtut`` directory:
+.. code-block:: text
+
+ c:\> set VENV=c:\pyramidtut
+
+Versions of Python use different paths, so you will need to adjust the
+path to the command for your Python version.
+
+Python 2.7:
+
+.. code-block:: text
- .. code-block:: text
+ c:\> c:\Python27\Scripts\virtualenv --no-site-packages %VENV%
- $ cd pyramidtut
+Python 3.2:
-Windows Requirements
---------------------
+.. code-block:: text
+
+ c:\> c:\Python32\Scripts\virtualenv --no-site-packages %VENV%
+
+Install Pyramid Into the Virtual Python Environment
+---------------------------------------------------
+
+On UNIX
+^^^^^^^
+
+.. code-block:: text
+
+ $ $VENV/bin/easy_install pyramid
+
+On Windows
+^^^^^^^^^^
+
+.. code-block:: text
-#. Switch to the ``pyramidtut`` directory:
+ c:\env> %VENV%\Scripts\easy_install pyramid
- .. code-block:: text
+Install SQLite3 and Its Development Packages
+--------------------------------------------
- c:\> cd pyramidtut
+If you used a package manager to install your Python or if you compiled
+your Python from source, then you must install SQLite3 and its
+development packages. If you downloaded your Python as an installer
+from python.org, then you already have it installed and can proceed to
+the next section :ref:`sql_making_a_project`..
+
+If you need to install the SQLite3 packages, then, for example, using
+the Debian system and apt-get, the command would be the following:
+
+.. code-block:: text
+
+ $ sudo apt-get install libsqlite3-dev
+
+Change Directory to Your Virtual Python Environment
+---------------------------------------------------
+
+Change directory to the ``pyramidtut`` directory.
+
+On UNIX
+^^^^^^^
+
+.. code-block:: text
+
+ $ cd pyramidtut
+
+On Windows
+^^^^^^^^^^
+
+.. code-block:: text
+
+ c:\> cd pyramidtut
.. _sql_making_a_project:
Making a Project
================
-Your next step is to create a project. For this tutorial, we will use the
-:term:`scaffold` named ``alchemy``, which generates an application
-that uses :term:`SQLAlchemy` and :term:`URL dispatch`. :app:`Pyramid`
-supplies a variety of scaffolds to generate sample projects.
+Your next step is to create a project. For this tutorial we will use
+the :term:`scaffold` named ``alchemy`` which generates an application
+that uses :term:`SQLAlchemy` and :term:`URL dispatch`.
+
+:app:`Pyramid` supplies a variety of scaffolds to generate sample
+projects. We will use `pcreate`—a script that comes with Pyramid to
+quickly and easily generate scaffolds usually with a single command—to
+create the scaffold for our project.
+
+By passing in `alchemy` into the `pcreate` command, the script creates
+the files needed to use SQLAlchemy. By passing in our application name
+`tutorial`, the script inserts that application name into all the
+required files. For example, `pcreate` creates the
+``initialize_tutorial_db`` in the ``pyramidtut/bin`` directory.
The below instructions assume your current working directory is the
"virtualenv" named "pyramidtut".
-On UNIX:
+On UNIX
+-------
.. code-block:: text
$ $VENV/bin/pcreate -s alchemy tutorial
-On Windows:
+On Windows
+----------
.. code-block:: text
@@ -75,18 +149,10 @@ On Windows:
startup problems, try putting both the virtualenv and the project
into directories that do not contain spaces in their paths.
-`pcreate` is a script that comes with Pyramid that helps by creating and organizing files
-needed as part of a Pyramid project. By passing in `alchemy`, we are asking the script to
-create the files needed to use SQLAlchemy. By passing in our app name `tutorial`, the script
-places that application name in all the different files required. For example, the ``initialize_tutorial_db``
-that is in the ``pyramidtut/bin`` directory was created by `pcreate`.
-
-
-
.. _installing_project_in_dev_mode:
-Installing the Project in "Development Mode"
-============================================
+Installing the Project in Development Mode
+==========================================
In order to do development on the project easily, you must "register"
the project as a development egg in your workspace using the
@@ -94,22 +160,25 @@ the project as a development egg in your workspace using the
directory you created in :ref:`sql_making_a_project`, and run the
``setup.py develop`` command using the virtualenv Python interpreter.
-On UNIX:
+On UNIX
+-------
.. code-block:: text
$ cd tutorial
$ $VENV/bin/python setup.py develop
-On Windows:
+On Windows
+----------
.. code-block:: text
c:\pyramidtut> cd tutorial
c:\pyramidtut\tutorial> %VENV%\Scripts\python setup.py develop
-Success executing this command will end with a line to the console something
-like::
+The console will show `setup.py` checking for packages and installing
+missing packages. Success executing this command will show a line like
+the following::
Finished processing dependencies for tutorial==0.0
@@ -121,13 +190,15 @@ Running the Tests
After you've installed the project in development mode, you may run
the tests for the project.
-On UNIX:
+On UNIX
+-------
.. code-block:: text
$ $VENV/bin/python setup.py test -q
-On Windows:
+On Windows
+----------
.. code-block:: text
@@ -153,13 +224,15 @@ tests.
To get this functionality working, we'll need to install the ``nose`` and
``coverage`` packages into our ``virtualenv``:
-On UNIX:
+On UNIX
+-------
.. code-block:: text
$ $VENV/bin/easy_install nose coverage
-On Windows:
+On Windows
+----------
.. code-block:: text
@@ -168,13 +241,15 @@ On Windows:
Once ``nose`` and ``coverage`` are installed, we can actually run the
coverage tests.
-On UNIX:
+On UNIX
+-------
.. code-block:: text
$ $VENV/bin/nosetests --cover-package=tutorial --cover-erase --with-coverage
-On Windows:
+On Windows
+----------
.. code-block:: text
@@ -212,13 +287,15 @@ script` to initialize our database.
Type the following command, make sure you are still in the ``tutorial``
directory (the directory with a ``development.ini`` in it):
-On UNIX:
+On UNIX
+-------
.. code-block:: text
$ $VENV/bin/initialize_tutorial_db development.ini
-On Windows:
+On Windows
+----------
.. code-block:: text
@@ -260,13 +337,15 @@ Starting the Application
Start the application.
-On UNIX:
+On UNIX
+-------
.. code-block:: text
$ $VENV/bin/pserve development.ini --reload
-On Windows:
+On Windows
+----------
.. code-block:: text
@@ -308,4 +387,3 @@ the following assumptions:
mechanism to map URLs to code (:term:`traversal`). However, for the
purposes of this tutorial, we'll only be using url dispatch and
SQLAlchemy.
-
diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt
index 15ea6614f..ee9fdb7fa 100644
--- a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt
@@ -69,8 +69,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer">&copy; Copyright 2008-2012, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt
index fbfa9870b..ee9fdb7fa 100644
--- a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt
@@ -69,8 +69,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer">&copy; Copyright 2008-2011, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/edit.pt b/docs/tutorials/wiki2/src/tests/tutorial/templates/edit.pt
index ca28b9fa5..2004273fe 100644
--- a/docs/tutorials/wiki2/src/tests/tutorial/templates/edit.pt
+++ b/docs/tutorials/wiki2/src/tests/tutorial/templates/edit.pt
@@ -54,9 +54,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer"
- >&copy; Copyright 2008-2011, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/login.pt b/docs/tutorials/wiki2/src/tests/tutorial/templates/login.pt
index 64e592ea9..5f8e9b98c 100644
--- a/docs/tutorials/wiki2/src/tests/tutorial/templates/login.pt
+++ b/docs/tutorials/wiki2/src/tests/tutorial/templates/login.pt
@@ -50,9 +50,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer"
- >&copy; Copyright 2008-2011, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt
index 14b88d16a..9c077568d 100644
--- a/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt
@@ -69,8 +69,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer">&copy; Copyright 2008-2011, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/view.pt b/docs/tutorials/wiki2/src/tests/tutorial/templates/view.pt
index 5a69818c1..19c50fb36 100644
--- a/docs/tutorials/wiki2/src/tests/tutorial/templates/view.pt
+++ b/docs/tutorials/wiki2/src/tests/tutorial/templates/view.pt
@@ -57,9 +57,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer"
- >&copy; Copyright 2008-2011, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt b/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt
index 3f2039cb6..5f962bbf5 100644
--- a/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt
+++ b/docs/tutorials/wiki2/src/views/tutorial/templates/edit.pt
@@ -50,9 +50,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer"
- >&copy; Copyright 2008-2011, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt
index fbfa9870b..ee9fdb7fa 100644
--- a/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt
@@ -69,8 +69,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer">&copy; Copyright 2008-2011, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt b/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt
index 423c1d5a1..78c0d2d4c 100644
--- a/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt
+++ b/docs/tutorials/wiki2/src/views/tutorial/templates/view.pt
@@ -53,9 +53,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer"
- >&copy; Copyright 2008-2011, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/docs/whatsnew-1.1.rst b/docs/whatsnew-1.1.rst
index f33fc94ba..5cba8dd3e 100644
--- a/docs/whatsnew-1.1.rst
+++ b/docs/whatsnew-1.1.rst
@@ -43,7 +43,7 @@ The major feature additions in Pyramid 1.1 are:
The object passed to a view callable as ``request`` is an instance of
:class:`pyramid.request.Request`. ``request.response`` is an instance of
- the class :class:`pyramid.request.Response`. View callables that are
+ the class :class:`pyramid.response.Response`. View callables that are
configured with a :term:`renderer` will return this response object to the
Pyramid router. Therefore, code in a renderer-using view callable can set
response attributes such as ``request.response.content_type`` (before they
@@ -95,7 +95,7 @@ Default HTTP Exception View
is passed for this value, an exception view for HTTP exceptions will not be
registered. Passing ``None`` returns the behavior of raising an HTTP
exception to that of Pyramid 1.0 (the exception will propagate to
- middleware and to the WSGI server).
+ :term:`middleware` and to the WSGI server).
``http_cache``
~~~~~~~~~~~~~~
@@ -289,7 +289,7 @@ Minor Feature Additions
when you want the static view to behave like the older deprecated version.
- A new api function :func:`pyramid.scripting.prepare` has been added. It is
- a lower-level analogue of :func:`pyramid.paster.boostrap` that accepts a
+ a lower-level analogue of :func:`pyramid.paster.bootstrap` that accepts a
request and a registry instead of a config file argument, and is used for
the same purpose:
@@ -313,7 +313,7 @@ Minor Feature Additions
- New API attribute :attr:`pyramid.config.global_registries` is an iterable
object that contains references to every Pyramid registry loaded into the
- current process via :meth:`pyramid.config.Configurator.make_app`. It also
+ current process via :meth:`pyramid.config.Configurator.make_wsgi_app`. It also
has a ``last`` attribute containing the last registry loaded. This is used
by the scripting machinery, and is available for introspection.
diff --git a/docs/whatsnew-1.2.rst b/docs/whatsnew-1.2.rst
index ea56cf52d..a9fc38908 100644
--- a/docs/whatsnew-1.2.rst
+++ b/docs/whatsnew-1.2.rst
@@ -31,11 +31,11 @@ Tweens
~~~~~~
A :term:`tween` is used to wrap the Pyramid router's primary request handling
-function. This is a feature that can be used by Pyramid framework
-extensions, to provide, for example, view timing support and can provide a
-convenient place to hang bookkeeping code. Tweens are is a little like
-:term:`WSGI` middleware, but have access to Pyramid functionality such as
-renderers and a full-featured request object.
+function. This is a feature that can be used by Pyramid framework extensions,
+to provide, for example, view timing support and can provide a convenient
+place to hang bookkeeping code. Tweens are a little like :term:`WSGI`
+:term:`middleware`, but have access to Pyramid functionality such as renderers
+and a full-featured request object.
To support this feature, a new configurator directive exists named
:meth:`pyramid.config.Configurator.add_tween`. This directive adds a
@@ -51,7 +51,7 @@ Scaffolding Changes
~~~~~~~~~~~~~~~~~~~
- All scaffolds now use the ``pyramid_tm`` package rather than the
- ``repoze.tm2`` middleware to manage transaction management.
+ ``repoze.tm2`` :term:`middleware` to manage transaction management.
- The ZODB scaffold now uses the ``pyramid_zodbconn`` package rather than the
``repoze.zodbconn`` package to provide ZODB integration.
@@ -59,9 +59,9 @@ Scaffolding Changes
- All scaffolds now use the ``pyramid_debugtoolbar`` package rather than the
``WebError`` package to provide interactive debugging features.
-- Projects created via a scaffold no longer depend on the ``WebError``
- package at all; configuration in the ``production.ini`` file which used to
- require its ``error_catcher`` middleware has been removed. Configuring
+- Projects created via a scaffold no longer depend on the ``WebError`` package
+ at all; configuration in the ``production.ini`` file which used to require
+ its ``error_catcher`` :term:`middleware` has been removed. Configuring
error catching / email sending is now the domain of the ``pyramid_exclog``
package (see http://docs.pylonsproject.org/projects/pyramid_exclog/dev/).
@@ -160,7 +160,7 @@ Minor Feature Additions
a value of ``edit``.
- Support an ``onerror`` keyword argument to
- :meth:`pyramid.config.Configurator.scan``. This argument is passed to
+ :meth:`pyramid.config.Configurator.scan`. This argument is passed to
:meth:`venusian.Scanner.scan` to influence error behavior when an exception
is raised during scanning.
diff --git a/docs/whatsnew-1.3.rst b/docs/whatsnew-1.3.rst
index ef0256383..2606c3df3 100644
--- a/docs/whatsnew-1.3.rst
+++ b/docs/whatsnew-1.3.rst
@@ -210,13 +210,13 @@ Not Found and Forbidden View Helpers
Not Found helpers:
- New API: :meth:`pyramid.config.Configurator.add_notfound_view`. This is a
- wrapper for :meth:`pyramid.Config.configurator.add_view` which provides
+ wrapper for :meth:`pyramid.config.Configurator.add_view` which provides
support for an "append_slash" feature as well as doing the right thing when
it comes to permissions (a Not Found View should always be public). It
should be preferred over calling ``add_view`` directly with
``context=HTTPNotFound`` as was previously recommended.
-- New API: :class:`pyramid.view.notfound_view_config``. This is a decorator
+- New API: :class:`pyramid.view.notfound_view_config`. This is a decorator
constructor like :class:`pyramid.view.view_config` that calls
:meth:`pyramid.config.Configurator.add_notfound_view` when scanned. It
should be preferred over using ``pyramid.view.view_config`` with
@@ -225,7 +225,7 @@ Not Found helpers:
Forbidden helpers:
- New API: :meth:`pyramid.config.Configurator.add_forbidden_view`. This is a
- wrapper for :meth:`pyramid.Config.configurator.add_view` which does the
+ wrapper for :meth:`pyramid.config.Configurator.add_view` which does the
right thing about permissions. It should be preferred over calling
``add_view`` directly with ``context=HTTPForbidden`` as was previously
recommended.
@@ -267,7 +267,7 @@ Minor Feature Additions
- We allow extra keyword arguments to be passed to the
:meth:`pyramid.config.Configurator.action` method.
-- Responses generated by Pyramid's :class:`pyramid.views.static_view` now use
+- Responses generated by Pyramid's :class:`pyramid.static.static_view` now use
a ``wsgi.file_wrapper`` (see
http://www.python.org/dev/peps/pep-0333/#optional-platform-specific-file-handling)
when one is provided by the web server.
@@ -389,8 +389,8 @@ Backwards Incompatibilities
and upgrade Pyramid itself "in-place"; it may simply break instead
(particularly if you use ZCML's ``includeOverrides`` directive).
-- String values passed to :meth:`Pyramid.request.Request.route_url` or
- :meth:`Pyramid.request.Request.route_path` that are meant to replace
+- String values passed to :meth:`pyramid.request.Request.route_url` or
+ :meth:`pyramid.request.Request.route_path` that are meant to replace
"remainder" matches will now be URL-quoted except for embedded slashes. For
example::
diff --git a/docs/whatsnew-1.4.rst b/docs/whatsnew-1.4.rst
index f725615f3..505b9d798 100644
--- a/docs/whatsnew-1.4.rst
+++ b/docs/whatsnew-1.4.rst
@@ -184,11 +184,12 @@ Minor Feature Additions
returns the policy object it creates.
- The DummySecurityPolicy created by
- :meth:`pyramid.config.testing_securitypolicy` now sets a ``forgotten`` value
- on the policy (the value ``True``) when its ``forget`` method is called.
+ :meth:`pyramid.config.Configurator.testing_securitypolicy` now sets a
+ ``forgotten`` value on the policy (the value ``True``) when its ``forget``
+ method is called.
- The DummySecurityPolicy created by
- :meth:`pyramid.config.testing_securitypolicy` now sets a
+ :meth:`pyramid.config.Configurator.testing_securitypolicy` now sets a
``remembered`` value on the policy, which is the value of the ``principal``
argument it's called with when its ``remember`` method is called.
@@ -301,7 +302,7 @@ Backwards Incompatibilities
:meth:`pyramid.config.Configurator.testing_add_subscriber` instead.
* ``registerTemplateRenderer`` (aka ``registerDummyRenderer``), use
- :meth:`pyramid.config.Configurator.testing_add_template` instead.
+ :meth:`pyramid.config.Configurator.testing_add_renderer` instead.
* ``registerView``, use :meth:`pyramid.config.Configurator.add_view` instead.
diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py
index e1320a55f..4f7899b54 100644
--- a/pyramid/config/__init__.py
+++ b/pyramid/config/__init__.py
@@ -864,14 +864,14 @@ class Configurator(
This pushes a dictionary containing the :term:`application
registry` implied by ``registry`` attribute of this
configurator and the :term:`request` implied by the
- ``request`` argument on to the :term:`thread local` stack
+ ``request`` argument onto the :term:`thread local` stack
consulted by various :mod:`pyramid.threadlocal` API
functions."""
self.manager.push({'registry':self.registry, 'request':request})
def end(self):
""" Indicate that application or test configuration has ended.
- This pops the last value pushed on to the :term:`thread local`
+ This pops the last value pushed onto the :term:`thread local`
stack (usually by the ``begin`` method) and returns that
value.
"""
@@ -963,7 +963,7 @@ class Configurator(
# registry configured.
global_registries.add(self.registry)
- # Push the registry on to the stack in case any code that depends on
+ # Push the registry onto the stack in case any code that depends on
# the registry threadlocal APIs used in listeners subscribed to the
# IApplicationCreated event.
self.manager.push({'registry':self.registry, 'request':None})
diff --git a/pyramid/config/views.py b/pyramid/config/views.py
index 1c7620e67..707c84043 100644
--- a/pyramid/config/views.py
+++ b/pyramid/config/views.py
@@ -257,7 +257,9 @@ class ViewDeriver(object):
view_name = getattr(request, 'view_name', None)
if self.authn_policy and self.authz_policy:
- if permission is None:
+ if permission is NO_PERMISSION_REQUIRED:
+ msg = 'Allowed (NO_PERMISSION_REQUIRED)'
+ elif permission is None:
msg = 'Allowed (no permission registered)'
else:
principals = self.authn_policy.effective_principals(
diff --git a/pyramid/decorator.py b/pyramid/decorator.py
index 82d2b1280..e5f2996dc 100644
--- a/pyramid/decorator.py
+++ b/pyramid/decorator.py
@@ -15,16 +15,14 @@ class reify(object):
And usage of Foo:
- .. code-block:: text
-
- >>> f = Foo()
- >>> v = f.jammy
- 'jammy called'
- >>> print v
- 1
- >>> f.jammy
- 1
- >>> # jammy func not called the second time; it replaced itself with 1
+ >>> f = Foo()
+ >>> v = f.jammy
+ 'jammy called'
+ >>> print v
+ 1
+ >>> f.jammy
+ 1
+ >>> # jammy func not called the second time; it replaced itself with 1
"""
def __init__(self, wrapped):
self.wrapped = wrapped
diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py
index f2627c1fc..061bcb717 100644
--- a/pyramid/mako_templating.py
+++ b/pyramid/mako_templating.py
@@ -82,7 +82,6 @@ class PkgResourceTemplateLookup(TemplateLookup):
"Can not locate template for uri %r" % uri)
return TemplateLookup.get_template(self, uri)
-
registry_lock = threading.Lock()
class MakoRendererFactoryHelper(object):
@@ -90,14 +89,11 @@ class MakoRendererFactoryHelper(object):
self.settings_prefix = settings_prefix
def __call__(self, info):
- p = re.compile(
- r'(?P<asset>[\w_.:/-]+)'
- r'(?:\#(?P<defname>[\w_]+))?'
- r'(\.(?P<ext>.*))'
- )
- asset, defname, ext = p.match(info.name).group(
- 'asset', 'defname', 'ext'
- )
+ defname = None
+ asset, ext = info.name.rsplit('.', 1)
+ if '#' in asset:
+ asset, defname = asset.rsplit('#', 1)
+
path = '%s.%s' % (asset, ext)
registry = info.registry
settings = info.settings
diff --git a/pyramid/paster.py b/pyramid/paster.py
index ce07d1fe0..967543849 100644
--- a/pyramid/paster.py
+++ b/pyramid/paster.py
@@ -23,26 +23,34 @@ def get_app(config_uri, name=None, options=None, loadapp=loadapp):
path, section = _getpathsec(config_uri, name)
config_name = 'config:%s' % path
here_dir = os.getcwd()
- if options:
- kw = {'global_conf': options}
- else:
- kw = {}
- app = loadapp(config_name, name=section, relative_to=here_dir, **kw)
+ app = loadapp(
+ config_name,
+ name=section,
+ relative_to=here_dir,
+ global_conf=options)
return app
-def get_appsettings(config_uri, name=None, appconfig=appconfig):
+def get_appsettings(config_uri, name=None, options=None, appconfig=appconfig):
""" Return a dictionary representing the key/value pairs in an ``app``
section within the file represented by ``config_uri``.
+ ``options``, if passed, should be a dictionary used as variable assignments
+ like ``{'http_port': 8080}``. This is useful if e.g. ``%(http_port)s`` is
+ used in the config file.
+
If the ``name`` is None, this will attempt to parse the name from
the ``config_uri`` string expecting the format ``inifile#name``.
If no name is found, the name will default to "main"."""
path, section = _getpathsec(config_uri, name)
config_name = 'config:%s' % path
here_dir = os.getcwd()
- return appconfig(config_name, name=section, relative_to=here_dir)
+ return appconfig(
+ config_name,
+ name=section,
+ relative_to=here_dir,
+ global_conf=options)
def setup_logging(config_uri, fileConfig=fileConfig,
configparser=configparser):
diff --git a/pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py b/pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py
index 66feb3008..7dfdece15 100644
--- a/pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py
+++ b/pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py
@@ -9,6 +9,8 @@ from pyramid.paster import (
setup_logging,
)
+from pyramid.scripts.common import parse_vars
+
from ..models import (
DBSession,
MyModel,
@@ -18,17 +20,18 @@ from ..models import (
def usage(argv):
cmd = os.path.basename(argv[0])
- print('usage: %s <config_uri>\n'
+ print('usage: %s <config_uri> [var=value]\n'
'(example: "%s development.ini")' % (cmd, cmd))
sys.exit(1)
def main(argv=sys.argv):
- if len(argv) != 2:
+ if len(argv) < 2:
usage(argv)
config_uri = argv[1]
+ options = parse_vars(argv[2:])
setup_logging(config_uri)
- settings = get_appsettings(config_uri)
+ settings = get_appsettings(config_uri, options=options)
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
Base.metadata.create_all(engine)
diff --git a/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl b/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl
index 99606fe0e..99b3fe31c 100644
--- a/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl
+++ b/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl
@@ -69,8 +69,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer">&copy; Copyright 2008-2012, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl b/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl
index 4a71dd992..34706ec2f 100644
--- a/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl
+++ b/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl
@@ -69,8 +69,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer">&copy; Copyright 2008-2012, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt
index 5391509fe..200dac6d0 100644
--- a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt
+++ b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt
@@ -69,8 +69,5 @@
</div>
</div>
</div>
- <div id="footer">
- <div class="footer">&copy; Copyright 2008-2012, Agendaless Consulting.</div>
- </div>
</body>
</html>
diff --git a/pyramid/tests/fixtures/dummy.ini b/pyramid/tests/fixtures/dummy.ini
new file mode 100644
index 000000000..bc2281168
--- /dev/null
+++ b/pyramid/tests/fixtures/dummy.ini
@@ -0,0 +1,4 @@
+[app:myapp]
+use = call:pyramid.tests.test_paster:make_dummyapp
+
+foo = %(bar)s
diff --git a/pyramid/tests/fixtures/hello .world.mako b/pyramid/tests/fixtures/hello .world.mako
new file mode 100644
index 000000000..7a06eed97
--- /dev/null
+++ b/pyramid/tests/fixtures/hello .world.mako
@@ -0,0 +1,3 @@
+## -*- coding: utf-8 -*-
+<%!from pyramid.compat import text_%><% a, b = 'foo', text_('föö', 'utf-8') %>
+Hello ${text_('föö', 'utf-8')} \ No newline at end of file
diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py
index 5388001f6..94bc497ba 100644
--- a/pyramid/tests/test_config/test_views.py
+++ b/pyramid/tests/test_config/test_views.py
@@ -2791,7 +2791,8 @@ class TestViewDeriver(unittest.TestCase):
self.assertEqual(len(logger.messages), 1)
self.assertEqual(logger.messages[0],
"debug_authorization of url url (view name "
- "'view_name' against context None): False")
+ "'view_name' against context None): "
+ "Allowed (NO_PERMISSION_REQUIRED)")
def test_secured_view_authn_policy_no_authz_policy(self):
response = DummyResponse()
diff --git a/pyramid/tests/test_mako_templating.py b/pyramid/tests/test_mako_templating.py
index 37264aa48..50ef360d9 100644
--- a/pyramid/tests/test_mako_templating.py
+++ b/pyramid/tests/test_mako_templating.py
@@ -270,6 +270,34 @@ class Test_renderer_factory(Base, unittest.TestCase):
self.assertEqual(renderer.lookup, lookup)
self.assertEqual(renderer.path, 'helloworld.mak')
+ def test_space_dot_name(self):
+ from pyramid.mako_templating import renderer_factory
+
+ info = DummyRendererInfo({
+ 'name':'hello .world.mako',
+ 'package':None,
+ 'registry':self.config.registry,
+ 'settings':{},
+ })
+
+ result = renderer_factory(info)
+ self.assertEqual(result.path, 'hello .world.mako')
+ self.assertTrue(result.defname is None)
+
+ def test_space_dot_name_def(self):
+ from pyramid.mako_templating import renderer_factory
+
+ info = DummyRendererInfo({
+ 'name':'hello .world#comp.mako',
+ 'package':None,
+ 'registry':self.config.registry,
+ 'settings':{},
+ })
+
+ result = renderer_factory(info)
+ self.assertEqual(result.path, 'hello .world.mako')
+ self.assertEqual(result.defname, 'comp')
+
class MakoRendererFactoryHelperTests(Base, unittest.TestCase):
def _getTargetClass(self):
from pyramid.mako_templating import MakoRendererFactoryHelper
diff --git a/pyramid/tests/test_paster.py b/pyramid/tests/test_paster.py
index b72e0e6b6..5e341172c 100644
--- a/pyramid/tests/test_paster.py
+++ b/pyramid/tests/test_paster.py
@@ -1,12 +1,12 @@
import os
import unittest
+here = os.path.dirname(__file__)
+
class Test_get_app(unittest.TestCase):
- def _callFUT(self, config_file, section_name, options=None, loadapp=None):
+ def _callFUT(self, config_file, section_name, **kw):
from pyramid.paster import get_app
- return get_app(
- config_file, section_name, options=options, loadapp=loadapp
- )
+ return get_app(config_file, section_name, **kw)
def test_it(self):
app = DummyApp()
@@ -55,15 +55,23 @@ class Test_get_app(unittest.TestCase):
self.assertEqual(loadapp.kw, {'global_conf':options})
self.assertEqual(result, app)
+ def test_it_with_dummyapp_requiring_options(self):
+ options = {'bar': 'baz'}
+ app = self._callFUT(
+ os.path.join(here, 'fixtures', 'dummy.ini'),
+ 'myapp', options=options)
+ self.assertEqual(app.settings['foo'], 'baz')
+
class Test_get_appsettings(unittest.TestCase):
- def _callFUT(self, config_file, section_name, appconfig):
+ def _callFUT(self, config_file, section_name, **kw):
from pyramid.paster import get_appsettings
- return get_appsettings(config_file, section_name, appconfig)
+ return get_appsettings(config_file, section_name, **kw)
def test_it(self):
values = {'a':1}
appconfig = DummyLoadWSGI(values)
- result = self._callFUT('/foo/bar/myapp.ini', 'myapp', appconfig)
+ result = self._callFUT('/foo/bar/myapp.ini', 'myapp',
+ appconfig=appconfig)
self.assertEqual(appconfig.config_name, 'config:/foo/bar/myapp.ini')
self.assertEqual(appconfig.section_name, 'myapp')
self.assertEqual(appconfig.relative_to, os.getcwd())
@@ -72,7 +80,8 @@ class Test_get_appsettings(unittest.TestCase):
def test_it_with_hash(self):
values = {'a':1}
appconfig = DummyLoadWSGI(values)
- result = self._callFUT('/foo/bar/myapp.ini#myapp', None, appconfig)
+ result = self._callFUT('/foo/bar/myapp.ini#myapp', None,
+ appconfig=appconfig)
self.assertEqual(appconfig.config_name, 'config:/foo/bar/myapp.ini')
self.assertEqual(appconfig.section_name, 'myapp')
self.assertEqual(appconfig.relative_to, os.getcwd())
@@ -81,12 +90,20 @@ class Test_get_appsettings(unittest.TestCase):
def test_it_with_hash_and_name_override(self):
values = {'a':1}
appconfig = DummyLoadWSGI(values)
- result = self._callFUT('/foo/bar/myapp.ini#myapp', 'yourapp', appconfig)
+ result = self._callFUT('/foo/bar/myapp.ini#myapp', 'yourapp',
+ appconfig=appconfig)
self.assertEqual(appconfig.config_name, 'config:/foo/bar/myapp.ini')
self.assertEqual(appconfig.section_name, 'yourapp')
self.assertEqual(appconfig.relative_to, os.getcwd())
self.assertEqual(result, values)
+ def test_it_with_dummyapp_requiring_options(self):
+ options = {'bar': 'baz'}
+ result = self._callFUT(
+ os.path.join(here, 'fixtures', 'dummy.ini'),
+ 'myapp', options=options)
+ self.assertEqual(result['foo'], 'baz')
+
class Test_setup_logging(unittest.TestCase):
def _callFUT(self, config_file):
from pyramid.paster import setup_logging
@@ -165,6 +182,12 @@ class DummyApp:
def __init__(self):
self.registry = dummy_registry
+def make_dummyapp(global_conf, **settings):
+ app = DummyApp()
+ app.settings = settings
+ app.global_conf = global_conf
+ return app
+
class DummyRequest:
application_url = 'http://example.com:5432'
script_name = ''
@@ -181,6 +204,3 @@ class DummyConfigParser(object):
class DummyConfigParserModule(object):
ConfigParser = DummyConfigParser
-
-
-
diff --git a/pyramid/util.py b/pyramid/util.py
index 56049af87..02bd7ba2a 100644
--- a/pyramid/util.py
+++ b/pyramid/util.py
@@ -234,18 +234,15 @@ def object_description(object):
""" Produce a human-consumable text description of ``object``,
usually involving a Python dotted name. For example:
- .. code-block:: python
-
- >>> object_description(None)
- u'None'
- >>> from xml.dom import minidom
- >>> object_description(minidom)
- u'module xml.dom.minidom'
- >>> object_description(minidom.Attr)
- u'class xml.dom.minidom.Attr'
- >>> object_description(minidom.Attr.appendChild)
- u'method appendChild of class xml.dom.minidom.Attr'
- >>>
+ >>> object_description(None)
+ u'None'
+ >>> from xml.dom import minidom
+ >>> object_description(minidom)
+ u'module xml.dom.minidom'
+ >>> object_description(minidom.Attr)
+ u'class xml.dom.minidom.Attr'
+ >>> object_description(minidom.Attr.appendChild)
+ u'method appendChild of class xml.dom.minidom.Attr'
If this method cannot identify the type of the object, a generic
description ala ``object <object.__name__>`` will be returned.
diff --git a/setup.py b/setup.py
index e37c348a2..4a3cecd98 100644
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2008-2011 Agendaless Consulting and Contributors.
+# Copyright (c) 2008-2013 Agendaless Consulting and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the BSD-like license at