summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2012-11-20 22:47:52 -0500
committerChris McDonough <chrism@plope.com>2012-11-20 22:47:52 -0500
commitc6a575052ae14e515c288e77a452440030c1cdcd (patch)
tree7bf6dc6f2b929e5a206aae6d751b0cda5d96aefd
parent8f4fcc47c9405f20cfed3a40931f12534b3b7193 (diff)
parentb5e4443dd28f3d4ed6e767e06d658838575d159e (diff)
downloadpyramid-c6a575052ae14e515c288e77a452440030c1cdcd.tar.gz
pyramid-c6a575052ae14e515c288e77a452440030c1cdcd.tar.bz2
pyramid-c6a575052ae14e515c288e77a452440030c1cdcd.zip
Merge branch 'master' into sontek-fix_commands
-rw-r--r--CHANGES.txt66
-rw-r--r--CONTRIBUTORS.txt2
-rw-r--r--docs/conf.py2
-rw-r--r--docs/tutorials/wiki/basiclayout.rst2
-rw-r--r--docs/tutorials/wiki/src/authorization/development.ini28
-rw-r--r--docs/tutorials/wiki/src/authorization/production.ini17
-rw-r--r--docs/tutorials/wiki/src/authorization/setup.py7
-rw-r--r--docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt6
-rw-r--r--docs/tutorials/wiki/src/basiclayout/development.ini30
-rw-r--r--docs/tutorials/wiki/src/basiclayout/production.ini17
-rw-r--r--docs/tutorials/wiki/src/basiclayout/setup.py2
-rw-r--r--docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt4
-rw-r--r--docs/tutorials/wiki/src/models/development.ini28
-rw-r--r--docs/tutorials/wiki/src/models/production.ini17
-rw-r--r--docs/tutorials/wiki/src/models/setup.py2
-rw-r--r--docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt6
-rw-r--r--docs/tutorials/wiki/src/tests/development.ini28
-rw-r--r--docs/tutorials/wiki/src/tests/production.ini17
-rw-r--r--docs/tutorials/wiki/src/tests/setup.py7
-rw-r--r--docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt6
-rw-r--r--docs/tutorials/wiki/src/views/development.ini30
-rw-r--r--docs/tutorials/wiki/src/views/production.ini17
-rw-r--r--docs/tutorials/wiki/src/views/setup.py8
-rw-r--r--docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt6
-rw-r--r--docs/tutorials/wiki2/basiclayout.rst6
-rw-r--r--docs/tutorials/wiki2/src/authorization/README.txt13
-rw-r--r--docs/tutorials/wiki2/src/authorization/development.ini20
-rw-r--r--docs/tutorials/wiki2/src/authorization/setup.py9
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/README.txt13
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/development.ini20
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/production.ini12
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/setup.py6
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt2
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/tutorial/views.py25
-rw-r--r--docs/tutorials/wiki2/src/models/README.txt13
-rw-r--r--docs/tutorials/wiki2/src/models/development.ini20
-rw-r--r--docs/tutorials/wiki2/src/models/setup.py6
-rw-r--r--docs/tutorials/wiki2/src/models/tutorial/views.py25
-rw-r--r--docs/tutorials/wiki2/src/tests/README.txt13
-rw-r--r--docs/tutorials/wiki2/src/tests/development.ini20
-rw-r--r--docs/tutorials/wiki2/src/tests/setup.py7
-rw-r--r--docs/tutorials/wiki2/src/tests/tutorial/views.py13
-rw-r--r--docs/tutorials/wiki2/src/views/README.txt13
-rw-r--r--docs/tutorials/wiki2/src/views/development.ini20
-rw-r--r--docs/tutorials/wiki2/src/views/setup.py6
-rw-r--r--docs/whatsnew-1.4.rst41
-rw-r--r--pyramid/config/util.py8
-rw-r--r--pyramid/config/views.py78
-rw-r--r--pyramid/request.py2
-rw-r--r--pyramid/router.py2
-rw-r--r--pyramid/scripts/pviews.py2
-rw-r--r--pyramid/tests/test_config/test_views.py23
-rw-r--r--pyramid/tests/test_request.py7
-rw-r--r--pyramid/tests/test_router.py17
-rw-r--r--pyramid/tests/test_scripts/test_pviews.py2
-rw-r--r--setup.py2
56 files changed, 649 insertions, 172 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 16e3d8586..51266d15f 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,9 +4,35 @@ Next release
Features
--------
+- Small microspeed enhancement which anticipates that a
+ ``pyramid.response.Response`` object is likely to be returned from a view.
+ Some code is shortcut if the class of the object returned by a view is this
+ class. A similar microoptimization was done to
+ ``pyramid.request.Request.is_response``.
+
+Bug Fixes
+---------
+
+- A failure when trying to locate the attribute ``__text__`` on route and view
+ predicates existed when the ``debug_routematch`` setting was true or when the
+ ``pviews`` command was used. See https://github.com/Pylons/pyramid/pull/727
+
+Documentation
+-------------
+
+- Sync up tutorial source files with the files that are rendered by the
+ scaffold that each uses.
+
+1.4a4 (2012-11-14)
+==================
+
+Features
+--------
+
- ``pyramid.authentication.AuthTktAuthenticationPolicy`` has been updated to
support newer hashing algorithms such as ``sha512``. Existing applications
- should consider updating if possible.
+ should consider updating if possible for improved security over the default
+ md5 hashing.
- Added an ``effective_principals`` route and view predicate.
@@ -21,18 +47,11 @@ Features
- Slightly better debug logging from
``pyramid.authentication.RepozeWho1AuthenticationPolicy``.
-- ``pyramid.security.view_execution_permitted`` used to return `True` if no
+- ``pyramid.security.view_execution_permitted`` used to return ``True`` if no
view could be found. It now raises a ``TypeError`` exception in that case, as
it doesn't make sense to assert that a nonexistent view is
execution-permitted. See https://github.com/Pylons/pyramid/issues/299.
-- Get rid of shady monkeypatching of ``pyramid.request.Request`` and
- ``pyramid.response.Response`` done within the ``__init__.py`` of Pyramid.
- Webob no longer relies on this being done. Instead, the ResponseClass
- attribute of the Pyramid Request class is assigned to the Pyramid response
- class; that's enough to satisfy WebOb and behave as it did before with the
- monkeypatching.
-
- Allow a ``_depth`` argument to ``pyramid.view.view_config``, which will
permit limited composition reuse of the decorator by other software that
wants to provide custom decorators that are much like view_config.
@@ -61,18 +80,26 @@ Bug Fixes
``physical_path`` predicate implementations; instead of raising an exception,
return False.
-- :func:`pyramid.view.render_view` was not functioning properly under
- Python 3.x due to a byte/unicode discrepancy. See
+- ``pyramid.view.render_view`` was not functioning properly under Python 3.x
+ due to a byte/unicode discrepancy. See
http://github.com/Pylons/pyramid/issues/721
Deprecations
------------
-- ``pyramid.authentication.AuthTktAuthenticationPolicy`` will emit a warning
- if an application is using the policy without explicitly setting the
- ``hashalg``. This is because the default is "md5" which is considered
- insecure. If you really want "md5" then you must specify it explicitly to
- get rid of the warning.
+- ``pyramid.authentication.AuthTktAuthenticationPolicy`` will emit a warning if
+ an application is using the policy without explicitly passing a ``hashalg``
+ argument. This is because the default is "md5" which is considered
+ theoretically subject to collision attacks. If you really want "md5" then you
+ must specify it explicitly to get rid of the warning.
+
+Documentation
+-------------
+
+- All of the tutorials that use
+ ``pyramid.authentication.AuthTktAuthenticationPolicy`` now explicitly pass
+ ``sha512`` as a ``hashalg`` argument.
+
Internals
---------
@@ -85,6 +112,13 @@ Internals
because that package should never be imported from non-Pyramid code.
TopologicalSorter is still not an API, but may become one.
+- Get rid of shady monkeypatching of ``pyramid.request.Request`` and
+ ``pyramid.response.Response`` done within the ``__init__.py`` of Pyramid.
+ Webob no longer relies on this being done. Instead, the ResponseClass
+ attribute of the Pyramid Request class is assigned to the Pyramid response
+ class; that's enough to satisfy WebOb and behave as it did before with the
+ monkeypatching.
+
1.4a3 (2012-10-26)
==================
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 34d904d0f..971c172f8 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -190,3 +190,5 @@ Contributors
- David Gay, 2012/09/16
- Robert Jackiewicz, 2012/11/12
+
+- John Anderson, 2012/11/14
diff --git a/docs/conf.py b/docs/conf.py
index 9bda4c798..5e17de18a 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -81,7 +81,7 @@ copyright = '%s, Agendaless Consulting' % datetime.datetime.now().year
# other places throughout the built documents.
#
# The short X.Y version.
-version = '1.4a3'
+version = '1.4a4'
# The full version, including alpha/beta/rc tags.
release = version
diff --git a/docs/tutorials/wiki/basiclayout.rst b/docs/tutorials/wiki/basiclayout.rst
index f6050f391..033dcb28c 100644
--- a/docs/tutorials/wiki/basiclayout.rst
+++ b/docs/tutorials/wiki/basiclayout.rst
@@ -165,7 +165,7 @@ Configuration in ``development.ini``
The ``development.ini`` (in the tutorial :term:`project` directory, as
opposed to the tutorial :term:`package` directory) looks like this:
-.. literalinclude:: src/views/development.ini
+.. literalinclude:: src/basiclayout/development.ini
:language: ini
Note the existence of an ``[app:main]`` section which specifies our WSGI
diff --git a/docs/tutorials/wiki/src/authorization/development.ini b/docs/tutorials/wiki/src/authorization/development.ini
index 996caa741..72bd22e54 100644
--- a/docs/tutorials/wiki/src/authorization/development.ini
+++ b/docs/tutorials/wiki/src/authorization/development.ini
@@ -1,5 +1,11 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
+
pyramid.reload_templates = true
pyramid.debug_authorization = false
pyramid.debug_notfound = false
@@ -13,15 +19,26 @@ pyramid.includes =
tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
+# By default, the toolbar only appears for clients from IP addresses
+# '127.0.0.1' and '::1'.
+# debugtoolbar.hosts = 127.0.0.1 ::1
+
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
-keys = root
+keys = root, tutorial
[handlers]
keys = console
@@ -33,6 +50,11 @@ keys = generic
level = INFO
handlers = console
+[logger_tutorial]
+level = DEBUG
+handlers =
+qualname = tutorial
+
[handler_console]
class = StreamHandler
args = (sys.stderr,)
@@ -41,5 +63,3 @@ formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
-
-# End logging configuration
diff --git a/docs/tutorials/wiki/src/authorization/production.ini b/docs/tutorials/wiki/src/authorization/production.ini
index ca8107802..d9bf27c42 100644
--- a/docs/tutorials/wiki/src/authorization/production.ini
+++ b/docs/tutorials/wiki/src/authorization/production.ini
@@ -1,5 +1,11 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
+
pyramid.reload_templates = false
pyramid.debug_authorization = false
pyramid.debug_notfound = false
@@ -12,12 +18,19 @@ pyramid.includes =
tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
keys = root, tutorial
@@ -45,5 +58,3 @@ formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
-
-# End logging configuration
diff --git a/docs/tutorials/wiki/src/authorization/setup.py b/docs/tutorials/wiki/src/authorization/setup.py
index 31c51dbcf..ac8cdf2d5 100644
--- a/docs/tutorials/wiki/src/authorization/setup.py
+++ b/docs/tutorials/wiki/src/authorization/setup.py
@@ -21,9 +21,8 @@ setup(name='tutorial',
description='tutorial',
long_description=README + '\n\n' + CHANGES,
classifiers=[
- "Intended Audience :: Developers",
- "Framework :: Pylons",
"Programming Language :: Python",
+ "Framework :: Pyramid",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
],
@@ -34,8 +33,8 @@ setup(name='tutorial',
packages=find_packages(),
include_package_data=True,
zip_safe=False,
- install_requires=requires,
- tests_require=requires,
+ install_requires = requires,
+ tests_require= requires,
test_suite="tutorial",
entry_points = """\
[paste.app_factory]
diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt
index 3597c679b..84824f605 100644
--- a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt
@@ -6,9 +6,9 @@
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
<link rel="shortcut icon" href="/static/favicon.ico" />
+ <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" />
- <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
<link rel="stylesheet" href="/static/ie6.css" type="text/css" media="screen" charset="utf-8" />
<![endif]-->
@@ -41,7 +41,7 @@
<h2>Pyramid links</h2>
<ul class="links">
<li>
- <a href="http://pylonsproject.org">Pylons Website</a>
+ <a href="http://pylonsproject.org/">Pylons Website</a>
</li>
<li>
<a href="http://docs.pylonsproject.org/projects/pyramid/current/#narrative-documentation">Narrative Documentation</a>
@@ -70,7 +70,7 @@
</div>
</div>
<div id="footer">
- <div class="footer">&copy; Copyright 2008-2011, Agendaless Consulting.</div>
+ <div class="footer">&copy; Copyright 2008-2012, Agendaless Consulting.</div>
</div>
</body>
</html>
diff --git a/docs/tutorials/wiki/src/basiclayout/development.ini b/docs/tutorials/wiki/src/basiclayout/development.ini
index f637ebaa6..72bd22e54 100644
--- a/docs/tutorials/wiki/src/basiclayout/development.ini
+++ b/docs/tutorials/wiki/src/basiclayout/development.ini
@@ -1,5 +1,11 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
+
pyramid.reload_templates = true
pyramid.debug_authorization = false
pyramid.debug_notfound = false
@@ -13,15 +19,26 @@ pyramid.includes =
tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
+# By default, the toolbar only appears for clients from IP addresses
+# '127.0.0.1' and '::1'.
+# debugtoolbar.hosts = 127.0.0.1 ::1
+
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
-keys = root
+keys = root, tutorial
[handlers]
keys = console
@@ -33,6 +50,11 @@ keys = generic
level = INFO
handlers = console
+[logger_tutorial]
+level = DEBUG
+handlers =
+qualname = tutorial
+
[handler_console]
class = StreamHandler
args = (sys.stderr,)
@@ -40,6 +62,4 @@ level = NOTSET
formatter = generic
[formatter_generic]
-format = %(asctime)s %(levelname)-5.5s [%(name)s] %(message)s
-
-# End logging configuration
+format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
diff --git a/docs/tutorials/wiki/src/basiclayout/production.ini b/docs/tutorials/wiki/src/basiclayout/production.ini
index ca8107802..d9bf27c42 100644
--- a/docs/tutorials/wiki/src/basiclayout/production.ini
+++ b/docs/tutorials/wiki/src/basiclayout/production.ini
@@ -1,5 +1,11 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
+
pyramid.reload_templates = false
pyramid.debug_authorization = false
pyramid.debug_notfound = false
@@ -12,12 +18,19 @@ pyramid.includes =
tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
keys = root, tutorial
@@ -45,5 +58,3 @@ formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
-
-# End logging configuration
diff --git a/docs/tutorials/wiki/src/basiclayout/setup.py b/docs/tutorials/wiki/src/basiclayout/setup.py
index 43600e239..c4a9067b6 100644
--- a/docs/tutorials/wiki/src/basiclayout/setup.py
+++ b/docs/tutorials/wiki/src/basiclayout/setup.py
@@ -21,7 +21,7 @@ setup(name='tutorial',
long_description=README + '\n\n' + CHANGES,
classifiers=[
"Programming Language :: Python",
- "Framework :: Pylons",
+ "Framework :: Pyramid",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
],
diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt
index 557e071ed..84824f605 100644
--- a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt
@@ -6,9 +6,9 @@
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
<link rel="shortcut icon" href="/static/favicon.ico" />
+ <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" />
- <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
<link rel="stylesheet" href="/static/ie6.css" type="text/css" media="screen" charset="utf-8" />
<![endif]-->
@@ -70,7 +70,7 @@
</div>
</div>
<div id="footer">
- <div class="footer">&copy; Copyright 2008-2011, Agendaless Consulting.</div>
+ <div class="footer">&copy; Copyright 2008-2012, Agendaless Consulting.</div>
</div>
</body>
</html>
diff --git a/docs/tutorials/wiki/src/models/development.ini b/docs/tutorials/wiki/src/models/development.ini
index 996caa741..72bd22e54 100644
--- a/docs/tutorials/wiki/src/models/development.ini
+++ b/docs/tutorials/wiki/src/models/development.ini
@@ -1,5 +1,11 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
+
pyramid.reload_templates = true
pyramid.debug_authorization = false
pyramid.debug_notfound = false
@@ -13,15 +19,26 @@ pyramid.includes =
tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
+# By default, the toolbar only appears for clients from IP addresses
+# '127.0.0.1' and '::1'.
+# debugtoolbar.hosts = 127.0.0.1 ::1
+
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
-keys = root
+keys = root, tutorial
[handlers]
keys = console
@@ -33,6 +50,11 @@ keys = generic
level = INFO
handlers = console
+[logger_tutorial]
+level = DEBUG
+handlers =
+qualname = tutorial
+
[handler_console]
class = StreamHandler
args = (sys.stderr,)
@@ -41,5 +63,3 @@ formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
-
-# End logging configuration
diff --git a/docs/tutorials/wiki/src/models/production.ini b/docs/tutorials/wiki/src/models/production.ini
index ca8107802..d9bf27c42 100644
--- a/docs/tutorials/wiki/src/models/production.ini
+++ b/docs/tutorials/wiki/src/models/production.ini
@@ -1,5 +1,11 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
+
pyramid.reload_templates = false
pyramid.debug_authorization = false
pyramid.debug_notfound = false
@@ -12,12 +18,19 @@ pyramid.includes =
tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
keys = root, tutorial
@@ -45,5 +58,3 @@ formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
-
-# End logging configuration
diff --git a/docs/tutorials/wiki/src/models/setup.py b/docs/tutorials/wiki/src/models/setup.py
index 43600e239..c4a9067b6 100644
--- a/docs/tutorials/wiki/src/models/setup.py
+++ b/docs/tutorials/wiki/src/models/setup.py
@@ -21,7 +21,7 @@ setup(name='tutorial',
long_description=README + '\n\n' + CHANGES,
classifiers=[
"Programming Language :: Python",
- "Framework :: Pylons",
+ "Framework :: Pyramid",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
],
diff --git a/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt
index 3597c679b..84824f605 100644
--- a/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt
@@ -6,9 +6,9 @@
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
<link rel="shortcut icon" href="/static/favicon.ico" />
+ <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" />
- <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
<link rel="stylesheet" href="/static/ie6.css" type="text/css" media="screen" charset="utf-8" />
<![endif]-->
@@ -41,7 +41,7 @@
<h2>Pyramid links</h2>
<ul class="links">
<li>
- <a href="http://pylonsproject.org">Pylons Website</a>
+ <a href="http://pylonsproject.org/">Pylons Website</a>
</li>
<li>
<a href="http://docs.pylonsproject.org/projects/pyramid/current/#narrative-documentation">Narrative Documentation</a>
@@ -70,7 +70,7 @@
</div>
</div>
<div id="footer">
- <div class="footer">&copy; Copyright 2008-2011, Agendaless Consulting.</div>
+ <div class="footer">&copy; Copyright 2008-2012, Agendaless Consulting.</div>
</div>
</body>
</html>
diff --git a/docs/tutorials/wiki/src/tests/development.ini b/docs/tutorials/wiki/src/tests/development.ini
index 996caa741..72bd22e54 100644
--- a/docs/tutorials/wiki/src/tests/development.ini
+++ b/docs/tutorials/wiki/src/tests/development.ini
@@ -1,5 +1,11 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
+
pyramid.reload_templates = true
pyramid.debug_authorization = false
pyramid.debug_notfound = false
@@ -13,15 +19,26 @@ pyramid.includes =
tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
+# By default, the toolbar only appears for clients from IP addresses
+# '127.0.0.1' and '::1'.
+# debugtoolbar.hosts = 127.0.0.1 ::1
+
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
-keys = root
+keys = root, tutorial
[handlers]
keys = console
@@ -33,6 +50,11 @@ keys = generic
level = INFO
handlers = console
+[logger_tutorial]
+level = DEBUG
+handlers =
+qualname = tutorial
+
[handler_console]
class = StreamHandler
args = (sys.stderr,)
@@ -41,5 +63,3 @@ formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
-
-# End logging configuration
diff --git a/docs/tutorials/wiki/src/tests/production.ini b/docs/tutorials/wiki/src/tests/production.ini
index ca8107802..d9bf27c42 100644
--- a/docs/tutorials/wiki/src/tests/production.ini
+++ b/docs/tutorials/wiki/src/tests/production.ini
@@ -1,5 +1,11 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
+
pyramid.reload_templates = false
pyramid.debug_authorization = false
pyramid.debug_notfound = false
@@ -12,12 +18,19 @@ pyramid.includes =
tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
keys = root, tutorial
@@ -45,5 +58,3 @@ formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
-
-# End logging configuration
diff --git a/docs/tutorials/wiki/src/tests/setup.py b/docs/tutorials/wiki/src/tests/setup.py
index a7ad7317c..b7e0a8935 100644
--- a/docs/tutorials/wiki/src/tests/setup.py
+++ b/docs/tutorials/wiki/src/tests/setup.py
@@ -22,9 +22,8 @@ setup(name='tutorial',
description='tutorial',
long_description=README + '\n\n' + CHANGES,
classifiers=[
- "Intended Audience :: Developers",
- "Framework :: Pylons",
"Programming Language :: Python",
+ "Framework :: Pyramid",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
],
@@ -35,8 +34,8 @@ setup(name='tutorial',
packages=find_packages(),
include_package_data=True,
zip_safe=False,
- install_requires=requires,
- tests_require=requires,
+ install_requires = requires,
+ tests_require= requires,
test_suite="tutorial",
entry_points = """\
[paste.app_factory]
diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt
index 3597c679b..84824f605 100644
--- a/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt
@@ -6,9 +6,9 @@
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
<link rel="shortcut icon" href="/static/favicon.ico" />
+ <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" />
- <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
<link rel="stylesheet" href="/static/ie6.css" type="text/css" media="screen" charset="utf-8" />
<![endif]-->
@@ -41,7 +41,7 @@
<h2>Pyramid links</h2>
<ul class="links">
<li>
- <a href="http://pylonsproject.org">Pylons Website</a>
+ <a href="http://pylonsproject.org/">Pylons Website</a>
</li>
<li>
<a href="http://docs.pylonsproject.org/projects/pyramid/current/#narrative-documentation">Narrative Documentation</a>
@@ -70,7 +70,7 @@
</div>
</div>
<div id="footer">
- <div class="footer">&copy; Copyright 2008-2011, Agendaless Consulting.</div>
+ <div class="footer">&copy; Copyright 2008-2012, Agendaless Consulting.</div>
</div>
</body>
</html>
diff --git a/docs/tutorials/wiki/src/views/development.ini b/docs/tutorials/wiki/src/views/development.ini
index f637ebaa6..72bd22e54 100644
--- a/docs/tutorials/wiki/src/views/development.ini
+++ b/docs/tutorials/wiki/src/views/development.ini
@@ -1,5 +1,11 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
+
pyramid.reload_templates = true
pyramid.debug_authorization = false
pyramid.debug_notfound = false
@@ -13,15 +19,26 @@ pyramid.includes =
tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
+# By default, the toolbar only appears for clients from IP addresses
+# '127.0.0.1' and '::1'.
+# debugtoolbar.hosts = 127.0.0.1 ::1
+
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
-keys = root
+keys = root, tutorial
[handlers]
keys = console
@@ -33,6 +50,11 @@ keys = generic
level = INFO
handlers = console
+[logger_tutorial]
+level = DEBUG
+handlers =
+qualname = tutorial
+
[handler_console]
class = StreamHandler
args = (sys.stderr,)
@@ -40,6 +62,4 @@ level = NOTSET
formatter = generic
[formatter_generic]
-format = %(asctime)s %(levelname)-5.5s [%(name)s] %(message)s
-
-# End logging configuration
+format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
diff --git a/docs/tutorials/wiki/src/views/production.ini b/docs/tutorials/wiki/src/views/production.ini
index ca8107802..d9bf27c42 100644
--- a/docs/tutorials/wiki/src/views/production.ini
+++ b/docs/tutorials/wiki/src/views/production.ini
@@ -1,5 +1,11 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
+
pyramid.reload_templates = false
pyramid.debug_authorization = false
pyramid.debug_notfound = false
@@ -12,12 +18,19 @@ pyramid.includes =
tm.attempts = 3
zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
keys = root, tutorial
@@ -45,5 +58,3 @@ formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
-
-# End logging configuration
diff --git a/docs/tutorials/wiki/src/views/setup.py b/docs/tutorials/wiki/src/views/setup.py
index a6be89b2e..ac8cdf2d5 100644
--- a/docs/tutorials/wiki/src/views/setup.py
+++ b/docs/tutorials/wiki/src/views/setup.py
@@ -21,9 +21,8 @@ setup(name='tutorial',
description='tutorial',
long_description=README + '\n\n' + CHANGES,
classifiers=[
- "Intended Audience :: Developers",
- "Framework :: Pylons",
"Programming Language :: Python",
+ "Framework :: Pyramid",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
],
@@ -34,11 +33,12 @@ setup(name='tutorial',
packages=find_packages(),
include_package_data=True,
zip_safe=False,
- install_requires=requires,
- tests_require=requires,
+ install_requires = requires,
+ tests_require= requires,
test_suite="tutorial",
entry_points = """\
[paste.app_factory]
main = tutorial:main
""",
)
+
diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt
index 3597c679b..84824f605 100644
--- a/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt
@@ -6,9 +6,9 @@
<meta name="keywords" content="python web application" />
<meta name="description" content="pyramid web application" />
<link rel="shortcut icon" href="/static/favicon.ico" />
+ <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" />
<link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" />
- <link rel="stylesheet" href="/static/pylons.css" type="text/css" media="screen" charset="utf-8" />
<!--[if lte IE 6]>
<link rel="stylesheet" href="/static/ie6.css" type="text/css" media="screen" charset="utf-8" />
<![endif]-->
@@ -41,7 +41,7 @@
<h2>Pyramid links</h2>
<ul class="links">
<li>
- <a href="http://pylonsproject.org">Pylons Website</a>
+ <a href="http://pylonsproject.org/">Pylons Website</a>
</li>
<li>
<a href="http://docs.pylonsproject.org/projects/pyramid/current/#narrative-documentation">Narrative Documentation</a>
@@ -70,7 +70,7 @@
</div>
</div>
<div id="footer">
- <div class="footer">&copy; Copyright 2008-2011, Agendaless Consulting.</div>
+ <div class="footer">&copy; Copyright 2008-2012, Agendaless Consulting.</div>
</div>
</body>
</html>
diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst
index dbd130c36..4f73dc914 100644
--- a/docs/tutorials/wiki2/basiclayout.rst
+++ b/docs/tutorials/wiki2/basiclayout.rst
@@ -171,6 +171,12 @@ application. Without being processed by ``scan``, the decorator effectively
does nothing. ``@view_config`` is inert without being detected via a
:term:`scan`.
+The sample ``my_view()`` created by the scaffold uses a ``try:`` and ``except:``
+clause, to detect if there is a problem accessing the project database and
+provide an alternate error response. That response will include the text
+shown at the end of the file, which will be displayed in the browser to
+inform the user about possible actions to take to solve the problem.
+
Content Models with ``models.py``
---------------------------------
diff --git a/docs/tutorials/wiki2/src/authorization/README.txt b/docs/tutorials/wiki2/src/authorization/README.txt
index 6f851e9b7..141851285 100644
--- a/docs/tutorials/wiki2/src/authorization/README.txt
+++ b/docs/tutorials/wiki2/src/authorization/README.txt
@@ -1 +1,14 @@
tutorial README
+==================
+
+Getting Started
+---------------
+
+- cd <directory containing this file>
+
+- $venv/bin/python setup.py develop
+
+- $venv/bin/initialize_tutorial_db development.ini
+
+- $venv/bin/pserve development.ini
+
diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini
index eb2f878c5..a9d53b296 100644
--- a/docs/tutorials/wiki2/src/authorization/development.ini
+++ b/docs/tutorials/wiki2/src/authorization/development.ini
@@ -1,3 +1,8 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
@@ -12,12 +17,23 @@ pyramid.includes =
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
+# By default, the toolbar only appears for clients from IP addresses
+# '127.0.0.1' and '::1'.
+# debugtoolbar.hosts = 127.0.0.1 ::1
+
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
keys = root, tutorial, sqlalchemy
@@ -53,5 +69,3 @@ formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
-
-# End logging configuration
diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py
index 2fd051927..d658cae93 100644
--- a/docs/tutorials/wiki2/src/authorization/setup.py
+++ b/docs/tutorials/wiki2/src/authorization/setup.py
@@ -13,8 +13,8 @@ requires = [
'pyramid_tm',
'pyramid_debugtoolbar',
'zope.sqlalchemy',
- 'docutils',
'waitress',
+ 'docutils',
]
setup(name='tutorial',
@@ -23,7 +23,7 @@ setup(name='tutorial',
long_description=README + '\n\n' + CHANGES,
classifiers=[
"Programming Language :: Python",
- "Framework :: Pylons",
+ "Framework :: Pyramid",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
],
@@ -35,11 +35,12 @@ setup(name='tutorial',
include_package_data=True,
zip_safe=False,
test_suite='tutorial',
- install_requires = requires,
- entry_points = """\
+ install_requires=requires,
+ entry_points="""\
[paste.app_factory]
main = tutorial:main
[console_scripts]
initialize_tutorial_db = tutorial.scripts.initializedb:main
""",
)
+
diff --git a/docs/tutorials/wiki2/src/basiclayout/README.txt b/docs/tutorials/wiki2/src/basiclayout/README.txt
index 6f851e9b7..141851285 100644
--- a/docs/tutorials/wiki2/src/basiclayout/README.txt
+++ b/docs/tutorials/wiki2/src/basiclayout/README.txt
@@ -1 +1,14 @@
tutorial README
+==================
+
+Getting Started
+---------------
+
+- cd <directory containing this file>
+
+- $venv/bin/python setup.py develop
+
+- $venv/bin/initialize_tutorial_db development.ini
+
+- $venv/bin/pserve development.ini
+
diff --git a/docs/tutorials/wiki2/src/basiclayout/development.ini b/docs/tutorials/wiki2/src/basiclayout/development.ini
index eb2f878c5..a9d53b296 100644
--- a/docs/tutorials/wiki2/src/basiclayout/development.ini
+++ b/docs/tutorials/wiki2/src/basiclayout/development.ini
@@ -1,3 +1,8 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
@@ -12,12 +17,23 @@ pyramid.includes =
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
+# By default, the toolbar only appears for clients from IP addresses
+# '127.0.0.1' and '::1'.
+# debugtoolbar.hosts = 127.0.0.1 ::1
+
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
keys = root, tutorial, sqlalchemy
@@ -53,5 +69,3 @@ formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
-
-# End logging configuration
diff --git a/docs/tutorials/wiki2/src/basiclayout/production.ini b/docs/tutorials/wiki2/src/basiclayout/production.ini
index 4684d2f7a..fa94c1b3e 100644
--- a/docs/tutorials/wiki2/src/basiclayout/production.ini
+++ b/docs/tutorials/wiki2/src/basiclayout/production.ini
@@ -1,3 +1,8 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
@@ -16,7 +21,10 @@ use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
keys = root, tutorial, sqlalchemy
@@ -52,5 +60,3 @@ formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
-
-# End logging configuration
diff --git a/docs/tutorials/wiki2/src/basiclayout/setup.py b/docs/tutorials/wiki2/src/basiclayout/setup.py
index 050de7299..1a1ad78aa 100644
--- a/docs/tutorials/wiki2/src/basiclayout/setup.py
+++ b/docs/tutorials/wiki2/src/basiclayout/setup.py
@@ -22,7 +22,7 @@ setup(name='tutorial',
long_description=README + '\n\n' + CHANGES,
classifiers=[
"Programming Language :: Python",
- "Framework :: Pylons",
+ "Framework :: Pyramid",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
],
@@ -34,8 +34,8 @@ setup(name='tutorial',
include_package_data=True,
zip_safe=False,
test_suite='tutorial',
- install_requires = requires,
- entry_points = """\
+ install_requires=requires,
+ entry_points="""\
[paste.app_factory]
main = tutorial:main
[console_scripts]
diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt
index fbfa9870b..15ea6614f 100644
--- a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt
+++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt
@@ -70,7 +70,7 @@
</div>
</div>
<div id="footer">
- <div class="footer">&copy; Copyright 2008-2011, Agendaless Consulting.</div>
+ <div class="footer">&copy; Copyright 2008-2012, Agendaless Consulting.</div>
</div>
</body>
</html>
diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/views.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/views.py
index 3e6abf2c2..daf21bb7b 100644
--- a/docs/tutorials/wiki2/src/basiclayout/tutorial/views.py
+++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/views.py
@@ -1,5 +1,8 @@
+from pyramid.response import Response
from pyramid.view import view_config
+from sqlalchemy.exc import DBAPIError
+
from .models import (
DBSession,
MyModel,
@@ -7,5 +10,25 @@ from .models import (
@view_config(route_name='home', renderer='templates/mytemplate.pt')
def my_view(request):
- one = DBSession.query(MyModel).filter(MyModel.name=='one').first()
+ try:
+ one = DBSession.query(MyModel).filter(MyModel.name=='one').first()
+ except DBAPIError:
+ return Response(conn_err_msg, content_type='text/plain', status_int=500)
return {'one':one, 'project':'tutorial'}
+
+conn_err_msg = """\
+Pyramid is having a problem using your SQL database. The problem
+might be caused by one of the following things:
+
+1. You may need to run the "initialize_tutorial_db" script
+ to initialize your database tables. Check your virtual
+ environment's "bin" directory for this script and try to run it.
+
+2. Your database server may not be running. Check that the
+ database server referred to by the "sqlalchemy.url" setting in
+ your "development.ini" file is running.
+
+After you fix the problem, please restart the Pyramid application to
+try it again.
+"""
+
diff --git a/docs/tutorials/wiki2/src/models/README.txt b/docs/tutorials/wiki2/src/models/README.txt
index 6f851e9b7..141851285 100644
--- a/docs/tutorials/wiki2/src/models/README.txt
+++ b/docs/tutorials/wiki2/src/models/README.txt
@@ -1 +1,14 @@
tutorial README
+==================
+
+Getting Started
+---------------
+
+- cd <directory containing this file>
+
+- $venv/bin/python setup.py develop
+
+- $venv/bin/initialize_tutorial_db development.ini
+
+- $venv/bin/pserve development.ini
+
diff --git a/docs/tutorials/wiki2/src/models/development.ini b/docs/tutorials/wiki2/src/models/development.ini
index eb2f878c5..a9d53b296 100644
--- a/docs/tutorials/wiki2/src/models/development.ini
+++ b/docs/tutorials/wiki2/src/models/development.ini
@@ -1,3 +1,8 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
@@ -12,12 +17,23 @@ pyramid.includes =
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
+# By default, the toolbar only appears for clients from IP addresses
+# '127.0.0.1' and '::1'.
+# debugtoolbar.hosts = 127.0.0.1 ::1
+
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
keys = root, tutorial, sqlalchemy
@@ -53,5 +69,3 @@ formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
-
-# End logging configuration
diff --git a/docs/tutorials/wiki2/src/models/setup.py b/docs/tutorials/wiki2/src/models/setup.py
index 050de7299..1a1ad78aa 100644
--- a/docs/tutorials/wiki2/src/models/setup.py
+++ b/docs/tutorials/wiki2/src/models/setup.py
@@ -22,7 +22,7 @@ setup(name='tutorial',
long_description=README + '\n\n' + CHANGES,
classifiers=[
"Programming Language :: Python",
- "Framework :: Pylons",
+ "Framework :: Pyramid",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
],
@@ -34,8 +34,8 @@ setup(name='tutorial',
include_package_data=True,
zip_safe=False,
test_suite='tutorial',
- install_requires = requires,
- entry_points = """\
+ install_requires=requires,
+ entry_points="""\
[paste.app_factory]
main = tutorial:main
[console_scripts]
diff --git a/docs/tutorials/wiki2/src/models/tutorial/views.py b/docs/tutorials/wiki2/src/models/tutorial/views.py
index 3e6abf2c2..daf21bb7b 100644
--- a/docs/tutorials/wiki2/src/models/tutorial/views.py
+++ b/docs/tutorials/wiki2/src/models/tutorial/views.py
@@ -1,5 +1,8 @@
+from pyramid.response import Response
from pyramid.view import view_config
+from sqlalchemy.exc import DBAPIError
+
from .models import (
DBSession,
MyModel,
@@ -7,5 +10,25 @@ from .models import (
@view_config(route_name='home', renderer='templates/mytemplate.pt')
def my_view(request):
- one = DBSession.query(MyModel).filter(MyModel.name=='one').first()
+ try:
+ one = DBSession.query(MyModel).filter(MyModel.name=='one').first()
+ except DBAPIError:
+ return Response(conn_err_msg, content_type='text/plain', status_int=500)
return {'one':one, 'project':'tutorial'}
+
+conn_err_msg = """\
+Pyramid is having a problem using your SQL database. The problem
+might be caused by one of the following things:
+
+1. You may need to run the "initialize_tutorial_db" script
+ to initialize your database tables. Check your virtual
+ environment's "bin" directory for this script and try to run it.
+
+2. Your database server may not be running. Check that the
+ database server referred to by the "sqlalchemy.url" setting in
+ your "development.ini" file is running.
+
+After you fix the problem, please restart the Pyramid application to
+try it again.
+"""
+
diff --git a/docs/tutorials/wiki2/src/tests/README.txt b/docs/tutorials/wiki2/src/tests/README.txt
index 6f851e9b7..141851285 100644
--- a/docs/tutorials/wiki2/src/tests/README.txt
+++ b/docs/tutorials/wiki2/src/tests/README.txt
@@ -1 +1,14 @@
tutorial README
+==================
+
+Getting Started
+---------------
+
+- cd <directory containing this file>
+
+- $venv/bin/python setup.py develop
+
+- $venv/bin/initialize_tutorial_db development.ini
+
+- $venv/bin/pserve development.ini
+
diff --git a/docs/tutorials/wiki2/src/tests/development.ini b/docs/tutorials/wiki2/src/tests/development.ini
index eb2f878c5..a9d53b296 100644
--- a/docs/tutorials/wiki2/src/tests/development.ini
+++ b/docs/tutorials/wiki2/src/tests/development.ini
@@ -1,3 +1,8 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
@@ -12,12 +17,23 @@ pyramid.includes =
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
+# By default, the toolbar only appears for clients from IP addresses
+# '127.0.0.1' and '::1'.
+# debugtoolbar.hosts = 127.0.0.1 ::1
+
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
keys = root, tutorial, sqlalchemy
@@ -53,5 +69,3 @@ formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
-
-# End logging configuration
diff --git a/docs/tutorials/wiki2/src/tests/setup.py b/docs/tutorials/wiki2/src/tests/setup.py
index 0f58d8a18..8a619d27b 100644
--- a/docs/tutorials/wiki2/src/tests/setup.py
+++ b/docs/tutorials/wiki2/src/tests/setup.py
@@ -24,7 +24,7 @@ setup(name='tutorial',
long_description=README + '\n\n' + CHANGES,
classifiers=[
"Programming Language :: Python",
- "Framework :: Pylons",
+ "Framework :: Pyramid",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
],
@@ -36,11 +36,12 @@ setup(name='tutorial',
include_package_data=True,
zip_safe=False,
test_suite='tutorial',
- install_requires = requires,
- entry_points = """\
+ install_requires=requires,
+ entry_points="""\
[paste.app_factory]
main = tutorial:main
[console_scripts]
initialize_tutorial_db = tutorial.scripts.initializedb:main
""",
)
+
diff --git a/docs/tutorials/wiki2/src/tests/tutorial/views.py b/docs/tutorials/wiki2/src/tests/tutorial/views.py
index 42ac0eb7f..0d085b0e2 100644
--- a/docs/tutorials/wiki2/src/tests/tutorial/views.py
+++ b/docs/tutorials/wiki2/src/tests/tutorial/views.py
@@ -37,14 +37,13 @@ def view_wiki(request):
permission='view')
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)
@@ -63,10 +62,9 @@ def view_page(request):
def add_page(request):
pagename = request.matchdict['pagename']
if 'form.submitted' in request.params:
- session = DBSession()
body = request.params['body']
page = Page(pagename, body)
- session.add(page)
+ DBSession.add(page)
return HTTPFound(location = request.route_url('view_page',
pagename=pagename))
save_url = request.route_url('add_page', pagename=pagename)
@@ -78,11 +76,10 @@ def add_page(request):
permission='edit')
def edit_page(request):
pagename = request.matchdict['pagename']
- session = DBSession()
- page = session.query(Page).filter_by(name=pagename).one()
+ page = DBSession.query(Page).filter_by(name=pagename).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=pagename))
return dict(
diff --git a/docs/tutorials/wiki2/src/views/README.txt b/docs/tutorials/wiki2/src/views/README.txt
index 6f851e9b7..141851285 100644
--- a/docs/tutorials/wiki2/src/views/README.txt
+++ b/docs/tutorials/wiki2/src/views/README.txt
@@ -1 +1,14 @@
tutorial README
+==================
+
+Getting Started
+---------------
+
+- cd <directory containing this file>
+
+- $venv/bin/python setup.py develop
+
+- $venv/bin/initialize_tutorial_db development.ini
+
+- $venv/bin/pserve development.ini
+
diff --git a/docs/tutorials/wiki2/src/views/development.ini b/docs/tutorials/wiki2/src/views/development.ini
index eb2f878c5..a9d53b296 100644
--- a/docs/tutorials/wiki2/src/views/development.ini
+++ b/docs/tutorials/wiki2/src/views/development.ini
@@ -1,3 +1,8 @@
+###
+# app configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+###
+
[app:main]
use = egg:tutorial
@@ -12,12 +17,23 @@ pyramid.includes =
sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
+# By default, the toolbar only appears for clients from IP addresses
+# '127.0.0.1' and '::1'.
+# debugtoolbar.hosts = 127.0.0.1 ::1
+
+###
+# wsgi server configuration
+###
+
[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543
-# Begin logging configuration
+###
+# logging configuration
+# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+###
[loggers]
keys = root, tutorial, sqlalchemy
@@ -53,5 +69,3 @@ formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
-
-# End logging configuration
diff --git a/docs/tutorials/wiki2/src/views/setup.py b/docs/tutorials/wiki2/src/views/setup.py
index 34b578e21..d658cae93 100644
--- a/docs/tutorials/wiki2/src/views/setup.py
+++ b/docs/tutorials/wiki2/src/views/setup.py
@@ -23,7 +23,7 @@ setup(name='tutorial',
long_description=README + '\n\n' + CHANGES,
classifiers=[
"Programming Language :: Python",
- "Framework :: Pylons",
+ "Framework :: Pyramid",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
],
@@ -35,8 +35,8 @@ setup(name='tutorial',
include_package_data=True,
zip_safe=False,
test_suite='tutorial',
- install_requires = requires,
- entry_points = """\
+ install_requires=requires,
+ entry_points="""\
[paste.app_factory]
main = tutorial:main
[console_scripts]
diff --git a/docs/whatsnew-1.4.rst b/docs/whatsnew-1.4.rst
index 59e1f7a96..5da28bb03 100644
--- a/docs/whatsnew-1.4.rst
+++ b/docs/whatsnew-1.4.rst
@@ -77,6 +77,11 @@ Subrequest Support
Minor Feature Additions
-----------------------
+- :class:`pyramid.authentication.AuthTktAuthenticationPolicy` has been updated
+ to support newer hashing algorithms such as ``sha512``. Existing applications
+ should consider updating if possible for improved security over the default
+ md5 hashing.
+
- :meth:`pyramid.config.Configurator.add_directive` now accepts arbitrary
callables like partials or objects implementing ``__call__`` which don't
have ``__name__`` and ``__doc__`` attributes. See
@@ -182,7 +187,6 @@ Minor Feature Additions
:meth:`pyramid.config.testing_securitypolicy` now sets a ``forgotten`` value
on the policy (the value ``True``) when its ``forget`` method is called.
-
- The DummySecurityPolicy created by
:meth:`pyramid.config.testing_securitypolicy` now sets a
``remembered`` value on the policy, which is the value of the ``principal``
@@ -196,6 +200,31 @@ Minor Feature Additions
view when some object is traversed to, but you can't be sure about what kind
of object it will be, so you can't use the ``context`` predicate.
+- Added an ``effective_principals`` route and view predicate.
+
+- Do not allow the userid returned from the
+ :func:`pyramid.security.authenticated_userid` or the userid that is one of the
+ list of principals returned by :func:`pyramid.security.effective_principals`
+ to be either of the strings ``system.Everyone`` or ``system.Authenticated``
+ when any of the built-in authorization policies that live in
+ :mod:`pyramid.authentication` are in use. These two strings are reserved for
+ internal usage by Pyramid and they will no longer be accepted as valid
+ userids.
+
+- Allow a ``_depth`` argument to :class:`pyramid.view.view_config`, which will
+ permit limited composition reuse of the decorator by other software that
+ wants to provide custom decorators that are much like view_config.
+
+- Allow an iterable of decorators to be passed to
+ :meth:`pyramid.config.Configurator.add_view`. This allows views to be wrapped
+ by more than one decorator without requiring combining the decorators
+ yourself.
+
+- :func:`pyramid.security.view_execution_permitted` used to return `True` if no
+ view could be found. It now raises a :exc:`TypeError` exception in that case,
+ as it doesn't make sense to assert that a nonexistent view is
+ execution-permitted. See https://github.com/Pylons/pyramid/issues/299.
+
Backwards Incompatibilities
---------------------------
@@ -289,6 +318,12 @@ Deprecations
used in its place (it has all of the same capabilities but can also extend
the request object with methods).
+- :class:`pyramid.authentication.AuthTktAuthenticationPolicy` will emit a
+ deprecation warning if an application is using the policy without explicitly
+ passing a ``hashalg`` argument. This is because the default is "md5" which is
+ considered theoretically subject to collision attacks. If you really want
+ "md5" then you must specify it explicitly to get rid of the warning.
+
Documentation Enhancements
--------------------------
@@ -299,6 +334,10 @@ Documentation Enhancements
- Added a :ref:`subrequest_chapter` chapter to the narrative documentation.
+- All of the tutorials that use
+ :class:`pyramid.authentication.AuthTktAuthenticationPolicy` now explicitly
+ pass ``sha512`` as a ``hashalg`` argument.
+
- Many cleanups and improvements to narrative and API docs.
Dependency Changes
diff --git a/pyramid/config/util.py b/pyramid/config/util.py
index c16755a75..a83e23798 100644
--- a/pyramid/config/util.py
+++ b/pyramid/config/util.py
@@ -42,8 +42,12 @@ class PredicateList(object):
## weighs_more_than = self.last_added or FIRST
## weighs_less_than = LAST
self.last_added = name
- self.sorter.add(name, factory, after=weighs_more_than,
- before=weighs_less_than)
+ self.sorter.add(
+ name,
+ factory,
+ after=weighs_more_than,
+ before=weighs_less_than,
+ )
def make(self, config, **kw):
# Given a configurator and a list of keywords, a predicate list is
diff --git a/pyramid/config/views.py b/pyramid/config/views.py
index 745b6f810..4e5af480d 100644
--- a/pyramid/config/views.py
+++ b/pyramid/config/views.py
@@ -59,6 +59,8 @@ from pyramid.registry import (
Deferred,
)
+from pyramid.response import Response
+
from pyramid.security import NO_PERMISSION_REQUIRED
from pyramid.static import static_view
from pyramid.threadlocal import get_current_registry
@@ -341,25 +343,28 @@ class ViewDeriver(object):
def rendered_view(context, request):
renderer = view_renderer
result = view(context, request)
- registry = self.registry
- # this must adapt, it can't do a simple interface check
- # (avoid trying to render webob responses)
- response = registry.queryAdapterOrSelf(result, IResponse)
- if response is None:
- attrs = getattr(request, '__dict__', {})
- if 'override_renderer' in attrs:
- # renderer overridden by newrequest event or other
- renderer_name = attrs.pop('override_renderer')
- renderer = renderers.RendererHelper(
- name=renderer_name,
- package=self.kw.get('package'),
- registry = registry)
- if '__view__' in attrs:
- view_inst = attrs.pop('__view__')
- else:
- view_inst = getattr(view, '__original_view__', view)
- response = renderer.render_view(request, result, view_inst,
- context)
+ if result.__class__ is Response: # potential common case
+ response = result
+ else:
+ registry = self.registry
+ # this must adapt, it can't do a simple interface check
+ # (avoid trying to render webob responses)
+ response = registry.queryAdapterOrSelf(result, IResponse)
+ if response is None:
+ attrs = getattr(request, '__dict__', {})
+ if 'override_renderer' in attrs:
+ # renderer overridden by newrequest event or other
+ renderer_name = attrs.pop('override_renderer')
+ renderer = renderers.RendererHelper(
+ name=renderer_name,
+ package=self.kw.get('package'),
+ registry = registry)
+ if '__view__' in attrs:
+ view_inst = attrs.pop('__view__')
+ else:
+ view_inst = getattr(view, '__original_view__', view)
+ response = renderer.render_view(request, result, view_inst,
+ context)
return response
return rendered_view
@@ -368,21 +373,26 @@ class ViewDeriver(object):
registry = self.registry
def viewresult_to_response(context, request):
result = view(context, request)
- response = registry.queryAdapterOrSelf(result, IResponse)
- if response is None:
- if result is None:
- append = (' You may have forgotten to return a value from '
- 'the view callable.')
- elif isinstance(result, dict):
- append = (' You may have forgotten to define a renderer in '
- 'the view configuration.')
- else:
- append = ''
- msg = ('Could not convert return value of the view callable %s '
- 'into a response object. '
- 'The value returned was %r.' + append)
-
- raise ValueError(msg % (view_description(view), result))
+ if result.__class__ is Response: # common case
+ response = result
+ else:
+ response = registry.queryAdapterOrSelf(result, IResponse)
+ if response is None:
+ if result is None:
+ append = (' You may have forgotten to return a value '
+ 'from the view callable.')
+ elif isinstance(result, dict):
+ append = (' You may have forgotten to define a '
+ 'renderer in the view configuration.')
+ else:
+ append = ''
+
+ msg = ('Could not convert return value of the view '
+ 'callable %s into a response object. '
+ 'The value returned was %r.' + append)
+
+ raise ValueError(msg % (view_description(view), result))
+
return response
return viewresult_to_response
diff --git a/pyramid/request.py b/pyramid/request.py
index 9e275c2c0..27ab337de 100644
--- a/pyramid/request.py
+++ b/pyramid/request.py
@@ -372,6 +372,8 @@ class Request(BaseRequest, DeprecatedRequestMethodsMixin, URLMethodsMixin,
def is_response(self, ob):
""" Return ``True`` if the object passed as ``ob`` is a valid
response object, ``False`` otherwise."""
+ if ob.__class__ is Response:
+ return True
registry = self.registry
adapted = registry.queryAdapterOrSelf(ob, IResponse)
if adapted is None:
diff --git a/pyramid/router.py b/pyramid/router.py
index 0c7f61071..9b6138ea9 100644
--- a/pyramid/router.py
+++ b/pyramid/router.py
@@ -103,7 +103,7 @@ class Router(object):
request.path_info,
route.pattern,
match,
- ', '.join([p.__text__ for p in route.predicates]))
+ ', '.join([p.text() for p in route.predicates]))
)
logger and logger.debug(msg)
diff --git a/pyramid/scripts/pviews.py b/pyramid/scripts/pviews.py
index 1bb4f2227..081c13e9d 100644
--- a/pyramid/scripts/pviews.py
+++ b/pyramid/scripts/pviews.py
@@ -188,7 +188,7 @@ class PViewsCommand(object):
self.out("%sroute pattern: %s" % (indent, route.pattern))
self.out("%sroute path: %s" % (indent, route.path))
self.out("%ssubpath: %s" % (indent, '/'.join(attrs['subpath'])))
- predicates = ', '.join([p.__text__ for p in route.predicates])
+ predicates = ', '.join([p.text() for p in route.predicates])
if predicates != '':
self.out("%sroute predicates (%s)" % (indent, predicates))
diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py
index 8324eb2b9..bb4c5d519 100644
--- a/pyramid/tests/test_config/test_views.py
+++ b/pyramid/tests/test_config/test_views.py
@@ -2483,6 +2483,29 @@ class TestViewDeriver(unittest.TestCase):
else: # pragma: no cover
raise AssertionError
+ def test_function_returns_true_Response_no_renderer(self):
+ from pyramid.response import Response
+ r = Response('Hello')
+ def view(request):
+ return r
+ deriver = self._makeOne()
+ result = deriver(view)
+ self.assertFalse(result is view)
+ response = result(None, None)
+ self.assertEqual(response, r)
+
+ def test_function_returns_true_Response_with_renderer(self):
+ from pyramid.response import Response
+ r = Response('Hello')
+ def view(request):
+ return r
+ renderer = object()
+ deriver = self._makeOne(renderer=renderer)
+ result = deriver(view)
+ self.assertFalse(result is view)
+ response = result(None, None)
+ self.assertEqual(response, r)
+
def test_requestonly_default_method_returns_non_adaptable(self):
request = DummyRequest()
class AView(object):
diff --git a/pyramid/tests/test_request.py b/pyramid/tests/test_request.py
index 945e36a7f..565c6377e 100644
--- a/pyramid/tests/test_request.py
+++ b/pyramid/tests/test_request.py
@@ -230,6 +230,13 @@ class TestRequest(unittest.TestCase):
request.registry = self.config.registry
self.assertEqual(request.is_response('abc'), False)
+ def test_is_response_true_ob_is_pyramid_response(self):
+ from pyramid.response import Response
+ r = Response('hello')
+ request = self._makeOne()
+ request.registry = self.config.registry
+ self.assertEqual(request.is_response(r), True)
+
def test_is_response_false_adapter_is_not_self(self):
from pyramid.interfaces import IResponse
request = self._makeOne()
diff --git a/pyramid/tests/test_router.py b/pyramid/tests/test_router.py
index 778b27473..65152ca05 100644
--- a/pyramid/tests/test_router.py
+++ b/pyramid/tests/test_router.py
@@ -24,7 +24,7 @@ class TestRouter(unittest.TestCase):
if mapper is None:
mapper = RoutesMapper()
self.registry.registerUtility(mapper, IRoutesMapper)
- mapper.connect(name, path, factory)
+ return mapper.connect(name, path, factory)
def _registerLogger(self):
from pyramid.interfaces import IDebugLogger
@@ -657,7 +657,8 @@ class TestRouter(unittest.TestCase):
root = object()
def factory(request):
return root
- self._connectRoute('foo', 'archives/:action/:article', factory)
+ route = self._connectRoute('foo', 'archives/:action/:article', factory)
+ route.predicates = [DummyPredicate()]
context = DummyContext()
self._registerTraverserFactory(context)
response = DummyResponse()
@@ -686,7 +687,11 @@ class TestRouter(unittest.TestCase):
"route matched for url http://localhost:8080"
"/archives/action1/article1; "
"route_name: 'foo', "
- "path_info: "))
+ "path_info: ")
+ )
+ self.assertTrue(
+ "predicates: 'predicate'" in logger.messages[0]
+ )
def test_call_route_match_miss_debug_routematch(self):
from pyramid.httpexceptions import HTTPNotFound
@@ -1159,6 +1164,12 @@ class TestRouter(unittest.TestCase):
start_response = DummyStartResponse()
self.assertRaises(RuntimeError, router, environ, start_response)
+class DummyPredicate(object):
+ def __call__(self, info, request):
+ return True
+ def text(self):
+ return 'predicate'
+
class DummyContext:
pass
diff --git a/pyramid/tests/test_scripts/test_pviews.py b/pyramid/tests/test_scripts/test_pviews.py
index 6a919c31b..266d1ec90 100644
--- a/pyramid/tests/test_scripts/test_pviews.py
+++ b/pyramid/tests/test_scripts/test_pviews.py
@@ -379,7 +379,7 @@ class TestPViewsCommand(unittest.TestCase):
L = []
command.out = L.append
def predicate(): pass
- predicate.__text__ = "predicate = x"
+ predicate.text = lambda *arg: "predicate = x"
route = dummy.DummyRoute('a', '/a', matchdict={}, predicate=predicate)
view = dummy.DummyView(context='context', view_name='a',
matched_route=route, subpath='')
diff --git a/setup.py b/setup.py
index 4ea63a3ee..2356e76ac 100644
--- a/setup.py
+++ b/setup.py
@@ -68,7 +68,7 @@ testing_extras = tests_require + [
]
setup(name='pyramid',
- version='1.4a3',
+ version='1.4a4',
description=('The Pyramid web application development framework, a '
'Pylons project'),
long_description=README + '\n\n' + CHANGES,