summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2012-02-17 18:29:44 -0500
committerChris McDonough <chrism@plope.com>2012-02-17 18:29:44 -0500
commit222638ad3760692ac0ec5368db4baaee9272e818 (patch)
treeb8fc997119a2b470db290c8270241e8991eb797e /docs
parentcdb5f5a395c53e18a250651b6c9c3e0322b0dfe5 (diff)
parent305d23f9e9dd095f4fdface116a2155bd86a453c (diff)
downloadpyramid-222638ad3760692ac0ec5368db4baaee9272e818.tar.gz
pyramid-222638ad3760692ac0ec5368db4baaee9272e818.tar.bz2
pyramid-222638ad3760692ac0ec5368db4baaee9272e818.zip
Merge branch '1.3-branch'
Diffstat (limited to 'docs')
-rw-r--r--docs/api/config.rst2
-rw-r--r--docs/api/interfaces.rst4
-rw-r--r--docs/api/request.rst2
-rw-r--r--docs/narr/hooks.rst88
-rw-r--r--docs/narr/introspector.rst15
-rw-r--r--docs/narr/project.rst19
-rw-r--r--docs/narr/renderers.rst20
-rw-r--r--docs/narr/resources.rst39
-rw-r--r--docs/narr/traversal.rst9
-rw-r--r--docs/tutorials/.gitignore1
-rw-r--r--docs/tutorials/wiki2/authorization.rst4
-rw-r--r--docs/tutorials/wiki2/definingviews.rst8
-rw-r--r--docs/tutorials/wiki2/src/authorization/tutorial/views.py13
-rw-r--r--docs/tutorials/wiki2/src/views/tutorial/views.py13
-rw-r--r--docs/whatsnew-1.3.rst100
15 files changed, 232 insertions, 105 deletions
diff --git a/docs/api/config.rst b/docs/api/config.rst
index d16930cc0..3fc2cfc44 100644
--- a/docs/api/config.rst
+++ b/docs/api/config.rst
@@ -94,6 +94,8 @@
.. automethod:: set_notfound_view
+ .. automethod:: add_traverser
+
.. automethod:: set_renderer_globals_factory(factory)
.. attribute:: introspectable
diff --git a/docs/api/interfaces.rst b/docs/api/interfaces.rst
index 11cd8cf7e..1dea5fab0 100644
--- a/docs/api/interfaces.rst
+++ b/docs/api/interfaces.rst
@@ -79,3 +79,7 @@ Other Interfaces
.. autointerface:: IAssetDescriptor
:members:
+
+ .. autointerface:: IResourceURL
+ :members:
+
diff --git a/docs/api/request.rst b/docs/api/request.rst
index 1ab84e230..e1b233fbc 100644
--- a/docs/api/request.rst
+++ b/docs/api/request.rst
@@ -183,6 +183,8 @@
.. automethod:: resource_url
+ .. automethod:: resource_path
+
.. attribute:: response_*
In Pyramid 1.0, you could set attributes on a
diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst
index fd6544416..2c4310080 100644
--- a/docs/narr/hooks.rst
+++ b/docs/narr/hooks.rst
@@ -406,11 +406,10 @@ via configuration.
.. code-block:: python
:linenos:
- from pyramid.interfaces import ITraverser
- from zope.interface import Interface
+ from pyramid.config import Configurator
from myapp.traversal import Traverser
-
- config.registry.registerAdapter(Traverser, (Interface,), ITraverser)
+ config = Configurator()
+ config.set_traverser(Traverser)
In the example above, ``myapp.traversal.Traverser`` is assumed to be a class
that implements the following interface:
@@ -456,12 +455,11 @@ used. Otherwise, the default traverser would be used. For example:
.. code-block:: python
:linenos:
- from pyramid.interfaces import ITraverser
- from zope.interface import Interface
from myapp.traversal import Traverser
from myapp.resources import MyRoot
-
- config.registry.registerAdapter(Traverser, (MyRoot,), ITraverser)
+ from pyramid.config import Configurator
+ config = Configurator()
+ config.set_traverser(Traverser, MyRoot)
If the above stanza was added to a Pyramid ``__init__.py`` file's ``main``
function, :app:`Pyramid` would use the ``myapp.traversal.Traverser`` only
@@ -481,58 +479,55 @@ When you add a traverser as described in :ref:`changing_the_traverser`, it's
often convenient to continue to use the
:meth:`pyramid.request.Request.resource_url` API. However, since the way
traversal is done will have been modified, the URLs it generates by default
-may be incorrect.
+may be incorrect when used against resources derived from your custom
+traverser.
If you've added a traverser, you can change how
:meth:`~pyramid.request.Request.resource_url` generates a URL for a specific
-type of resource by adding a registerAdapter call for
-:class:`pyramid.interfaces.IContextURL` to your application:
+type of resource by adding a call to
+:meth:`pyramid.config.add_resource_url_adapter`.
+
+For example:
.. code-block:: python
:linenos:
- from pyramid.interfaces import ITraverser
- from zope.interface import Interface
- from myapp.traversal import URLGenerator
+ from myapp.traversal import ResourceURLAdapter
from myapp.resources import MyRoot
- config.registry.registerAdapter(URLGenerator, (MyRoot, Interface),
- IContextURL)
+ config.add_resource_url_adapter(ResourceURLAdapter, resource_iface=MyRoot)
-In the above example, the ``myapp.traversal.URLGenerator`` class will be used
-to provide services to :meth:`~pyramid.request.Request.resource_url` any time
-the :term:`context` passed to ``resource_url`` is of class
-``myapp.resources.MyRoot``. The second argument in the ``(MyRoot,
-Interface)`` tuple represents the type of interface that must be possessed by
-the :term:`request` (in this case, any interface, represented by
-``zope.interface.Interface``).
+In the above example, the ``myapp.traversal.ResourceURLAdapter`` class will
+be used to provide services to :meth:`~pyramid.request.Request.resource_url`
+any time the :term:`resource` passed to ``resource_url`` is of the class
+``myapp.resources.MyRoot``. The ``resource_iface`` argument ``MyRoot``
+represents the type of interface that must be possessed by the resource for
+this resource url factory to be found. If the ``resource_iface`` argument is
+omitted, this resource url adapter will be used for *all* resources.
-The API that must be implemented by a class that provides
-:class:`~pyramid.interfaces.IContextURL` is as follows:
+The API that must be implemented by your a class that provides
+:class:`~pyramid.interfaces.IResourceURL` is as follows:
.. code-block:: python
:linenos:
- from zope.interface import Interface
-
- class IContextURL(Interface):
- """ An adapter which deals with URLs related to a context.
+ class MyResourceURL(object):
+ """ An adapter which provides the virtual and physical paths of a
+ resource
"""
- def __init__(self, context, request):
- """ Accept the context and request """
-
- def virtual_root(self):
- """ Return the virtual root object related to a request and the
- current context"""
-
- def __call__(self):
- """ Return a URL that points to the context """
+ def __init__(self, resource, request):
+ """ Accept the resource and request and set self.physical_path and
+ self.virtual_path"""
+ self.virtual_path = some_function_of(resource, request)
+ self.physical_path = some_other_function_of(resource, request)
The default context URL generator is available for perusal as the class
-:class:`pyramid.traversal.TraversalContextURL` in the `traversal module
+:class:`pyramid.traversal.ResourceURL` in the `traversal module
<http://github.com/Pylons/pyramid/blob/master/pyramid/traversal.py>`_ of the
:term:`Pylons` GitHub Pyramid repository.
+See :meth:`pyramid.config.add_resource_url_adapter` for more information.
+
.. index::
single: IResponse
single: special view responses
@@ -606,24 +601,24 @@ adapter to the more complex IResponse interface:
If you want to implement your own Response object instead of using the
:class:`pyramid.response.Response` object in any capacity at all, you'll have
to make sure the object implements every attribute and method outlined in
-:class:`pyramid.interfaces.IResponse` and you'll have to ensure that it's
-marked up with ``zope.interface.implements(IResponse)``:
+:class:`pyramid.interfaces.IResponse` and you'll have to ensure that it uses
+``zope.interface.implementer(IResponse)`` as a class decoratoror.
.. code-block:: python
:linenos:
from pyramid.interfaces import IResponse
- from zope.interface import implements
+ from zope.interface import implementer
+ @implementer(IResponse)
class MyResponse(object):
- implements(IResponse)
# ... an implementation of every method and attribute
# documented in IResponse should follow ...
When an alternate response object implementation is returned by a view
callable, if that object asserts that it implements
:class:`~pyramid.interfaces.IResponse` (via
-``zope.interface.implements(IResponse)``) , an adapter needn't be registered
+``zope.interface.implementer(IResponse)``) , an adapter needn't be registered
for the object; Pyramid will use it directly.
An IResponse adapter for ``webob.Response`` (as opposed to
@@ -812,14 +807,15 @@ performed, enabling you to set up the utility in advance:
.. code-block:: python
:linenos:
+ from zope.interface import implementer
+
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from mypackage.interfaces import IMyUtility
+ @implementer(IMyUtility)
class UtilityImplementation:
- implements(IMyUtility)
-
def __init__(self):
self.registrations = {}
diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst
index 11d779854..08cc430f6 100644
--- a/docs/narr/introspector.rst
+++ b/docs/narr/introspector.rst
@@ -529,6 +529,21 @@ introspectables in categories not described here.
A normalized version of the ``spec`` argument provided to
``add_static_view``.
+``traversers``
+
+ Each introspectable in the ``traversers`` category represents a call to
+ :meth:`pyramid.config.Configurator.add_traverser`; each will have the
+ following data.
+
+ ``iface``
+
+ The (resolved) interface or class object that represents the return value
+ of a root factory that this traverser will be used for.
+
+ ``factory``
+
+ The (resolved) traverser class.
+
Introspection in the Toolbar
----------------------------
diff --git a/docs/narr/project.rst b/docs/narr/project.rst
index d69f0cf13..4566a4fb8 100644
--- a/docs/narr/project.rst
+++ b/docs/narr/project.rst
@@ -322,9 +322,26 @@ image again.
.. image:: project-debug.png
+If you don't see the debug toolbar image on the right hand top of the page,
+it means you're browsing from a system that does not have debugging access.
+By default, for security reasons, only a browser originating from
+``localhost`` (``127.0.0.1``) can see the debug toolbar. To allow your
+browser on a remote system to access the server, add the a line within the
+``[app:main]`` section of the ``development.ini`` file in the form
+``debugtoolbar.hosts = X.X.X.X``. For example, if your Pyramid application
+is running on a remote system, and you're browsing from a host with the IP
+address ``192.168.1.1``, you'd add something like this to enable the toolbar
+when your system contacts Pyramid:
+
+.. code-block:: ini
+
+ [app:main]
+ # .. other settings ...
+ debugtoolbar.hosts = 192.168.1.1
+
For more information about what the debug toolbar allows you to do, see `the
documentation for pyramid_debugtoolbar
-<http://docs.pylonsproject.org/projects/pyramid_debugtoolbar/dev/>`_.
+<http://docs.pylonsproject.org/projects/pyramid_debugtoolbar/en/latest/>`_.
The debug toolbar will not be shown (and all debugging will be turned off)
when you use the ``production.ini`` file instead of the ``development.ini``
diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst
index ed391f4fe..1f1b1943b 100644
--- a/docs/narr/renderers.rst
+++ b/docs/narr/renderers.rst
@@ -156,7 +156,6 @@ dictionary:
.. code-block:: python
:linenos:
- from pyramid.response import Response
from pyramid.view import view_config
@view_config(renderer='string')
@@ -193,7 +192,6 @@ render the returned dictionary to a JSON serialization:
.. code-block:: python
:linenos:
- from pyramid.response import Response
from pyramid.view import view_config
@view_config(renderer='json')
@@ -335,15 +333,15 @@ dictionary, an error will be raised.
Before passing keywords to the template, the keyword arguments derived from
the dictionary returned by the view are augmented. The callable object --
-whatever object was used to define the view -- will be automatically
-inserted into the set of keyword arguments passed to the template as the
-``view`` keyword. If the view callable was a class, the ``view`` keyword
-will be an instance of that class. Also inserted into the keywords passed to
-the template are ``renderer_name`` (the string used in the ``renderer``
-attribute of the directive), ``renderer_info`` (an object containing
-renderer-related information), ``context`` (the context resource of the view
-used to render the template), and ``request`` (the request passed to the view
-used to render the template).
+whatever object was used to define the view -- will be automatically inserted
+into the set of keyword arguments passed to the template as the ``view``
+keyword. If the view callable was a class, the ``view`` keyword will be an
+instance of that class. Also inserted into the keywords passed to the
+template are ``renderer_name`` (the string used in the ``renderer`` attribute
+of the directive), ``renderer_info`` (an object containing renderer-related
+information), ``context`` (the context resource of the view used to render
+the template), and ``request`` (the request passed to the view used to render
+the template). ``request`` is also available as ``req`` in Pyramid 1.3+.
Here's an example view configuration which uses a Chameleon ZPT renderer:
diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst
index 256f69fc3..a24c44f29 100644
--- a/docs/narr/resources.rst
+++ b/docs/narr/resources.rst
@@ -303,13 +303,22 @@ The ``__resource_url__`` hook is passed two arguments: ``request`` and
two keys:
``physical_path``
- The "physical path" computed for the resource, as defined by
- ``pyramid.traversal.resource_path(resource)``.
+ A string representing the "physical path" computed for the resource, as
+ defined by ``pyramid.traversal.resource_path(resource)``. It will begin
+ and end with a slash.
``virtual_path``
- The "virtual path" computed for the resource, as defined by
- :ref:`virtual_root_support`. This will be identical to the physical path
- if virtual rooting is not enabled.
+ A string representing the "virtual path" computed for the resource, as
+ defined by :ref:`virtual_root_support`. This will be identical to the
+ physical path if virtual rooting is not enabled. It will begin and end
+ with a slash.
+
+``app_url``
+ A string representing the application URL generated during
+ ``request.resource_url``. It will not end with a slash. It represents a
+ potentially customized URL prefix, containing potentially custom scheme,
+ host and port information passed by the user to ``request.resource_url``.
+ It should be preferred over use of ``request.application_url``.
The ``__resource_url__`` method of a resource should return a string
representing a URL. If it cannot override the default, it should return
@@ -322,16 +331,16 @@ Here's an example ``__resource_url__`` method.
class Resource(object):
def __resource_url__(self, request, info):
- return request.application_url + info['virtual_path']
+ return info['app_url'] + info['virtual_path']
The above example actually just generates and returns the default URL, which
-would have been what was returned anyway, but your code can perform arbitrary
-logic as necessary. For example, your code may wish to override the hostname
-or port number of the generated URL.
+would have been what was generated by the default ``resource_url`` machinery,
+but your code can perform arbitrary logic as necessary. For example, your
+code may wish to override the hostname or port number of the generated URL.
Note that the URL generated by ``__resource_url__`` should be fully
qualified, should end in a slash, and should not contain any query string or
-anchor elements (only path elements) to work best with
+anchor elements (only path elements) to work with
:meth:`~pyramid.request.Request.resource_url`.
.. index::
@@ -540,14 +549,14 @@ declares that the blog entry implements an :term:`interface`.
:linenos:
import datetime
- from zope.interface import implements
+ from zope.interface import implementer
from zope.interface import Interface
class IBlogEntry(Interface):
pass
+ @implementer(IBlogEntry)
class BlogEntry(object):
- implements(IBlogEntry)
def __init__(self, title, body, author):
self.title = title
self.body = body
@@ -556,15 +565,15 @@ declares that the blog entry implements an :term:`interface`.
This resource consists of two things: the class which defines the resource
constructor as the class ``BlogEntry``, and an :term:`interface` attached to
-the class via an ``implements`` statement at class scope using the
-``IBlogEntry`` interface as its sole argument.
+the class via an ``implementer`` class decorator using the ``IBlogEntry``
+interface as its sole argument.
The interface object used must be an instance of a class that inherits from
:class:`zope.interface.Interface`.
A resource class may implement zero or more interfaces. You specify that a
resource implements an interface by using the
-:func:`zope.interface.implements` function at class scope. The above
+:func:`zope.interface.implementer` function as a class decorator. The above
``BlogEntry`` resource implements the ``IBlogEntry`` interface.
You can also specify that a particular resource *instance* provides an
diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst
index 8c5d950c1..8e7f93a1b 100644
--- a/docs/narr/traversal.rst
+++ b/docs/narr/traversal.rst
@@ -488,20 +488,21 @@ you must create an interface and mark up your resource classes or instances
with interface declarations that refer to this interface.
To attach an interface to a resource *class*, you define the interface and
-use the :func:`zope.interface.implements` function to associate the interface
-with the class.
+use the :func:`zope.interface.implementer` class decorator to associate the
+interface with the class.
.. code-block:: python
:linenos:
from zope.interface import Interface
- from zope.interface import implements
+ from zope.interface import implementer
class IHello(Interface):
""" A marker interface """
+ @implementer(IHello)
class Hello(object):
- implements(IHello)
+ pass
To attach an interface to a resource *instance*, you define the interface and
use the :func:`zope.interface.alsoProvides` function to associate the
diff --git a/docs/tutorials/.gitignore b/docs/tutorials/.gitignore
new file mode 100644
index 000000000..71e689620
--- /dev/null
+++ b/docs/tutorials/.gitignore
@@ -0,0 +1 @@
+env*/
diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst
index 56237a1b9..b1d0bf37c 100644
--- a/docs/tutorials/wiki2/authorization.rst
+++ b/docs/tutorials/wiki2/authorization.rst
@@ -159,14 +159,14 @@ logged in user and redirect back to the front page.
The ``login`` view callable will look something like this:
.. literalinclude:: src/authorization/tutorial/views.py
- :lines: 90-116
+ :lines: 87-113
:linenos:
:language: python
The ``logout`` view callable will look something like this:
.. literalinclude:: src/authorization/tutorial/views.py
- :lines: 118-122
+ :lines: 115-119
:linenos:
:language: python
diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst
index bda0a2eb7..a067dbd66 100644
--- a/docs/tutorials/wiki2/definingviews.rst
+++ b/docs/tutorials/wiki2/definingviews.rst
@@ -126,7 +126,7 @@ HTML anchor for each *WikiWord* reference in the rendered HTML using a
compiled regular expression.
.. literalinclude:: src/views/tutorial/views.py
- :lines: 23-44
+ :lines: 23-43
:linenos:
:language: python
@@ -161,7 +161,7 @@ The ``matchdict`` attribute of the request passed to the ``add_page`` view
will have the values we need to construct URLs and find model objects.
.. literalinclude:: src/views/tutorial/views.py
- :lines: 46-58
+ :lines: 45-56
:linenos:
:language: python
@@ -184,7 +184,7 @@ If the view execution *is* a result of a form submission (if the expression
``'form.submitted' in request.params`` is ``True``), we scrape the page body
from the form data, create a Page object with this page body and the name
taken from ``matchdict['pagename']``, and save it into the database using
-``session.add``. We then redirect back to the ``view_page`` view for the
+``DBSession.add``. We then redirect back to the ``view_page`` view for the
newly created page.
The ``edit_page`` view function
@@ -197,7 +197,7 @@ request passed to the ``edit_page`` view will have a ``'pagename'`` key
matching the name of the page the user wants to edit.
.. literalinclude:: src/views/tutorial/views.py
- :lines: 60-73
+ :lines: 58-70
:linenos:
:language: python
diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views.py b/docs/tutorials/wiki2/src/authorization/tutorial/views.py
index 375f1f5a5..087e6076b 100644
--- a/docs/tutorials/wiki2/src/authorization/tutorial/views.py
+++ b/docs/tutorials/wiki2/src/authorization/tutorial/views.py
@@ -33,14 +33,13 @@ def view_wiki(request):
@view_config(route_name='view_page', renderer='templates/view.pt')
def view_page(request):
pagename = request.matchdict['pagename']
- session = DBSession()
- page = session.query(Page).filter_by(name=pagename).first()
+ page = DBSession.query(Page).filter_by(name=pagename).first()
if page is None:
return HTTPNotFound('No such page')
def check(match):
word = match.group(1)
- exists = session.query(Page).filter_by(name=word).all()
+ exists = DBSession.query(Page).filter_by(name=word).all()
if exists:
view_url = request.route_url('view_page', pagename=word)
return '<a href="%s">%s</a>' % (view_url, word)
@@ -59,10 +58,9 @@ def view_page(request):
def add_page(request):
name = request.matchdict['pagename']
if 'form.submitted' in request.params:
- session = DBSession()
body = request.params['body']
page = Page(name, body)
- session.add(page)
+ DBSession.add(page)
return HTTPFound(location = request.route_url('view_page',
pagename=name))
save_url = request.route_url('add_page', pagename=name)
@@ -74,11 +72,10 @@ def add_page(request):
permission='edit')
def edit_page(request):
name = request.matchdict['pagename']
- session = DBSession()
- page = session.query(Page).filter_by(name=name).one()
+ page = DBSession.query(Page).filter_by(name=name).one()
if 'form.submitted' in request.params:
page.data = request.params['body']
- session.add(page)
+ DBSession.add(page)
return HTTPFound(location = request.route_url('view_page',
pagename=name))
return dict(
diff --git a/docs/tutorials/wiki2/src/views/tutorial/views.py b/docs/tutorials/wiki2/src/views/tutorial/views.py
index 5c49dd2e8..c2a94a96b 100644
--- a/docs/tutorials/wiki2/src/views/tutorial/views.py
+++ b/docs/tutorials/wiki2/src/views/tutorial/views.py
@@ -23,14 +23,13 @@ def view_wiki(request):
@view_config(route_name='view_page', renderer='templates/view.pt')
def view_page(request):
pagename = request.matchdict['pagename']
- session = DBSession()
- page = session.query(Page).filter_by(name=pagename).first()
+ page = DBSession.query(Page).filter_by(name=pagename).first()
if page is None:
return HTTPNotFound('No such page')
def check(match):
word = match.group(1)
- exists = session.query(Page).filter_by(name=word).all()
+ exists = DBSession.query(Page).filter_by(name=word).all()
if exists:
view_url = request.route_url('view_page', pagename=word)
return '<a href="%s">%s</a>' % (view_url, word)
@@ -47,10 +46,9 @@ def view_page(request):
def add_page(request):
name = request.matchdict['pagename']
if 'form.submitted' in request.params:
- session = DBSession()
body = request.params['body']
page = Page(name, body)
- session.add(page)
+ DBSession.add(page)
return HTTPFound(location = request.route_url('view_page',
pagename=name))
save_url = request.route_url('add_page', pagename=name)
@@ -60,11 +58,10 @@ def add_page(request):
@view_config(route_name='edit_page', renderer='templates/edit.pt')
def edit_page(request):
name = request.matchdict['pagename']
- session = DBSession()
- page = session.query(Page).filter_by(name=name).one()
+ page = DBSession.query(Page).filter_by(name=name).one()
if 'form.submitted' in request.params:
page.data = request.params['body']
- session.add(page)
+ DBSession.add(page)
return HTTPFound(location = request.route_url('view_page',
pagename=name))
return dict(
diff --git a/docs/whatsnew-1.3.rst b/docs/whatsnew-1.3.rst
index b6cfde039..acb884d49 100644
--- a/docs/whatsnew-1.3.rst
+++ b/docs/whatsnew-1.3.rst
@@ -54,7 +54,8 @@ to make some changes:
- We've replaced the ``paster`` command with Pyramid-specific analogues.
-- We've made the default WSGI server the ``waitress`` server.
+- We've made the default WSGI server used by Pyramid scaffolding the
+ :term:`waitress` server.
Previously (in Pyramid 1.0, 1.1 and 1.2), you created a Pyramid application
using ``paster create``, like so::
@@ -259,6 +260,74 @@ Minor Feature Additions
http://readthedocs.org/docs/venusian/en/latest/#ignore-scan-argument for
more information about how to use the ``ignore`` argument to ``scan``.
+- Add :meth:`pyramid.config.Configurator.add_traverser` API method. See
+ :ref:`changing_the_traverser` for more information. This is not a new
+ feature, it just provides an API for adding a traverser without needing to
+ use the ZCA API.
+
+- Add :meth:`pyramid.config.Configurator.add_resource_url_adapter` API
+ method. See :ref:`changing_resource_url` for more information. This is
+ not a new feature, it just provides an API for adding a resource url
+ adapter without needing to use the ZCA API.
+
+- The :meth:`pyramid.config.Configurator.scan` method can now be passed an
+ ``ignore`` argument, which can be a string, a callable, or a list
+ consisting of strings and/or callables. This feature allows submodules,
+ subpackages, and global objects from being scanned. See
+ http://readthedocs.org/docs/venusian/en/latest/#ignore-scan-argument for
+ more information about how to use the ``ignore`` argument to ``scan``.
+
+- Better error messages when a view callable returns a value that cannot be
+ converted to a response (for example, when a view callable returns a
+ dictionary without a renderer defined, or doesn't return any value at all).
+ The error message now contains information about the view callable itself
+ as well as the result of calling it.
+
+- Better error message when a .pyc-only module is ``config.include`` -ed.
+ This is not permitted due to error reporting requirements, and a better
+ error message is shown when it is attempted. Previously it would fail with
+ something like "AttributeError: 'NoneType' object has no attribute
+ 'rfind'".
+
+- The system value ``req`` is now supplied to renderers as an alias for
+ ``request``. This means that you can now, for example, in a template, do
+ ``req.route_url(...)`` instead of ``request.route_url(...)``. This is
+ purely a change to reduce the amount of typing required to use request
+ methods and attributes from within templates. The value ``request`` is
+ still available too, this is just an alternative.
+
+- A new interface was added: :class:`pyramid.interfaces.IResourceURL`. An
+ adapter implementing its interface can be used to override resource URL
+ generation when :meth:`pyramid.request.Request.resource_url` is called.
+ This interface replaces the now-deprecated
+ ``pyramid.interfaces.IContextURL`` interface.
+
+- The dictionary passed to a resource's ``__resource_url__`` method (see
+ :ref:`overriding_resource_url_generation`) now contains an ``app_url`` key,
+ representing the application URL generated during
+ :meth:`pyramid.request.Request.resource_url`. It represents a potentially
+ customized URL prefix, containing potentially custom scheme, host and port
+ information passed by the user to ``request.resource_url``. It should be
+ used instead of ``request.application_url`` where necessary.
+
+- The :meth:`pyramid.request.Request.resource_url` API now accepts these
+ arguments: ``app_url``, ``scheme``, ``host``, and ``port``. The app_url
+ argument can be used to replace the URL prefix wholesale during url
+ generation. The ``scheme``, ``host``, and ``port`` arguments can be used
+ to replace the respective default values of ``request.application_url``
+ partially.
+
+- A new API named :meth:`pyramid.request.Request.resource_path` now exists.
+ It works like :meth:`pyramid.request.Request.resource_url`` but produces a
+ relative URL rather than an absolute one.
+
+- The :meth:`pyramid.request.Request.route_url` API now accepts these
+ arguments: ``_app_url``, ``_scheme``, ``_host``, and ``_port``. The
+ ``_app_url`` argument can be used to replace the URL prefix wholesale
+ during url generation. The ``_scheme``, ``_host``, and ``_port`` arguments
+ can be used to replace the respective default values of
+ ``request.application_url`` partially.
+
Backwards Incompatibilities
---------------------------
@@ -295,9 +364,10 @@ Backwards Incompatibilities
and upgrade Pyramid itself "in-place"; it may simply break instead
(particularly if you use ZCML's ``includeOverrides`` directive).
-- String values passed to ``route_url`` or ``route_path`` that are meant to
- replace "remainder" matches will now be URL-quoted except for embedded
- slashes. For example::
+- String values passed to :meth:`Pyramid.request.Request.route_url` or
+ :meth:`Pyramid.request.Request.route_path` that are meant to replace
+ "remainder" matches will now be URL-quoted except for embedded slashes. For
+ example::
config.add_route('remain', '/foo*remainder')
request.route_path('remain', remainder='abc / def')
@@ -316,8 +386,8 @@ Backwards Incompatibilities
``route_path`` or ``route_url`` to do this now.
- If you pass a bytestring that contains non-ASCII characters to
- ``add_route`` as a pattern, it will now fail at startup time. Use Unicode
- instead.
+ :meth:`pyramid.config.Configurator.add_route` as a pattern, it will now
+ fail at startup time. Use Unicode instead.
- The ``path_info`` route and view predicates now match against
``request.upath_info`` (Unicode) rather than ``request.path_info``
@@ -328,6 +398,22 @@ Backwards Incompatibilities
no negative affect because the implementation was broken for dict-based
arguments.
+- The ``pyramid.interfaces.IContextURL`` interface has been deprecated.
+ People have been instructed to use this to register a resource url adapter
+ in the "Hooks" chapter to use to influence
+ :meth:`pyramid.request.Request.resource_url` URL generation for resources
+ found via custom traversers since Pyramid 1.0.
+
+ The interface still exists and registering an adapter using it as
+ documented in older versions still works, but this interface will be
+ removed from the software after a few major Pyramid releases. You should
+ replace it with an equivalent :class:`pyramid.interfaces.IResourceURL`
+ adapter, registered using the new
+ :meth:`pyramid.config.Configurator.add_resource_url_adapter` API. A
+ deprecation warning is now emitted when a
+ ``pyramid.interfaces.IContextURL`` adapter is found when
+ :meth:`pyramid.request.Request.resource_url` is called.
+
Documentation Enhancements
--------------------------
@@ -375,6 +461,8 @@ Dependency Changes
- Pyramid no longer depends on the ``Paste`` or ``PasteScript`` packages.
These packages are not Python 3 compatible.
+- Depend on ``venusian`` >= 1.0a3 to provide scan ``ignore`` support.
+
Scaffolding Changes
-------------------