summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt5
-rw-r--r--CONTRIBUTORS.txt2
-rw-r--r--HISTORY.txt6
-rw-r--r--README.rst8
-rw-r--r--docs/narr/logging.rst2
-rw-r--r--docs/narr/myproject/README.txt2
-rw-r--r--docs/narr/project.rst2
-rw-r--r--docs/quick_tour.rst4
-rw-r--r--docs/quick_tour/logging/README.txt2
-rw-r--r--docs/quick_tour/package/README.txt2
-rw-r--r--docs/quick_tour/sessions/README.txt2
-rw-r--r--docs/quick_tour/sqla_demo/README.txt2
-rw-r--r--docs/quick_tutorial/cookiecutters.rst2
-rw-r--r--docs/quick_tutorial/cookiecutters/README.txt2
-rw-r--r--docs/tutorials/modwsgi/index.rst2
-rw-r--r--docs/tutorials/wiki/installation.rst2
-rw-r--r--docs/tutorials/wiki/src/authorization/README.txt2
-rw-r--r--docs/tutorials/wiki/src/basiclayout/README.txt2
-rw-r--r--docs/tutorials/wiki/src/installation/README.txt2
-rw-r--r--docs/tutorials/wiki/src/models/README.txt2
-rw-r--r--docs/tutorials/wiki/src/tests/README.txt2
-rw-r--r--docs/tutorials/wiki/src/views/README.txt2
-rw-r--r--docs/tutorials/wiki2/installation.rst2
-rw-r--r--docs/tutorials/wiki2/src/authentication/README.txt2
-rw-r--r--docs/tutorials/wiki2/src/authentication/tutorial/views/default.py6
-rw-r--r--docs/tutorials/wiki2/src/authorization/README.txt2
-rw-r--r--docs/tutorials/wiki2/src/authorization/tutorial/views/default.py6
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/README.txt2
-rw-r--r--docs/tutorials/wiki2/src/installation/README.txt2
-rw-r--r--docs/tutorials/wiki2/src/models/README.txt2
-rw-r--r--docs/tutorials/wiki2/src/tests/README.txt2
-rw-r--r--docs/tutorials/wiki2/src/tests/tutorial/views/default.py6
-rw-r--r--docs/tutorials/wiki2/src/views/README.txt2
-rw-r--r--docs/tutorials/wiki2/src/views/tutorial/views/default.py6
-rw-r--r--docs/whatsnew-1.8.rst7
-rw-r--r--pyramid/config/__init__.py40
-rw-r--r--pyramid/config/security.py7
-rw-r--r--pyramid/config/views.py4
-rw-r--r--pyramid/tests/test_config/test_init.py16
39 files changed, 125 insertions, 48 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 7d70abbb8..a2e2d6db1 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -32,6 +32,11 @@ Features
See https://github.com/Pylons/pyramid/pull/2854 and
https://github.com/Pylons/pyramid/pull/3019
+- The ``pyramid.config.Configurator`` can now be used as a context manager
+ which will automatically push/pop threadlocals (similar to
+ ``config.begin()`` and ``config.end()``). It will also automatically perform
+ a ``config.commit()`` and thus it is only recommended to be used at the
+ top-level of your app. See https://github.com/Pylons/pyramid/pull/2874
Bug Fixes
---------
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 750f6d29f..ca1f56f51 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -296,3 +296,5 @@ Contributors
- Martin Frlin, 2016/12/7
- Kirill Kuzminykh, 2017/03/01
+
+- Jeremy(Ching-Rui) Chen, 2017/04/19
diff --git a/HISTORY.txt b/HISTORY.txt
index c10747af4..c69d9514e 100644
--- a/HISTORY.txt
+++ b/HISTORY.txt
@@ -198,6 +198,12 @@ Features
See https://github.com/Pylons/pyramid/pull/2873
+- Added a new ``callback`` option to ``config.set_default_csrf_options`` which
+ can be used to determine per-request whether CSRF checking should be enabled
+ to allow for a mix authentication methods. Only cookie-based methods
+ generally require CSRF checking.
+ See https://github.com/Pylons/pyramid/pull/2778
+
Bug Fixes
---------
diff --git a/README.rst b/README.rst
index f05dd8bbf..302590fe1 100644
--- a/README.rst
+++ b/README.rst
@@ -31,10 +31,10 @@ and deployment more fun, more predictable, and more productive.
return Response('Hello %(name)s!' % request.matchdict)
if __name__ == '__main__':
- config = Configurator()
- config.add_route('hello', '/hello/{name}')
- config.add_view(hello_world, route_name='hello')
- app = config.make_wsgi_app()
+ with Configurator() as config:
+ config.add_route('hello', '/hello/{name}')
+ config.add_view(hello_world, route_name='hello')
+ app = config.make_wsgi_app()
server = make_server('0.0.0.0', 8080, app)
server.serve_forever()
diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst
index 87682158b..9cc5b4ed8 100644
--- a/docs/narr/logging.rst
+++ b/docs/narr/logging.rst
@@ -16,7 +16,7 @@ to send log messages to loggers that you've configured.
cookiecutter which does not create these files, the configuration information in
this chapter may not be applicable.
-.. index:
+.. index::
pair: settings; logging
pair: .ini; logging
pair: logging; configuration
diff --git a/docs/narr/myproject/README.txt b/docs/narr/myproject/README.txt
index 41ef0ff91..2ffc0acba 100644
--- a/docs/narr/myproject/README.txt
+++ b/docs/narr/myproject/README.txt
@@ -1,5 +1,5 @@
MyProject
-===============================
+=========
Getting Started
---------------
diff --git a/docs/narr/project.rst b/docs/narr/project.rst
index ce7e90793..9c44d4f16 100644
--- a/docs/narr/project.rst
+++ b/docs/narr/project.rst
@@ -94,7 +94,7 @@ If prompted for the first item, accept the default ``yes`` by hitting return.
You've cloned ~/.cookiecutters/pyramid-cookiecutter-starter before.
Is it okay to delete and re-clone it? [yes]: yes
project_name [Pyramid Scaffold]: myproject
- repo_name [scaffold]: myproject
+ repo_name [myproject]: myproject
Select template_language:
1 - jinja2
2 - chameleon
diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst
index 02c3ff811..571dfb356 100644
--- a/docs/quick_tour.rst
+++ b/docs/quick_tour.rst
@@ -519,7 +519,7 @@ If prompted for the first item, accept the default ``yes`` by hitting return.
You've cloned ~/.cookiecutters/pyramid-cookiecutter-starter before.
Is it okay to delete and re-clone it? [yes]: yes
project_name [Pyramid Scaffold]: hello_world
- repo_name [scaffold]: hello_world
+ repo_name [hello_world]: hello_world
Select template_language:
1 - jinja2
2 - chameleon
@@ -875,7 +875,7 @@ If prompted for the first item, accept the default ``yes`` by hitting return.
You've cloned ~/.cookiecutters/pyramid-cookiecutter-alchemy before.
Is it okay to delete and re-clone it? [yes]: yes
project_name [Pyramid Scaffold]: sqla_demo
- repo_name [scaffold]: sqla_demo
+ repo_name [sqla_demo]: sqla_demo
We then run through the following commands as before.
diff --git a/docs/quick_tour/logging/README.txt b/docs/quick_tour/logging/README.txt
index fb7bde0a7..ff70a1354 100644
--- a/docs/quick_tour/logging/README.txt
+++ b/docs/quick_tour/logging/README.txt
@@ -1,5 +1,5 @@
hello_world
-===============================
+===========
Getting Started
---------------
diff --git a/docs/quick_tour/package/README.txt b/docs/quick_tour/package/README.txt
index fb7bde0a7..ff70a1354 100644
--- a/docs/quick_tour/package/README.txt
+++ b/docs/quick_tour/package/README.txt
@@ -1,5 +1,5 @@
hello_world
-===============================
+===========
Getting Started
---------------
diff --git a/docs/quick_tour/sessions/README.txt b/docs/quick_tour/sessions/README.txt
index fb7bde0a7..ff70a1354 100644
--- a/docs/quick_tour/sessions/README.txt
+++ b/docs/quick_tour/sessions/README.txt
@@ -1,5 +1,5 @@
hello_world
-===============================
+===========
Getting Started
---------------
diff --git a/docs/quick_tour/sqla_demo/README.txt b/docs/quick_tour/sqla_demo/README.txt
index 1659e47ab..27bbff5a7 100644
--- a/docs/quick_tour/sqla_demo/README.txt
+++ b/docs/quick_tour/sqla_demo/README.txt
@@ -1,5 +1,5 @@
sqla_demo
-===============================
+=========
Getting Started
---------------
diff --git a/docs/quick_tutorial/cookiecutters.rst b/docs/quick_tutorial/cookiecutters.rst
index edfd8cd69..337a5c535 100644
--- a/docs/quick_tutorial/cookiecutters.rst
+++ b/docs/quick_tutorial/cookiecutters.rst
@@ -37,7 +37,7 @@ Steps
You've cloned ~/.cookiecutters/pyramid-cookiecutter-starter before.
Is it okay to delete and re-clone it? [yes]: yes
project_name [Pyramid Scaffold]: cc_starter
- repo_name [scaffold]: cc_starter
+ repo_name [cc_starter]: cc_starter
Select template_language:
1 - jinja2
2 - chameleon
diff --git a/docs/quick_tutorial/cookiecutters/README.txt b/docs/quick_tutorial/cookiecutters/README.txt
index 4b1f31bf3..55c5dcec6 100644
--- a/docs/quick_tutorial/cookiecutters/README.txt
+++ b/docs/quick_tutorial/cookiecutters/README.txt
@@ -1,5 +1,5 @@
cc_starter
-===============================
+==========
Getting Started
---------------
diff --git a/docs/tutorials/modwsgi/index.rst b/docs/tutorials/modwsgi/index.rst
index 690266586..170f2ebc8 100644
--- a/docs/tutorials/modwsgi/index.rst
+++ b/docs/tutorials/modwsgi/index.rst
@@ -48,7 +48,7 @@ specific path information for commands and files.
You've cloned ~/.cookiecutters/pyramid-cookiecutter-starter before.
Is it okay to delete and re-clone it? [yes]: yes
project_name [Pyramid Scaffold]: myproject
- repo_name [scaffold]: myproject
+ repo_name [myproject]: myproject
Select template_language:
1 - jinja2
2 - chameleon
diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst
index 6be826395..de057b1cc 100644
--- a/docs/tutorials/wiki/installation.rst
+++ b/docs/tutorials/wiki/installation.rst
@@ -50,7 +50,7 @@ If prompted for the first item, accept the default ``yes`` by hitting return.
You've cloned ~/.cookiecutters/pyramid-cookiecutter-zodb before.
Is it okay to delete and re-clone it? [yes]: yes
project_name [Pyramid Scaffold]: myproj
- repo_name [scaffold]: tutorial
+ repo_name [myproj]: tutorial
Change directory into your newly created project
------------------------------------------------
diff --git a/docs/tutorials/wiki/src/authorization/README.txt b/docs/tutorials/wiki/src/authorization/README.txt
index 98683bf8c..5ec53bf9d 100644
--- a/docs/tutorials/wiki/src/authorization/README.txt
+++ b/docs/tutorials/wiki/src/authorization/README.txt
@@ -1,5 +1,5 @@
myproj
-===============================
+======
Getting Started
---------------
diff --git a/docs/tutorials/wiki/src/basiclayout/README.txt b/docs/tutorials/wiki/src/basiclayout/README.txt
index 98683bf8c..5ec53bf9d 100644
--- a/docs/tutorials/wiki/src/basiclayout/README.txt
+++ b/docs/tutorials/wiki/src/basiclayout/README.txt
@@ -1,5 +1,5 @@
myproj
-===============================
+======
Getting Started
---------------
diff --git a/docs/tutorials/wiki/src/installation/README.txt b/docs/tutorials/wiki/src/installation/README.txt
index 98683bf8c..5ec53bf9d 100644
--- a/docs/tutorials/wiki/src/installation/README.txt
+++ b/docs/tutorials/wiki/src/installation/README.txt
@@ -1,5 +1,5 @@
myproj
-===============================
+======
Getting Started
---------------
diff --git a/docs/tutorials/wiki/src/models/README.txt b/docs/tutorials/wiki/src/models/README.txt
index 98683bf8c..5ec53bf9d 100644
--- a/docs/tutorials/wiki/src/models/README.txt
+++ b/docs/tutorials/wiki/src/models/README.txt
@@ -1,5 +1,5 @@
myproj
-===============================
+======
Getting Started
---------------
diff --git a/docs/tutorials/wiki/src/tests/README.txt b/docs/tutorials/wiki/src/tests/README.txt
index 98683bf8c..5ec53bf9d 100644
--- a/docs/tutorials/wiki/src/tests/README.txt
+++ b/docs/tutorials/wiki/src/tests/README.txt
@@ -1,5 +1,5 @@
myproj
-===============================
+======
Getting Started
---------------
diff --git a/docs/tutorials/wiki/src/views/README.txt b/docs/tutorials/wiki/src/views/README.txt
index 98683bf8c..5ec53bf9d 100644
--- a/docs/tutorials/wiki/src/views/README.txt
+++ b/docs/tutorials/wiki/src/views/README.txt
@@ -1,5 +1,5 @@
myproj
-===============================
+======
Getting Started
---------------
diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst
index 9eeb1711d..c61d4360d 100644
--- a/docs/tutorials/wiki2/installation.rst
+++ b/docs/tutorials/wiki2/installation.rst
@@ -62,7 +62,7 @@ If prompted for the first item, accept the default ``yes`` by hitting return.
You've cloned ~/.cookiecutters/pyramid-cookiecutter-alchemy before.
Is it okay to delete and re-clone it? [yes]: yes
project_name [Pyramid Scaffold]: myproj
- repo_name [scaffold]: tutorial
+ repo_name [myproj]: tutorial
Change directory into your newly created project
------------------------------------------------
diff --git a/docs/tutorials/wiki2/src/authentication/README.txt b/docs/tutorials/wiki2/src/authentication/README.txt
index 5e21b8aa4..81102a869 100644
--- a/docs/tutorials/wiki2/src/authentication/README.txt
+++ b/docs/tutorials/wiki2/src/authentication/README.txt
@@ -1,5 +1,5 @@
myproj
-===============================
+======
Getting Started
---------------
diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/views/default.py b/docs/tutorials/wiki2/src/authentication/tutorial/views/default.py
index 1b071434c..2d058d874 100644
--- a/docs/tutorials/wiki2/src/authentication/tutorial/views/default.py
+++ b/docs/tutorials/wiki2/src/authentication/tutorial/views/default.py
@@ -1,4 +1,4 @@
-import cgi
+from pyramid.compat import escape
import re
from docutils.core import publish_parts
@@ -32,10 +32,10 @@ def view_page(request):
exists = request.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, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (view_url, escape(word))
else:
add_url = request.route_url('add_page', pagename=word)
- return '<a href="%s">%s</a>' % (add_url, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (add_url, escape(word))
content = publish_parts(page.data, writer_name='html')['html_body']
content = wikiwords.sub(add_link, content)
diff --git a/docs/tutorials/wiki2/src/authorization/README.txt b/docs/tutorials/wiki2/src/authorization/README.txt
index 5e21b8aa4..81102a869 100644
--- a/docs/tutorials/wiki2/src/authorization/README.txt
+++ b/docs/tutorials/wiki2/src/authorization/README.txt
@@ -1,5 +1,5 @@
myproj
-===============================
+======
Getting Started
---------------
diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py
index 9358993ea..65c12ed3b 100644
--- a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py
+++ b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py
@@ -1,4 +1,4 @@
-import cgi
+from pyramid.compat import escape
import re
from docutils.core import publish_parts
@@ -25,10 +25,10 @@ def view_page(request):
exists = request.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, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (view_url, escape(word))
else:
add_url = request.route_url('add_page', pagename=word)
- return '<a href="%s">%s</a>' % (add_url, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (add_url, escape(word))
content = publish_parts(page.data, writer_name='html')['html_body']
content = wikiwords.sub(add_link, content)
diff --git a/docs/tutorials/wiki2/src/basiclayout/README.txt b/docs/tutorials/wiki2/src/basiclayout/README.txt
index 5e21b8aa4..81102a869 100644
--- a/docs/tutorials/wiki2/src/basiclayout/README.txt
+++ b/docs/tutorials/wiki2/src/basiclayout/README.txt
@@ -1,5 +1,5 @@
myproj
-===============================
+======
Getting Started
---------------
diff --git a/docs/tutorials/wiki2/src/installation/README.txt b/docs/tutorials/wiki2/src/installation/README.txt
index 5e21b8aa4..81102a869 100644
--- a/docs/tutorials/wiki2/src/installation/README.txt
+++ b/docs/tutorials/wiki2/src/installation/README.txt
@@ -1,5 +1,5 @@
myproj
-===============================
+======
Getting Started
---------------
diff --git a/docs/tutorials/wiki2/src/models/README.txt b/docs/tutorials/wiki2/src/models/README.txt
index 5e21b8aa4..81102a869 100644
--- a/docs/tutorials/wiki2/src/models/README.txt
+++ b/docs/tutorials/wiki2/src/models/README.txt
@@ -1,5 +1,5 @@
myproj
-===============================
+======
Getting Started
---------------
diff --git a/docs/tutorials/wiki2/src/tests/README.txt b/docs/tutorials/wiki2/src/tests/README.txt
index 5e21b8aa4..81102a869 100644
--- a/docs/tutorials/wiki2/src/tests/README.txt
+++ b/docs/tutorials/wiki2/src/tests/README.txt
@@ -1,5 +1,5 @@
myproj
-===============================
+======
Getting Started
---------------
diff --git a/docs/tutorials/wiki2/src/tests/tutorial/views/default.py b/docs/tutorials/wiki2/src/tests/tutorial/views/default.py
index 9358993ea..65c12ed3b 100644
--- a/docs/tutorials/wiki2/src/tests/tutorial/views/default.py
+++ b/docs/tutorials/wiki2/src/tests/tutorial/views/default.py
@@ -1,4 +1,4 @@
-import cgi
+from pyramid.compat import escape
import re
from docutils.core import publish_parts
@@ -25,10 +25,10 @@ def view_page(request):
exists = request.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, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (view_url, escape(word))
else:
add_url = request.route_url('add_page', pagename=word)
- return '<a href="%s">%s</a>' % (add_url, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (add_url, escape(word))
content = publish_parts(page.data, writer_name='html')['html_body']
content = wikiwords.sub(add_link, content)
diff --git a/docs/tutorials/wiki2/src/views/README.txt b/docs/tutorials/wiki2/src/views/README.txt
index 5e21b8aa4..81102a869 100644
--- a/docs/tutorials/wiki2/src/views/README.txt
+++ b/docs/tutorials/wiki2/src/views/README.txt
@@ -1,5 +1,5 @@
myproj
-===============================
+======
Getting Started
---------------
diff --git a/docs/tutorials/wiki2/src/views/tutorial/views/default.py b/docs/tutorials/wiki2/src/views/tutorial/views/default.py
index bb6300b75..3b95e0f59 100644
--- a/docs/tutorials/wiki2/src/views/tutorial/views/default.py
+++ b/docs/tutorials/wiki2/src/views/tutorial/views/default.py
@@ -1,4 +1,4 @@
-import cgi
+from pyramid.compat import escape
import re
from docutils.core import publish_parts
@@ -31,10 +31,10 @@ def view_page(request):
exists = request.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, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (view_url, escape(word))
else:
add_url = request.route_url('add_page', pagename=word)
- return '<a href="%s">%s</a>' % (add_url, cgi.escape(word))
+ return '<a href="%s">%s</a>' % (add_url, escape(word))
content = publish_parts(page.data, writer_name='html')['html_body']
content = wikiwords.sub(add_link, content)
diff --git a/docs/whatsnew-1.8.rst b/docs/whatsnew-1.8.rst
index adc60b34b..ff16c1a4b 100644
--- a/docs/whatsnew-1.8.rst
+++ b/docs/whatsnew-1.8.rst
@@ -114,6 +114,13 @@ Minor Feature Additions
later calls to place translation directories at a higher priority then
earlier calls. See https://github.com/Pylons/pyramid/pull/2902
+- Added a new ``callback`` option to
+ :meth:`pyramid.config.Configurator.set_default_csrf_options`` which
+ can be used to determine per-request whether CSRF checking should be enabled
+ to allow for a mix authentication methods. Only cookie-based methods
+ generally require CSRF checking.
+ See https://github.com/Pylons/pyramid/pull/2778
+
Backwards Incompatibilities
---------------------------
diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py
index b05effbde..a34f0b4db 100644
--- a/pyramid/config/__init__.py
+++ b/pyramid/config/__init__.py
@@ -110,6 +110,17 @@ class Configurator(
A Configurator is used to configure a :app:`Pyramid`
:term:`application registry`.
+ The Configurator lifecycle can be managed by using a context manager to
+ automatically handle calling :meth:`pyramid.config.Configurator.begin` and
+ :meth:`pyramid.config.Configurator.end` as well as
+ :meth:`pyramid.config.Configurator.commit`.
+
+ .. code-block:: python
+
+ with Configurator(settings=settings) as config:
+ config.add_route('home', '/')
+ app = config.make_wsgi_app()
+
If the ``registry`` argument is not ``None``, it must
be an instance of the :class:`pyramid.registry.Registry` class
representing the registry to configure. If ``registry`` is ``None``, the
@@ -265,6 +276,11 @@ class Configurator(
.. versionadded:: 1.6
The ``root_package`` argument.
The ``response_factory`` argument.
+
+ .. versionadded:: 1.9
+ The ability to use the configurator as a context manager with the
+ ``with``-statement to make threadlocal configuration available for
+ further configuration with an implicit commit.
"""
manager = manager # for testing injection
venusian = venusian # for testing injection
@@ -647,12 +663,22 @@ class Configurator(
_ctx = action_state # bw compat
def commit(self):
- """ Commit any pending configuration actions. If a configuration
+ """
+ Commit any pending configuration actions. If a configuration
conflict is detected in the pending configuration actions, this method
will raise a :exc:`ConfigurationConflictError`; within the traceback
of this error will be information about the source of the conflict,
usually including file names and line numbers of the cause of the
- configuration conflicts."""
+ configuration conflicts.
+
+ .. warning::
+ You should think very carefully before manually invoking
+ ``commit()``. Especially not as part of any reusable configuration
+ methods. Normally it should only be done by an application author at
+ the end of configuration in order to override certain aspects of an
+ addon.
+
+ """
self.begin()
try:
self.action_state.execute_actions(introspector=self.introspector)
@@ -934,6 +960,16 @@ class Configurator(
"""
return self.manager.pop()
+ def __enter__(self):
+ self.begin()
+ return self
+
+ def __exit__(self, exc_type, exc_value, exc_traceback):
+ self.end()
+
+ if exc_value is None:
+ self.commit()
+
# this is *not* an action method (uses caller_package)
def scan(self, package=None, categories=None, onerror=None, ignore=None,
**kw):
diff --git a/pyramid/config/security.py b/pyramid/config/security.py
index 8e4c908d3..20b816161 100644
--- a/pyramid/config/security.py
+++ b/pyramid/config/security.py
@@ -207,9 +207,14 @@ class SecurityConfiguratorMixin(object):
are not subject to CSRF attacks. For example, if a request is
authenticated using the ``Authorization`` header instead of a cookie,
this may return ``False`` for that request so that clients do not
- need to send the ``X-CSRF-Token` header. The callback is only tested
+ need to send the ``X-CSRF-Token`` header. The callback is only tested
for non-safe methods as defined by ``safe_methods``.
+ .. versionadded:: 1.7
+
+ .. versionchanged:: 1.8
+ Added the ``callback`` option.
+
"""
options = DefaultCSRFOptions(
require_csrf, token, header, safe_methods, callback,
diff --git a/pyramid/config/views.py b/pyramid/config/views.py
index 2fc243fac..48c4e3437 100644
--- a/pyramid/config/views.py
+++ b/pyramid/config/views.py
@@ -976,7 +976,7 @@ class ViewsConfiguratorMixin(object):
def register_view(classifier, request_iface, derived_view):
# A multiviews is a set of views which are registered for
# exactly the same context type/request type/name triad. Each
- # consituent view in a multiview differs only by the
+ # constituent view in a multiview differs only by the
# predicates which it possesses.
# To find a previously registered view for a context
@@ -1036,7 +1036,7 @@ class ViewsConfiguratorMixin(object):
# XXX we could try to be more efficient here and register
# a non-secured view for a multiview if none of the
- # multiview's consituent views have a permission
+ # multiview's constituent views have a permission
# associated with them, but this code is getting pretty
# rough already
if is_multiview:
diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py
index 53c601537..ab584cc3d 100644
--- a/pyramid/tests/test_config/test_init.py
+++ b/pyramid/tests/test_config/test_init.py
@@ -141,6 +141,22 @@ class ConfiguratorTests(unittest.TestCase):
self.assertEqual(manager.pushed, pushed)
self.assertEqual(manager.popped, True)
+ def test_context_manager(self):
+ from pyramid.config import Configurator
+ config = Configurator()
+ manager = DummyThreadLocalManager()
+ config.manager = manager
+ view = lambda r: None
+ with config as ctx:
+ self.assertTrue(config is ctx)
+ self.assertEqual(manager.pushed,
+ {'registry': config.registry, 'request': None})
+ self.assertFalse(manager.popped)
+ config.add_view(view)
+ self.assertTrue(manager.popped)
+ config.add_view(view) # did not raise a conflict because of commit
+ config.commit()
+
def test_ctor_with_package_registry(self):
import sys
from pyramid.config import Configurator