summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-12-09 00:34:50 +0000
committerChris McDonough <chrism@agendaless.com>2009-12-09 00:34:50 +0000
commit8b1f6e5ed3f9fc32b5eb03257d24eaf754a797a9 (patch)
treeb0525c11e88c5adf6c233c09d7e9318429d54265
parentf46de3bb0a9d2c9823aa3221fd28d80aed65b719 (diff)
downloadpyramid-8b1f6e5ed3f9fc32b5eb03257d24eaf754a797a9.tar.gz
pyramid-8b1f6e5ed3f9fc32b5eb03257d24eaf754a797a9.tar.bz2
pyramid-8b1f6e5ed3f9fc32b5eb03257d24eaf754a797a9.zip
- General documentation freshening which takes imperative
configuration into account in more places and uses glossary references more liberally.
-rw-r--r--CHANGES.txt10
-rw-r--r--docs/glossary.rst188
-rw-r--r--docs/narr/configuration.rst39
-rw-r--r--docs/narr/templates.rst19
-rw-r--r--docs/tutorials/gae/index.rst2
-rw-r--r--repoze/bfg/authentication.py10
-rw-r--r--repoze/bfg/authorization.py28
-rw-r--r--repoze/bfg/configuration.py284
-rw-r--r--repoze/bfg/events.py44
-rw-r--r--repoze/bfg/interfaces.py36
-rw-r--r--repoze/bfg/location.py28
-rw-r--r--repoze/bfg/path.py1
-rw-r--r--repoze/bfg/request.py6
-rw-r--r--repoze/bfg/router.py10
-rw-r--r--repoze/bfg/scripting.py5
-rw-r--r--repoze/bfg/security.py51
-rw-r--r--repoze/bfg/testing.py132
-rw-r--r--repoze/bfg/traversal.py155
-rw-r--r--repoze/bfg/url.py54
-rw-r--r--repoze/bfg/view.py196
-rw-r--r--repoze/bfg/wsgi.py20
21 files changed, 693 insertions, 625 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 885c5e8b1..0ae688938 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,13 @@
+Next release
+============
+
+Documentation
+-------------
+
+- General documentation freshening which takes imperative
+ configuration into account in more places and uses glossary
+ references more liberally.
+
1.2a4 (2009-12-07)
==================
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 79b780092..aa7847879 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -10,11 +10,12 @@ Glossary
A ``WebOb`` request object. See :ref:`webob_chapter` for
information about request objects.
Response
- An object that has three attributes: app_iter (representing an
- iterable body), headerlist (representing the http headers sent
- upstream), and status (representing the http status string). This
- is the interface defined for ``WebOb`` response objects. See
- :ref:`webob_chapter` for information about response objects.
+ An object that has three attributes: ``app_iter`` (representing an
+ iterable body), ``headerlist`` (representing the http headers sent
+ to the user agent), and ``status`` (representing the http status
+ string sent to the user agent). This is the interface defined for
+ ``WebOb`` response objects. See :ref:`webob_chapter` for
+ information about response objects.
Repoze
"Repoze" is essentially a "brand" of software developed by
`Agendaless Consulting <http://agendaless.com>`_ and a set of
@@ -37,11 +38,12 @@ Glossary
Any file contained within a Python :term:`package` which is *not*
a Python source code file.
Resource Specification
- A colon-delimited identifier for a resource. The colon separates
- a Python :term:`package` name from a package subpath. For
- example, the resource specification ``my.package:static/baz.css``
- identifies the file named ``baz.css`` in the ``static``
- subdirectory of the ``my.package`` Python package.
+ A colon-delimited identifier for a :term:`resource`. The colon
+ separates a Python :term:`package` name from a package subpath.
+ For example, the resource specification
+ ``my.package:static/baz.css`` identifies the file named
+ ``baz.css`` in the ``static`` subdirectory of the ``my.package``
+ Python :term:`package`.
Package
A directory on disk which contains an ``__init__.py`` file, making
it recognizable to Python as a location which can be ``import`` -ed.
@@ -85,10 +87,10 @@ Glossary
configuration information. This configuration information helps
map the view callable to URLs and can influence the response of a
view callable. :mod:`repoze.bfg` views can be configured via
- :term:`ZCML` or by a special ``@bfg_view`` decorator (see
- :ref:`mapping_views_to_urls_using_a_decorator_section`.). See
+ :term:`imperative configuration`, :term:`ZCML` or by a special
+ ``@bfg_view`` decorator coupled with a :term:`scan`. See
:ref:`views_chapter` for more information about view
- configuration.
+ configuration.
View name
The "URL name" of a view, e.g ``index.html``. If a view is
configured without a name, its name is considered to be the empty
@@ -108,9 +110,10 @@ Glossary
used, a model is a node in the object graph traversed by the
system. When traversal is used, a model instance becomes the
:term:`context` of a :term:`view`. If :mod:`url dispatch` is
- used, a single :term:`context` (which isn't really a model,
- because it contains no data except security elements) is generated
- for each request and is used as the context of a view.
+ used, a single :term:`context` is generated for each request and
+ is used as the context of a view: this object is also technically
+ a "model" in :mod:`repoze.bfg` terms, although this terminology
+ can be a bit confusing: see :ref:`model_traversal_confusion`.
Traversal
The act of descending "down" a graph of model objects from a root
model in order to find a :term:`context`. The :mod:`repoze.bfg`
@@ -129,15 +132,15 @@ Glossary
URL dispatch
An alternative to graph traversal as a mechanism for locating a
:term:`context` for a :term:`view`. When you use a :term:`route`
- in your :mod:`repoze.bfg` application via a ``<route>``
- :term:`ZCML declaration` in ZCML, you are using URL dispatch. See the
+ in your :mod:`repoze.bfg` application via a :term:`route
+ configuration`, you are using URL dispatch. See the
:ref:`urldispatch_chapter` for more information.
Context
An object in the system that is found during :term:`traversal` or
:term:`URL dispatch` based on URL data; if it's found via
traversal, it's usually a :term:`model` object that is part of an
object graph; if it's found via :term:`URL dispatch`, it's a
- object manufacture on behalf of the route's "factory". A context
+ object manufactured on behalf of the route's "factory". A context
becomes the subject of a :term:`view`, and typically has security
information attached to it. See the :ref:`traversal_chapter`
chapter and the :ref:`urldispatch_chapter` chapter for more
@@ -187,9 +190,7 @@ Glossary
given the :term:`authentication` information in the request.
Authentication
The act of determining that the credentials a user presents during
- a particular request are "good". :mod:`repoze.bfg` does not
- perfom authentication: it leaves it up to an upstream component
- such as :term:`repoze.who`. :mod:`repoze.bfg` uses the
+ a particular request are "good". :mod:`repoze.bfg` uses the
:term:`authentication` data supplied by the upstream component as
one input during :term:`authorization`. Authentication in
:mod:`repoze.bfg` is performed via an :term:`authentication
@@ -203,13 +204,12 @@ Glossary
its :term:`authorization policy`.
Principal
A *principal* is a string or unicode object representing a user or
- a user's membership in a group. It is provided by the
- :term:`authentication` machinery "upstream", typically (such as
- :term:`repoze.who`). For example, if a user had the user id
- "bob", and Bob was part of two groups named "group foo" and "group
- bar", the request might have information attached to it that would
- indictate that Bob was represented by three principals: "bob",
- "group foo" and "group bar".
+ a user's membership in a group. It is provided by an
+ :term:`authentication policy`. For example, if a user had the
+ user id "bob", and Bob was part of two groups named "group foo"
+ and "group bar", the request might have information attached to it
+ that would indictate that Bob was represented by three principals:
+ "bob", "group foo" and "group bar".
Authorization Policy
An authorization policy in :mod:`repoze.bfg` terms is a bit of
code which has an API which determines whether or not the
@@ -274,15 +274,7 @@ Glossary
the ability to use bracketed (Genshi-style) ``${name}`` syntax,
even within ZPT. It is also much faster than the reference
implementations of both ZPT and Genshi. :mod:`repoze.bfg` offers
- Chameleon templating out of the box in ZPT flavor and offers the
- Genshi flavor as an add on within the
- :mod:`repoze.bfg.chameleon_genshi` package.
- chameleon.zpt
- ``chameleon.zpt`` is the package which provides :term:`ZPT`
- templating support under the :term:`Chameleon` templating engine.
- z3c.pt
- This was the previous name for :term:`Chameleon`, and is now a
- Zope 3 compatibility package for Chameleon.
+ Chameleon templating out of the box in ZPT and text flavors.
ZPT
The `Zope Page Template <http://wiki.zope.org/ZPT/FrontPage>`_
templating language.
@@ -307,11 +299,12 @@ Glossary
which generally resolves to a :term:`root factory` (and then
ultimately a :term:`view`). See also :term:`url dispatch`.
Route Configuration
- Route configuration is the act of using a :term:`ZCML` ``<route>``
- statement to associate request parameters with a particular
- :term:`route` using pattern matching and :term:`route predicate`
- statements. See :ref:`urldispatch_chapter` for more information
- about route configuration.
+ Route configuration is the act of using :term:`imperative
+ configuration` or a :term:`ZCML` ``<route>`` statement to
+ associate request parameters with a particular :term:`route` using
+ pattern matching and :term:`route predicate` statements. See
+ :ref:`urldispatch_chapter` for more information about route
+ configuration.
ZCML
`Zope Configuration Markup Language
<http://www.muthukadan.net/docs/zca.html#zcml>`_, an XML dialect
@@ -320,8 +313,8 @@ Glossary
declaration`, but its primary purpose in :mod:`repoze.bfg` is to
perform :term:`view configuration` and :term:`route configuration`
within the ``configure.zcml`` file in a :mod:`repoze.bfg`
- application. ZCML in a :mod:`repoze.bfg` application represents
- the application's :term:`application registry`.
+ application. You can use ZCML as an alternative to
+ :term:`imperative configuration`.
ZCML Directive
A ZCML "tag" such as ``<view>`` or ``<route>``.
ZCML Declaration
@@ -351,51 +344,42 @@ Glossary
subpath. See :ref:`star_subpath` for more information.
Interface
A `Zope interface <http://pypi.python.org/pypi/zope.interface>`_
- object. In :mod:`repoze.bfg`, an interface may be attached to an
- model object or a request object in order to identify that the
- object is "of a type". Interfaces are used internally by
- :mod:`repoze.bfg` to perform view lookups and other policy
- lookups. Interfaces are exposed to application programmers by the
- ``view`` ZCML directive or the corresponding ``bfg_view``
- decorator in the form of both the ``for`` attribute and the
- ``request_type`` attribute. They may be exposed to application
- developers when using the :term:`event` system as
- well. Fundamentally, :mod:`repoze.bfg` programmers can think of an
- interface as something that they can attach to an object that
- stamps it with a "type" unrelated to its underlying Python type.
- Interfaces can also be used to describe the behavior of an object
- (its methods and attributes), but unless they choose to,
- :mod:`repoze.bfg` programmers do not need to understand or use
+ object. In :mod:`repoze.bfg`, an interface may be attached to a
+ :term:`model` object or a :term:`request` object in order to
+ identify that the object is "of a type". Interfaces are used
+ internally by :mod:`repoze.bfg` to perform view lookups and other
+ policy lookups. The ability to make use of an interface is
+ exposed to an application programmers during :term:`view
+ configuration` via the ``for`` argument, the ``request_type``
+ argument and the ``containment`` argument. Interfaces are also
+ exposed to application developers when they make use of the
+ :term:`event` system. Fundamentally, :mod:`repoze.bfg` programmers
+ can think of an interface as something that they can attach to an
+ object that stamps it with a "type" unrelated to its underlying
+ Python type. Interfaces can also be used to describe the behavior
+ of an object (its methods and attributes), but unless they choose
+ to, :mod:`repoze.bfg` programmers do not need to understand or use
this feature of interfaces.
Event
An object broadcast to zero or more :term:`subscriber` callables
- during normal system operations. :mod:`repoze.bfg` emits events
- during its lifetime routine. Application code can subscribe to
+ during normal :mod:`repoze.bfg` system operations during the
+ lifetime of an application. Application code can subscribe to
these events by using the subscriber functionality described in
- :ref:`events_chapter`. Application code can also generate its own
- events using the ``zope.component.event.dispatch`` function.
- Application-code generated events may be subscribed to in the same
- way as system-generated events.
+ :ref:`events_chapter`.
Subscriber
A callable which receives an :term:`event`. A callable becomes a
- subscriber through an application registry registration. See
- :ref:`events_chapter` for more information.
+ subscriber via :term:`imperative configuration` or the
+ ``<subscriber>`` ZCML directive. See :ref:`events_chapter` for
+ more information.
Request type
An attribute of a :term:`request` that allows for specialization
- of view code based on arbitrary categorization. The every
+ of view invocation based on arbitrary categorization. The every
:term:`request` object that bfg generates and manipulates has one
or more :term:`interface` objects attached to it. The default
interface attached to a request object is
- ``repoze.bfg.interfaces.IRequest``. When a user writes view code,
- and registers a view without specifying a particular request type,
- the view is assumed to be registered for requests that have
- ``repoze.bfg.interfaces.IRequest`` attached to them. However if
- the view is registered with a different interface as its request
- type, the view will be invoked only when the request possesses
- that particular interface. Application code can cause requests to
- possess a different interface by adding the interface to the
- request object within a :term:`subscriber` to the
- ``repoze.bfg.interfaces.INewRequest`` event type.
+ ``repoze.bfg.interfaces.IRequest``. See
+ :ref:`using_an_event_to_vary_the_request_type` for more
+ information.
repoze.lemonade
Zope2 CMF-like `data structures and helper facilities
<http://docs.repoze.org/lemonade>`_ for CA-and-ZODB-based
@@ -419,22 +403,22 @@ Glossary
application root factory) unless :ref:`vhosting_chapter` is in
use.
Lineage
- An ordered sequence of objects based on a ":term:`location` -aware"
- context. The lineage of any given :term:`context` is composed of
- itself, its parent, its parent's parent, and so on. The order of
- the sequence is context-first, then the parent of the context,
- then its parent's parent, and so on.
+ An ordered sequence of objects based on a ":term:`location`
+ -aware" context. The lineage of any given :term:`context` is
+ composed of itself, its parent, its parent's parent, and so on.
+ The order of the sequence is context-first, then the parent of the
+ context, then its parent's parent, and so on. The parent of an
+ object in a lineage is available as its ``__parent__`` attribute.
Root Factory
The "root factory" of an :mod:`repoze.bfg` application is called
on every request sent to the application. The root factory
returns the traversal root of an application. It is
- conventionally named ``get_root``. An application must supply a
- root factory to :mod:`repoze.bfg` within a call to
- ``repoze.bfg.router.make_app``; however, an application's root
- factory may be passed to ``make_app`` as ``None``, in which case
- the application uses a default root object (this pattern is often
- used in application which use :term:`URL dispatch` for all
- URL-to-view code mappings).
+ conventionally named ``get_root``. An application may supply a
+ root factory to :mod:`repoze.bfg` during the construction of a
+ :term:`Configurator`. If a root factory is not supplied, the
+ application uses a default root object. Use of the default root
+ object is useful in application which use :term:`URL dispatch` for
+ all URL-to-view code mappings.
SQLAlchemy
`SQLAlchemy' <http://www.sqlalchemy.org/>`_ is an object
relational mapper used in tutorials within this documentation.
@@ -454,22 +438,22 @@ Glossary
applications (such as applications developed using
:mod:`repoze.bfg`) to be served using the Apache web server.
View Predicate
- An attribute of a ZCML ``view`` directive or an argument to a
- ``bfg_view`` decorator which implies a value which evaluates to
- true or false for a given :term:`request`. All predicates
+ An argument to a :term:`view configuration` which evaluates to
+ ``True`` or ``False`` for a given :term:`request`. All predicates
attached to a view configuration must evaluate to true for the
associated view to be considered as a possible callable for a
given request.
Route Predicate
- An attribute of a ZCML ``route`` directive which implies a value
- that evaluates to true or false for a given :term:`request`. All
- predicates attached to a route configuration must evaluate to true
- for the associated route to "match" the current request. If a
- route does not match the current request, the next route (in
- definition order) is attempted.
+ An argument to a :term:`route configuration` which implies a value
+ that evaluates to ``True`` or ``False`` for a given
+ :term:`request`. All predicates attached to a :term:`route
+ configuration` must evaluate to ``True`` for the associated route
+ to "match" the current request. If a route does not match the
+ current request, the next route (in definition order) is
+ attempted.
Predicate
- A test which returns true or false. Two different types of
- predicates exist in :mod:`repoze.bfg`: a :term:`view predicate`
+ A test which returns ``True`` or ``False``. Two different types
+ of predicates exist in :mod:`repoze.bfg`: a :term:`view predicate`
and a :term:`route predicate`. View predicates are attached to
:term:`view configuration` and route predicates are attached to
:term:`route configuration`.
diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst
index 705e5aef5..7720bf5fc 100644
--- a/docs/narr/configuration.rst
+++ b/docs/narr/configuration.rst
@@ -21,18 +21,17 @@ used to create all kinds of web applications.
libraries to create an application is often initially easier than
using a framework to create an application, because the developer
can choose to cede control to library code he has not authored
- selectively, making the resulting application easier to understand.
- When using a framework, the developer is typically required to cede
- a greater portion of control to code he has not authored: code that
- resides in the framework itself. You needn't use a framework at
- all to create a web application using Python. A rich set of
- libraries exists for the platform which you can snap together to
- effectively create your own framework. In practice, however, using
- an existing framework to create an application is often more
- practical than rolling your own via a set of libraries if the
- framework provides a set of facilities and assumptions that fit
- your application requirements. :mod:`repoze.bfg` is a framework
- that fits a large set of assumptions in the domain of web
+ selectively. When using a framework, the developer is typically
+ required to cede a greater portion of control to code he has not
+ authored: code that resides in the framework itself. You needn't
+ use a framework at all to create a web application using Python. A
+ rich set of libraries exists for the platform which you can snap
+ together to effectively create your own framework. In practice,
+ however, using an existing framework to create an application is
+ often more practical than rolling your own via a set of libraries
+ if the framework provides a set of facilities and assumptions that
+ fit your application requirements. :mod:`repoze.bfg` is a
+ framework that fits a large set of assumptions in the domain of web
application construction.
As a framework, the primary job of :mod:`repoze.bfg` is to make it
@@ -51,11 +50,10 @@ instance, it's easy to think of the values implied by a ``.ini`` file
which is parsed at application startup time as "configuration".
:mod:`repoze.bfg` extends this pattern all the way out to application
development, using the term "configuration" to express standardized
-methods the framework makes available to developers which can be used
-to plug code into a deployment of the framework itself. When you plug
-code into the :mod:`repoze.bfg` framework, you are indeed
-"configuring" :mod:`repoze.bfg` for the purpose of creating a
-particular application deployment.
+methods which can be used to plug code into a deployment of the
+framework itself. When you plug code into the :mod:`repoze.bfg`
+framework, you are indeed "configuring" :mod:`repoze.bfg` for the
+purpose of creating a particular application deployment.
There are a number of different mechanisms you may use to configure
:mod:`repoze.bfg` to create an application: *imperative* configuration
@@ -75,9 +73,10 @@ Hello World, Configured Imperatively
------------------------------------
Experienced Python programmers may find the "imperative" configuration
-mechanism fits the way they already do things. This is the configuration
-mode in which developers cede the least amount of control to the framework.
-Because of this, it is also the easiest configuration mode to understand.
+mechanism fits the way they already do things. This is the
+configuration mode in which developers cede the least amount of
+control to the framework. It is often the easiest configuration mode
+to understand.
Here's one of the simplest :mod:`repoze.bfg` applications, configured
imperatively:
diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst
index a94c493a6..4417ffcd5 100644
--- a/docs/narr/templates.rst
+++ b/docs/narr/templates.rst
@@ -16,10 +16,9 @@ Like :term:`Zope`, :mod:`repoze.bfg` uses Zope Page Templates
(:term:`ZPT`) as its default and best-supported templating
language. However, :mod:`repoze.bfg` uses a different implementation
of the :term:`ZPT` specification than Zope does: the :term:`Chameleon`
-:term:`chameleon.zpt` templating engine. This templating engine
-complies largely with the `Zope Page Template
-<http://wiki.zope.org/ZPT/FrontPage>`_ template specification, however
-it is significantly faster.
+templating engine. This templating engine complies largely with the
+`Zope Page Template <http://wiki.zope.org/ZPT/FrontPage>`_ template
+specification, however it is significantly faster.
.. note:: The language definition documentation for Chameleon
ZPT-style templates is available from `the Chameleon website
@@ -27,7 +26,7 @@ it is significantly faster.
<http://chameleon.repoze.org/docs/latest/>`_ for the Chameleon ZPT
language specification.
-Given that there is a :term:`chameleon.zpt` template named ``foo.pt``
+Given that there is a :term:`Chameleon` ZPT template named ``foo.pt``
in a directory in your application named ``templates``, you can render
the template from a view like so:
@@ -90,7 +89,7 @@ changing the content-type and status:
A Sample Template
~~~~~~~~~~~~~~~~~
-Here's what a simple :term:`chameleon.zpt` template used under
+Here's what a simple :term:`Chameleon` ZPT template used under
:mod:`repoze.bfg` might look like:
.. code-block:: xml
@@ -113,7 +112,7 @@ Here's what a simple :term:`chameleon.zpt` template used under
</html>
Note the use of :term:`Genshi` -style ``${replacements}`` above. This
-is one of the ways that :term:`chameleon.zpt` differs from standard
+is one of the ways that :term:`Chameleon` ZPT differs from standard
ZPT. The above template expects to find a ``project`` key in the set
of keywords passed in to it via ``render_template`` or
``render_template_to_response``. Typical ZPT attribute-based syntax
@@ -124,9 +123,9 @@ Using ZPT Macros in :mod:`repoze.bfg`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unlike Zope "browser views", :mod:`repoze.bfg` doesn't make any names
-(such as ``context`` or ``view``) available to :term:`chameleon.zpt`
-templates by default. Instead, it expects you to pass all the names
-you need into the template.
+(such as ``context`` or ``view``) available to :term:`Chameleon` ZPT
+templates by default unless a :term:`renderer` is used. Instead, it
+expects you to pass all the names you need into the template.
One of the common needs in ZPT-based template is to one template's
"macros" from within a different template. In Zope, this is typically
diff --git a/docs/tutorials/gae/index.rst b/docs/tutorials/gae/index.rst
index c48350dff..2cdb3bf81 100644
--- a/docs/tutorials/gae/index.rst
+++ b/docs/tutorials/gae/index.rst
@@ -12,7 +12,7 @@ This tutorial is written in terms of using the command line on a UNIX
system; it should be possible to perform similar actions on a Windows
system.
-.. note:: :term:`chameleon.zpt` cannot easily be used on Google App
+.. note:: :term:`Chameleon` cannot easily be used on Google App
Engine due to GAE environment limitations, so the tutorial is
presented in terms of using :term:`Jinja2` as the templating
language in the generated BFG application. It is possible to *use*
diff --git a/repoze/bfg/authentication.py b/repoze/bfg/authentication.py
index 6989cb23f..d532a3a09 100644
--- a/repoze/bfg/authentication.py
+++ b/repoze/bfg/authentication.py
@@ -170,11 +170,11 @@ class AuthTktAuthenticationPolicy(CallbackAuthenticationPolicy):
``callback``
- Default: ``None``. A callback passed the userid and the request,
- expected to return None if the userid doesn't exist or a sequence
- of group identifiers (possibly empty) if the user does exist. If
- ``callback`` is None, the userid will be assumed to exist with no
- groups. Optional.
+ Default: ``None``. A callback passed the userid and the
+ request, expected to return ``None`` if the userid doesn't
+ exist or a sequence of group identifiers (possibly empty) if
+ the user does exist. If ``callback`` is ``None``, the userid
+ will be assumed to exist with no groups. Optional.
``cookie_name``
diff --git a/repoze/bfg/authorization.py b/repoze/bfg/authorization.py
index 7113ddd23..bc8b92b5e 100644
--- a/repoze/bfg/authorization.py
+++ b/repoze/bfg/authorization.py
@@ -12,10 +12,10 @@ from repoze.bfg.security import Everyone
class ACLAuthorizationPolicy(object):
""" An :term:`authorization policy` which consults an :term:`ACL`
object attached to a :term:`context` to determine authorization
- information about a a :term:`principal` or multiple principals. If
- the context is part of a :term:`lineage`, the context's parents are
- consulted for ACL information too. The following is true about this
- security policy.
+ information about a a :term:`principal` or multiple principals.
+ If the context is part of a :term:`lineage`, the context's parents
+ are consulted for ACL information too. The following is true
+ about this security policy.
- When checking whether the 'current' user is permitted (via the
``permits`` method), the security policy consults the
@@ -27,14 +27,15 @@ class ACLAuthorizationPolicy(object):
During this processing, if any ``Deny`` ACE is found matching
any principal in ``principals``, stop processing by returning an
- ``ACLDenied`` (equals False) immediately. If any ``Allow`` ACE
- is found matching any principal, stop processing by returning an
- ``ACLAllowed`` (equals True) immediately. If we exhaust the
- context's lineage, and no ACE has explicitly permitted or denied
- access, return an ``ACLDenied``. This differs from the
- non-inheriting security policy (the ``ACLSecurityPolicy``) by
- virtue of the fact that it does not stop looking for ACLs in the
- object lineage after it finds the first one.
+ ``ACLDenied`` (equals ``False``) immediately. If any ``Allow``
+ ACE is found matching any principal, stop processing by
+ returning an ``ACLAllowed`` (equals ``True``) immediately. If
+ we exhaust the context's lineage, and no ACE has explicitly
+ permitted or denied access, return an ``ACLDenied``. This
+ differs from the non-inheriting security policy (the
+ ``ACLSecurityPolicy``) by virtue of the fact that it does not
+ stop looking for ACLs in the object lineage after it finds the
+ first one.
- When computing principals allowed by a permission via the
``principals_allowed_by_permission`` method, we compute the set
@@ -92,7 +93,8 @@ class ACLAuthorizationPolicy(object):
def principals_allowed_by_permission(self, context, permission):
""" Return the set of principals explicitly granted the
permission named ``permission`` according to the ACL directly
- attached to the context context as well as inherited ACLs. """
+ attached to the ``context`` as well as inherited ACLs based on
+ :term:`lineage`."""
allowed = set()
for location in reversed(list(lineage(context))):
diff --git a/repoze/bfg/configuration.py b/repoze/bfg/configuration.py
index a0409bd06..b858f405a 100644
--- a/repoze/bfg/configuration.py
+++ b/repoze/bfg/configuration.py
@@ -75,11 +75,11 @@ class Configurator(object):
If the ``registry`` argument is passed as a non-``None`` value, it
must be an instance of the :mod:`repoze.bfg.registry.Registry`
class representing the registry to configure. If ``registry`` is
- ``None``, the configurator will create a Registry instance itself;
- it will also perform some default configuration that would not
- otherwise be done. After construction, the configurator may be
- used to add configuration to the registry. The overall state of a
- registry is called the 'configuration state'.
+ ``None``, the configurator will create a ``Registry`` instance
+ itself; it will also perform some default configuration that would
+ not otherwise be done. After construction, the configurator may
+ be used to add configuration to the registry. The overall state
+ of a registry is called the 'configuration state'.
.. warning:: If a ``registry`` is passed to the Configurator
constructor, all other constructor arguments except ``package``
@@ -109,9 +109,9 @@ class Configurator(object):
If ``authorization_policy`` is passed, it should be an instance
of an :term:`authorization policy`.
- .. note:: A ``ConfigurationError`` will be raised if an
- authorization policy is supplied without authentication policy
- also being supplied (authorization requires authentication).
+ .. note:: A ``ConfigurationError`` will be raised when an
+ authorization policy is supplied without also supplying an
+ authentication policy (authorization requires authentication).
If ``renderers`` is passed, it should be a list of tuples
representing a set of :term:`renderer` factories which should be
@@ -120,7 +120,9 @@ class Configurator(object):
If ``debug_logger`` is not passed, a default debug logger that
logs to stderr will be used. If it is passed, it should be an
- instance of a ``logging.Logger`` (PEP 282) class.
+ instance of the ``logging.Logger`` (PEP 282) standard library
+ class. The debug logger is used by :mod:`repoze.bfg` itself to
+ log warnings and authorization debugging information.
"""
def __init__(self, registry=None, package=None, settings=None,
root_factory=None, authentication_policy=None,
@@ -250,9 +252,9 @@ class Configurator(object):
def view(context, request):
return {}
else:
- raise ConfigurationError('"view" attribute was not '
- 'specified and no renderer '
- 'specified')
+ raise ConfigurationError(
+ '"view" argument was not specified and no renderer '
+ 'specified')
derived_view = self._derive_view(view, attr=attr,
renderer_name=renderer,
@@ -273,14 +275,15 @@ class Configurator(object):
# API
def add_subscriber(self, subscriber, iface=None):
- """Add an event subscriber for the event stream implied by
- the supplied ``iface`` interface. The ``subscriber`` argument
- represents a callable object; it will be called with a single
- object ``event`` whenever :mod:`repoze.bfg` emits an event
- associated with the ``iface``. Using the default ``iface``
- value, ``None`` will cause the subscriber to be registered for
- all event types. See :ref:`events_chapter` for more
- information about events and subscribers."""
+ """Add an event :term:`subscriber` for the event stream
+ implied by the supplied ``iface`` interface. The
+ ``subscriber`` argument represents a callable object; it will
+ be called with a single object ``event`` whenever
+ :mod:`repoze.bfg` emits an :term:`event` associated with the
+ ``iface``. Using the default ``iface`` value, ``None`` will
+ cause the subscriber to be registered for all event types. See
+ :ref:`events_chapter` for more information about events and
+ subscribers."""
if iface is None:
iface = (Interface,)
if not isinstance(iface, (tuple, list)):
@@ -337,33 +340,36 @@ class Configurator(object):
configuration state. Arguments to ``add_view`` are broken
down below into *predicate* arguments and *non-predicate*
arguments. Predicate arguments narrow the circumstances in
- which a view will be invoked; non-predicate arguments are
+ which the view callable will be invoked when a request is
+ presented to :mod:`repoze.bfg`; non-predicate arguments are
informational.
Non-Predicate Arguments
view
- The Python dotted-path name to the view callable. This
- argument is required unless a ``renderer`` attribute also
- exists. If a ``renderer`` argument is passed, this
- attribute defaults to a view that returns an empty
- dictionary (see :ref:`views_which_use_a_renderer`).
+ A reference to a :term:`view callable`. This argument is
+ required unless a ``renderer`` argument also exists. If a
+ ``renderer`` argument is passed, and a ``view`` argument is
+ not provided, the view callable defaults to a callable that
+ returns an empty dictionary (see
+ :ref:`views_which_use_a_renderer`).
permission
- The name of a *permission* that the user must possess in
- order to call the view. See :ref:`view_security_section`
- for more information about view security and permissions.
+ The name of a :term:`permission` that the user must possess
+ in order to invoke the :term:`view callable`. See
+ :ref:`view_security_section` for more information about view
+ security and permissions.
attr
The view machinery defaults to using the ``__call__`` method
- of the view callable (or the function itself, if the view
- callable is a function) to obtain a response dictionary.
- The ``attr`` value allows you to vary the method attribute
- used to obtain the response. For example, if your view was
- a class, and the class has a method named ``index`` and you
+ of the :term:`view callable` (or the function itself, if the
+ view callable is a function) to obtain a response. The
+ ``attr`` value allows you to vary the method attribute used
+ to obtain the response. For example, if your view was a
+ class, and the class has a method named ``index`` and you
wanted to use this method instead of the class' ``__call__``
method to return the response, you'd say ``attr="index"`` in the
view configuration for the view. This is
@@ -373,55 +379,58 @@ class Configurator(object):
This is either a single string term (e.g. ``json``) or a
string implying a path or :term:`resource specification`
- (e.g. ``templates/views.pt``). If the renderer value is a
- single term (does not contain a dot ``.``), the specified
- term will be used to look up a renderer implementation, and
- that renderer implementation will be used to construct a
- response from the view return value. If the renderer term
- contains a dot (``.``), the specified term will be treated
- as a path, and the filename extension of the last element in
- the path will be used to look up the renderer
- implementation, which will be passed the full path. The
- renderer implementation will be used to construct a response
- from the view return value.
-
- Note that if the view itself returns a response (see
+ (e.g. ``templates/views.pt``) naming a :term:`renderer`
+ implementation. If the ``renderer`` value does not contain
+ a dot ``.``, the specified string will be used to look up a
+ renderer implementation, and that renderer implementation
+ will be used to construct a response from the view return
+ value. If the ``renderer`` value contains a dot (``.``),
+ the specified term will be treated as a path, and the
+ filename extension of the last element in the path will be
+ used to look up the renderer implementation, which will be
+ passed the full path. The renderer implementation will be
+ used to construct a :term:`response` from the view return
+ value.
+
+ Note that if the view itself returns a :term:`response` (see
:ref:`the_response`), the specified renderer implementation
is never called.
When the renderer is a path, although a path is usually just
a simple relative pathname (e.g. ``templates/foo.pt``,
implying that a template named"foo.pt" is in the "templates"
- directory relative to the directory of *package* of the
- Configurator), a path can be absolute, starting with a slash
- on UNIX or a drive letter prefix on Windows. The path can
- alternately be a :term:`resource specification` in the form
+ directory relative to the directory of the current
+ :term:`package` of the Configurator), a path can be
+ absolute, starting with a slash on UNIX or a drive letter
+ prefix on Windows. The path can alternately be a
+ :term:`resource specification` in the form
``some.dotted.package_name:relative/path``, making it
possible to address template resources which live in a
separate package.
The ``renderer`` attribute is optional. If it is not
- defined, the "null" renderer is assumed (no rendering is performed
- and the value is passed back to the upstream BFG machinery
- unmolested).
+ defined, the "null" renderer is assumed (no rendering is
+ performed and the value is passed back to the upstream BFG
+ machinery unmolested).
wrapper
- The :term:`view name` of another view declared elsewhere in
- configuration which will receive the response body of this
+ The :term:`view name` of a different :term:`view
+ configuration` which will receive the response body of this
view as the ``request.wrapped_body`` attribute of its own
- request, and the response returned by this view as the
- ``request.wrapped_response`` attribute of its own request.
- Using a wrapper makes it possible to
- "chain" views together to form a composite response. The response
- of the outermost wrapper view will be returned to the user. The
- wrapper view will be found as any view is found: see
- :ref:`view_lookup_ordering`. The "best" wrapper view will be found
- based on the lookup ordering: "under the hood" this wrapper view is
- looked up via ``repoze.bfg.view.render_view_to_response(context,
- request, 'wrapper_viewname')``. The context and request of a wrapper
- view is the same context and request of the inner view. If this
- attribute is unspecified, no view wrapping is done.
+ :term:`request`, and the :term:`response` returned by this
+ view as the ``request.wrapped_response`` attribute of its
+ own request. Using a wrapper makes it possible to "chain"
+ views together to form a composite response. The response
+ of the outermost wrapper view will be returned to the user.
+ The wrapper view will be found as any view is found: see
+ :ref:`view_lookup_ordering`. The "best" wrapper view will
+ be found based on the lookup ordering: "under the hood" this
+ wrapper view is looked up via
+ ``repoze.bfg.view.render_view_to_response(context, request,
+ 'wrapper_viewname')``. The context and request of a wrapper
+ view is the same context and request of the inner view. If
+ this attribute is unspecified, no view wrapping is done.
Predicate Arguments
@@ -442,17 +451,20 @@ class Configurator(object):
route_name
- *This argument services an advanced feature that isn't often
- used unless you want to perform traversal *after* a route
- has matched.* This value must match the ``name`` of a
- ``<route>`` declaration (see :ref:`urldispatch_chapter`)
+ This value must match the ``name`` of a :term:`route
+ configuration` declaration (see :ref:`urldispatch_chapter`)
that must match before this view will be called. Note that
the ``route`` configuration referred to by ``route_name``
usually has a ``*traverse`` token in the value of its
``path``, representing a part of the path that will be used
by traversal against the result of the route's :term:`root
- factory`.See :ref:`hybrid_chapter` for more information on
- using this advanced feature.
+ factory`.
+
+ .. warning:: Using this argument services an advanced
+ feature that isn't often used unless you want to perform
+ traversal *after* a route has matched. See
+ :ref:`hybrid_chapter` for more information on using this
+ advanced feature.
request_type
@@ -474,22 +486,23 @@ class Configurator(object):
This value can be any string. A view declaration with this
argument ensures that the view will only be called when the
- request has a key in the ``request.params`` dictionary (an
- HTTP ``GET`` or ``POST`` variable) that has a name which
- matches the supplied value. If the value supplied to the
- attribute has a ``=`` sign in it, e.g. ``request_params="foo=123"``,
- then the key (``foo``) must both exist in the ``request.params``
- dictionary, and the value must match the right hand side of the
- expression (``123``) for the view to "match" the current request.
+ :term:`request` has a key in the ``request.params``
+ dictionary (an HTTP ``GET`` or ``POST`` variable) that has a
+ name which matches the supplied value. If the value
+ supplied has a ``=`` sign in it,
+ e.g. ``request_params="foo=123"``, then the key (``foo``)
+ must both exist in the ``request.params`` dictionary, *and*
+ the value must match the right hand side of the expression
+ (``123``) for the view to "match" the current request.
containment
- This value should be a reference to a Python class that a
- graph traversal parent object of the :term:`context` must be
- an instance of or :term:`interface` that a parent object
- must provide in order for this view to be found and called.
- Your models must be"location-aware" to use this feature. See
- :ref:`location_aware` for more information about location-awareness.
+ This value should be a reference to a Python class or
+ :term:`interface` that a parent object in the
+ :term:`lineage` must provide in order for this view to be
+ found and called. Your models must be"location-aware" to
+ use this feature. See :ref:`location_aware` for more
+ information about location-awareness.
xhr
@@ -503,7 +516,7 @@ class Configurator(object):
accept
- The value of this attribute represents a match query for one
+ The value of this argument represents a match query for one
or more mimetypes in the ``Accept`` HTTP request header. If
this value is specified, it must be in one of the following
forms: a mimetype match token in the form ``text/plain``, a
@@ -518,27 +531,25 @@ class Configurator(object):
name/value pair. If the value contains a ``:`` (colon), it
will be considered a name/value pair
(e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``). The
- *value* of an attribute that represent a name/value pair
- should be a regular expression. If the value does not
- contain a colon, the entire value will be considered to be
- the header name (e.g. ``If-Modified-Since``). If the value
- evaluates to a header name only without a value, the header
- specified by the name must be present in the request for
- this predicate to be true. If the value evaluates to a
- header name/value pair, the header specified by the name
- must be present in the request *and* the regular expression
- specified as the value must match the header value. Whether
- or not the value represents a header name or a header
- name/value pair, the case of the header name is not
- significant.
+ value portion should be a regular expression. If the value
+ does not contain a colon, the entire value will be
+ considered to be the header name
+ (e.g. ``If-Modified-Since``). If the value evaluates to a
+ header name only without a value, the header specified by
+ the name must be present in the request for this predicate
+ to be true. If the value evaluates to a header name/value
+ pair, the header specified by the name must be present in
+ the request *and* the regular expression specified as the
+ value must match the header value. Whether or not the value
+ represents a header name or a header name/value pair, the
+ case of the header name is not significant.
path_info
This value represents a regular expression pattern that will
be tested against the ``PATH_INFO`` WSGI environment
variable. If the regex matches, this predicate will be
- true.
-
+ ``True``.
"""
if not view:
@@ -658,11 +669,9 @@ class Configurator(object):
configuration` to be used to specify a :term:`view callable`
that will be invoked when this route matches. The arguments
to this method are divided into *predicate*, *non-predicate*,
- and *view-related* types. Predicate arguments narrow the
- circumstances in which a route will be match a request;
- non-predicate arguments are informational. View-related types
- are used to modify the
-
+ and *view-related* types. :term:`Route predicate` arguments
+ narrow the circumstances in which a route will be match a
+ request; non-predicate arguments are informational.
Non-Predicate Arguments
@@ -670,15 +679,15 @@ class Configurator(object):
The name of the route, e.g. ``myroute``. This attribute is
required. It must be unique among all defined routes in a given
- configuration.
+ application.
factory
- A reference to a Python object (often a function) that will
- generate a :mod:`repoze.bfg` context object when this route
- matches. e.g. ``mypackage.models.MyFactoryClass``. If this
- argument is not specified, a default root factory will be
- used.
+ A reference to a Python object (often a function or a class)
+ that will generate a :mod:`repoze.bfg` :term:`context`
+ object when this route matches. For example,
+ ``mypackage.models.MyFactoryClass``. If this argument is
+ not specified, a default root factory will be used.
Predicate Arguments
@@ -686,7 +695,8 @@ class Configurator(object):
The path of the route e.g. ``ideas/:idea``. This argument
is required. See :ref:`route_path_pattern_syntax` for
- information about the syntax of route paths.
+ information about the syntax of route paths. If the path
+ doesn't match the current URL, route matching continues.
xhr
@@ -696,23 +706,23 @@ class Configurator(object):
``X-Requested-With``) header for this route to match. This
is useful for detecting AJAX requests issued from jQuery,
Prototype and other Javascript libraries. If this predicate
- returns false, route matching continues.
+ returns ``False``, route matching continues.
request_method
A string representing an HTTP method name, e.g. ``GET``,
``POST``, ``HEAD``, ``DELETE``, ``PUT``. If this argument
is not specified, this route will match if the request has
- *any* request method. If this predicate returns false,
+ *any* request method. If this predicate returns ``False``,
route matching continues.
path_info
This value represents a regular expression pattern that will
be tested against the ``PATH_INFO`` WSGI environment
- variable. If the regex matches, this predicate will be
- true. If this predicate returns false, route matching
- continues.
+ variable. If the regex matches, this predicate will return
+ ``True``. If this predicate returns ``False``, route
+ matching continues.
request_param
@@ -726,17 +736,17 @@ class Configurator(object):
(``foo``) must both exist in the ``request.params`` dictionary, and
the value must match the right hand side of the expression (``123``)
for the route to "match" the current request. If this predicate
- returns false, route matching continues.
+ returns ``False``, route matching continues.
header
- This value represents an HTTP header name or a header
- name/value pair. If the value contains a ``:`` (colon), it
- will be considered a name/value pair
- (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``). The
- *value* of such a pair should be a regular expression. If
- the value does not contain a colon, the entire value will be
- considered to be the header name
+ This argument represents an HTTP header name or a header
+ name/value pair. If the argument contains a ``:`` (colon),
+ it will be considered a name/value pair
+ (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``). If
+ the value contains a colon, the value portion should be a
+ regular expression. If the value does not contain a colon,
+ the entire value will be considered to be the header name
(e.g. ``If-Modified-Since``). If the value evaluates to a
header name only without a value, the header specified by
the name must be present in the request for this predicate
@@ -746,7 +756,7 @@ class Configurator(object):
value must match the header value. Whether or not the value
represents a header name or a header name/value pair, the
case of the header name is not significant. If this
- predicate returns false, route matching continues.
+ predicate returns ``False``, route matching continues.
accept
@@ -758,7 +768,7 @@ class Configurator(object):
match-all wildcard mimetype match token in the form ``*/*``.
If any of the forms matches the ``Accept`` header of the
request, this predicate will be true. If this predicate
- returns false, route matching continues.
+ returns ``False``, route matching continues.
View-Related Arguments
@@ -829,12 +839,12 @@ class Configurator(object):
view_containment
- This a reference to a Python object representing the class
- that a graph traversal parent object of the :term:`context`
- must be an instance of (or :term:`interface` that a parent
- object must provide) in order for this view to be found and
- called. Your models must be "location-aware" to use this feature.
- See :ref:`location_aware` for more information about
+ This value should be a reference to a Python class or
+ :term:`interface` that a parent object in the
+ :term:`lineage` must provide in order for the view related
+ to this route to be found and called. Your models must be
+ 'location-aware' to use this feature. See
+ :ref:`location_aware` for more information about
location-awareness.
If the ``view`` argument is not provided, this argument has no
@@ -902,7 +912,7 @@ class Configurator(object):
def scan(self, package=None, _info=u''):
""" Scan a Python package and any of its subpackages for
- objects marked with configuration decorators such as
+ objects marked with :term:`configuration decoration` such as
``@bfg_view``. Any decorated object found will influence the
current configuration state.
diff --git a/repoze/bfg/events.py b/repoze/bfg/events.py
index 14e47ca3f..75a5aec5a 100644
--- a/repoze/bfg/events.py
+++ b/repoze/bfg/events.py
@@ -6,19 +6,20 @@ from repoze.bfg.interfaces import INewResponse
from repoze.bfg.interfaces import IWSGIApplicationCreatedEvent
class NewRequest(object):
- """ An instance of this class is emitted as an event whenever
- repoze.bfg begins to process a new request. The instance has an
- attribute, ``request``, which is the request object. This class
- implements the ``repoze.bfg.interfaces.INewRequest`` interface."""
+ """ An instance of this class is emitted as an :term:`event`
+ whenever repoze.bfg begins to process a new request. The instance
+ has an attribute, ``request``, which is a :term:`request` object.
+ This class implements the ``repoze.bfg.interfaces.INewRequest``
+ interface."""
implements(INewRequest)
def __init__(self, request):
self.request = request
class NewResponse(object):
- """ An instance of this class is emitted as an event whenever any
- repoze.bfg view returns a response.. The instance has an
- attribute, ``response``, which is the response object returned by
- the view. This class implements the
+ """ An instance of this class is emitted as an :term:`event`
+ whenever any repoze.bfg view returns a :term:`response`.. The
+ instance has an attribute, ``response``, which is the response
+ object returned by the view. This class implements the
``repoze.bfg.interfaces.INewResponse`` interface."""
implements(INewResponse)
def __init__(self, response):
@@ -26,23 +27,24 @@ class NewResponse(object):
class AfterTraversal(object):
implements(IAfterTraversal)
- """ An instance of this class is emitted as an event after the
- repoze.bfg router performs traversal (but before any view code is
- executed). The instance has an attribute, ``request``, which is
- the request object returned by the view. Notably, the request
- object will have an attribute named ``context``, which is the
- context that will be provided to the view which will eventually be
- called, as well as other attributes defined by the traverser.
- This class implements the
- ``repoze.bfg.interfaces.IAfterTraversal`` interface."""
+ """ An instance of this class is emitted as an :term:`event` after
+ the repoze.bfg :term:`router` performs traversal but before any
+ view code is executed. The instance has an attribute,
+ ``request``, which is the request object generated by
+ :mod:`repoze.bfg`. Notably, the request object will have an
+ attribute named ``context``, which is the context that will be
+ provided to the view which will eventually be called, as well as
+ other attributes defined by the traverser. This class implements
+ the ``repoze.bfg.interfaces.IAfterTraversal`` interface."""
def __init__(self, request):
self.request = request
class WSGIApplicationCreatedEvent(object):
- """ An instance of this class is emitted as an event whenever a
- ``repoze.bfg`` application starts. The instance has an attribute,
- ``app``, which is an instance of the ``repoze.bfg.router.Router``
- class that will handle WSGI requests. This class implements the
+ """ An instance of this class is emitted as an :term:`event` when
+ the ``make_wsgi_app`` method of a :term:`Configurator` is called).
+ The instance has an attribute, ``app``, which is an instance of
+ the ``repoze.bfg.router.Router`` class that will handle WSGI
+ requests. This class implements the
``repoze.bfg.interfaces.IWSGIApplicationCreatedEvent`` interface."""
implements(IWSGIApplicationCreatedEvent)
def __init__(self, app):
diff --git a/repoze/bfg/interfaces.py b/repoze/bfg/interfaces.py
index 479e3a751..553f6775f 100644
--- a/repoze/bfg/interfaces.py
+++ b/repoze/bfg/interfaces.py
@@ -28,6 +28,10 @@ class IWSGIApplicationCreatedEvent(Interface):
class IRequest(Interface):
""" Request type interface attached to all request objects """
+class IRouteRequest(Interface):
+ """ *internal only* interface used as in a utility lookup to find
+ route-specific interfaces. Not an API."""
+
class IResponse(Interface):
status = Attribute('WSGI status code of response')
headerlist = Attribute('List of response headers')
@@ -65,10 +69,6 @@ class IAuthorizationPolicy(Interface):
""" Return a set of principal identifiers allowed by the permission """
-class IRouteRequest(Interface):
- """ *internal only* interface used as in a utility lookup to find
- route-specific interfaces. Not an API."""
-
class IResponseFactory(Interface):
""" A utility which generates a response factory """
def __call__():
@@ -102,15 +102,15 @@ class IMultiView(ISecuredView):
""" Add a view to the multiview. """
class IRootFactory(Interface):
- def __call__(environ):
- """ Return a root object based on the WSGI environ """
+ def __call__(request):
+ """ Return a root object based on the request """
class IDefaultRootFactory(Interface):
- def __call__(environ):
+ def __call__(request):
""" Return the *default* root object for an application """
class ITraverser(Interface):
- def __call__(environ):
+ def __call__(request):
""" Return a dictionary with (at least) the keys ``root``,
``context``, ``view_name``, ``subpath``, ``traversed``,
``virtual_root``, and ``virtual_root_path``. These values are
@@ -143,7 +143,7 @@ class IRenderer(Interface):
unicode object useful as a response body). Values computed by
the system are passed by the system in the ``system``
parameter, which is a dictionary. Keys in the dictionary
- include: ``view`` (the view object that returned the value),
+ include: ``view`` (the view callable that returned the value),
``renderer_name`` (the template name or simple name of the
renderer), ``context`` (the context object passed to the
view), and ``request`` (the request object passed to the
@@ -172,7 +172,8 @@ class IRouter(Interface):
class ISettings(Interface):
""" Runtime settings utility for repoze.bfg; represents the
- deployment settings for the application"""
+ deployment settings for the application. Implements a mapping
+ interface."""
# this interface, even if it becomes unused within BFG, is imported by
# other packages (such as repoze.bfg.traversalwrapper)
@@ -188,7 +189,20 @@ ILogger = IDebugLogger # b/c
class IRoutesMapper(Interface):
""" Interface representing a Routes ``Mapper`` object """
-
+ def get_routes():
+ """ Return a sequence of Route objects registered in the mapper."""
+
+ def connect(path, name, factory=None, predicates=()):
+ """ Add a new route. """
+
+ def generate(name, kw):
+ """ Generate a URL using the route named ``name`` with the
+ keywords implied by kw"""
+
+ def __call__(request):
+ """ Return a matchdict for the request; the ``route`` key will
+ either be a Route object or ``None`` if no route matched."""
+
class IForbiddenView(Interface):
""" A utility which returns an IResponse as the result of the
denial of a view invocation by a security policy."""
diff --git a/repoze/bfg/location.py b/repoze/bfg/location.py
index 8e8eff671..fd3bd3792 100644
--- a/repoze/bfg/location.py
+++ b/repoze/bfg/location.py
@@ -12,18 +12,14 @@
#
##############################################################################
-"""Location support loosely based from ``zope.location``, but without
-``zope.security`` support or proxy support, neither of which is used
-by ``repoze.bfg``
-"""
-
def inside(model1, model2):
"""Is ``model1`` 'inside' ``model2``? Return ``True`` if so, else
``False``.
- ``model1`` is 'inside' ``model2`` if ``model2`` is a `location
- ancestor` of ``model1``. It is a location ancestor if its parent
- (or one of its parent's parents, etc.) is an ancestor.
+ ``model1`` is 'inside' ``model2`` if ``model2`` is a
+ :term:`lineage` ancestor of ``model1``. It is a lineage ancestor
+ if its parent (or one of its parent's parents, etc.) is an
+ ancestor.
"""
while model1 is not None:
if model1 is model2:
@@ -34,14 +30,14 @@ def inside(model1, model2):
def lineage(model):
"""
- Return a generator representing the model lineage. The generator
- first returns ``model`` unconditionally. Then, if ``model``
- supplies a ``__parent__`` attribute, return the object represented
- by ``model.__parent__``. If *that* object has a ``__parent__``
- attribute, return that object's parent, and so on, until the
- object being inspected either has no ``__parent__`` attribute or
- which has a ``__parent__`` attribute of ``None``. For example, if
- the object tree is::
+ Return a generator representing the :term:`lineage` of the
+ ``model``. The generator first returns ``model`` unconditionally.
+ Then, if ``model`` supplies a ``__parent__`` attribute, return the
+ object represented by ``model.__parent__``. If *that* object has
+ a ``__parent__`` attribute, return that object's parent, and so
+ on, until the object being inspected either has no ``__parent__``
+ attribute or which has a ``__parent__`` attribute of ``None``.
+ For example, if the object tree is::
thing1 = Thing()
thing2 = Thing()
diff --git a/repoze/bfg/path.py b/repoze/bfg/path.py
index 2c1c0f4e3..30c72b436 100644
--- a/repoze/bfg/path.py
+++ b/repoze/bfg/path.py
@@ -3,7 +3,6 @@ import pkg_resources
import sys
def caller_path(path, level=2):
- """ Return an absolute path """
if not os.path.isabs(path):
module = caller_module(level+1)
prefix = package_path(module)
diff --git a/repoze/bfg/request.py b/repoze/bfg/request.py
index a7f4f32ba..f3443dfa2 100644
--- a/repoze/bfg/request.py
+++ b/repoze/bfg/request.py
@@ -7,9 +7,9 @@ from webob import Request as WebobRequest
from repoze.bfg.interfaces import IRequest
def make_request_ascii(event):
- """ An event handler that causes the request charset to be ASCII;
- used as an INewRequest subscriber so code written before 0.7.0 can
- continue to work without a change"""
+ """ An function that is useful as a ``INewRequest`` :term:`event`
+ :term:`subscriber` that causes the request charset to be ASCII so
+ code written before 0.7.0 can continue to work without a change"""
request = event.request
request.charset = None
diff --git a/repoze/bfg/router.py b/repoze/bfg/router.py
index b3f41442e..deffa4e17 100644
--- a/repoze/bfg/router.py
+++ b/repoze/bfg/router.py
@@ -29,7 +29,6 @@ from repoze.bfg.view import default_notfound_view
make_app # prevent pyflakes from complaining
class Router(object):
- """ The main repoze.bfg WSGI application. """
implements(IRouter)
debug_notfound = False
@@ -50,10 +49,11 @@ class Router(object):
def __call__(self, environ, start_response):
"""
- Accept ``environ`` and ``start_response``; route requests to
- ``repoze.bfg`` views based on registrations within the
- application registry; call ``start_response`` and return an
- iterable.
+ Accept ``environ`` and ``start_response``; create a
+ :term:`request` and route the request to a :mod:`repoze.bfg`
+ view based on introspection of :term:`view configuration`
+ within the application registry; call ``start_response`` and
+ return an iterable.
"""
registry = self.registry
has_listeners = registry.has_listeners
diff --git a/repoze/bfg/scripting.py b/repoze/bfg/scripting.py
index bf2423a8c..3e743524a 100644
--- a/repoze/bfg/scripting.py
+++ b/repoze/bfg/scripting.py
@@ -7,8 +7,9 @@ def get_root(app, request=None):
``closer`` returned is a callable (accepting no arguments) that
should be called when your scripting application is finished using
the root. If ``request`` is not None, it is used as the request
- passed to the BFG application root factory. A faux request is
- constructed and passed to the root factory if ``request`` is None."""
+ passed to the :mod:`repoze.bfg` application root factory. A
+ request is constructed and passed to the root factory if
+ ``request`` is None."""
registry = app.registry
if request is None:
request = Request.blank('/')
diff --git a/repoze/bfg/security.py b/repoze/bfg/security.py
index 56bcf5e52..f7ed8e050 100644
--- a/repoze/bfg/security.py
+++ b/repoze/bfg/security.py
@@ -60,8 +60,8 @@ def has_permission(permission, context, request):
def authenticated_userid(request):
""" Return the userid of the currently authenticated user or
- ``None`` if there is no authentication policy in effect or there
- is no currently authenticated user. """
+ ``None`` if there is no :term:`authentication policy` in effect or
+ there is no currently authenticated user."""
try:
reg = request.registry
except AttributeError:
@@ -73,11 +73,11 @@ def authenticated_userid(request):
return policy.authenticated_userid(request)
def effective_principals(request):
- """ Return the list of 'effective' principal identifiers for the
- request. This will include the userid of the currently
- authenticated user if a user is currently authenticated. If no
- authentication policy is in effect, this will return an empty
- sequence."""
+ """ Return the list of 'effective' :term:`principal` identifiers
+ for the ``request``. This will include the userid of the
+ currently authenticated user if a user is currently
+ authenticated. If no :term:`authentication policy` is in effect,
+ this will return an empty sequence."""
try:
reg = request.registry
except AttributeError:
@@ -89,16 +89,17 @@ def effective_principals(request):
return policy.effective_principals(request)
def principals_allowed_by_permission(context, permission):
- """ Provided a context (a model object), and a permission (a
- string or unicode object), return a sequence of principal ids that
- possess the permission in the context. If no authorization policy
- is in effect, this will return a sequence with the single value
+ """ Provided a ``context`` (a model object), and a ``permission``
+ (a string or unicode object), if a :term:`authorization policy` is
+ in effect, return a sequence of :term:`principal` ids that possess
+ the permission in the ``context``. If no authorization policy is
+ in effect, this will return a sequence with the single value
representing ``Everyone`` (the special principal identifier
representing all principals).
- .. note:: even if an authorization policy *is* in effect, some
- (exotic) authorization policies may not implement the required
- machinery for this function; those will cause a
+ .. note:: even if an :term:`authorization policy` is in effect,
+ some (exotic) authorization policies may not implement the
+ required machinery for this function; those will cause a
``NotImplementedError`` exception to be raised when this
function is invoked.
"""
@@ -110,11 +111,11 @@ def principals_allowed_by_permission(context, permission):
def view_execution_permitted(context, request, name=''):
""" If the view specified by ``context`` and ``name`` is protected
- by a permission, check the permission associated with the view
- using the effective authentication/authorization policies and the
- ``request``. Return a boolean result. If no authentication
- policy is in effect, or if the view is not protected by a
- permission, return True."""
+ by a :term:`permission`, check the permission associated with the
+ view using the effective authentication/authorization policies and
+ the ``request``. Return a boolean result. If no
+ :term:`authorization policy` is in effect, or if the view is not
+ protected by a permission, return True."""
try:
reg = request.registry
except AttributeError:
@@ -141,10 +142,10 @@ def remember(request, principal, **kw):
response.headerlist.extend(headers)
return response
- If no authentication policy is in use, this function will always
- return an empty sequence. If used, the composition and meaning of
- ``**kw`` must be agreed upon by the calling code and the effective
- authentication policy."""
+ If no :term:`authentication policy` is in use, this function will
+ always return an empty sequence. If used, the composition and
+ meaning of ``**kw`` must be agreed upon by the calling code and
+ the effective authentication policy."""
try:
reg = request.registry
except AttributeError:
@@ -168,8 +169,8 @@ def forget(request):
response.headerlist.extend(headers)
return response
- If no authentication policy is in use, this function will always
- return an empty sequence."""
+ If no :term:`authentication policy` is in use, this function will
+ always return an empty sequence."""
try:
reg = request.registry
except AttributeError:
diff --git a/repoze/bfg/testing.py b/repoze/bfg/testing.py
index 127f54283..428f1c11f 100644
--- a/repoze/bfg/testing.py
+++ b/repoze/bfg/testing.py
@@ -40,17 +40,17 @@ zcml_configure # prevent pyflakes from complaining
_marker = object()
def registerDummySecurityPolicy(userid=None, groupids=(), permissive=True):
- """ Registers a dummy ``repoze.bfg`` security policy (actually, a
- pair of policies: an authorization policy and an authentication
- policy) using the userid ``userid`` and the group ids
- ``groupids``. If ``permissive`` is true, a 'permissive' security
- policy is registered; this policy allows all access. If
- ``permissive`` is false, a nonpermissive security policy is
- registered; this policy denies all access. This function is most
- useful when testing code that uses the ``repoze.bfg.security``
- APIs named ``has_permission``, ``authenticated_userid``,
- ``effective_principals``, ``principals_allowed_by_permission``,
- and so on.
+ """ Registers a a pair of dummy :mod:`repoze.bfg` security
+ policies: an :term:`authorization policy` and an
+ :term:`authentication policy`) using the userid ``userid`` and the
+ group ids ``groupids``. If ``permissive`` is true, a 'permissive'
+ authorization policy is registered; this policy allows all access.
+ If ``permissive`` is false, a nonpermissive authorization policy
+ is registered; this policy denies all access. This function is
+ most useful when testing code that uses the
+ ``repoze.bfg.security`` APIs named ``has_permission``,
+ ``authenticated_userid``, ``effective_principals``,
+ ``principals_allowed_by_permission``, and so on.
"""
policy = DummySecurityPolicy(userid, groupids, permissive)
reg = get_current_registry()
@@ -58,7 +58,8 @@ def registerDummySecurityPolicy(userid=None, groupids=(), permissive=True):
reg.registerUtility(policy, IAuthenticationPolicy)
def registerModels(models):
- """ Registers a dictionary of models. This is most useful for
+ """ Registers a dictionary of models that can be resolved via
+ ``repoze.bfg.traversal.find_model``. This is most useful for
testing code that wants to call the
``repoze.bfg.traversal.find_model`` API. The ``find_model`` API
is called with a path as one of its arguments. If the dictionary
@@ -83,13 +84,14 @@ def registerModels(models):
return models
def registerEventListener(event_iface=Interface):
- """ Registers an event listener (aka 'subscriber') listening for
- events of the type ``event_iface`` and returns a list which is
- appended to by the subscriber. When an event is dispatched that
- matches ``event_iface``, that event will be appended to the list.
- You can then compare the values in the list to expected event
- notifications. This method is useful when testing code that wants
- to call ``zope.component.event.dispatch`` or
+ """ Registers an :term:`event` listener (aka :term:`subscriber`)
+ listening for events of the type ``event_iface`` and returns a
+ list which is appended to by the subscriber. When an event is
+ dispatched that matches ``event_iface``, that event will be
+ appended to the list. You can then compare the values in the list
+ to expected event notifications. This method is useful when
+ testing code that wants to call ``registry.notify``,
+ ``zope.component.event.dispatch`` or
``zope.component.event.objectEventNotify``."""
L = []
def subscriber(*event):
@@ -98,7 +100,7 @@ def registerEventListener(event_iface=Interface):
return L
def registerTemplateRenderer(path, renderer=None):
- """ Register a 'template renderer' at ``path`` (usually a relative
+ """ Register a template tenderer at ``path`` (usually a relative
filename ala ``templates/foo.pt``) and return the renderer object.
If the ``renderer`` argument is None, a 'dummy' renderer will be
used. This function is useful when testing code that calls the
@@ -114,16 +116,16 @@ registerDummyRenderer = registerTemplateRenderer
def registerView(name, result='', view=None, for_=(Interface, Interface),
permission=None):
- """ Registers ``repoze.bfg`` view function under the name
+ """ Registers a :mod:`repoze.bfg` view callable under the name
``name``. The view will return a webob Response object with the
``result`` value as its body attribute. To gain more control, if
you pass in a non-None ``view``, this view function will be used
instead of an automatically generated view function (and
- ``result`` is not used). To protect the view using a permission,
- pass in a non-``None`` value as ``permission``. This permission
- will be checked by any existing security policy when view
- execution is attempted. This function is useful when dealing with
- code that wants to call,
+ ``result`` is not used). To protect the view using a
+ :term:`permission`, pass in a non-``None`` value as
+ ``permission``. This permission will be checked by any existing
+ security policy when view execution is attempted. This function
+ is useful when dealing with code that wants to call,
e.g. ``repoze.bfg.view.render_view_to_response``."""
if view is None:
def view(context, request):
@@ -144,20 +146,21 @@ def registerView(name, result='', view=None, for_=(Interface, Interface),
def registerViewPermission(name, result=True, viewpermission=None,
for_=(Interface, Interface)):
- """ Registers a ``repoze.bfg`` 'view permission' object under
- the name ``name``. The view permission return a result
- denoted by the ``result`` argument. If ``result`` is True, a
+ """ Registers a :mod:`repoze.bfg` 'view permission' object under
+ the name ``name``. The view permission return a result denoted by
+ the ``result`` argument. If ``result`` is True, a
``repoze.bfg.security.Allowed`` object is returned; else a
- ``repoze.bfg.security.Denied`` object is returned. To gain
- more control, if you pass in a non-None ``viewpermission``,
- this view permission object will be used instead of an
- automatically generated view permission (and ``result`` is not
- used). This method is useful when dealing with code that
- wants to call, e.g. ``repoze.bfg.view.view_execution_permitted``.
- Note that view permissions are not checked unless a security
- policy is in effect (see ``registerSecurityPolicy``).
-
- **This function was deprecated in repoze.bfg 1.1.**
+ ``repoze.bfg.security.Denied`` object is returned. To gain more
+ control, if you pass in a non-None ``viewpermission``, this view
+ permission object will be used instead of an automatically
+ generated view permission (and ``result`` is not used). This
+ method is useful when dealing with code that wants to call,
+ e.g. ``repoze.bfg.view.view_execution_permitted``. Note that view
+ permissions are not checked unless a security policy is in effect
+ (see ``registerSecurityPolicy``).
+
+ .. warning:: This function was deprecated in repoze.bfg 1.1; it
+ has no real effect in 1.2+.
"""
if result is True:
result = Allowed('message')
@@ -180,19 +183,20 @@ deprecated('registerViewPermission',
'``permission`` argument.')
def registerUtility(impl, iface=Interface, name=''):
- """ Register a Zope component architecture utility component.
+ """ Register a utility component.
``impl`` is the implementation of the utility. ``iface`` is the
interface type ``zope.interface.Interface`` by default. ``name``
- is the empty string by default. See `The ZCA book
- <http://www.muthukadan.net/docs/zca.html>`_ for more information
- about ZCA utilities."""
+ is the empty string by default.
+
+ See `The ZCA book <http://www.muthukadan.net/docs/zca.html>`_ for
+ more information about ZCA utilities."""
reg = get_current_registry()
reg.registerUtility(impl, iface, name=name)
return impl
def registerAdapter(impl, for_=Interface, provides=Interface, name=''):
- """ Register a Zope component architecture adapter component.
+ """ Register an adapter component.
``impl`` is the implementation of the component (often a class).
``for_`` is the ``for`` interface type
@@ -201,9 +205,10 @@ def registerAdapter(impl, for_=Interface, provides=Interface, name=''):
to underlying ZCA registerAdapter API. ``name`` is the empty
string by default. ``provides`` is the ZCA provides interface,
also ``zope.interface.Interface`` by default. ``name`` is the
- name of the adapter, the empty string by default. See `The ZCA
- book <http://www.muthukadan.net/docs/zca.html>`_ for more
- information about ZCA adapters."""
+ name of the adapter, the empty string by default.
+
+ See `The ZCA book <http://www.muthukadan.net/docs/zca.html>`_ for
+ more information about ZCA adapters."""
reg = get_current_registry()
if not isinstance(for_, (tuple, list)):
for_ = (for_,)
@@ -211,16 +216,17 @@ def registerAdapter(impl, for_=Interface, provides=Interface, name=''):
return impl
def registerSubscriber(subscriber, iface=Interface):
- """ Register a Zope component architecture subscriber component.
+ """ Register a subscriber component.
``subscriber`` is the implementation of the component (often a
function). ``iface`` is the interface type the subscriber will be
registered for (``zope.interface.Interface`` by default). If
``iface`` is not a tuple or list, it will be converted to a
- one-tuple before being passed to underlying zca registerHandler
- query. See `The ZCA book
- <http://www.muthukadan.net/docs/zca.html>`_ for more information
- about ZCA subscribers."""
+ one-tuple before being passed to underlying ZCA registerHandler
+ query.
+
+ See `The ZCA book <http://www.muthukadan.net/docs/zca.html>`_ for
+ more information about ZCA subscribers."""
reg = get_current_registry()
if not isinstance(iface, (tuple, list)):
iface = (iface,)
@@ -231,9 +237,10 @@ def registerTraverser(traverser, for_=Interface):
return registerAdapter(traverser, for_, ITraverser)
def registerRoute(path, name, factory=None):
- """ Register a new route using a path (e.g. ``:pagename``), a name
- (e.g. 'home'), and an optional root factory. This is useful for
- testing code that calls e.g. ``route_url``.
+ """ Register a new :term:`route` using a path
+ (e.g. ``:pagename``), a name (e.g. 'home'), and an optional root
+ factory. This is useful for testing code that calls
+ e.g. ``route_url``.
.. note:: This API was added in :mod:`repoze.bfg` version 1.1.
"""
@@ -338,10 +345,10 @@ class DummySecurityPolicy:
class DummyTemplateRenderer:
"""
An instance of this class is returned from
- ``registerTemplateRenderer``. It has a helper function (``assert_``)
- that makes it possible to make an assertion which compares data
- passed to the renderer by the view function against expected
- key/value pairs.
+ ``registerTemplateRenderer``. It has a helper function
+ (``assert_``) that makes it possible to make an assertion which
+ compares data passed to the renderer by the view function against
+ expected key/value pairs.
"""
def __init__(self, string_response=''):
@@ -467,10 +474,11 @@ class DummyModel:
return inst
class DummyRequest:
- """ A dummy request object (imitates a :term:`WebOb` ``Request`` object).
+ """ A dummy request object (imitates a :term:`request` object).
- The ``params``, ``environ``, ``headers``, ``path``, and ``cookies``
- arguments correspond to their WebOb equivalents.
+ The ``params``, ``environ``, ``headers``, ``path``, and
+ ``cookies`` arguments correspond to their :term`WebOb`
+ equivalents.
The ``post`` argument, if passed, populates the request's
``POST`` attribute, but *not* ``params``, in order to allow testing
diff --git a/repoze/bfg/traversal.py b/repoze/bfg/traversal.py
index 43680be0d..051a4c34c 100644
--- a/repoze/bfg/traversal.py
+++ b/repoze/bfg/traversal.py
@@ -81,8 +81,8 @@ def find_interface(model, class_or_interface):
Return the first object found in the parent chain of ``model``
which, a) if ``class_or_interface`` is a Python class object, is
an instance of the class or any subclass of that class or b) if
- ``class_or_interface`` is a Zope interface, provides the specified
- interface. Return ``None`` if no object providing
+ ``class_or_interface`` is a :term:`interface`, provides the
+ specified interface. Return ``None`` if no object providing
``interface_or_class`` can be found in the parent chain. The
``model`` passed in *must* be :term:`location`-aware.
"""
@@ -149,67 +149,70 @@ def traverse(model, path):
A definition of each value in the returned dictionary:
- - ``context``: The context (a 'model' object) found via traversal
- or url dispatch. If the ``path`` passed in is the empty string,
- the value of the ``model`` argument passed to this function is
- returned.
+ - ``context``: The :term:`context` (a :term:`model` object) found
+ via traversal or url dispatch. If the ``path`` passed in is the
+ empty string, the value of the ``model`` argument passed to this
+ function is returned.
- - ``root``: The model object at which traversal begins. If the
- ``model`` passed in was found via url dispatch or if the
+ - ``root``: The model object at which :term:`traversal` begins.
+ If the ``model`` passed in was found via url dispatch or if the
``path`` passed in was relative (non-absolute), the value of the
``model`` argument passed to this function is returned.
- - ``view_name``: The 'view name' found during traversal or url
- dispatch; if the ``model`` was found via traversal, this is
- usually a representation of the path segment which directly
- follows the path to the ``context`` in the ``path``. The
- ``view_name`` will be a Unicode object or the empty string. The
- ``view_name`` will be the empty string if there is no element
- which follows the ``context`` path. An example: if the path
- passed is ``/foo/bar``, and a context object is found at
- ``/foo`` (but not at ``/foo/bar``), the 'view name' will be
- ``u'bar'``. If the ``model`` was found via urldispatch, the
- view_name will be the name the route found was registered with.
-
- - ``subpath``: For a ``model`` found via traversal, this is a
- sequence of path segments found in the ``path`` that follow the
- ``view_name`` (if any). Each of these items is a Unicode
+ - ``view_name``: The :term:`view name` found during
+ :term:`traversal` or :term:`url dispatch`; if the ``model`` was
+ found via traversal, this is usually a representation of the
+ path segment which directly follows the path to the ``context``
+ in the ``path``. The ``view_name`` will be a Unicode object or
+ the empty string. The ``view_name`` will be the empty string if
+ there is no element which follows the ``context`` path. An
+ example: if the path passed is ``/foo/bar``, and a context
+ object is found at ``/foo`` (but not at ``/foo/bar``), the 'view
+ name' will be ``u'bar'``. If the ``model`` was found via
+ urldispatch, the view_name will be the name the route found was
+ registered with.
+
+ - ``subpath``: For a ``model`` found via :term:`traversal`, this
+ is a sequence of path segments found in the ``path`` that follow
+ the ``view_name`` (if any). Each of these items is a Unicode
object. If no path segments follow the ``view_name``, the
- subpath will be the empty list. An example: if the path passed
- is ``/foo/bar/baz/buz``, and a context object is found at
+ subpath will be the empty sequence. An example: if the path
+ passed is ``/foo/bar/baz/buz``, and a context object is found at
``/foo`` (but not ``/foo/bar``), the 'view name' will be
- ``u'bar'`` and the subpath will be ``[u'baz', u'buz']``. For a
- ``model`` found via url dispatch, the subpath will be a sequence
- of values discerned from ``*subpath`` in the route pattern
- matched or the empty sequence.
+ ``u'bar'`` and the :term:`subpath` will be ``[u'baz', u'buz']``.
+ For a ``model`` found via url dispatch, the subpath will be a
+ sequence of values discerned from ``*subpath`` in the route
+ pattern matched or the empty sequence.
- ``traversed``: The sequence of path elements traversed from the
- root to find the ``context`` object. Each of these items is a
- Unicode object. If no path segments were traversed to find the
- ``context`` object (e.g. if the ``path`` provided is the empty
- string), the ``traversed`` value will be the empty list. If the
- ``model`` is a model found via urldispatch, traversed will be
- None.
+ root to find the ``context`` object during :term:`traversal`.
+ Each of these items is a Unicode object. If no path segments
+ were traversed to find the ``context`` object (e.g. if the
+ ``path`` provided is the empty string), the ``traversed`` value
+ will be the empty sequence. If the ``model`` is a model found
+ via :term:`url dispatch`, traversed will be None.
- ``virtual_root``: A model object representing the 'virtual' root
- of the object graph being traversed. See
- :ref:`vhosting_chapter` for a definition of the virtual root
+ of the object graph being traversed during :term:`traversal`.
+ See :ref:`vhosting_chapter` for a definition of the virtual root
object. If no virtual hosting is in effect, and the ``path``
passed in was absolute, the ``virtual_root`` will be the
- *physical* root object (the object at which traversal begins).
- If the ``model`` passed in was found via URL dispatch or if the
- ``path`` passed in was relative, the ``virtual_root`` will
- always equal the ``root`` object (the model passed in).
-
- - ``virtual_root_path`` -- If traversal was used to find the
- ``model``, this will be the sequence of path elements traversed
- to find the ``virtual_root`` object. Each of these items is a
- Unicode object. If no path segments were traversed to find the
- ``virtual_root`` object (e.g. if virtual hosting is not in
- effect), the ``traversed`` value will be the empty list. If url
- dispatch was used to find the ``model``, this will be None.
+ *physical* root object (the object at which :term:`traversal`
+ begins). If the ``model`` passed in was found via :term:`URL
+ dispatch` or if the ``path`` passed in was relative, the
+ ``virtual_root`` will always equal the ``root`` object (the
+ model passed in).
+
+ - ``virtual_root_path`` -- If :term:`traversal` was used to find
+ the ``model``, this will be the sequence of path elements
+ traversed to find the ``virtual_root`` object. Each of these
+ items is a Unicode object. If no path segments were traversed
+ to find the ``virtual_root`` object (e.g. if virtual hosting is
+ not in effect), the ``traversed`` value will be the empty list.
+ If url dispatch was used to find the ``model``, this will be
+ None.
- If the path cannot be resolved, a KeyError will be raised.
+ If the path cannot be resolved, a ``KeyError`` will be raised.
Rules for passing a *string* as the ``path`` argument: if the
first character in the path string is the with the ``/``
@@ -244,14 +247,14 @@ def traverse(model, path):
Explanation of the conversion of ``path`` segment values to
Unicode during traversal: Each segment is URL-unquoted, and
decoded into Unicode. Each segment is assumed to be encoded using
- the UTF-8 encoding (or a subset, such as ASCII); a TypeError is
- raised if a segment cannot be decoded. If a segment name is empty
- or if it is ``.``, it is ignored. If a segment name is ``..``,
- the previous segment is deleted, and the ``..`` is ignored. As a
- result of this process, the return values ``view_name``, each
- element in the ``subpath``, each element in ``traversed``, and
- each element in the ``virtual_root_path`` will be Unicode as
- opposed to a string, and will be URL-decoded.
+ the UTF-8 encoding (or a subset, such as ASCII); a ``TypeError``
+ is raised if a segment cannot be decoded. If a segment name is
+ empty or if it is ``.``, it is ignored. If a segment name is
+ ``..``, the previous segment is deleted, and the ``..`` is
+ ignored. As a result of this process, the return values
+ ``view_name``, each element in the ``subpath``, each element in
+ ``traversed``, and each element in the ``virtual_root_path`` will
+ be Unicode as opposed to a string, and will be URL-decoded.
"""
if hasattr(path, '__iter__'):
@@ -279,8 +282,8 @@ def traverse(model, path):
def model_path_tuple(model, *elements):
"""
Return a tuple representing the absolute physical path of the
- model object based on its position in the model graph, e.g ``('',
- 'foo', 'bar')``. Any positional arguments passed in as
+ ``model`` object based on its position in an object graph, e.g
+ ``('', 'foo', 'bar')``. Any positional arguments passed in as
``elements`` will be appended as elements in the tuple
representing the the model path. For instance, if the model's
path is ``('', 'foo', 'bar')`` and elements equals ``('a', 'b')``,
@@ -324,11 +327,12 @@ def _model_path_list(model, *elements):
def virtual_root(model, request):
"""
- Provided any model and a request object, return the model object
- representing the 'virtual root' of the current request. Using a
- virtual root in a traversal-based :mod:`repoze.bfg` application
- permits rooting, for example, the object at the traversal path
- ``/cms`` at ``http://example.com/`` instead of rooting it at
+ Provided any :term:`model` and a :term:`request` object, return
+ the model object representing the :term:`virtual root` of the
+ current :term:`request`. Using a virtual root in a
+ :term:`traversal` -based :mod:`repoze.bfg` application permits
+ rooting, for example, the object at the traversal path ``/cms`` at
+ ``http://example.com/`` instead of rooting it at
``http://example.com/cms/``.
If the ``model`` passed in is a context obtained via
@@ -336,9 +340,9 @@ def virtual_root(model, request):
WSGI environment, the value of this key will be treated as a
'virtual root path': the :func:`repoze.bfg.traversal.find_model`
API will be used to find the virtual root object using this path;
- if the object is found, it will found will be returned. If the
- ``%s`` key is is not present in the WSGI environment, the physical
- :term:`root` of the graph will be returned instead.
+ if the object is found, it will be returned. If the
+ ``HTTP_X_VHM_ROOT`` key is is not present in the WSGI environment,
+ the physical :term:`root` of the graph will be returned instead.
Virtual roots are not useful at all in applications that use
:term:`URL dispatch`. Contexts obtained via URL dispatch don't
@@ -595,13 +599,14 @@ class TraversalContextURL(object):
return find_root(self.context)
def __call__(self):
- """ Generate a URL based on the lineage of a model obtained
- via traversal. If any model in the context lineage has a
- unicode name, it will be converted to a UTF-8 string before
- being attached to the URL. If a ``HTTP_X_VHM_ROOT`` key is
- present in the WSGI environment, its value will be treated as
- a 'virtual root path': the path of the URL generated by this
- will be left-stripped of this virtual root path value.
+ """ Generate a URL based on the :term:`lineage` of a
+ :term:`model` object obtained via :term:`traversal`. If any
+ model in the context lineage has a Unicode name, it will be
+ converted to a UTF-8 string before being attached to the URL.
+ If a ``HTTP_X_VHM_ROOT`` key is present in the WSGI
+ environment, its value will be treated as a 'virtual root
+ path': the path of the URL generated by this will be
+ left-stripped of this virtual root path value.
"""
path = model_path(self.context)
if path != '/':
diff --git a/repoze/bfg/url.py b/repoze/bfg/url.py
index 2079b41cd..741fab9ce 100644
--- a/repoze/bfg/url.py
+++ b/repoze/bfg/url.py
@@ -15,7 +15,8 @@ from repoze.bfg.traversal import TraversalContextURL
from repoze.bfg.traversal import quote_path_segment
def route_url(route_name, request, *elements, **kw):
- """Generates a fully qualified URL for a named BFG route.
+ """Generates a fully qualified URL for a named :mod:`repoze.bfg`
+ :term:`route configuration`.
Use the route's ``name`` as the first positional argument. Use a
request object as the second positional argument. Additional
@@ -23,7 +24,7 @@ def route_url(route_name, request, *elements, **kw):
after it is generated.
Use keyword arguments to supply values which match any dynamic
- path elements in the route definition. Raises a KeyError
+ path elements in the route definition. Raises a ``KeyError``
exception if the URL cannot be generated for any reason (not
enough arguments, for example).
@@ -118,22 +119,11 @@ def route_url(route_name, request, *elements, **kw):
def model_url(model, request, *elements, **kw):
"""
- Generate a string representing the absolute URL of the model (or
- context) object based on the ``wsgi.url_scheme``, ``HTTP_HOST`` or
- ``SERVER_NAME`` in the request, plus any ``SCRIPT_NAME``. If a
- 'virtual root path' is present in the request environment (the
- value of the WSGI environ key ``HTTP_X_VHM_ROOT``), and the
- ``model`` was obtained via traversal, the URL path will not
- include the virtual root prefix (it will be stripped out of the
- generated URL). If a ``query`` keyword argument is provided, a
- query string based on its value will be composed and appended to
- the generated URL string (see details below). The overall result
- of this function is always a UTF-8 encoded string (never unicode).
-
- .. note:: If the ``model`` used is the result of a traversal, it
- must be :term:`location`-aware. The 'model' can also be the
- context of a URL dispatch; contexts found this way do not need
- to be location-aware.
+ Generate a string representing the absolute URL of the ``model``
+ object based on the ``wsgi.url_scheme``, ``HTTP_HOST`` or
+ ``SERVER_NAME`` in the ``request``, plus any ``SCRIPT_NAME``. The
+ overall result of this function is always a UTF-8 encoded string
+ (never unicode).
Examples::
@@ -151,7 +141,7 @@ def model_url(model, request, *elements, **kw):
model_url(context, request, 'a.html', anchor='abc') =>
- http://example.com/#abc
+ http://example.com/a.html#abc
Any positional arguments passed in as ``elements`` must be strings
or unicode objects. These will be joined by slashes and appended
@@ -197,6 +187,19 @@ def model_url(model, request, *elements, **kw):
If both ``anchor`` and ``query`` are specified, the anchor element
will always follow the query element,
e.g. ``http://example.com?foo=1#bar``.
+
+ .. note:: If the ``model`` used is the result of a
+ :term:`traversal`, it must be :term:`location`-aware.
+ The ``model`` can also be the context of a :term:`URL
+ dispatch`; contexts found this way do not need to be
+ location-aware.
+
+ .. note:: If a 'virtual root path' is present in the request
+ environment (the value of the WSGI environ key
+ ``HTTP_X_VHM_ROOT``), and the ``model`` was obtained via
+ :term:`traversal`, the URL path will not include the
+ virtual root prefix (it will be stripped off the
+ left hand side of the generated URL).
"""
try:
reg = request.registry
@@ -229,9 +232,10 @@ def model_url(model, request, *elements, **kw):
def static_url(path, request, **kw):
"""
- Generates a fully qualified URL for a static resource. The
- resource must live within a location defined via the ``<static>``
- ZCML directive (see :ref:`static_resources_section`).
+ Generates a fully qualified URL for a static :term:`resource`.
+ The resource must live within a location defined via the
+ ``add_static_view`` :term:`configuration declaration` or the
+ ``<static>`` ZCML directive (see :ref:`static_resources_section`).
Example::
@@ -247,7 +251,7 @@ def static_url(path, request, **kw):
may not be an absolute filesystem path (a ValueError will be
raised if this function is supplied with an absolute path).
- The ``request`` argument should be a WebOb request.
+ The ``request`` argument should be a :term:`request` object.
The purpose of the ``**kw`` argument is the same as the purpose of
the ``route_url`` ``**kw`` argument. See the documentation for
@@ -255,8 +259,8 @@ def static_url(path, request, **kw):
it. However, typically, you don't need to pass anything as
``*kw`` when generating a static resource URL.
- This function raises a ValueError if a ``<static>`` ZCML
- definition cannot be found which matches the path specification.
+ This function raises a ValueError if a static view definition
+ cannot be found which matches the path specification.
.. note:: This feature is new in :mod:`repoze.bfg` 1.1.
"""
diff --git a/repoze/bfg/view.py b/repoze/bfg/view.py
index d682d762b..e5b271262 100644
--- a/repoze/bfg/view.py
+++ b/repoze/bfg/view.py
@@ -50,14 +50,15 @@ deprecated('NotFound',
_marker = object()
def render_view_to_response(context, request, name='', secure=True):
- """ Render the view named ``name`` against the specified
- ``context`` and ``request`` to an object implementing
- ``repoze.bfg.interfaces.IResponse`` or ``None`` if no such view
- exists. This function will return ``None`` if a corresponding
- view cannot be found. If ``secure`` is ``True``, and the view is
- protected by a permission, the permission will be checked before
- calling the view function. If the permission check disallows view
- execution (based on the current security policy), a
+ """ Render the view with the :term:`view name` ``name`` against
+ the specified ``context`` and ``request`` and return a
+ :term:`response` object or ``None`` if no such view exists.
+
+ This function will return ``None`` if a corresponding view cannot
+ be found. If ``secure`` is ``True``, and the view is protected by
+ a permission, the permission will be checked before calling the
+ view function. If the permission check disallows view execution
+ (based on the current security policy), a
``repoze.bfg.exceptions.Forbidden`` exception will be raised; its
``args`` attribute explains why the view access was disallowed.
If ``secure`` is ``False``, no permission checking is done."""
@@ -83,18 +84,20 @@ def render_view_to_response(context, request, name='', secure=True):
def render_view_to_iterable(context, request, name='', secure=True):
""" Render the view named ``name`` against the specified
``context`` and ``request``, and return an iterable representing
- the view response's ``app_iter`` (see the interface named
- ``repoze.bfg.interfaces.IResponse``). This function will return
- ``None`` if a corresponding view cannot be found. Additionally,
- this function will raise a ``ValueError`` if a view function is
- found and called but the view does not return an object which
- implements ``repoze.bfg.interfaces.IResponse``. You can usually
+ the view response's ``app_iter`` (see :ref:`the_response`).
+
+ This function will return ``None`` if a corresponding view cannot
+ be found. Additionally, this function will raise a ``ValueError``
+ if a view function is found and called but the view function's
+ result does not have an ``app_iter`` attribute. You can usually
get the string representation of the return value of this function
by calling ``''.join(iterable)``, or just use ``render_view``
- instead. If ``secure`` is ``True``, and the view is protected by
- a permission, the permission will be checked before calling the
- view function. If the permission check disallows view execution
- (based on the current security policy), a
+ instead.
+
+ If ``secure`` is ``True``, and the view is protected by a
+ permission, the permission will be checked before the view
+ function is invoked. If the permission check disallows view
+ execution (based on the current :term:`authentication policy`), a
``repoze.bfg.exceptions.Forbidden`` exception will be raised; its
``args`` attribute explains why the view access was disallowed.
If ``secure`` is ``False``, no permission checking is done."""
@@ -106,16 +109,16 @@ def render_view_to_iterable(context, request, name='', secure=True):
def render_view(context, request, name='', secure=True):
""" Render the view named ``name`` against the specified
``context`` and ``request``, and unwind the the view response's
- ``app_iter`` (see the interface named
- ``repoze.bfg.interfaces.IResponse``) into a single string. This
+ ``app_iter`` (see :ref:`the_response`) into a single string. This
function will return ``None`` if a corresponding view cannot be
found. Additionally, this function will raise a ``ValueError`` if
a view function is found and called but the view does not return
an object which implements ``repoze.bfg.interfaces.IResponse``.
+
If ``secure`` is ``True``, and the view is protected by a
- permission, the permission will be checked before calling the view
- function. If the permission check disallows view execution (based
- on the current security policy), a
+ permission, the permission will be checked before the view is
+ invoked. If the permission check disallows view execution (based
+ on the current :term:`authorization policy`), a
``repoze.bfg.exceptions.Forbidden`` exception will be raised; its
``args`` attribute explains why the view access was disallowed.
If ``secure`` is ``False``, no permission checking is done."""
@@ -125,11 +128,12 @@ def render_view(context, request, name='', secure=True):
return ''.join(iterable)
def is_response(ob):
- """ Return True if ``ob`` implements the
- ``repoze.bfg.interfaces.IResponse`` interface, False if not. Note
- that this isn't actually a true Zope interface check, it's a
- duck-typing check, as response objects are not obligated to
- actually implement a Zope interface."""
+ """ Return ``True`` if ``ob`` implements the interface implied by
+ :ref:`the_response`. ``False`` if not.
+
+ .. note:: this isn't a true interface check (in Zope terms), it's a
+ duck-typing check, as response objects are not obligated to
+ actually implement a Zope interface."""
# response objects aren't obligated to implement a Zope interface,
# so we do it the hard way
if ( hasattr(ob, 'app_iter') and hasattr(ob, 'headerlist') and
@@ -141,39 +145,40 @@ def is_response(ob):
return False
class static(object):
- """ An instance of this class is a callable which can act as a BFG
- view; this view will serve static files from a directory on disk
- based on the ``root_dir`` you provide to its constructor.
+ """ An instance of this class is a callable which can act as a
+ :mod:`repoze.bfg` :term:`view callable`; this view will serve
+ static files from a directory on disk based on the ``root_dir``
+ you provide to its constructor.
The directory may contain subdirectories (recursively); the static
view implementation will descend into these directories as
necessary based on the components of the URL in order to resolve a
path into a response.
- You may pass an absolute or relative filesystem path to the
- directory containing static files directory to the constructor as
- the ``root_dir`` argument.
-
- If the path is relative, and the ``package`` argument is ``None``,
- it will be considered relative to the directory in which the
- Python file which calls ``static`` resides. If the ``package``
- name argument is provided, and a relative ``root_dir`` is
- provided, the ``root_dir`` will be considered relative to the
- Python package specified by ``package_name`` (a dotted path to a
- Python package).
-
- ``cache_max_age`` influences the Expires and Max-Age response
- headers returned by the view (default is 3600 seconds or five
- minutes). ``level`` influences how relative directories are
- resolved (the number of hops in the call stack), not used very
- often.
-
- .. note:: If the ``root_dir`` is relative to a package, the BFG
- ``resource`` ZCML directive can be used to override resources
- within the named ``root_dir`` package-relative directory.
- However, if the ``root_dir`` is absolute, the ``resource``
- directive will not be able to override the resources it
- contains.
+ You may pass an absolute or relative filesystem path or a
+ :term:`resource specification` representing the directory
+ containing static files as the ``root_dir`` argument to this
+ class' constructor.
+
+ If the ``root_dir`` path is relative, and the ``package_name``
+ argument is ``None``, ``root_dir`` will be considered relative to
+ the directory in which the Python file which *calls* ``static``
+ resides. If the ``package_name`` name argument is provided, and a
+ relative ``root_dir`` is provided, the ``root_dir`` will be
+ considered relative to the Python :term:`package` specified by
+ ``package_name`` (a dotted path to a Python package).
+
+ ``cache_max_age`` influences the ``Expires`` and ``Max-Age``
+ response headers returned by the view (default is 3600 seconds or
+ five minutes).
+
+ .. note:: If the ``root_dir`` is relative to a :term:`package`, or
+ is a :term:`resource specification` the BFG ``resource`` ZCML
+ directive or :term:`Configurator` method can be used to
+ override resources within the named ``root_dir``
+ package-relative directory. However, if the ``root_dir`` is
+ absolute, the ``resource`` directive will not be able to
+ override the resources it contains.
"""
def __init__(self, root_dir, cache_max_age=3600, package_name=None):
# package_name is for bw compat; it is preferred to pass in a
@@ -200,31 +205,41 @@ class static(object):
return request_copy.get_response(self.app)
class bfg_view(object):
- """ Function or class decorator which allows Python code to make
- view registrations instead of using ZCML for the same purpose.
+ """ A function, class or method :term:`decorator` which allows a
+ developer to create view registrations nearer to a :term:`view
+ callable` definition than use of :term:`ZCML` or :term:`imperative
+ configuration` to do the same.
- E.g. in the module ``views.py``::
+ For example, this code in a module ``views.py``::
- from models import IMyModel
- from repoze.bfg.interfaces import IRequest
+ from models import MyModel
- @bfg_view(name='my_view', request_type=IRequest, for_=IMyModel,
- permission='read', route_name='site1'))
+ @bfg_view(name='my_view', for_=MyModel, permission='read',
+ route_name='site1')
def my_view(context, request):
- return render_template_to_response('templates/my.pt')
+ return 'OK'
+
+ Might replace the following call to the ``add_view`` method of a
+ :term:`Configurator`::
+
+ import views
+ import models
+ config.add_view(views.my_view, for_=models.MyModel, name='my_view',
+ permission='read', 'route_name='site1')
- Equates to the ZCML::
+ Or might relpace the following ZCML ``view`` declaration::
<view
- for='.models.IMyModel'
+ for='.models.MyModel'
view='.views.my_view'
name='my_view'
permission='read'
route_name='site1'
/>
- The following arguments are supported: ``for_``, ``permission``,
- ``name``, ``request_type``, ``route_name``, ``request_method``,
+ The following arguments are supported as arguments to
+ ``bfg_view``: ``for_``, ``permission``, ``name``,
+ ``request_type``, ``route_name``, ``request_method``,
``request_param``, ``containment``, ``xhr``, ``accept``,
``header`` and ``path_info``.
@@ -251,10 +266,10 @@ class bfg_view(object):
``repoze.bfg.interfaces.IRequest`` is used, implying the standard
request interface type.
- If ``route_name`` is not supplied, the view declaration is
+ If ``route_name`` is not supplied, the view configuration is
considered to be made against a URL that doesn't match any defined
:term:`route`. The use of a ``route_name`` is an advanced
- feature, useful only if you're using :term:`url dispatch`.
+ feature, useful only if you're also using :term:`url dispatch`.
If ``request_method`` is not supplied, this view will match a
request with any HTTP ``REQUEST_METHOD``
@@ -276,10 +291,11 @@ class bfg_view(object):
current request.
If ``containment`` is not supplied, this view will be called when
- the context of the request has any location lineage. If
- ``containment`` *is* supplied, it must be a class or :term:`interface`,
- denoting that the view 'matches' the current request only if any graph
- lineage node possesses this class or interface.
+ the context of the request has any (or no) :term:`lineage`. If
+ ``containment`` *is* supplied, it must be a class or
+ :term:`interface`, denoting that the view 'matches' the current
+ request only if any graph :term:`lineage` node possesses this
+ class or interface.
If ``xhr`` is specified, it must be a boolean value. If the value
is ``True``, the view will only be invoked if the request's
@@ -314,12 +330,10 @@ class bfg_view(object):
...
Such a registration implies that the view name will be
- ``my_view``, registered for models with the
- ``zope.interface.Interface`` interface, using no permission,
- registered against requests which implement the default IRequest
- interface when no urldispatch route matches, with any
- REQUEST_METHOD, any set of request.params values, in any lineage
- containment.
+ ``my_view``, registered for any :term:`context` object, using no
+ permission, registered against all non-URL-dispatch-based
+ requests, with any ``REQUEST_METHOD``, any set of request.params
+ values, without respect to any object in the :term:`lineage`.
The ``bfg_view`` decorator can also be used as a class decorator
in Python 2.6 and better (Python 2.5 and below do not support
@@ -336,8 +350,8 @@ class bfg_view(object):
def __call__(self):
return Response('hello from %s!' % self.context)
- In Python 2.5 and below, the bfg_view decorator can still be used
- against a class, although not in decorator form::
+ In Python 2.5 and below, the ``bfg_view`` decorator can still be
+ used against a class, although not in decorator form::
from webob import Response
from repoze.bfg.view import bfg_view
@@ -399,10 +413,16 @@ class bfg_view(object):
method decorator is new in :mod:`repoze.bfg` version
1.1.
- To make use of any bfg_view declaration, you *must* insert the
- following boilerplate into your application registry's ZCML::
+ To make use of any bfg_view declaration, you must perform a
+ :term:`scan`. To do so, either insert the following boilerplate
+ into your application registry's ZCML::
<scan package="."/>
+
+ Or, if you don't use ZCML, use the ``scan`` method of a
+ :term:`Configurator`::
+
+ config.scan()
"""
def __init__(self, name='', request_type=None, for_=None, permission=None,
route_name=None, request_method=None, request_param=None,
@@ -486,12 +506,18 @@ def append_slash_notfound_view(context, request):
data information (turning it into a GET), so you shouldn't rely on
this to redirect POST requests.
- Add the following to your application's ``configure.zcml`` to use
- this view as the Not Found view::
+ If you use ZCML, add the following to your application's
+ ``configure.zcml`` to use this view as the Not Found view::
<notfound
view="repoze.bfg.view.append_slash_notfound_view"/>
+ Or use the ``notfound`` method of a :term:`Configurator` if you
+ don't use ZCML::
+
+ from repoze.bfg.view import append_slash_notfound_view
+ config.notfound(append_slash_notfound_view)
+
See also :ref:`changing_the_notfound_view`.
.. note:: This function is new as of :mod:`repoze.bfg` version 1.1.
diff --git a/repoze/bfg/wsgi.py b/repoze/bfg/wsgi.py
index 10d067901..26229836a 100644
--- a/repoze/bfg/wsgi.py
+++ b/repoze/bfg/wsgi.py
@@ -8,7 +8,7 @@ def wsgiapp(wrapped):
WSGI environment *are not* performed before the application is
invoked.
- E.g.::
+ E.g., the following in a ``views.py`` module::
@wsgiapp
def hello_world(environ, start_response):
@@ -17,14 +17,18 @@ def wsgiapp(wrapped):
('Content-Length', len(body)) ] )
return [body]
- Allows the following view declaration to be made::
+ Allows the following ZCML view declaration to be made::
<view
view=".views.hello_world"
name="hello_world.txt"
- context="*"
/>
+ Or the following :term:`Configurator` ``add_view`` method call::
+
+ from views import hello_world
+ config.add_view(hello_world, name='hello_world.txt')
+
The wsgiapp decorator will convert the result of the WSGI
application to a Response and return it to repoze.bfg as if the
WSGI app were a repoze.bfg view.
@@ -41,7 +45,7 @@ def wsgiapp2(wrapped):
WSGI environment *are* performed before the application is
invoked.
- E.g.::
+ E.g. the following in a ``views.py`` module::
@wsgiapp2
def hello_world(environ, start_response):
@@ -50,14 +54,18 @@ def wsgiapp2(wrapped):
('Content-Length', len(body)) ] )
return [body]
- Allows the following view declaration to be made::
+ Allows the following ZCML view declaration to be made::
<view
view=".views.hello_world"
name="hello_world.txt"
- context="*"
/>
+ Or the following :term:`Configurator` ``add_view`` method call::
+
+ from views import hello_world
+ config.add_view(hello_world, name='hello_world.txt')
+
The wsgiapp2 decorator will convert the result of the WSGI
application to a Response and return it to repoze.bfg as if the
WSGI app were a repoze.bfg view. The ``SCRIPT_NAME`` and